Did commenting
This commit is contained in:
parent
2e9347cfb3
commit
1d87754f53
|
@ -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<Integer> 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<Integer> winningOptions = getRowCompletionOptions(options, board, id);
|
||||
for (Integer i: winningOptions) {
|
||||
return i.intValue();
|
||||
}
|
||||
|
||||
// Get options which would prevent an instant win of the enemy.
|
||||
Set<Integer> 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<Integer> getRowCompletionOptions(Set<Integer> options, int[][] board, int id) {
|
||||
// Get winning patterns from Generator.
|
||||
Set<Pattern> pats = PatternGenerator.winningPatterns(id);
|
||||
// Get patterns, that match anywhere on the board.
|
||||
Set<Pattern> matches = Pattern.matchingPatterns(pats, board);
|
||||
// Create set to be returned.
|
||||
Set<Integer> ret = new HashSet<>();
|
||||
// Iterate over all matches.
|
||||
for (Pattern p: matches) {
|
||||
// Get all positions, this pattern matches.
|
||||
Set<Position> 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<Integer> copySet(Set<Integer> s) {
|
||||
return new HashSet<Integer>(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<Integer> 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue