Merge branch 'master' of woodyfolsom.net:/opt/git/cs8803p4
This commit is contained in:
@@ -26,7 +26,6 @@ public class BoardPanelMouseListener implements MouseListener, MouseWheelListene
|
|||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
Tile tile = (Tile) e.getComponent();
|
Tile tile = (Tile) e.getComponent();
|
||||||
humanPlayer.setCell(tile.getRow(), tile.getCol());
|
humanPlayer.setCell(tile.getRow(), tile.getCol());
|
||||||
System.out.println("mouseClicked() " + (clickNum++));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ public class Board {
|
|||||||
BLUE, GREEN, NONE, RED, YELLOW
|
BLUE, GREEN, NONE, RED, YELLOW
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int NUM_COLS = 4;
|
public static final int NUM_COLS = 5;
|
||||||
public static final int NUM_ROWS = 4;
|
public static final int NUM_ROWS = 5;
|
||||||
public static final int ROW_REMOVAL_SIZE = 3;
|
public static final int ROW_REMOVAL_SIZE = 3;
|
||||||
|
|
||||||
private final TileColor[][] board;
|
private final TileColor[][] board;
|
||||||
@@ -20,9 +20,9 @@ public class Board {
|
|||||||
public Board(Board that) {
|
public Board(Board that) {
|
||||||
board = new TileColor[NUM_ROWS][NUM_COLS];
|
board = new TileColor[NUM_ROWS][NUM_COLS];
|
||||||
|
|
||||||
for (int i = 0; i < NUM_COLS; i++) {
|
for (int r = 0; r < NUM_ROWS; r++) {
|
||||||
for (int j = 0; j < NUM_ROWS; j++) {
|
for (int c = 0; c < NUM_COLS; c++) {
|
||||||
this.board[j][i] = that.board[j][i];
|
this.board[r][c] = that.board[r][c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,4 +230,18 @@ public class Board {
|
|||||||
numPlies++;
|
numPlies++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb1 = new StringBuilder();
|
||||||
|
for (int r = 0; r < NUM_ROWS; r++) {
|
||||||
|
StringBuilder sb2 = new StringBuilder();
|
||||||
|
for (int c = 0; c < NUM_COLS; c++) {
|
||||||
|
sb2.append(board[r][c].toString().charAt(0));
|
||||||
|
}
|
||||||
|
sb1.append(sb2);
|
||||||
|
sb1.append("\n");
|
||||||
|
}
|
||||||
|
return sb1.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
package model;
|
package model;
|
||||||
|
|
||||||
public class CellPointer {
|
public class CellPointer {
|
||||||
|
public static final CellPointer NONE = new CellPointer(-1,-1);
|
||||||
|
|
||||||
|
public final int c;
|
||||||
|
public final int r;
|
||||||
|
|
||||||
public CellPointer(int row, int col) {
|
public CellPointer(int row, int col) {
|
||||||
r = row;
|
this.r = row;
|
||||||
c = col;
|
this.c = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int r;
|
@Override
|
||||||
public int c;
|
public String toString() {
|
||||||
|
return "(" + r + "," + c +")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -28,4 +28,9 @@ public class Move {
|
|||||||
public TileColor getColor() {
|
public TileColor getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Play " + color + "@" + cp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
package model;
|
package model;
|
||||||
|
|
||||||
|
import model.Board.TileColor;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import player.AlphaBetaComPlayer;
|
import player.AlphaBetaComPlayer;
|
||||||
import player.HumanPlayer;
|
import player.HumanPlayer;
|
||||||
|
import player.MinimaxComPlayer;
|
||||||
import player.Player;
|
import player.Player;
|
||||||
import view.BoardPanel;
|
import view.BoardPanel;
|
||||||
import view.MessagePanel;
|
import view.MessagePanel;
|
||||||
import view.ScorePanel;
|
import view.ScorePanel;
|
||||||
import model.Board.TileColor;
|
|
||||||
|
|
||||||
public class Referee implements Runnable {
|
public class Referee implements Runnable {
|
||||||
|
|
||||||
|
|||||||
16
src/model/SearchResult.java
Normal file
16
src/model/SearchResult.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package model;
|
||||||
|
|
||||||
|
public class SearchResult {
|
||||||
|
public final Move move;
|
||||||
|
public final int score;
|
||||||
|
|
||||||
|
public SearchResult(Move move, int score) {
|
||||||
|
this.move = move;
|
||||||
|
this.score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return move + ", score: " + score;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import model.Board.TileColor;
|
|||||||
|
|
||||||
|
|
||||||
public class HumanPlayer implements Player {
|
public class HumanPlayer implements Player {
|
||||||
private final CellPointer cell = new CellPointer(0, 0);
|
private CellPointer cell = CellPointer.NONE;
|
||||||
|
|
||||||
private boolean ready = false;
|
private boolean ready = false;
|
||||||
private TileColor color = TileColor.BLUE;
|
private TileColor color = TileColor.BLUE;
|
||||||
@@ -72,9 +72,7 @@ public class HumanPlayer implements Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setCell(int row, int col) {
|
public void setCell(int row, int col) {
|
||||||
cell.r = row;
|
cell = new CellPointer(row, col);
|
||||||
cell.c = col;
|
|
||||||
|
|
||||||
ready = true;
|
ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
package player;
|
package player;
|
||||||
|
|
||||||
public class MinimaxComPlayer {
|
import model.Board;
|
||||||
|
import model.Move;
|
||||||
|
import player.generator.MinimaxMoveGenerator;
|
||||||
|
import player.generator.MoveGenerator;
|
||||||
|
|
||||||
|
public class MinimaxComPlayer implements Player{
|
||||||
|
private MoveGenerator moveGenerator = new MinimaxMoveGenerator();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Move getMove(Board board) {
|
||||||
|
return moveGenerator.genMove(board, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void denyMove() {
|
||||||
|
throw new UnsupportedOperationException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
return true; // always ready to play a random valid move
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,46 +6,56 @@ import java.util.List;
|
|||||||
import model.Board;
|
import model.Board;
|
||||||
import model.BoardScorer;
|
import model.BoardScorer;
|
||||||
import model.Move;
|
import model.Move;
|
||||||
|
import model.SearchResult;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
public class AlphaBetaMoveGenerator implements MoveGenerator {
|
public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||||
private static final Logger LOGGER = Logger
|
private static final Logger LOGGER = Logger
|
||||||
.getLogger(AlphaBetaMoveGenerator.class.getName());
|
.getLogger(AlphaBetaMoveGenerator.class.getName());
|
||||||
private static final int DEFAULT_RECURSIVE_PLAYS = 3;
|
private static final int DEFAULT_RECURSIVE_PLAYS = 2;
|
||||||
|
|
||||||
private final BoardScorer scorer = new BoardScorer();
|
private final BoardScorer scorer = new BoardScorer();
|
||||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||||
|
|
||||||
private Move bestPick = Move.NONE;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Move genMove(Board board, boolean asHuman) {
|
public Move genMove(Board board, boolean asHuman) {
|
||||||
|
|
||||||
int alpha = Integer.MIN_VALUE;
|
|
||||||
int beta = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
if (!asHuman) {
|
if (!asHuman) {
|
||||||
getMaxValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2, alpha,
|
return getMaxValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2, Integer.MIN_VALUE,
|
||||||
beta);
|
Integer.MAX_VALUE).move;
|
||||||
} else {
|
} else {
|
||||||
getMinValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2, alpha,
|
return getMinValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2, Integer.MIN_VALUE,
|
||||||
beta);
|
Integer.MAX_VALUE).move;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestPick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxValue(Board board, boolean asHuman, int recursionLevel,
|
private SearchResult getMax(SearchResult sr1, SearchResult sr2) {
|
||||||
|
if (sr1.score >= sr2.score) {
|
||||||
|
return sr1;
|
||||||
|
} else {
|
||||||
|
return sr2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchResult getMin(SearchResult sr1, SearchResult sr2) {
|
||||||
|
if (sr1.score <= sr2.score) {
|
||||||
|
return sr1;
|
||||||
|
} else {
|
||||||
|
return sr2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchResult getMaxValue(Board board, boolean asHuman, int recursionLevel,
|
||||||
int alpha, int beta) {
|
int alpha, int beta) {
|
||||||
if (terminalTest(recursionLevel)) {
|
if (recursionLevel < 1) {
|
||||||
return getUtility(board);
|
return new SearchResult(Move.NONE,scorer.getScore(board));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
|
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
|
||||||
MoveGenerator.ALL_MOVES);
|
MoveGenerator.ALL_MOVES);
|
||||||
|
|
||||||
int value = Integer.MIN_VALUE;
|
SearchResult bestResult = new SearchResult(Move.NONE,Integer.MIN_VALUE);
|
||||||
|
|
||||||
for (Move nextMove : validMoves) {
|
for (Move nextMove : validMoves) {
|
||||||
Board nextBoard = new Board(board);
|
Board nextBoard = new Board(board);
|
||||||
@@ -55,35 +65,31 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
|||||||
"Illegal move attempted during search!");
|
"Illegal move attempted during search!");
|
||||||
}
|
}
|
||||||
|
|
||||||
int minValue = getMinValue(nextBoard, !asHuman, recursionLevel - 1,
|
SearchResult searchResult = new SearchResult(nextMove,getMinValue(nextBoard, !asHuman, recursionLevel - 1,
|
||||||
alpha, beta);
|
alpha, beta).score);
|
||||||
|
|
||||||
if (minValue > value) {
|
bestResult = getMax(bestResult,searchResult);
|
||||||
value = minValue;
|
|
||||||
if (recursionLevel == DEFAULT_RECURSIVE_PLAYS * 2) {
|
if (bestResult.score >= beta) {
|
||||||
bestPick = nextMove;
|
return bestResult;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value >= beta) {
|
alpha = Math.max(alpha, bestResult.score);
|
||||||
return value;
|
|
||||||
}
|
|
||||||
alpha = Math.max(alpha, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return bestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMinValue(Board board, boolean asHuman, int recursionLevel,
|
private SearchResult getMinValue(Board board, boolean asHuman, int recursionLevel,
|
||||||
int alpha, int beta) {
|
int alpha, int beta) {
|
||||||
if (terminalTest(recursionLevel)) {
|
if (recursionLevel < 1) {
|
||||||
return getUtility(board);
|
return new SearchResult(Move.NONE,scorer.getScore(board));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
|
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
|
||||||
MoveGenerator.ALL_MOVES);
|
MoveGenerator.ALL_MOVES);
|
||||||
|
|
||||||
int value = Integer.MAX_VALUE;
|
SearchResult bestResult = new SearchResult(Move.NONE,Integer.MAX_VALUE);
|
||||||
|
|
||||||
for (Move nextMove : validMoves) {
|
for (Move nextMove : validMoves) {
|
||||||
Board nextBoard = new Board(board);
|
Board nextBoard = new Board(board);
|
||||||
@@ -93,31 +99,19 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
|||||||
"Illegal move attempted during search!");
|
"Illegal move attempted during search!");
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxValue = getMaxValue(nextBoard, !asHuman, recursionLevel - 1,
|
SearchResult searchResult = new SearchResult(nextMove,getMaxValue(nextBoard, !asHuman, recursionLevel - 1,
|
||||||
alpha, beta);
|
alpha, beta).score);
|
||||||
|
|
||||||
if (maxValue < value) {
|
bestResult = getMin(bestResult,searchResult);
|
||||||
value = maxValue;
|
|
||||||
if (recursionLevel == 2 * DEFAULT_RECURSIVE_PLAYS) {
|
if (bestResult.score <= alpha) {
|
||||||
bestPick = nextMove;
|
return bestResult;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value <= alpha) {
|
beta = Math.min(beta, bestResult.score);
|
||||||
return value;
|
|
||||||
}
|
|
||||||
beta = Math.min(beta, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return bestResult;
|
||||||
}
|
|
||||||
|
|
||||||
private boolean terminalTest(int recursionLevel) {
|
|
||||||
return recursionLevel < 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getUtility(Board board) {
|
|
||||||
return scorer.getScore(board);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
105
src/player/generator/MinimaxMoveGenerator.java
Normal file
105
src/player/generator/MinimaxMoveGenerator.java
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package player.generator;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import model.Board;
|
||||||
|
import model.BoardScorer;
|
||||||
|
import model.Move;
|
||||||
|
import model.SearchResult;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
public class MinimaxMoveGenerator implements MoveGenerator {
|
||||||
|
private static final Logger LOGGER = Logger
|
||||||
|
.getLogger(MinimaxMoveGenerator.class.getName());
|
||||||
|
private static final int DEFAULT_RECURSIVE_PLAYS = 2;
|
||||||
|
|
||||||
|
private final BoardScorer scorer = new BoardScorer();
|
||||||
|
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Move genMove(Board board, boolean asHuman) {
|
||||||
|
//asHuman may appear redundant, but is for later use when the com and human
|
||||||
|
//have different types of moves.
|
||||||
|
SearchResult searchResult;
|
||||||
|
if (!asHuman) {
|
||||||
|
searchResult = getMaxValue(board, Move.NONE, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||||
|
} else {
|
||||||
|
searchResult = getMinValue(board, Move.NONE, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(searchResult);
|
||||||
|
return searchResult.move;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchResult getMaxValue(Board board, Move lastMove, boolean asHuman, int recursionLevel) {
|
||||||
|
if (terminalTest(recursionLevel)) {
|
||||||
|
return new SearchResult(lastMove,scorer.getScore(board));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
|
||||||
|
MoveGenerator.ALL_MOVES);
|
||||||
|
|
||||||
|
SearchResult bestResult = new SearchResult(Move.NONE,Integer.MIN_VALUE);
|
||||||
|
|
||||||
|
for (Move nextMove : validMoves) {
|
||||||
|
Board nextBoard = new Board(board);
|
||||||
|
|
||||||
|
if (!nextBoard.playTile(nextMove.getCell(), nextMove.getColor())) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Illegal move attempted during search!");
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult searchResult = getMinValue(nextBoard, nextMove, !asHuman, recursionLevel - 1);
|
||||||
|
|
||||||
|
if (searchResult.score > bestResult.score) {
|
||||||
|
bestResult = new SearchResult(nextMove,searchResult.score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchResult getMinValue(Board board, Move lastMove, boolean asHuman, int recursionLevel) {
|
||||||
|
if (terminalTest(recursionLevel)) {
|
||||||
|
return new SearchResult(lastMove,scorer.getScore(board));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
|
||||||
|
MoveGenerator.ALL_MOVES);
|
||||||
|
|
||||||
|
SearchResult bestResult = new SearchResult(Move.NONE,Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
for (Move nextMove : validMoves) {
|
||||||
|
Board nextBoard = new Board(board);
|
||||||
|
|
||||||
|
if (!nextBoard.playTile(nextMove.getCell(), nextMove.getColor())) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Illegal move attempted during search!");
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult searchResult = getMaxValue(nextBoard, nextMove,!asHuman, recursionLevel - 1);
|
||||||
|
|
||||||
|
if (searchResult.score < bestResult.score) {
|
||||||
|
bestResult = new SearchResult(nextMove,searchResult.score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean terminalTest(int recursionLevel) {
|
||||||
|
return recursionLevel < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlphaBetaMoveGenerator2 does not support this method.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Move> genMoves(Board board, boolean asHuman, int nMoves) {
|
||||||
|
Move[] doNothing = new Move[] { Move.NONE };
|
||||||
|
LOGGER.info("Minimax genMoves() stub returning []");
|
||||||
|
return Arrays.asList(doNothing);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package player.generator;
|
package player.generator;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import model.Board;
|
import model.Board;
|
||||||
@@ -10,7 +11,8 @@ import model.Move;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
public class ValidMoveGenerator implements MoveGenerator {
|
public class ValidMoveGenerator implements MoveGenerator {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ValidMoveGenerator.class.getName());
|
private static final Logger LOGGER = Logger
|
||||||
|
.getLogger(ValidMoveGenerator.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Move genMove(Board board, boolean asHuman) {
|
public Move genMove(Board board, boolean asHuman) {
|
||||||
@@ -26,16 +28,17 @@ public class ValidMoveGenerator implements MoveGenerator {
|
|||||||
for (int i = 0; i < Board.NUM_ROWS; i++) {
|
for (int i = 0; i < Board.NUM_ROWS; i++) {
|
||||||
for (int j = 0; j < Board.NUM_COLS; j++) {
|
for (int j = 0; j < Board.NUM_COLS; j++) {
|
||||||
if (board.getTile(i, j) == TileColor.NONE) {
|
if (board.getTile(i, j) == TileColor.NONE) {
|
||||||
for (TileColor color : TileColor.values()) {
|
for (TileColor color : TileColor.values()) {
|
||||||
if (color == TileColor.NONE) {
|
if (color == TileColor.NONE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
validMoves.add(new Move(color, i, j));
|
validMoves.add(new Move(color, i, j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collections.shuffle(validMoves);
|
||||||
return validMoves;
|
return validMoves;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
test/model/BoardScorerTest.java
Normal file
32
test/model/BoardScorerTest.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package model;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import model.Board.TileColor;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class BoardScorerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScore() {
|
||||||
|
Board board = new Board();
|
||||||
|
board.playTile(new CellPointer(0,0), TileColor.BLUE);
|
||||||
|
board.playTile(new CellPointer(0,1), TileColor.GREEN);
|
||||||
|
board.playTile(new CellPointer(1,0), TileColor.BLUE);
|
||||||
|
board.playTile(new CellPointer(2,0), TileColor.GREEN);
|
||||||
|
board.playTile(new CellPointer(1,1), TileColor.BLUE);
|
||||||
|
board.playTile(new CellPointer(0,2), TileColor.BLUE);
|
||||||
|
board.playTile(new CellPointer(3,0), TileColor.BLUE);
|
||||||
|
board.playTile(new CellPointer(0,3), TileColor.BLUE);
|
||||||
|
|
||||||
|
BoardScorer boardScorer = new BoardScorer();
|
||||||
|
System.out.println("Board 1: ");
|
||||||
|
System.out.println(board);
|
||||||
|
assertEquals(8,boardScorer.getScore(board));
|
||||||
|
board.playTile(new CellPointer(1,2), TileColor.BLUE);
|
||||||
|
|
||||||
|
System.out.println("Board 2: ");
|
||||||
|
System.out.println(board);
|
||||||
|
assertEquals(6,boardScorer.getScore(board));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user