diff --git a/Makefile b/Makefile index d366ea7..e134f54 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ src/game/GameEntry.java \ src/game/PlayerObject.java \ src/player/Player.java \ src/player/malte/MalteAI.java \ +src/player/malte/Pattern.java \ +src/player/malte/Item.java \ src/player/maurizio/MaurizioAI.java OBJECTS=$($(subst $(CLASSPATH),$(BUILDS),$(CLASSES)):.java=.class) @@ -26,6 +28,8 @@ BUILDFILES=$(OBJECTS) $(FXMLS_BUILD) MAIN=game.Main +N=100 + all: $(CLASSES) $(FXMLS_BUILD) $(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(BUILDS) @@ -33,6 +37,9 @@ all: $(CLASSES) $(FXMLS_BUILD) run: $(CLASSES) $(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN) +simulate: $(CLASSES) + $(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN) $(N) + doc: $(CLASSES) $(JAVADOC) $(JAVADOC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(DOC) diff --git a/src/game/Game.java b/src/game/Game.java index c171796..d6da950 100644 --- a/src/game/Game.java +++ b/src/game/Game.java @@ -3,7 +3,8 @@ package game; import java.util.Random; import player.Player; -import player.MaurizioAI; +import player.maurizio.MaurizioAI; +import player.malte.MalteAI; /** * Represents a game of Connect Four. @@ -13,12 +14,12 @@ public class Game { /** * Number of columns on the board. */ - private final static int GAME_COLUMNS = 7; + public final static int GAME_COLUMNS = 7; /** * Number of rows on the board. */ - private final static int GAME_ROWS = 6; + public final static int GAME_ROWS = 6; /** * Player One @@ -69,6 +70,39 @@ public class Game { this.gameOn = false; } + /** + * Simulates n games. + * Simulates the games and prints statistical output to stdout. + * + * @param runs The number of games to simulate. + */ + public static void simulate(int runs) { + Player p1 = new MaurizioAI("Maurizio"); + Player p2 = new MalteAI("Malte"); + // 0 - Draw + // 1 - p1 wins + // 2 - p2 wins + int[] statistic = new int[3]; + for (int i = 0; i < runs; i++) { + int result = new Game(p1, p2).start(false, true); + // TODO: Improve IDs + statistic[result]++; + } + double[] percents = new double[3]; + for (int i = 0; i < statistic.length; i++) { + percents[i] = ((double)statistic[i]) / runs * 100.0; + } + System.out.println("Draws : " + statistic[0]); + System.out.println(p1.getName() + ": " + statistic[1] + " wins"); + System.out.println(p2.getName() + ": " + statistic[2] + " wins"); + + System.out.println("PERCENTAGE:"); + System.out.println("Draws : " + percents[0] + "%"); + System.out.println(p1.getName() + ": " + percents[1] + "% wins"); + System.out.println(p2.getName() + ": " + percents[2] + "% wins"); + + } + /** * Start a game. * @param output determines, whether game info etc. gets printed to the console @@ -168,14 +202,14 @@ public class Game { * @return the state of the game, -1 = still undecided , 0 = draw, 1 = Player 1 wins, ... */ private int checkState(boolean output) { - if(MaurizioAI.checkWin(this.board, p1.getID())){ + if(checkWin(this.board, p1.getID())){ this.gameOn = false; if(output){ System.out.println(p1.getP().getName() + " wins!"); } return p1.getID(); // player 1 wins } - if(MaurizioAI.checkWin(this.board, p2.getID())){ + if(checkWin(this.board, p2.getID())){ this.gameOn = false; if(output){ System.out.println(p2.getP().getName() + " wins!"); @@ -242,4 +276,83 @@ public class Game { } System.out.println(); } + + public static boolean checkWin(int[][] board, int player){ + int winLength = 4; + boolean win = false; + // check columns for win + for(int i=0;i options = new HashSet<>(Arrays.asList(0,1,2,3,4,5,6)); for (Integer i: copySet(options)) { @@ -22,11 +29,28 @@ public class MalteAI implements Player{ options.remove(i); } } + Set instantWins = getWinningOptions(options, board); // Set preventions = getPreventionOptions(options, board); return takeRandom(options).intValue(); } + private Set getWinningOptions(Set options, int[][] board) { + Pattern topOfColumn = new Pattern(new Item(0, 0, 0), + new Item(0, 1, id), + new Item(0, 2, id), + new Item(0, 3, id)); + Pattern leftInRow = new Pattern(new Item(0, 0, 0), + new Item(1, 0, id), + new Item(2, 0, id), + new Item(3, 0, id)); + Pattern rightInRow = new Pattern(new Item(0, 0, 0), + new Item(-1, 0, id), + new Item(-2, 0, id), + new Item(-3, 0, id)); + return null; + } + private Set copySet(Set s) { return new HashSet(s); } diff --git a/src/player/malte/Pattern.java b/src/player/malte/Pattern.java new file mode 100644 index 0000000..156f03f --- /dev/null +++ b/src/player/malte/Pattern.java @@ -0,0 +1,10 @@ +package player.malte; + +public class Pattern { + + private Item[] parts; + + public Pattern(Item... parts) { + this.parts = parts; + } +} diff --git a/src/player/maurizio/MaurizioAI.java b/src/player/maurizio/MaurizioAI.java index a517d10..c613e3a 100644 --- a/src/player/maurizio/MaurizioAI.java +++ b/src/player/maurizio/MaurizioAI.java @@ -1,17 +1,24 @@ -package player; +package player.maurizio; import java.util.Random; +import player.Player; + public class MaurizioAI implements Player { private String name; private Random ran; + private int id; public MaurizioAI(String name){ this.name = name; this.ran = new Random(); } + public void setPlayerID(int id) { + this.id = id; + } + public int move(int[][] board){ int choice = ran.nextInt(7); while (board[choice][0] != 0) { @@ -20,83 +27,6 @@ public class MaurizioAI implements Player { return choice; } - public static boolean checkWin(int[][] board, int player){ - int winLength = 4; - boolean win = false; - // check columns for win - for(int i=0;i