diff --git a/src/CheckersAI.java b/src/CheckersAI.java index e728930..36a5b07 100644 --- a/src/CheckersAI.java +++ b/src/CheckersAI.java @@ -9,9 +9,34 @@ public class CheckersAI{ this.player = player; } - public Move minimax(CheckersGameState s, int ply){ + private boolean stop(CheckersGameState state, boolean jumped, int depth, int min_ply){ + CheckersGameState3 s = (CheckersGameState3) state; + if(depth < min_ply){ + return false; + } + else if(depth == min_ply && !s.canJump() && !jumped && !s.canExchange()){ + return true; + } + else if(depth == min_ply +1 && !s.canJump() && !s.canExchange() && depth == 4){ + return true; + } + else if(depth > min_ply +1 && depth < min_ply + 10 && !s.canJump()){ + return true; + } + else if(depth > min_ply +10 && depth < min_ply + 20 && s.twoKings()){ + return true; + } + else if(depth >= min_ply + 20){ + return true; + } + else{ + return false; + } + } + + public Move minimax(CheckersGameState s, int min_ply){ int depth = 0; - if(s.isTerminal() || depth == ply){ + if(s.isTerminal()){ return null; } double alpha = Double.NEGATIVE_INFINITY; @@ -21,7 +46,7 @@ public class CheckersAI{ Move max = null; // System.out.println(s.actions().size()); for(Move a: s.actions()){ - check = minValue(s.result(a), alpha, beta, ply, depth + 1); + check = minValue(s.result(a), alpha, beta, depth + 1, a.isJump(), min_ply); if(check > v){ v = check; max = a; @@ -34,15 +59,14 @@ public class CheckersAI{ return max; } - private double maxValue(CheckersGameState s, double alpha, double beta, int ply, int depth){ - - if(s.isTerminal() || depth == ply){ - return eval.evaluate(s, this.player); // if terminal, piece ratio should be infinite + private double maxValue(CheckersGameState s, double alpha, double beta, int depth, boolean jumped, int min_ply){ + if(s.isTerminal() || stop(s, jumped, depth, min_ply)){ + return eval.evaluate(s, this.player); // if terminal, piece ratio should be infinite } double v = Double.NEGATIVE_INFINITY; double check; for(Move a: s.actions()){ - check = minValue(s.result(a), alpha, beta, ply, depth + 1); + check = minValue(s.result(a), alpha, beta, depth + 1, a.isJump(), min_ply); if(check > v){ v = check; } @@ -54,15 +78,14 @@ public class CheckersAI{ return v; } - private double minValue(CheckersGameState s, double alpha, double beta, int ply, int depth){ - - if(s.isTerminal() || depth == ply){ + private double minValue(CheckersGameState s, double alpha, double beta, int depth, boolean jumped, int min_ply){ + if(s.isTerminal() || stop(s, jumped, depth, min_ply)){ return eval.evaluate(s, this.player); } double v = Double.POSITIVE_INFINITY; double check; for(Move a: s.actions()){ - check = maxValue(s.result(a), alpha, beta, ply, depth + 1); + check = maxValue(s.result(a), alpha, beta, depth + 1, a.isJump(), min_ply); if(check < v){ v = check; } diff --git a/src/CheckersGameState3.java b/src/CheckersGameState3.java index 7c52cf5..aefb6e2 100644 --- a/src/CheckersGameState3.java +++ b/src/CheckersGameState3.java @@ -5,10 +5,13 @@ public class CheckersGameState3 implements CheckersGameState{ int player; int[] board; + List actions; public CheckersGameState3(int player, int[] board){ this.player = player; this.board = board; + //System.out.println(this.moves()); + this.actions = this.moves(); } public CheckersGameState3() { @@ -23,14 +26,53 @@ public class CheckersGameState3 implements CheckersGameState{ 2,2,2,2, 2,2,2,2 }; + this.actions = this.moves(); } public CheckersGameState3(int player, String[] board){ this.player = player; this.board = to_array(board); + this.actions = this.moves(); } - public int convert(String s){ + + boolean canJump(){ + //System.out.println(this.moves); + return (this.actions.size() > 0 && this.actions.get(0).isJump()); + } + + boolean canExchange(){ + if(canJump()){ + for(Move m: this.actions){ + if(m.captures().length == 1){ + for(Move n: this.result(m).actions()){ + if(n.captures().length == 1){ + return true; + } + } + } + } + return false; + } + return false; + } + + boolean twoKings(){ + int bkings = 0; + int wkings = 0; + for(int i = 0; i < board.length; i++){ + if(board[i] == 3){ + bkings++; + } + else if(board[i] == 4){ + wkings++; + } + } + return Math.abs(bkings - wkings) >= 2; + } + + + public int convert(String s){ if(s.equals("-")){ return 0; } @@ -144,6 +186,11 @@ public class CheckersGameState3 implements CheckersGameState{ } public List actions(){ + return this.actions; + } + + + public List moves(){ LinkedList moves = new LinkedList(); LinkedList jumps = new LinkedList(); for(int i = 0; i < this.board.length; i++){ @@ -166,6 +213,8 @@ public class CheckersGameState3 implements CheckersGameState{ } } } + //System.out.println(jumps); + //System.out.println(moves); if(jumps.isEmpty()){ return moves; } @@ -285,8 +334,8 @@ public class CheckersGameState3 implements CheckersGameState{ double mypieces = 0.0; for(int i = 0; i0){ + currentState.printState(); Move myMove = ai.minimax(currentState, 8); writeMessageAndEcho(myMove.toString()); if(!applyMove(myMove.toString())) {