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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 35 additions & 12 deletions src/CheckersAI.java
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
55 changes: 52 additions & 3 deletions src/CheckersGameState3.java
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 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;
}
Expand Down Expand Up @@ -144,6 +186,11 @@ public class CheckersGameState3 implements CheckersGameState{
}

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 class CheckersGameState3 implements CheckersGameState{
}
}
}
//System.out.println(jumps);
//System.out.println(moves);
if(jumps.isEmpty()){
return moves;
}
Expand Down Expand Up @@ -285,8 +334,8 @@ public class CheckersGameState3 implements CheckersGameState{
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 class CheckersGameState3 implements CheckersGameState{

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
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
Expand Up @@ -37,6 +37,10 @@ public class Move3 implements Move{
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
Expand Up @@ -144,6 +144,7 @@ public class RmCheckersClient {
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