Compare commits
11 Commits
d03b4443f6
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f7ff56204 | |||
|
|
b8d9480ae7 | ||
|
|
3ba0db6ebd | ||
|
|
924780baaf | ||
|
|
48915071d4 | ||
|
|
490d3d0bf6 | ||
|
|
f4ed883d63 | ||
|
|
a9fbdfb50e | ||
|
|
f6e4a32b82 | ||
|
|
e9ead0edda | ||
|
|
f81db19586 |
@@ -5,6 +5,5 @@
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.10.jar"/>
|
||||
<classpathentry kind="lib" path="lib/log4j-1.2.16.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
7
LICENSE.txt
Normal file
7
LICENSE.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
16
README.TXT
Normal file
16
README.TXT
Normal file
@@ -0,0 +1,16 @@
|
||||
MatchAttack! Instructions
|
||||
---------------------------
|
||||
|
||||
Unzip the attached archive 'CS8803_P4.zip' and change to the new directory.
|
||||
|
||||
To build MatchAttack!: run 'ant clean' then 'ant' in this directory.
|
||||
|
||||
To run MatchAttack!: change to the 'dist' directory, then run java -jar CS8803_P4.jar
|
||||
|
||||
For full instructions, see writeup/CS8803_P4.PDF.
|
||||
|
||||
For assistance, please contact Woody Folsom <woody.folsom@gatech.edu> or Marshall Gillson <mgillson1@gmail.com>.
|
||||
|
||||
NOTICE
|
||||
------
|
||||
Unless otherwise attributed, code in the 'aima' package is (c) Ciaran O'Reilly and Ravi Mohan. It is used under the MIT license. See LICENSE.TXT for more information. Note that this is the actual license referenced by the project site, with placeholders for date and author names.
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<target name="compile" depends="copy-resources">
|
||||
<!-- Compile the java code from ${src} into ${build} -->
|
||||
<javac srcdir="${src}" destdir="${build}" classpathref="build.classpath" debug="true" source="1.6" target="1.6"/>
|
||||
<javac srcdir="${src}" destdir="${build}" classpathref="build.classpath" debug="true" source="1.8" target="1.8"/>
|
||||
</target>
|
||||
|
||||
<target name="compile-test" depends="compile">
|
||||
|
||||
Binary file not shown.
@@ -33,7 +33,11 @@ public class MDPFactory {
|
||||
public static ActionsFunction<GridCell<Double>, GridWorldAction> createActionsFunctionForTileGame(
|
||||
final GridWorld<Double> cw, int maxTiles, int maxScore) {
|
||||
final Set<GridCell<Double>> terminals = new HashSet<GridCell<Double>>();
|
||||
terminals.add(cw.getCellAt(maxTiles,maxScore));
|
||||
|
||||
for (int score = 1; score <= maxScore; score++) {
|
||||
terminals.add(cw.getCellAt(maxTiles,score));
|
||||
}
|
||||
//terminals.add(cw.getCellAt(maxTiles,maxScore));
|
||||
|
||||
ActionsFunction<GridCell<Double>, GridWorldAction> af = new ActionsFunction<GridCell<Double>, GridWorldAction>() {
|
||||
|
||||
|
||||
@@ -12,13 +12,19 @@ public class Board {
|
||||
public static final int NUM_ROWS = 5;
|
||||
public static final int ROW_REMOVAL_SIZE = 3;
|
||||
|
||||
public static boolean isLegal(Board brd, CellPointer cp) {
|
||||
private boolean boardEmpty = true;
|
||||
|
||||
public boolean isLegal(CellPointer cp) {
|
||||
//coordinates are out of board bounds
|
||||
if (cp.r < 0 || cp.r >= Board.NUM_ROWS || cp.c < 0
|
||||
|| cp.c >= Board.NUM_COLS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean legal = (brd.getTile(cp.r, cp.c) == TileColor.NONE);
|
||||
//target coordinate already has a tile
|
||||
if (board[cp.r][cp.c] != TileColor.NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean rowUp = (cp.r - 1) >= 0;
|
||||
boolean rowDown = (cp.r + 1) < Board.NUM_ROWS;
|
||||
@@ -27,49 +33,49 @@ public class Board {
|
||||
|
||||
// r-1 / c-1
|
||||
if (rowUp && colUp
|
||||
&& (brd.getTile(cp.r - 1, cp.c - 1) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
&& (board[cp.r - 1][ cp.c - 1] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r-1 / c
|
||||
if (rowUp && (brd.getTile(cp.r - 1, cp.c) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
if (rowUp && (board[cp.r - 1][ cp.c] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r-1 / c+1
|
||||
if (rowUp && colDown
|
||||
&& (brd.getTile(cp.r - 1, cp.c + 1) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
&& (board[cp.r - 1][ cp.c + 1] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r / c-1
|
||||
if (colUp && (brd.getTile(cp.r, cp.c - 1) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
if (colUp && (board[cp.r][ cp.c - 1] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r / c+1
|
||||
if (colDown && (brd.getTile(cp.r, cp.c + 1) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
if (colDown && (board[cp.r][ cp.c + 1] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r+1 / c-1
|
||||
if (rowDown && colUp
|
||||
&& (brd.getTile(cp.r + 1, cp.c - 1) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
&& (board[cp.r + 1][ cp.c - 1] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r+1 / c
|
||||
if (rowDown && (brd.getTile(cp.r + 1, cp.c) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
if (rowDown && (board[cp.r + 1][ cp.c] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// r+1 / c+1
|
||||
if (rowDown && colDown
|
||||
&& (brd.getTile(cp.r + 1, cp.c + 1) != TileColor.NONE)) {
|
||||
return legal && true;
|
||||
&& (board[cp.r + 1][ cp.c + 1] != TileColor.NONE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return brd.isEmpty();
|
||||
return boardEmpty;
|
||||
}
|
||||
|
||||
private final TileColor[][] board;
|
||||
@@ -91,6 +97,7 @@ public class Board {
|
||||
|
||||
for (int r = 0; r < NUM_ROWS; r++) {
|
||||
for (int c = 0; c < NUM_COLS; c++) {
|
||||
this.boardEmpty = that.boardEmpty;
|
||||
this.board[r][c] = that.board[r][c];
|
||||
}
|
||||
}
|
||||
@@ -163,7 +170,7 @@ public class Board {
|
||||
}
|
||||
|
||||
public boolean playTile(CellPointer cp, TileColor tile) {
|
||||
if (!isLegal(this, cp)) {
|
||||
if (!isLegal(cp)) {
|
||||
return false; // Illegal move.
|
||||
}
|
||||
|
||||
@@ -304,6 +311,8 @@ public class Board {
|
||||
}
|
||||
|
||||
numPlies++;
|
||||
|
||||
boardEmpty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -320,16 +329,4 @@ public class Board {
|
||||
}
|
||||
return sb1.toString();
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
for (int r = 0; r < Board.NUM_ROWS; r++) {
|
||||
for (int c = 0; c < Board.NUM_COLS; c++) {
|
||||
if (getTile(r, c) != TileColor.NONE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,6 @@ import model.comPlayer.Player;
|
||||
import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import view.BoardPanel;
|
||||
import view.HighScoreDialog;
|
||||
import view.MainFrame;
|
||||
@@ -16,8 +14,6 @@ import view.ScorePanel;
|
||||
public class Referee implements Runnable {
|
||||
public static final String COM_TURN = "Waiting for the computer's move.";
|
||||
public static final String GAME_OVER = "Game over!";
|
||||
public static final Logger LOGGER = Logger.getLogger(Referee.class
|
||||
.getName());
|
||||
|
||||
public static final String PLAYER_TURN = "Waiting for the player's move.";
|
||||
|
||||
@@ -153,7 +149,6 @@ public class Referee implements Runnable {
|
||||
}
|
||||
|
||||
private void play() {
|
||||
int plies = 0;
|
||||
while (!isOver()) {
|
||||
if (board.isPlayerTurn()) {
|
||||
boolean wasInterrupted = false;
|
||||
@@ -197,7 +192,7 @@ public class Referee implements Runnable {
|
||||
getScorePanel().updateScore(getPlayerScore());
|
||||
mf.updateMessage(getMessage());
|
||||
boardPanel.updateIcons();
|
||||
LOGGER.info("plies: " + plies++);
|
||||
|
||||
try {
|
||||
Thread.sleep(250L);
|
||||
} catch (InterruptedException ie) {
|
||||
|
||||
@@ -44,7 +44,7 @@ public class AdaptiveComPlayer implements Player {
|
||||
// take 10 turns to place 6 tiles
|
||||
double defaultPenalty = -0.25;
|
||||
|
||||
int maxScore = target.getTargetScore();
|
||||
int maxScore = Math.max(1,target.getTargetScore());
|
||||
int maxTiles = Board.NUM_COLS * Board.NUM_ROWS;
|
||||
|
||||
gw = GridWorldFactory.createGridWorldForTileGame(maxTiles,
|
||||
@@ -79,10 +79,11 @@ public class AdaptiveComPlayer implements Player {
|
||||
if (action == null || state == null) {
|
||||
System.out
|
||||
.println("Board state outside of parameters of MDP. Reverting to failsafe behavior.");
|
||||
action = GridWorldAction.RandomMove;
|
||||
}
|
||||
System.out.println("Performing action " + action + " at state " + state
|
||||
action = GridWorldAction.AddTile;
|
||||
} else {
|
||||
System.out.println("Performing action " + action + " at state " + state
|
||||
+ " per policy.");
|
||||
}
|
||||
switch (action) {
|
||||
case AddTile:
|
||||
// System.out.println("Performing action #" +
|
||||
|
||||
@@ -8,7 +8,7 @@ import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
public class AlphaBetaComPlayer implements Player {
|
||||
private final MoveGenerator moveGenerator = new AlphaBetaMoveGenerator();
|
||||
final MoveGenerator moveGenerator = new AlphaBetaMoveGenerator();
|
||||
|
||||
@Override
|
||||
public void denyMove() {
|
||||
|
||||
@@ -286,7 +286,7 @@ public class CountingPlayer implements Player {
|
||||
|
||||
for (int r = 0; r < Board.NUM_ROWS; r++) {
|
||||
for (int c = 0; c < Board.NUM_COLS; c++) {
|
||||
if (Board.isLegal(board, new CellPointer(r, c))) {
|
||||
if (board.isLegal(new CellPointer(r, c))) {
|
||||
moves.add(new Move(TileColor.BLUE, r, c));
|
||||
moves.add(new Move(TileColor.GREEN, r, c));
|
||||
moves.add(new Move(TileColor.RED, r, c));
|
||||
|
||||
@@ -8,7 +8,7 @@ import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
public class MinimaxComPlayer implements Player {
|
||||
private final MoveGenerator moveGenerator = new MinimaxMoveGenerator();
|
||||
final MoveGenerator moveGenerator = new MinimaxMoveGenerator();
|
||||
|
||||
public MinimaxComPlayer() {
|
||||
super();
|
||||
|
||||
@@ -8,7 +8,7 @@ import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
public class MonteCarloComPlayer implements Player {
|
||||
private final MoveGenerator moveGenerator = new MonteCarloMoveGenerator();
|
||||
final MoveGenerator moveGenerator = new MonteCarloMoveGenerator();
|
||||
|
||||
@Override
|
||||
public void denyMove() {
|
||||
|
||||
@@ -8,13 +8,9 @@ import model.BoardScorer;
|
||||
import model.Move;
|
||||
import model.SearchResult;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||
private static final Logger LOGGER = Logger
|
||||
.getLogger(AlphaBetaMoveGenerator.class.getName());
|
||||
|
||||
private int lookahead = DEFAULT_RECURSIVE_PLAYS;
|
||||
private final BoardScorer scorer = new BoardScorer();
|
||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||
|
||||
@@ -22,10 +18,10 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
public Move genMove(Board board, boolean asHuman) {
|
||||
|
||||
if (!asHuman) {
|
||||
return getMaxValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2,
|
||||
return getMaxValue(board, asHuman, lookahead * 2,
|
||||
Integer.MIN_VALUE, Integer.MAX_VALUE).move;
|
||||
} else {
|
||||
return getMinValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2,
|
||||
return getMinValue(board, asHuman, lookahead * 2,
|
||||
Integer.MIN_VALUE, Integer.MAX_VALUE).move;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +32,6 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -119,4 +114,9 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
|
||||
return bestResult;
|
||||
}
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
this.lookahead = lookahead;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,9 @@ 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 static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||
private int lookahead = DEFAULT_RECURSIVE_PLAYS;
|
||||
|
||||
private final BoardScorer scorer = new BoardScorer();
|
||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||
@@ -24,12 +21,12 @@ public class MinimaxMoveGenerator implements MoveGenerator {
|
||||
//have different types of moves.
|
||||
SearchResult searchResult;
|
||||
if (!asHuman) {
|
||||
searchResult = getMaxValue(board, Move.NONE, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||
searchResult = getMaxValue(board, Move.NONE, asHuman, lookahead * 2);
|
||||
} else {
|
||||
searchResult = getMinValue(board, Move.NONE, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||
searchResult = getMinValue(board, Move.NONE, asHuman, lookahead * 2);
|
||||
}
|
||||
|
||||
System.out.println(searchResult);
|
||||
//System.out.println(searchResult);
|
||||
return searchResult.move;
|
||||
}
|
||||
|
||||
@@ -93,13 +90,15 @@ public class MinimaxMoveGenerator implements MoveGenerator {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
this.lookahead = lookahead;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,9 @@ import model.BoardScorer;
|
||||
import model.Move;
|
||||
import model.SearchResult;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class MonteCarloMoveGenerator implements MoveGenerator {
|
||||
private static final Logger LOGGER = Logger
|
||||
.getLogger(MonteCarloMoveGenerator.class.getName());
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 3;
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||
private int lookahead = DEFAULT_RECURSIVE_PLAYS;
|
||||
private static final int MOVES_PER_LEVEL = 12;
|
||||
|
||||
private final BoardScorer scorer = new BoardScorer();
|
||||
@@ -22,7 +19,7 @@ public class MonteCarloMoveGenerator implements MoveGenerator {
|
||||
@Override
|
||||
public Move genMove(Board board, boolean asHuman) {
|
||||
|
||||
SearchResult bestResult = genMove(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||
SearchResult bestResult = genMove(board, asHuman, lookahead * 2);
|
||||
|
||||
return bestResult.move;
|
||||
}
|
||||
@@ -73,13 +70,15 @@ public class MonteCarloMoveGenerator implements MoveGenerator {
|
||||
return new SearchResult(bestResult.move, (int)Math.round((double)totalScore / validMoves.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
this.lookahead = lookahead;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,5 @@ public interface MoveGenerator {
|
||||
|
||||
public Move genMove(Board board, boolean asHuman);
|
||||
public List<Move> genMoves(Board board, boolean asHuman, int nMoves);
|
||||
public boolean setLookahead(int lookahead);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ public class NeuralNetworkMoveGenerator implements MoveGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
while (!Board.isLegal(board, mv.getCell())) {
|
||||
while (!board.isLegal(mv.getCell())) {
|
||||
mv = new Move(mv.getColor(), new CellPointer(
|
||||
PlayerModel.rand.nextInt(Board.NUM_ROWS),
|
||||
PlayerModel.rand.nextInt(Board.NUM_COLS)));
|
||||
@@ -94,5 +94,8 @@ public class NeuralNetworkMoveGenerator implements MoveGenerator {
|
||||
// Do nothing.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -9,15 +9,9 @@ import model.Board.TileColor;
|
||||
import model.CellPointer;
|
||||
import model.Move;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class ValidMoveGenerator implements MoveGenerator {
|
||||
private static final Logger LOGGER = Logger
|
||||
.getLogger(ValidMoveGenerator.class.getName());
|
||||
|
||||
@Override
|
||||
public Move genMove(Board board, boolean asHuman) {
|
||||
LOGGER.info("ValidMoveGenerator genMove() stub returning NONE");
|
||||
return Move.NONE;
|
||||
}
|
||||
|
||||
@@ -28,13 +22,11 @@ public class ValidMoveGenerator implements MoveGenerator {
|
||||
|
||||
for (int r = 0; r < Board.NUM_ROWS; r++) {
|
||||
for (int c = 0; c < Board.NUM_COLS; c++) {
|
||||
if (Board.isLegal(board, new CellPointer(r, c))) {
|
||||
for (TileColor color : TileColor.values()) {
|
||||
if (color == TileColor.NONE) {
|
||||
continue;
|
||||
}
|
||||
validMoves.add(new Move(color, r, c));
|
||||
}
|
||||
if (board.isLegal(new CellPointer(r, c))) {
|
||||
validMoves.add(new Move(TileColor.BLUE, r, c));
|
||||
validMoves.add(new Move(TileColor.GREEN, r, c));
|
||||
validMoves.add(new Move(TileColor.RED, r, c));
|
||||
validMoves.add(new Move(TileColor.YELLOW, r, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,4 +39,9 @@ public class ValidMoveGenerator implements MoveGenerator {
|
||||
return validMoves.subList(0, Math.min(validMoves.size(), nMoves));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@ public class ArgParser {
|
||||
public static ParsedArgs parse(String[] cmdLineArgs) {
|
||||
ParsedArgs parsedArgs = new ParsedArgs();
|
||||
for (int i = 0; i < cmdLineArgs.length; i++) {
|
||||
if (cmdLineArgs[i].toUpperCase().startsWith("COM=")) {
|
||||
String arg = cmdLineArgs[i].replaceAll("-","");
|
||||
if (arg.toUpperCase().startsWith("COM=")) {
|
||||
String comPlayer = cmdLineArgs[i].split("=")[1];
|
||||
parsedArgs.setComPlayer(comPlayer);
|
||||
System.out.println("ComPlayer set to: " + comPlayer);
|
||||
} else {
|
||||
System.out.println("Ignoring unrecognized argument: " + cmdLineArgs[i]);
|
||||
System.out.println("Ignoring unrecognized argument: " + arg);
|
||||
}
|
||||
}
|
||||
return parsedArgs;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class UserChooserFrame extends JFrame {
|
||||
|
||||
public static final String PLAYER_LIST_FILE = "players.dat";
|
||||
public static final JLabel RULES_TEXT = new JLabel(
|
||||
"Here should go some rules text. Lorem ipsum dolor sit amet, consectetur adipiscing elit...");
|
||||
"<html>Welcome to <i>MatchAttack!</i><br><br>The rules of <i>MatchAttack!</i> are very straightforward.<ol><li>The goal of <i>MatchAttack!</i> is to maxmize your score.<br>You earn a point for each tile you place on the board.</li><li>Unless the board is empty, every tile you place must be adjacent to an existing tile.</li><li>If you create a line of three or more tiles of the same color, horizontally or vertically,<br>then every tile in that row will be removed.</li><li>After each tile you place, the computer will place a tile.<br>The computer will attempt to fill the board.</li></ol>Enter your name below to begin!</html>");
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Player comPlayer;
|
||||
|
||||
Binary file not shown.
114
test/model/comPlayer/SpeedTest.java
Normal file
114
test/model/comPlayer/SpeedTest.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package model.comPlayer;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import model.Board;
|
||||
import model.Board.TileColor;
|
||||
import model.playerModel.PlayerModel;
|
||||
import model.CellPointer;
|
||||
|
||||
public class SpeedTest {
|
||||
private static final Board board = new Board();
|
||||
private static final int nTestRounds = 10;
|
||||
private static final int lookahead = 3;
|
||||
|
||||
static {
|
||||
board.playTile(new CellPointer(2,2), TileColor.BLUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandom() {
|
||||
long testTime = 0L;
|
||||
|
||||
RandomComPlayer player = new RandomComPlayer();
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for RandomMoveGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonteCarlo() {
|
||||
long testTime = 0L;
|
||||
|
||||
MonteCarloComPlayer player = new MonteCarloComPlayer();
|
||||
player.moveGenerator.setLookahead(lookahead);
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for MonteCarloGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
public void testMinimax() {
|
||||
long testTime = 0L;
|
||||
|
||||
MinimaxComPlayer player = new MinimaxComPlayer();
|
||||
player.moveGenerator.setLookahead(lookahead);
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for MinimaxMoveGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlphaBeta() {
|
||||
long testTime = 0L;
|
||||
|
||||
AlphaBetaComPlayer player = new AlphaBetaComPlayer();
|
||||
player.moveGenerator.setLookahead(lookahead);
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for AlphaBetaMoveGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user