state: Added more functionality
This commit is contained in:
parent
7ed595dced
commit
2179ba5eaa
@ -65,6 +65,6 @@ public class Coord {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "(" + x + ", " + y + ")";
|
return x + "," + y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,4 +79,13 @@ public class Island {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String str = "i " + this.bonus;
|
||||||
|
for (Coord c : this.coords) {
|
||||||
|
str += " " + c.toString();
|
||||||
|
}
|
||||||
|
return str + ";";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,4 +200,47 @@ public class Player {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the player's piece's coords
|
||||||
|
* @return coord[] list of all the player's piece's coords
|
||||||
|
*/
|
||||||
|
public Coord[] getPieces() {
|
||||||
|
Coord[] pieces = new Coord[settlers.length + villages.length];
|
||||||
|
for (int i = 0; i < settlers.length; i++) {
|
||||||
|
pieces[i] = settlers[i];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < villages.length; i++) {
|
||||||
|
pieces[settlers.length + i] = villages[i];
|
||||||
|
}
|
||||||
|
return pieces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get number of pieces on island
|
||||||
|
* @param island Island island to check
|
||||||
|
* @return int number of pieces on island
|
||||||
|
*/
|
||||||
|
public int getNumPiecesOnIsland(Island island) {
|
||||||
|
int numPieces = 0;
|
||||||
|
for (Coord piece : getPieces()) {
|
||||||
|
if (island.containsCoord(piece)) {
|
||||||
|
numPieces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numPieces;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String str = "p " + playerID + " " + score + " " + numCoconuts + " " + numBamboo + " " + numWater + " " + numPreciousStones + " " + numStatuette + " S";
|
||||||
|
for (Coord coord : settlers) {
|
||||||
|
str += " " + coord.toString();
|
||||||
|
}
|
||||||
|
str += " T";
|
||||||
|
for (Coord coord : villages) {
|
||||||
|
str += " " + coord.toString();
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package comp1110.ass2;
|
|||||||
public class Resource {
|
public class Resource {
|
||||||
private char type;
|
private char type;
|
||||||
private Coord coord;
|
private Coord coord;
|
||||||
|
private boolean claimed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for Resource class
|
* Constructor for Resource class
|
||||||
@ -18,6 +19,7 @@ public class Resource {
|
|||||||
public Resource(char type, Coord coord) {
|
public Resource(char type, Coord coord) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.coord = coord;
|
this.coord = coord;
|
||||||
|
this.claimed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,4 +63,28 @@ public class Resource {
|
|||||||
return (this.type == resource.type && this.coord.equals(resource.coord));
|
return (this.type == resource.type && this.coord.equals(resource.coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the resource to be claimed
|
||||||
|
* This is used to check if the resource has been claimed
|
||||||
|
*/
|
||||||
|
public void setClaimed() {
|
||||||
|
this.claimed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the resource has been claimed
|
||||||
|
* @return boolean true if the resource has been claimed
|
||||||
|
*/
|
||||||
|
public boolean isClaimed() {
|
||||||
|
return this.claimed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Resource{" +
|
||||||
|
"type=" + type +
|
||||||
|
", coord=" + coord +
|
||||||
|
", claimed=" + claimed +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package comp1110.ass2;
|
package comp1110.ass2;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to store the game state
|
* Object to store the game state
|
||||||
* This stores the state of the game in a way that is easy to access and modify
|
* This stores the state of the game in a way that is easy to access and modify
|
||||||
@ -8,6 +12,8 @@ package comp1110.ass2;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class State {
|
public class State {
|
||||||
|
|
||||||
|
// region Variables
|
||||||
final int boardHeight;
|
final int boardHeight;
|
||||||
private int numPlayers;
|
private int numPlayers;
|
||||||
private int currentPlayer;
|
private int currentPlayer;
|
||||||
@ -15,15 +21,20 @@ public class State {
|
|||||||
|
|
||||||
private Island[] islands;
|
private Island[] islands;
|
||||||
private Coord[] stonesCoords;
|
private Coord[] stonesCoords;
|
||||||
private Resource[] unclaimedResources;
|
private Resource[] resources;
|
||||||
private Player[] players;
|
private Player[] players;
|
||||||
|
|
||||||
|
private boolean distributedResources;
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Setup methods/constructors
|
||||||
/**
|
/**
|
||||||
* Constructor for the state object
|
* Constructor for the state object
|
||||||
* This takes a string containing the state of the game and initialises the object
|
* This takes a string containing the state of the game and initialises the object
|
||||||
* @param stateString String containing the state of the game
|
* @param stateString String containing the state of the game
|
||||||
*/
|
*/
|
||||||
public State(String stateString) {
|
public State(String stateString) {
|
||||||
|
distributedResources = false;
|
||||||
|
|
||||||
// Split the state string into its components
|
// Split the state string into its components
|
||||||
String[] components = stateString.split(";");
|
String[] components = stateString.split(";");
|
||||||
@ -81,21 +92,22 @@ public class State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unclaimed resources part
|
// Unclaimed resources part
|
||||||
String[] unclaimedResourcesComponents = components[3+islandcount].trim().split(" ");
|
String[] resourcesComponents = components[3+islandcount].trim().split(" ");
|
||||||
unclaimedResources = new Resource[unclaimedResourcesComponents.length-1];
|
resources = new Resource[resourcesComponents.length-6];
|
||||||
int currentResource = 0;
|
int currentResource = 0;
|
||||||
char type = 'C';
|
char type = 'C';
|
||||||
for (int i=1; i<unclaimedResourcesComponents.length; i++)
|
for (int i=1; i<resourcesComponents.length; i++)
|
||||||
{
|
{
|
||||||
if (unclaimedResourcesComponents[i].matches("[CBWPS]")){
|
if (resourcesComponents[i].matches("[CBWPS]")){
|
||||||
currentResource++;
|
currentResource++;
|
||||||
type = unclaimedResourcesComponents[i].charAt(0);
|
type = resourcesComponents[i].charAt(0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] coordComponents = unclaimedResourcesComponents[i].split(",");
|
distributedResources = true;
|
||||||
|
String[] coordComponents = resourcesComponents[i].split(",");
|
||||||
Coord tmpCoord = new Coord(Integer.parseInt(coordComponents[0]), Integer.parseInt(coordComponents[1]));
|
Coord tmpCoord = new Coord(Integer.parseInt(coordComponents[0]), Integer.parseInt(coordComponents[1]));
|
||||||
unclaimedResources[i-1-currentResource] = new Resource(type, tmpCoord);
|
resources[i-1-currentResource] = new Resource(type, tmpCoord);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Players part
|
// Players part
|
||||||
@ -131,6 +143,74 @@ public class State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void distributeResources() {
|
||||||
|
// Do some checks
|
||||||
|
if (distributedResources) return; // Resources have already been distributed
|
||||||
|
if (stonesCoords.length != 32) return; // There are not enough stones to distribute resources
|
||||||
|
|
||||||
|
|
||||||
|
// Create a random object and an arrays and list to shuffle the stone circles
|
||||||
|
Random rand = new Random();
|
||||||
|
|
||||||
|
// Number of times to shuffle the stone circles (can be changed)
|
||||||
|
int shuffle_number = 3;
|
||||||
|
|
||||||
|
// Create a copy of the stone circle array to shuffle
|
||||||
|
Coord[] stoneCircleRandom = stonesCoords;
|
||||||
|
|
||||||
|
// Shuffle the stone circles the specified number of times
|
||||||
|
for (int i = 0; i < shuffle_number; i++) {
|
||||||
|
// Create a temporary array to store the shuffled stone circles
|
||||||
|
Coord[] tempStoneCircleRandom = new Coord[32];
|
||||||
|
// Create a list to store the used cords (to avoid duplicates)
|
||||||
|
List<Coord> usedCords = new ArrayList<Coord>();
|
||||||
|
|
||||||
|
// Shuffle the array
|
||||||
|
for (int j = 0; j < 32; j++) {
|
||||||
|
// For 0-31 generate a random cord from the stone circle array and check if it has been used
|
||||||
|
int randomIndex = rand.nextInt(31);
|
||||||
|
while (usedCords.contains(stonesCoords[randomIndex])) {
|
||||||
|
// If it has been used, try the next in line
|
||||||
|
if (randomIndex == 31) {
|
||||||
|
randomIndex = 0;
|
||||||
|
}
|
||||||
|
else randomIndex++;
|
||||||
|
}
|
||||||
|
// If it hasn't been used, add it to the new array
|
||||||
|
tempStoneCircleRandom[j] = stoneCircleRandom[randomIndex];
|
||||||
|
usedCords.add(stonesCoords[randomIndex]);
|
||||||
|
}
|
||||||
|
// Replace the old array with the new one
|
||||||
|
stoneCircleRandom = tempStoneCircleRandom;
|
||||||
|
}
|
||||||
|
// Initialise unclaimed resources
|
||||||
|
resources = new Resource[32];
|
||||||
|
|
||||||
|
// Create an array for each resource type
|
||||||
|
char[] toDistribute = {'C', 'B', 'W', 'P'};
|
||||||
|
|
||||||
|
// Create a variable to keep track of how many resources have been sorted
|
||||||
|
int numSorted = 0;
|
||||||
|
|
||||||
|
// For each resource type
|
||||||
|
for (char r:toDistribute){
|
||||||
|
// Assign 6 to a stone circle
|
||||||
|
for (int i = 0; i < 6; i++){
|
||||||
|
resources[numSorted] = new Resource(r, stoneCircleRandom[numSorted]);
|
||||||
|
numSorted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign 8 statuettes to a stone circle
|
||||||
|
for (int i = 0; i < 8; i++){
|
||||||
|
resources[numSorted] = new Resource('S', stoneCircleRandom[numSorted]);
|
||||||
|
numSorted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Getters/Setters
|
||||||
/**
|
/**
|
||||||
* Get the board height
|
* Get the board height
|
||||||
* @return int board height
|
* @return int board height
|
||||||
@ -199,6 +279,11 @@ public class State {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player with a given index
|
||||||
|
* @param i int index of player
|
||||||
|
* @return Player player
|
||||||
|
*/
|
||||||
public Player getPlayer(int i) {
|
public Player getPlayer(int i) {
|
||||||
return players[i];
|
return players[i];
|
||||||
}
|
}
|
||||||
@ -207,8 +292,8 @@ public class State {
|
|||||||
* Get the unclaimed resources
|
* Get the unclaimed resources
|
||||||
* @return Resource[] unclaimed resources
|
* @return Resource[] unclaimed resources
|
||||||
*/
|
*/
|
||||||
public Resource[] getUnclaimedResources() {
|
public Resource[] getResources() {
|
||||||
return unclaimedResources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,10 +301,10 @@ public class State {
|
|||||||
* @param type char type of resource
|
* @param type char type of resource
|
||||||
* @return Resource[] unclaimed resources of type
|
* @return Resource[] unclaimed resources of type
|
||||||
*/
|
*/
|
||||||
public Resource[] getUnclaimedResources(char type) {
|
public Resource[] getResources(char type) {
|
||||||
Resource[] tmpResources = new Resource[unclaimedResources.length];
|
Resource[] tmpResources = new Resource[resources.length];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Resource resource : unclaimedResources) {
|
for (Resource resource : resources) {
|
||||||
if (resource.getType() == type){
|
if (resource.getType() == type){
|
||||||
tmpResources[i] = resource;
|
tmpResources[i] = resource;
|
||||||
i++;
|
i++;
|
||||||
@ -231,4 +316,182 @@ public class State {
|
|||||||
}
|
}
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unclaimed resource at a given coordinate
|
||||||
|
* @param coord Coord coordinate to check
|
||||||
|
* @return Resource unclaimed resource at coordinate
|
||||||
|
*/
|
||||||
|
public Resource getUnclaimedResource(Coord coord) {
|
||||||
|
for (Resource resource : resources) {
|
||||||
|
if (resource.getCoord().equals(coord)) return resource;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Game play functions
|
||||||
|
/**
|
||||||
|
* Start next player's turn
|
||||||
|
*/
|
||||||
|
public void nextPlayer() {
|
||||||
|
currentPlayer++;
|
||||||
|
if (currentPlayer >= numPlayers) currentPlayer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start next phase.
|
||||||
|
* This handles changing the current player and scoring
|
||||||
|
*/
|
||||||
|
public void nextPhase() {
|
||||||
|
currentPhase++;
|
||||||
|
if (currentPhase > 1) currentPhase = 0;
|
||||||
|
nextPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place a piece on the board. Uses current turn's player
|
||||||
|
* @param coord Coord coordinate to place piece
|
||||||
|
* @param type char type of piece
|
||||||
|
*/
|
||||||
|
public void placePiece(Coord coord, char type) {
|
||||||
|
if (type == 'S') {
|
||||||
|
players[currentPlayer].addSettler(coord);
|
||||||
|
}
|
||||||
|
else if (type == 'V' || type == 'T') {
|
||||||
|
players[currentPlayer].addVillage(coord);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Claim resource if it is a stone circle
|
||||||
|
if (isStone(coord)) {
|
||||||
|
for (Resource resource : resources) {
|
||||||
|
if (resource.getCoord().equals(coord) && !resource.isClaimed()) {
|
||||||
|
players[currentPlayer].addResource(1, resource.getType());
|
||||||
|
resource.setClaimed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Scoring
|
||||||
|
/**
|
||||||
|
* Get score of player ID based on current phase and game state
|
||||||
|
* @param playerID int player ID base 0
|
||||||
|
* @return int score
|
||||||
|
*/
|
||||||
|
public int createScore(int playerID) {
|
||||||
|
int score = 0;
|
||||||
|
if (getCurrentPhase() == 'E') {
|
||||||
|
// Score exploration phase
|
||||||
|
score += scoreTotalIslands(playerID);
|
||||||
|
score += scoreMajorities(playerID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get score from total islands
|
||||||
|
* @param playerID int player to score
|
||||||
|
* @return int score
|
||||||
|
*/
|
||||||
|
public int scoreTotalIslands(int playerID) {
|
||||||
|
int score = 0;
|
||||||
|
int islandCount = 0;
|
||||||
|
for (Island island : islands) {
|
||||||
|
// Get island coords
|
||||||
|
Coord[] islandCoords = island.getCoords();
|
||||||
|
// Get player's coords
|
||||||
|
Coord[] playerCoords = players[playerID].getPieces();
|
||||||
|
// Check if player has a piece on the island
|
||||||
|
boolean hasPiece = false;
|
||||||
|
for (Coord playerCoord : playerCoords) {
|
||||||
|
for (Coord islandCoord : islandCoords) {
|
||||||
|
if (playerCoord.equals(islandCoord)) {
|
||||||
|
hasPiece = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasPiece) break;
|
||||||
|
}
|
||||||
|
if (hasPiece) islandCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (islandCount >= 8) score = 20;
|
||||||
|
else if (islandCount == 7) score = 10;
|
||||||
|
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Score majorities
|
||||||
|
* @param playerID int player to score
|
||||||
|
* @return int score
|
||||||
|
*/
|
||||||
|
public int scoreMajorities(int playerID){
|
||||||
|
int score = 0;
|
||||||
|
|
||||||
|
for (Island island:islands){
|
||||||
|
int[] playerPieces = new int[getNumPlayers()];
|
||||||
|
|
||||||
|
for (int i = 0; i < getNumPlayers()-1; i++){
|
||||||
|
playerPieces[i] = players[i].getNumPiecesOnIsland(island);
|
||||||
|
}
|
||||||
|
boolean ishighest = true;
|
||||||
|
int ties = 0;
|
||||||
|
for (int i = 0; i < getNumPlayers(); i++){
|
||||||
|
if (i == playerID) continue;
|
||||||
|
if (playerPieces[i] > playerPieces[playerID]) {
|
||||||
|
ishighest = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (playerPieces[i] == playerPieces[playerID]) ties++;
|
||||||
|
}
|
||||||
|
if (ishighest) {
|
||||||
|
if (ties > 0){
|
||||||
|
score += island.getBonus()/(ties + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
score += island.getBonus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String str = "a " + boardHeight + " " + getNumPlayers() + "; c " + getCurrentPlayer() + " " + getCurrentPhase() + "; ";
|
||||||
|
for (Island island : islands) {
|
||||||
|
str += island.toString() + " ";
|
||||||
|
}
|
||||||
|
str += "s";
|
||||||
|
for (Coord s: stonesCoords) {
|
||||||
|
str += " " + s.toString();
|
||||||
|
}
|
||||||
|
str += "; r";
|
||||||
|
|
||||||
|
char[] types = {'C', 'B', 'W', 'P', 'S'};
|
||||||
|
for (char type : types) {
|
||||||
|
str += " " + type;
|
||||||
|
for (Resource resource : resources) {
|
||||||
|
if (resource.getType() == type) str += " " + resource.getCoord().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str += ";";
|
||||||
|
for (Player player : players) {
|
||||||
|
str += " " + player.toString() + ";";
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user