Skip to content

Feature/variable depth #22

Merged
merged 2 commits into from
Apr 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions src/CheckersAI.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,34 @@ public CheckersAI(Evaluator e, int player){
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;
Expand All @@ -21,7 +46,7 @@ public Move minimax(CheckersGameState s, int ply){
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;
Expand All @@ -34,15 +59,14 @@ public Move minimax(CheckersGameState s, int ply){
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;
}
Expand All @@ -54,15 +78,14 @@ private double maxValue(CheckersGameState s, double alpha, double beta, int ply,
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;
}
Expand Down
55 changes: 52 additions & 3 deletions src/CheckersGameState3.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ public class CheckersGameState3 implements CheckersGameState{

int player;
int[] board;
List<Move> actions;

public CheckersGameState3(int player, int[] board){
this.player = player;
this.board = board;
//System.out.println(this.moves());
this.actions = this.moves();
}

public CheckersGameState3() {
Expand All @@ -23,14 +26,53 @@ public CheckersGameState3() {
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;
}
Expand Down Expand Up @@ -144,6 +186,11 @@ private boolean any_jumps(int orig, int delta1, int delta2, int[] board, boolean
}

public List<Move> actions(){
return this.actions;
}


public List<Move> moves(){
LinkedList<Move> moves = new LinkedList<Move>();
LinkedList<Move> jumps = new LinkedList<Move>();
for(int i = 0; i < this.board.length; i++){
Expand All @@ -166,6 +213,8 @@ public List<Move> actions(){
}
}
}
//System.out.println(jumps);
//System.out.println(moves);
if(jumps.isEmpty()){
return moves;
}
Expand Down Expand Up @@ -285,8 +334,8 @@ public double pieceRatio(int player){
double mypieces = 0.0;
for(int i = 0; i<this.board.length; i++){
if(i%9!=8){
if(this.board[i] != 0 ) total+=1.0;
if(myPiece(this.board[i], player)) mypieces+=1.0;
else if(this.board[i] != 0 ) total+=1.0;
}
}
//System.out.println("" + mypieces);
Expand All @@ -295,7 +344,7 @@ public double pieceRatio(int player){

public boolean isTerminal(){
double rat = pieceRatio(this.player);
return (rat == 0 || rat == 1);
return (rat == 0 || rat == Double.POSITIVE_INFINITY);
}

public void printState(){
Expand Down
3 changes: 3 additions & 0 deletions src/Move.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ public interface Move {
// Returns the string representation of a move
public String toString();

boolean isJump();


}
4 changes: 4 additions & 0 deletions src/Move3.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public int[] captures(){
return kills;
}

public boolean isJump(){
return this.kills != null;
}

// private String convert(int pos){
// int x;
// int y;
Expand Down
1 change: 1 addition & 0 deletions src/RmCheckersClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ else if(player == 2) { // white
readAndEcho(); // move query
}
while(currentState.actions().size()>0){
currentState.printState();
Move myMove = ai.minimax(currentState, 8);
writeMessageAndEcho(myMove.toString());
if(!applyMove(myMove.toString())) {
Expand Down