Coverage Summary for Class: Board (it.polimi.ingsw.model)
Class |
Class, %
|
Method, %
|
Line, %
|
Board |
100%
(1/1)
|
100%
(17/17)
|
100%
(107/107)
|
package it.polimi.ingsw.model;
import it.polimi.ingsw.controller.Initializer;
import java.io.Serializable;
import java.util.*;
import static it.polimi.ingsw.model.Color.*;
/**
* class which represent the common board where the players choose the cards. Mutable
* @author Ettori Faccincani
*
*/
public class Board implements Serializable {
private final int DIM = 9;
private final Card[][] gameBoard = new Card[DIM][DIM];
/** the first common objective */
public CommonObjective commonObjective_1;
/** the second common objective */
public CommonObjective commonObjective_2;
/** the points available for the first common objective */
public LinkedList<Integer> pointsCO_1;
/** the points available for the second common objective */
public LinkedList<Integer> pointsCO_2;
private ArrayList<Card> bucketOfCards = Initializer.setBucketOfCards();
private int[][] gameMatrix;
/** the name of the player owning this board */
public String name;
/**
* normal constructor for this type of object
* @param numPlayers the number of players in this game
* @param CO_1 the first common objective chosen
* @param CO_2 the second common objective chosen
*/
public Board(int numPlayers, CommonObjective CO_1, CommonObjective CO_2){
commonObjective_1 = CO_1;
commonObjective_2 = CO_2;
if(numPlayers == 2){
pointsCO_1 = new LinkedList<>(Arrays.asList(4, 8)); // they need to be taken with the method list.pop() --> from right to left
pointsCO_2 = new LinkedList<>(Arrays.asList(4, 8));
}
else if(numPlayers == 3){
pointsCO_1 = new LinkedList<>(Arrays.asList(4,6,8));
pointsCO_2 = new LinkedList<>(Arrays.asList(4,6,8));
}
else{
pointsCO_1 = new LinkedList<>(Arrays.asList(2,4,6,8));
pointsCO_2 = new LinkedList<>(Arrays.asList(2,4,6,8));
}
}
/**
* copy constructor for this class, used for deep copying objects
* @param b the object to copy (game board)
*/
public Board(Board b){
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++){
gameBoard[i][j] = new Card(b.gameBoard[i][j]);
}
}
commonObjective_1 = b.commonObjective_1;
commonObjective_2 = b.commonObjective_2;
pointsCO_1 = new LinkedList<>(b.pointsCO_1);
pointsCO_2 = new LinkedList<>(b.pointsCO_2);
bucketOfCards = new ArrayList<>(b.bucketOfCards);
name = b.name;
gameMatrix = b.gameMatrix;
}
/**
* getter for the game board
* @author Ettori
*/
public Card[][] getGameBoard(){return gameBoard;} // useful getter :-)
/**
* getter for the CO 1
* @author Ettori
*/
public CommonObjective getCO_1(){return commonObjective_1;}
/**
* getter for the CO 2
* @author Ettori
*/
public CommonObjective getCO_2(){return commonObjective_2;}
/**
* check if the index is valid in the current board
* @author Ettori
* @param x pos x
* @param y pos y
* @return true iff index is valid
*/
private boolean isValidIndex(int x, int y){
return x >= 0 && x < DIM && y >= 0 && y < DIM;
}
/**
* check if the card has other card near
* @author Ettori
* @param x pos x
* @param y pos y
* @return true iff the card is alone
*/
private boolean isAlone(int x, int y){
return (!isValidIndex(x + 1, y) || gameBoard[x + 1][y].color == EMPTY) && ((!isValidIndex(x - 1, y) || gameBoard[x - 1][y].color == EMPTY) || (!isValidIndex(x, y + 1) || gameBoard[x][y + 1].color == EMPTY) || (!isValidIndex(x, y - 1) || gameBoard[x][y - 1].color == EMPTY));
}
/**
* check if the current board is unplayable
* @author Ettori
* @return true if it is unplayable
*/
public boolean isBoardUnplayable() {
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++){
if(gameBoard[i][j].color != EMPTY && !isAlone(i, j)) // found a not empty and not lonely card, so the board is not unplayable
return false;
}
}
// if it's unplayable, call the method fillBoard(number of players)
return true;
}
/**
* check if the card has at least one free side
* @author Ettori
* @param x pos x
* @param y pos y
* @return true if it has at least one free side
*/
public boolean hasOneFreeSide(int x, int y){
if(!isValidIndex(x , y) || gameBoard[x][y].color == EMPTY) // check if the current card is in a valid spot, then look for near cards
return false;
if(isValidIndex(x + 1, y) && gameBoard[x + 1][y].color == EMPTY)
return true;
if(isValidIndex(x - 1, y) && gameBoard[x - 1][y].color == EMPTY)
return true;
if(isValidIndex(x, y + 1) && gameBoard[x][y + 1].color == EMPTY)
return true;
if(isValidIndex(x, y - 1) && gameBoard[x][y - 1].color == EMPTY)
return true;
return false;
}
/**
* check if the cards picked are all near one to the other
* @author Ettori
* @param coords list of paired coordinates
* @return true if for each position it exists (at least) one card adjacent to it
*/
private boolean areCardsNear(ArrayList<Integer> coords){
boolean flag;
for(int i = 0; i < coords.size(); i += 2){
flag = false;
for(int j = 0; j < coords.size(); j += 2){
//check if the cards have distance each other equals to 1 (if yes, are near)
if(Math.abs(coords.get(i) - coords.get(j)) + Math.abs(coords.get(i + 1) - coords.get(j + 1)) == 1)
flag = true;
}
if(!flag)
return false;
}
return true;
}
/**
* check if the cards picked are in a valid position
* @author Ettori
* @param cardPositions list of paired coordinates
* @return true iff they are in a valid position
*/
public boolean areCardsPickable(ArrayList<Integer> cardPositions) {
for(int i = 0; i < cardPositions.size(); i += 2 ){
if(!hasOneFreeSide(cardPositions.get(i), cardPositions.get(i + 1)))
return false;
}
return cardPositions.size() == 2 || (areCardsAligned(cardPositions) && areCardsNear(cardPositions));
}
/**
* check if the cards are on a straight line
* @author Ettori
* @param cardPosition list of paired coordinates
* @return true iff they are on a straight line
*/
public boolean areCardsAligned(ArrayList<Integer> cardPosition){
boolean allInRow = true;
for(int i = 0; i < cardPosition.size(); i += 2){
//!equals is null-safe
if(!Objects.equals(cardPosition.get(i), cardPosition.get(0)))
allInRow = false;
}
boolean allInCol = true;
for(int i = 1; i < cardPosition.size(); i += 2){
//!equals is null-safe
if(!Objects.equals(cardPosition.get(i), cardPosition.get(1)))
allInCol = false;
}
return allInRow || allInCol;
}
/**
* initialize a new board
* @author Ettori
* @param numPlayers number of players
*/
public void initBoard(int numPlayers){
shuffleCardsBucket();
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++)
gameBoard[i][j] = new Card();
}
fillBoard(numPlayers);
}
/**
* fill the board (start of the game or when it is unplayable)
* @author Ettori
* @param numPlayers number of players
*/
public void fillBoard(int numPlayers){
gameMatrix = new int[][]{
{0,0,0,3,4,0,0,0,0},
{0,0,0,2,2,4,0,0,0},
{0,0,3,2,2,2,3,0,0},
{0,4,2,2,2,2,2,2,3},
{4,2,2,2,2,2,2,2,4},
{3,2,2,2,2,2,2,4,0},
{0,0,3,2,2,2,3,0,0},
{0,0,0,4,2,2,0,0,0},
{0,0,0,0,4,3,0,0,0}
};
Card card;
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++){
if(gameMatrix[i][j] == 0)
continue;
if(gameBoard[i][j].color == EMPTY && numPlayers >= gameMatrix[i][j]){
card = bucketOfCards.get(0);
gameBoard[i][j] = new Card(card);
bucketOfCards.remove(0); // bucketOfCards gets exchanged with the server through the client
}
}
}
}
/**
* randomize the card array so that we get a random board
* @author Ettori
*/
public void shuffleCardsBucket(){
Random rand = new Random();
Card temp;
int j;
for(int i = 0; i < bucketOfCards.size(); i++){
j = rand.nextInt(bucketOfCards.size());
temp = bucketOfCards.get(i);
bucketOfCards.set(i, bucketOfCards.get(j));
bucketOfCards.set(j, temp);
}
}
/**
* setter for the gameBoard (only used by testing)
* @author Gumus Giammusso
* @param g the matrix to copy in the board
*/
public void setGameBoard(Card[][] g){
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++)
gameBoard[i][j] = new Card(g[i][j]);
}
}
/**
* method that print the game board
* @author Gumus
*/
public void draw() {
System.out.println("\nThe main board of the game");
System.out.print(" ");
for (int i = 0; i < DIM; i++)
System.out.print((i + 1) + " ");
System.out.println();
for (int i = 0; i < DIM; i++) {
System.out.print((i + 1) + " ");
for (int j = 0; j < DIM; j++) {
gameBoard[i][j].draw();
System.out.print(" ");
}
System.out.println();
}
System.out.println();
System.out.println("\n---------------------------------------------");
commonObjective_1.draw(pointsCO_1.size() != 0 ? pointsCO_1.peekLast() : 0);
System.out.println("\n---------------------------------------------\n");
commonObjective_2.draw(pointsCO_2.size() != 0 ? pointsCO_2.peekLast() : 0);
System.out.println("---------------------------------------------\n");
}
}