game: Added player actions

This commit is contained in:
Nathan Woodburn 2023-05-01 14:32:22 +10:00
parent 3307b01bf2
commit c37ee0c5f7
Signed by: nathanwoodburn
GPG Key ID: 203B000478AD0EF1
5 changed files with 203 additions and 18 deletions

View File

@ -307,7 +307,6 @@ public class BlueLagoon {
!isAdjacent(moveCoords, playerVillageCoords)) return false; !isAdjacent(moveCoords, playerVillageCoords)) return false;
} }
} }
System.out.println(coordsContainer);
return true; return true;
} }

View File

@ -20,6 +20,7 @@ public class Player {
private int numStatuette; private int numStatuette;
private Coord[] settlers; private Coord[] settlers;
private Coord[] villages; private Coord[] villages;
private Coord lastMove;
/** /**
* Constructor for Player class * Constructor for Player class
@ -36,6 +37,7 @@ public class Player {
this.numStatuette = 0; this.numStatuette = 0;
this.settlers = new Coord[0]; this.settlers = new Coord[0];
this.villages = new Coord[0]; this.villages = new Coord[0];
lastMove = new Coord(-1, -1);
} }
// endregion // endregion
// region Getters and Setters // region Getters and Setters
@ -151,6 +153,7 @@ public class Player {
} }
newSettlers[settlers.length] = coord; newSettlers[settlers.length] = coord;
settlers = newSettlers; settlers = newSettlers;
lastMove = coord;
} }
/** /**
@ -169,6 +172,7 @@ public class Player {
} }
newVillages[villages.length] = coord; newVillages[villages.length] = coord;
villages = newVillages; villages = newVillages;
lastMove = coord;
} }
/** /**
@ -224,6 +228,10 @@ public class Player {
return numPieces; return numPieces;
} }
public Coord getLastMove() {
return lastMove;
}
// endregion // endregion
/** /**
@ -259,6 +267,7 @@ public class Player {
int x = Integer.parseInt(coordStr.split(",")[0]); int x = Integer.parseInt(coordStr.split(",")[0]);
int y = Integer.parseInt(coordStr.split(",")[1]); int y = Integer.parseInt(coordStr.split(",")[1]);
Coord coord = new Coord(x, y); Coord coord = new Coord(x, y);
lastMove = coord;
state.placePiece(coord, pieceType); state.placePiece(coord, pieceType);
state.nextPlayer(); state.nextPlayer();
return; return;
@ -309,6 +318,7 @@ public class Player {
int x = Integer.parseInt(coordStr.split(",")[0]); int x = Integer.parseInt(coordStr.split(",")[0]);
int y = Integer.parseInt(coordStr.split(",")[1]); int y = Integer.parseInt(coordStr.split(",")[1]);
Coord coord = new Coord(x, y); Coord coord = new Coord(x, y);
lastMove = coord;
state.placePiece(coord, pieceType); state.placePiece(coord, pieceType);
state.nextPlayer(); state.nextPlayer();
} }

View File

@ -30,6 +30,27 @@ public class Resource {
return type; return type;
} }
/**
* Get the type of the resource
* @return String type of the resource
*/
public String getTypeString() {
switch (type){
case 'C':
return "Coconut";
case 'B':
return "Bamboo";
case 'W':
return "Water";
case 'P':
return "Precious Stone";
case 'S':
return "Statuette";
default:
return "Invalid";
}
}
/** /**
* Get the coordinate of the resource * Get the coordinate of the resource
* @return Coord coordinate of the resource * @return Coord coordinate of the resource

View File

@ -394,6 +394,18 @@ public class State {
} }
} }
/**
* Is move valid?
* @param coord Coord coordinate to place piece
* @param type char type of piece
* @return boolean true if move is valid
*/
public boolean isMoveValid(Coord coord, char type){
// Create moveString
String moveString = type + " " + coord.toString();
return BlueLagoon.isMoveValid(this.toString(), moveString);
}
/** /**
* is the phase over? * is the phase over?
* Defaults to simple mode * Defaults to simple mode

View File

@ -1,9 +1,6 @@
package comp1110.ass2.gui; package comp1110.ass2.gui;
import comp1110.ass2.Coord; import comp1110.ass2.*;
import comp1110.ass2.Island;
import comp1110.ass2.Player;
import comp1110.ass2.State;
import javafx.application.Application; import javafx.application.Application;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
@ -22,8 +19,6 @@ import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment; import javafx.scene.text.TextAlignment;
import javafx.stage.Stage; import javafx.stage.Stage;
// FIXME Task 14
// FIXME Task 15
public class Game extends Application { public class Game extends Application {
// region Variables // region Variables
@ -35,13 +30,18 @@ public class Game extends Application {
State currentGame; State currentGame;
String message; String message;
Boolean messageError;
Coord selectedTile;
// endregion // endregion
@Override @Override
public void start(Stage stage) throws Exception { public void start(Stage stage) throws Exception {
selectedTile = new Coord(-1,-1);
message = "Waiting for Move..."; message = "Waiting for Move...";
messageError = false;
Scene scene = new Scene(this.root, WINDOW_WIDTH, WINDOW_HEIGHT); Scene scene = new Scene(this.root, WINDOW_WIDTH, WINDOW_HEIGHT);
// From Viewer // From Viewer
@ -68,6 +68,8 @@ public class Game extends Application {
Button threePlayer = new Button("3 Player"); Button threePlayer = new Button("3 Player");
Button fourPlayer = new Button("4 Player"); Button fourPlayer = new Button("4 Player");
Button AIMove = new Button("AI Move"); Button AIMove = new Button("AI Move");
Button placeVillage = new Button("Place Village");
Button placeSettler = new Button("Place Settler");
twoPlayer.setOnAction(new EventHandler<ActionEvent>() { twoPlayer.setOnAction(new EventHandler<ActionEvent>() {
@ -96,8 +98,22 @@ public class Game extends Application {
} }
}); });
placeVillage.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
doMove(1);
}
});
placeSettler.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
doMove(0);
}
});
HBox hb = new HBox(); HBox hb = new HBox();
hb.getChildren().addAll(newLabel, twoPlayer,threePlayer,fourPlayer,AIMove); hb.getChildren().addAll(newLabel, twoPlayer,threePlayer,fourPlayer,AIMove,placeVillage,placeSettler);
hb.setSpacing(10); hb.setSpacing(10);
hb.setLayoutX(50); hb.setLayoutX(50);
hb.setLayoutY(WINDOW_HEIGHT - 50); hb.setLayoutY(WINDOW_HEIGHT - 50);
@ -129,15 +145,66 @@ public class Game extends Application {
// region Game Play // region Game Play
void doMove(){ /**
* Do a move of the given type
* @param type the type of move 0 = place settler, 1 = place village
*/
void doMove(int type){
if (selectedTile.equals(new Coord(-1,-1))){
sendMessage("No tile selected");
return;
} }
void doAIMove(){
if (!currentGame.isPhaseOver()){
currentGame.getCurrentPlayer().doAIMove(currentGame);
if (currentGame.isPhaseOver()){ if (currentGame.isPhaseOver()){
sendMessage("Phase is over"); sendMessage("Phase is over");
return;
}
else {
char typeC = 'S';
if (type == 1){
typeC = 'T';
}
if (currentGame.isMoveValid(selectedTile,typeC)){
currentGame.placePiece(selectedTile,typeC);
Player player = currentGame.getCurrentPlayer();
Coord lastMove = player.getLastMove();
if (currentGame.isStone(lastMove)){
for (Resource resource : currentGame.getResources()) {
if (resource.getCoord().equals(lastMove) ) {
sendMessage("Player " + player.getPlayerID() +" picked up a " + resource.getTypeString().toLowerCase());
}
}
}
currentGame.nextPlayer();
selectedTile = new Coord(-1,-1);
}
else {
sendMessage("Invalid move",true);
}
}
refresh();
}
/**
* Do an AI move for the current player
*/
void doAIMove(){
if (!currentGame.isPhaseOver()){
Player player = currentGame.getCurrentPlayer();
player.doAIMove(currentGame);
if (currentGame.isPhaseOver()){
sendMessage("Phase is over");
}
if (!player.getLastMove().equals(new Coord(-1,-1))){
Coord lastMove = player.getLastMove();
if (currentGame.isStone(lastMove)){
for (Resource resource : currentGame.getResources()) {
if (resource.getCoord().equals(lastMove) ) {
sendMessage("Player " + player.getPlayerID() +" picked up a " + resource.getTypeString().toLowerCase());
}
}
}
} }
refresh(); refresh();
} }
@ -149,14 +216,34 @@ public class Game extends Application {
// region HID // region HID
/**
* Send a message to the user without error
* @param message the message to send
*/
void sendMessage(String message){ void sendMessage(String message){
sendMessage(message, false); sendMessage(message, false);
} }
/**
* Send a message to the user
* @param message the message to send
* @param error if the message is an error
*/
void sendMessage(String message, boolean error){ void sendMessage(String message, boolean error){
this.message = message; this.message = message;
messageError = error;
refresh(); refresh();
} }
void tileClick(String coordString){
int y = Integer.parseInt(coordString.split(",")[0]);
int x = Integer.parseInt(coordString.split(",")[1]);
selectedTile = new Coord(y,x);
sendMessage("Tile " + selectedTile.toString() + " selected");
refresh();
}
// endregion // endregion
@ -171,11 +258,17 @@ public class Game extends Application {
messageLabel.setLayoutX(50); messageLabel.setLayoutX(50);
messageLabel.setLayoutY(50); messageLabel.setLayoutY(50);
messageLabel.setFont(Font.font("Sans Serif",FontWeight.BOLD, 20)); messageLabel.setFont(Font.font("Sans Serif",FontWeight.BOLD, 20));
if (messageError){
messageLabel.setTextFill(Color.RED);
}
else {
messageLabel.setTextFill(Color.BLACK);
}
root.getChildren().add(messageLabel); root.getChildren().add(messageLabel);
// Intizialiation of the grid // Intizialiation of the grid
GridPane viewerGrid = new GridPane(); GridPane viewerGrid = new GridPane();
String[] parts = currentGame.toString().split("; ?");
int boardHeight = 0; int boardHeight = 0;
int boardHeightPx = 0; int boardHeightPx = 0;
int tileSize = 0; int tileSize = 0;
@ -273,9 +366,13 @@ public class Game extends Application {
viewerGrid.relocate((WINDOW_WIDTH/2-viewerGrid.getPrefWidth()/2), ((WINDOW_HEIGHT+100)/2-viewerGrid.getPrefHeight()/2)); viewerGrid.relocate((WINDOW_WIDTH/2-viewerGrid.getPrefWidth()/2), ((WINDOW_HEIGHT+100)/2-viewerGrid.getPrefHeight()/2));
root.getChildren().add(viewerGrid); root.getChildren().add(viewerGrid);
// Add selected tile
if (!selectedTile.equals(new Coord(-1,-1))){
addTileSelector(viewerGrid, tileSize, selectedTile.toString());
}
// Move buttons to front // Move buttons to front
controls.toFront(); controls.toFront();
} }
// Generating the big board tiles such as the water tiles and the island tiles // Generating the big board tiles such as the water tiles and the island tiles
@ -292,6 +389,12 @@ public class Game extends Application {
// Translate the whole tile's Y axis downwards so they connect and there's no gap // Translate the whole tile's Y axis downwards so they connect and there's no gap
hex.setTranslateY(Integer.parseInt(coords[0]) * -0.25 * tileSize); hex.setTranslateY(Integer.parseInt(coords[0]) * -0.25 * tileSize);
board.add(hex, Integer.parseInt(coords[1]), Integer.parseInt(coords[0])); board.add(hex, Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
// Add a mouse click event to the tile
hex.setOnMouseClicked(event -> {
tileClick(coordString);
});
} }
// Generating the small tiles such as resources, stones, etc // Generating the small tiles such as resources, stones, etc
@ -312,6 +415,11 @@ public class Game extends Application {
// Translate the tile so they look center // Translate the tile so they look center
hex.setTranslateX(7 + hex.getTranslateX()); hex.setTranslateX(7 + hex.getTranslateX());
board.add(hex, Integer.parseInt(coords[1]), Integer.parseInt(coords[0])); board.add(hex, Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
// Add a mouse click event to the tile
hex.setOnMouseClicked(event -> {
tileClick(coordString);
});
} }
void addTileToBoard(GridPane board, int tileSize, String coordString, Color color) { void addTileToBoard(GridPane board, int tileSize, String coordString, Color color) {
@ -331,6 +439,11 @@ public class Game extends Application {
// Translate the tile so they look center // Translate the tile so they look center
hex.setTranslateX(12 + hex.getTranslateX()); hex.setTranslateX(12 + hex.getTranslateX());
board.add(hex, Integer.parseInt(coords[1]), Integer.parseInt(coords[0])); board.add(hex, Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
// Add a mouse click event to the tile
hex.setOnMouseClicked(event -> {
tileClick(coordString);
});
} }
// Adding labels to the resources tiles and stones tiles // Adding labels to the resources tiles and stones tiles
@ -349,6 +462,11 @@ public class Game extends Application {
// Making the label center // Making the label center
newLabel.setTranslateX(19.5 + newLabel.getTranslateX()); newLabel.setTranslateX(19.5 + newLabel.getTranslateX());
board.add(newLabel, Integer.parseInt(coords[1]), Integer.parseInt(coords[0])); board.add(newLabel, Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
// Add a mouse click event to the tile
newLabel.setOnMouseClicked(event -> {
tileClick(coordString);
});
} }
// Adding labels to the villagers and settlers // Adding labels to the villagers and settlers
@ -367,6 +485,31 @@ public class Game extends Application {
// Making the label center // Making the label center
newLabel.setTranslateX(11 + newLabel.getTranslateX()); newLabel.setTranslateX(11 + newLabel.getTranslateX());
board.add(newLabel, Integer.parseInt(coords[1]), Integer.parseInt(coords[0])); board.add(newLabel, Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
// Add a mouse click event to the tile
newLabel.setOnMouseClicked(event -> {
tileClick(coordString);
});
}
void addTileSelector(GridPane board, int tileSize, String coordString){
// If the string empty, stop the function
if (coordString.equals("")) return;
String[] coords = coordString.split(",");
Label newLabel = new Label("X");
newLabel.setFont(Font.font("Sans Serif", 20));
// Following the tile's pos format
if (Integer.parseInt(coords[0]) % 2 == 0) newLabel.setTranslateX(tileSize/2);
newLabel.setTranslateY(Integer.parseInt(coords[0]) * -0.25 * tileSize);
// Making the label center
newLabel.setTranslateX(17 + newLabel.getTranslateX());
newLabel.setTextFill(Color.RED);
board.add(newLabel, Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
// Add a mouse click event to the tile
newLabel.setOnMouseClicked(event -> {
tileClick(coordString);
});
} }
// A hexagon nested class shape // A hexagon nested class shape