From 1d87754f53d7627549cee2d5d920e0fcd7550236 Mon Sep 17 00:00:00 2001 From: Malte Tammena Date: Fri, 20 Oct 2017 13:24:11 +0200 Subject: [PATCH] Did commenting --- src/player/malte/MalteAI.java | 82 ++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/player/malte/MalteAI.java b/src/player/malte/MalteAI.java index 6ea639a..bcd1f3d 100644 --- a/src/player/malte/MalteAI.java +++ b/src/player/malte/MalteAI.java @@ -7,18 +7,42 @@ import java.util.Arrays; import player.Player; +/** + * Maltes artificial intelligence for playing a game of Connect Four + */ public class MalteAI implements Player{ + /** + * Name of the player. + */ private String name; + + /** + * Random Object. + */ private Random ran; + + /** + * The players ID. + */ private int id; + + /** + * The enemy's ID. + */ private int enemyID; + /** + * Constructor. + * + * @param name The name for the player. + */ public MalteAI(String name){ this.name = name; this.ran = new Random(); } + @Override public void setPlayerID(int id) { this.id = id; this.enemyID = id == 1 ? 2: 1; @@ -28,29 +52,40 @@ public class MalteAI implements Player{ this.enemyID = enemyID; } + @Override public int move(int[][] board){ + // Create a set of all possible options. Set options = new HashSet<>(Arrays.asList(0,1,2,3,4,5,6)); + // Remove impossible options. for (Integer i: copySet(options)) { if (board[i][0] != 0) { options.remove(i); } } + // Get options which would lead to instant win. Set winningOptions = getRowCompletionOptions(options, board, id); for (Integer i: winningOptions) { return i.intValue(); } - + // Get options which would prevent an instant win of the enemy. Set preventionsOptions = getRowCompletionOptions(options, board, enemyID); for (Integer i: preventionsOptions) { + // Only accept options, that would not cause a winning opportunity for the enemy. int[][] fakeBoard = makeMove(copyBoard(board), i, id); if (getRowCompletionOptions(options, fakeBoard, enemyID).size() == 0) { return i.intValue(); } } - + // If nothing applies, take a random valied one. return takeRandom(options).intValue(); } + /** + * Copies the given board. + * + * @param board The board to be copied. + * @return A deep copy of the board. + */ private int[][] copyBoard(int[][] board) { int[][] copy = new int[board.length][board[0].length]; for (int i = 0; i < board.length; i++) { @@ -61,25 +96,56 @@ public class MalteAI implements Player{ return copy; } + /** + * Makes a move on the given board. + * Makes a move on the given board, no winning check or anything, + * just a fake move on the given board. Necessary for confirming that + * a chosen move will not give the enemy an instant win. + * + * @param board The board on which the move is made. + * @param choice The column to play in. + * @param id The player's id. + * @return The modified board. + */ private int[][] makeMove(int[][] board, int choice, int id) { int column = 0; + // If the column is full, do nothing. if (board[choice][column] != 0) { return board; } + // Find the last empty row. while (board[choice][column + 1] == 0) { column++; } + // Add the players piece. board[choice][column] = id; return board; } + /** + * Instant winning options. + * Returns a set of options for the player to choose from. If any one is choosen and + * played by the player with the given id, a win is certain. + * + * @param options The options, that are valid, a subset is returned. + * @param board The current game's board. + * @param id The players id. + * @return A subset of options which would lead to a win. + */ private Set getRowCompletionOptions(Set options, int[][] board, int id) { + // Get winning patterns from Generator. Set pats = PatternGenerator.winningPatterns(id); + // Get patterns, that match anywhere on the board. Set matches = Pattern.matchingPatterns(pats, board); + // Create set to be returned. Set ret = new HashSet<>(); + // Iterate over all matches. for (Pattern p: matches) { + // Get all positions, this pattern matches. Set positions = p.matches(board); + // Get empty spaces in the pattern. for (Item i: p.getZeros()) { + // Add all options to the set. for(Position pos: positions) { ret.add(new Integer(i.getPosX() + pos.getPosX())); } @@ -88,10 +154,19 @@ public class MalteAI implements Player{ return ret; } + /** + * Copies a set of Integer. + */ private Set copySet(Set s) { return new HashSet(s); } + /** + * Takes a random Integer from a set of Integer. + * + * @param s The set to take from. + * @return A random element of s. + */ private Integer takeRandom(Set s) { int item = ran.nextInt(s.size()); int i = 0; @@ -105,6 +180,9 @@ public class MalteAI implements Player{ return 0; } + /** + * Get the player's name. + */ public String getName(){ return this.name; }