diff --git a/src/GameState1.java b/src/GameState1.java index 5a27c90..9847d7c 100644 --- a/src/GameState1.java +++ b/src/GameState1.java @@ -1,70 +1,60 @@ import java.util.ArrayList; import java.util.List; +import java.util.Arrays; +import java.util.Random; public class GameState1 implements CheckersGameState{ public static void main(String[] args){ //testing some methods - GameState1 game = new GameState1(); //initial game state - game.printState(); //print the state - List moves = game.actions(); - System.out.println(); - System.out.println("Available Moves:"); - for(Move m : moves){ - m.printMove(); - } - System.out.println("\n" + "Test1: Move(2,1) to (3,0) result (moving black piece foward"); - CheckersGameState result = game.result(new Move(2,1,3,0,false)); - result.printState(); - List moves2 = result.actions(); - System.out.println(); - System.out.println("Available Moves:"); - for(Move m : moves2){ - m.printMove(); - } - System.out.println("\n" + "Test2: Move(5,2) to (4,1) result (moving white piece foward"); - CheckersGameState result2 = result.result(new Move(5,2,4,1,false)); - result2.printState(); - List moves3 = result2.actions(); - System.out.println(); - System.out.println("Available Moves:"); - for(Move m3 : moves3){ - m3.printMove(); - } - System.out.println("\n" + "Test3: Move(3,0) to (5,2) result (jumping and capturing a piece)"); - CheckersGameState result3 = result2.result(new Move(3,0,5,2,true)); - result3.printState(); - - String[][] b = new String[8][8]; - b[1][0] = "w"; - b[0][3] = "b"; - b[0][5] = "b"; - GameState1 g = new GameState1(b,false); - g.printState(); - List m4 = g.actions(); - for(Move m : m4){ - m.printMove(); + Random r = new Random(); + String[][] b3 = new String[8][8]; + b3[4][2] = "B"; + b3[3][1] = "w"; + b3[1][1] = "w"; + b3[1][3] = "w"; + b3[3][3] = "w"; + CheckersGameState g7 = new GameState1(b3,true); + g7.printState(); + List m6 = g7.actions(); + for(Move m : m6){ + System.out.println(m); } + g7.result(g7.actions().get(0)).printState(); + CheckersGameState g1 = new GameState1(); + g1.printState(); + for(Move m: g1.actions()){ + System.out.println(m); + } + g1.result(g1.actions().get(0)).printState(); + b3[5][3] = "w"; + b3[6][4] = "b"; + b3[4][2] = null; + CheckersGameState g2 = new GameState1(b3, false); + g2.printState(); + for(Move m: g2.actions()){ + System.out.println(m); + } + g2.result(g2.actions().get(0)).printState(); + CheckersGameState g3 = new GameState1(b3, true); + g3.printState(); + for(Move m: g3.actions()){ + System.out.println(m); + } + g3.result(g3.actions().get(0)).printState(); + System.out.println("This is initial board followed by entire game played"); + CheckersGameState state = new GameState1(); + state.printState(); + List actions = state.actions(); + while(actions.size() > 0){ + for(Move m: actions){ + System.out.println(m +" ~~ "); + } + state = state.result(actions.get(r.nextInt(actions.size()))); + state.printState(); + actions = state.actions(); + } - System.out.println("\n" + "Test4: Move(1,0) to (0,1) result (creating a king)"); - CheckersGameState g2 = g.result(new Move(1,0,0,1,false)); - g2.printState(); - - String[][] b2 = new String[8][8]; - b2[4][2] = "W"; - b2[3][1] = "b"; - b2[3][3] = "B"; - b2[5][1] = "b"; - b2[5][3] = "b"; - GameState1 g3 = new GameState1(b2,false); - g3.printState(); - List m5 = g3.actions(); - for(Move m : m5){ - m.printMove(); - } - System.out.println("\n" + "Test6: Move(4,2) to (2,0) result (king jumping backward and capturing)"); - CheckersGameState g4 = g3.result(new Move(4,2,2,0,true)); - g4.printState(); } @@ -74,30 +64,30 @@ public static void main(String[] args){ public GameState1(){ String[][] b = new String[8][8]; - b[0][1]="b"; - b[0][3]="b"; - b[0][5]="b"; - b[0][7]="b"; - b[1][0]="b"; - b[1][2]="b"; - b[1][4]="b"; - b[1][6]="b"; - b[2][1]="b"; - b[2][3]="b"; - b[2][5]="b"; - b[2][7]="b"; - b[5][0]="w"; - b[5][2]="w"; - b[5][4]="w"; - b[5][6]="w"; - b[6][1]="w"; - b[6][3]="w"; - b[6][5]="w"; - b[6][7]="w"; - b[7][0]="w"; - b[7][2]="w"; - b[7][4]="w"; - b[7][6]="w"; + b[7][1]="b"; + b[7][3]="b"; + b[7][5]="b"; + b[7][7]="b"; + b[6][0]="b"; + b[6][2]="b"; + b[6][4]="b"; + b[6][6]="b"; + b[5][1]="b"; + b[5][3]="b"; + b[5][5]="b"; + b[5][7]="b"; + b[2][0]="w"; + b[2][2]="w"; + b[2][4]="w"; + b[2][6]="w"; + b[1][1]="w"; + b[1][3]="w"; + b[1][5]="w"; + b[1][7]="w"; + b[0][0]="w"; + b[0][2]="w"; + b[0][4]="w"; + b[0][6]="w"; _board = b; _player = true; @@ -109,162 +99,183 @@ public GameState1(String[][] board, boolean player){ } - @Override + + public List actions() { - GameState1 game = this; - ArrayList list = new ArrayList<>(); - String[][] b = game._board; + List jumps = new ArrayList(); + List moves = new ArrayList(); + String[][] b = _board; for(int i=0; i<8; i++){ for(int j=0; j<8; j++){ - if(b[i][j]!=null && this._player){//if not null and blacks turn - if(b[i][j] == "b"){ - if(game.canJumpL(i,j)){list.add(new Move(i,j,i+2,j-2,true));} - if(game.canJumpR(i,j)){list.add(new Move(i,j,i+2,j+2,true));} - if(game.canMoveL(i,j)){list.add(new Move(i,j,i+1,j-1,false));} - if(game.canMoveR(i,j)){list.add(new Move(i,j,i+1,j+1,false));} - - } - else if(b[i][j] == "B"){ - if(game.canJumpL(i,j)){list.add(new Move(i,j,i+2,j-2,true));} - if(game.canJumpR(i,j)){list.add(new Move(i,j,i+2,j+2,true));} - if(game.canMoveL(i,j)){list.add(new Move(i,j,i+1,j-1,false));} - if(game.canMoveR(i,j)){list.add(new Move(i,j,i+1,j+1,false));} - if(game.canBackL(i,j)){list.add(new Move(i,j,i-1,j-1,false));} - if(game.canBackR(i,j)){list.add(new Move(i,j,i-1,j+1,false));} - if(game.canJumpBackL(i,j)){list.add(new Move(i,j,i-2,j-2,true));} - if(game.canJumpBackR(i,j)){list.add(new Move(i,j,i-2,j-2,true));} - } - } - else if(b[i][j]!=null && !this._player){ - if(b[i][j] == "w"){ - if(game.canJumpBackL(i,j)){list.add(new Move(i,j,i-2,j-2,true));} - if(game.canJumpBackR(i,j)){list.add(new Move(i,j,i-2,j+2,true));} - if(game.canBackL(i,j)){list.add(new Move(i,j,i-1,j-1,false));} - if(game.canBackR(i,j)){list.add(new Move(i,j,i-1,j+1,false));} - } - else if(b[i][j] == "W"){ - if(game.canJumpL(i,j)){list.add(new Move(i,j,i+2,j-2,true));} - if(game.canJumpR(i,j)){list.add(new Move(i,j,i+2,j+2,true));} - if(game.canMoveL(i,j)){list.add(new Move(i,j,i+1,j-1,false));} - if(game.canMoveR(i,j)){list.add(new Move(i,j,i+1,j+1,false));} - if(game.canBackL(i,j)){list.add(new Move(i,j,i-1,j-1,false));} - if(game.canBackR(i,j)){list.add(new Move(i,j,i-1,j+1,false));} - if(game.canJumpBackL(i,j)){list.add(new Move(i,j,i-2,j-2,true));} - if(game.canJumpBackR(i,j)){list.add(new Move(i,j,i-2,j+2,true));} - } - } - + if(b[j][i]!=null && matches(i, j, _board)){//if not null and blacks turn + if(b[j][i].equals("w")){ + generate_moves(i, j, 1, moves, jumps, false); + } + else if(b[j][i].equals("W")){ + generate_moves(i, j, 1, moves, jumps, true); + } + else if(b[j][i].equals("b")){ + generate_moves(i, j, -1, moves, jumps, false); + } + else if(b[j][i].equals("B")){ + generate_moves(i, j, -1, moves, jumps, true); + } } } - return list; + } + if(jumps.isEmpty()){ + return moves; + } + return jumps; } - @Override + + private void generate_moves(int x, int y, int deltay, List moves, List jumps, boolean king){ + ArrayList path = new ArrayList(); + path.add(""+y+":"+x); + calculate_jumps(x, y, deltay, king, path, jumps, this._board); + if(jumps.isEmpty()){ + if(can_move(x+1, y+deltay)){ + ArrayList m = new ArrayList(); + m.add(""+y+":"+x); + m.add(""+(y+deltay)+":"+(x+1)); + moves.add(new Move1(m)); + } + if(can_move(x-1, y+deltay)){ + ArrayList m = new ArrayList(); + m.add(""+y+":"+x); + m.add(""+(y+deltay)+":"+(x-1)); + moves.add(new Move1(m)); + } + if(can_move(x-1, y-deltay) && king){ + ArrayList m = new ArrayList(); + m.add(""+y+":"+x); + m.add(""+(y - deltay)+":"+(x-1)); + moves.add(new Move1(m)); + } + if(can_move(x+1, y-deltay) && king){ + ArrayList m = new ArrayList(); + m.add(""+y+":"+x); + m.add(""+(y-deltay)+":"+(x+1)); + moves.add(new Move1(m)); + } + } + } + + + private boolean within_bounds(int x, int y){ + return (x<=7 && y<=7 && x>=0 && y>=0); + } + + private boolean can_move(int x, int y){ + return within_bounds(x, y) && empty(x, y, this._board); + } + + private boolean matches(int x, int y, String[][] board){ + return (board[y][x] != null) && (((board[y][x].equals("b")||board[y][x].equals("B"))&& this._player) || ((board[y][x].equals("w") || board[y][x].equals("W")) && !this._player)); + } + + private boolean empty(int x, int y, String[][] board){ + return board[y][x] == null; + } + + private boolean can_jump(int x_i, int y_i, int x, int y, String[][] board){ + return (within_bounds(x_i + x, y_i + y) && !matches(x_i + x, y_i + y, board) && within_bounds(x_i + 2*x, y_i + 2*y) && empty(x_i + 2*x, y_i + 2*y, board) && board[y_i+y][x_i + x]!=null); + } + + private boolean any_jumps(int x_i, int y_i, int y, String[][] board, boolean king){ + boolean forward = can_jump(x_i, y_i, 1, y, board) || can_jump(x_i, y_i, -1, y, board); + if(!king){ + return forward; + } + boolean backward = can_jump(x_i, y_i, 1, -1 * y, board) || can_jump(x_i, y_i, -1, -1 * y, board); + return backward || forward; + } + + private String[][] copy(String[][] b){ + String[][] ret = new String[8][]; + for(int i=0; i<8; i++){ + ret[i] = b[i].clone(); + } + return ret; + } + + + public void calculate_jumps(int x_i, int y_i, int y, boolean king, ArrayList path, List jumps, String[][] board){ + if(!any_jumps(x_i, y_i, y, board, king)){ + if(path.size()>1){ + jumps.add(new Move1(path)); + } + return; + } + if(can_jump(x_i, y_i, 1, y, board)){ + String j = "" + (y_i + 2*y)+ ":" + (x_i + 2); + String[][] b = copy(board); + b[y_i+y] [x_i + 1]= null; + b[y_i + 2*y] [x_i +2]= b[y_i][x_i]; + b[y_i][x_i]=null; + ArrayList new_path = (ArrayList) path.clone(); + new_path.add(j); + calculate_jumps(x_i + 2, y_i + 2*y, y, king, new_path, jumps, b); + } + if(can_jump(x_i, y_i, -1, y, board)){ + String j = "" + (y_i + 2*y) + ":" +( x_i + -2); + String[][] b = copy(board); + b[y_i+y][x_i + -1]= null; + b[y_i + 2*y][x_i +-2]= b[y_i][x_i]; + b[y_i][x_i]=null; + ArrayList new_path = (ArrayList) path.clone(); + new_path.add(j); + calculate_jumps(x_i -2, y_i + 2*y, y, king, new_path, jumps, b); + } + if(king && can_jump(x_i, y_i, -1, -1 *y, board)){ + String j = "" + (y_i - (2*y))+ ":" + (x_i + -2); + String[][] b = copy(board); + b[y_i-y][x_i + -1] = null; + b[y_i - 2*y][x_i +-2] = b[y_i][x_i]; + b[y_i][x_i]=null; + ArrayList new_path = (ArrayList) path.clone(); + new_path.add(j); + calculate_jumps(x_i + -2, y_i - 2*y, y, king, new_path, jumps, b); + } + if(king && can_jump(x_i, y_i, 1, -1 *y, board)){ + String j = "" +(y_i - (2*y)) + ":" + (x_i + 2) ; + String[][] b = copy(board); + b[y_i-y][x_i + 1] = null; + b[y_i - 2*y][x_i +2]= b[y_i][x_i]; + b[y_i][x_i]=null; + ArrayList new_path = (ArrayList) path.clone(); + new_path.add(j); + calculate_jumps(x_i + 2, y_i - 2*y, y, king, new_path, jumps, b); + } + + + } + //fix this - public CheckersGameState result(Move x) { - GameState1 game = this; - String[][] b = this._board; - boolean p = this._player; - CheckersGameState next = null; - //check if this situation will result in a king B - if((x._x == 6 && x._x2 == 7)&& (b[x._x][x._y] != "W")){ - b[x._x2][x._y2] = "B"; - b[x._x][x._y] = null; - if(game.canJumpBackL(x._x2, x._y2) || game.canJumpBackR(x._x2, x._y2) ){ - next = new GameState1(b,p); - } - else - next = new GameState1(b,!p); - } - //check if this will result in king W - else if((x._x == 1 && x._x2 == 0)&& (b[x._x][x._y] != "B")){ - b[x._x2][x._y2] = "W"; - b[x._x][x._y] = null; - if(game.canJumpL(x._x2, x._y2) || game.canJumpR(x._x2, x._y2)){ - next = new GameState1(b,p); - } - else - next = new GameState1(b,!p); - } - //if you get a king by jumping into end of whites side, change to B and remove captured piece - else if((x._x == 5 && x._x2 == 7)&& (b[x._x][x._y] != "W")){ - b[x._x2][x._y2] = "B"; - b[x._x][x._y] = null; - if(x._y2>x._y){ //jumping right, set the one you jumped over to be null - b[x._x+1][x._y+1] = null; - } - else{ - b[x._x+1][x._y-1] = null; - } - if(game.canJumpBackL(x._x2, x._y2) || game.canJumpBackR(x._x2, x._y2)){ - //if there is another jump we can take, return state with same players turn - next = new GameState1(b,p); - } - else{ - next = new GameState1(b,!p); - } - } - //if you get a king by jumping to end of blacks side, change to W and remove captured piece - else if((x._x == 2 && x._x2 == 0)&& (b[x._x][x._y] != "B")){ - b[x._x2][x._y2] = "W"; - b[x._x][x._y] = null; - if(x._y2>x._y){ //jumping right, set the one you jumped over to be null - b[x._x-1][x._y+1] = null; - } - else{ - b[x._x-1][x._y-1] = null; - } - if(game.canJumpL(x._x2, x._y2) || game.canJumpR(x._x2, x._y2)){ - //if there is another jump we can take, return state with same players turn - next = new GameState1(b,p); - } - else{ - next = new GameState1(b,!p); - } - } - //if just a normal jump - else if(x._b){ - String s = b[x._x][x._y]; - b[x._x2][x._y2] = s; - if(x._y2>x._y && x._x2>x._x){ - b[x._x+1][x._y+1] = null; - b[x._x][x._y]=null; - next = new GameState1(b,!p); - } - else if(x._y2x._x){ - b[x._x+1][x._y-1] = null; - b[x._x][x._y]=null; - next = new GameState1(b,!p); - } - else if(x._y2>x._y && x._x2=0; i--){ System.out.println(); for(int j=0; j<8; j++){ if(board[i][j]==null) @@ -275,7 +286,6 @@ public void printState() { System.out.println("\n\n" + this.player() + "'s move"); } - @Override public String player() { if(!this._player) @@ -283,111 +293,4 @@ public String player() { return "Black"; } - private boolean canBackL(int i, int j){ - GameState1 game = this; - String[][] b = game._board; - if(j!=0 && i!=0){ - if(b[i-1][j-1]==null){ - return true; - } - } - return false; - } - private boolean canMoveL(int i, int j){ - GameState1 game = this; - String[][] b = game._board; - if(j!=0 && i!=7){ - if(b[i+1][j-1]==null){ - return true; - } - } - return false; - } - private boolean canBackR(int i, int j){ - GameState1 game = this; - String[][] b = this._board; - if(j!=7 && i!=0){ - if(b[i-1][j+1]==null){ - return true; - } - } - return false; - } - private boolean canMoveR(int i, int j){ - GameState1 game = this; - String[][] b = this._board; - if(j!=7 && i!=7){ - if(b[i+1][j+1]==null){ - return true; - } - } - return false; - } - private boolean canJumpBackL(int i, int j){ - GameState1 game = this; - String[][] b = this._board; - if(j!=0 && j!=1 && i!=0 && i!=1){ - if(!game._player){ - if(b[i-1][j-1] =="b" || b[i-1][j-1]=="B"){ - if(b[i-2][j-2]==null){ - return true; - } - } - } - else if(game._player){ - if(b[i-1][j-1] =="w" || b[i-1][j-1]=="W"){ - if(b[i-2][j-2]==null){ - return true; - } - } - } - } - return false; - } - private boolean canJumpL(int i, int j){ - GameState1 game = this; - String[][] b = this._board; - if(j!=0 && j!=1 && i!=6 && i!=7){ - if(b[i+1][j-1] =="w" || b[i+1][j-1]=="W" || b[i][j] == "B" || b[i][j] == "W"){ - if(b[i+2][j-2]==null){ - return true; - } - } - } - return false; - } - private boolean canJumpBackR(int i, int j){ - GameState1 game = this; - String[][] b = this._board; - if(j!=6 && j!=7 && i!=0 && i!=1){ - if(!game._player){ - if(b[i-1][j+1]=="b" || b[i-1][j+1]=="B"){ - if(b[i-2][j+2]==null){ - return true; - } - } - } - else if(game._player){ - if(b[i-1][j+1]=="w" || b[i-1][j+1]=="W"){ - if(b[i-2][j+2]==null){ - return true; - } - } - } - } - return false; - } - private boolean canJumpR(int i, int j){ - GameState1 game = this; - String[][] b = this._board; - if(j!=6 && j!=7 && i!=6 && i!=7){ - if(b[i+1][j+1]=="w" || b[i+1][j+1]=="W" || b[i][j] == "B" || b[i][j] == "W"){ - if(b[i+2][j+2]==null){ - return true; - } - } - } - return false; - } - } diff --git a/src/Move1.java b/src/Move1.java index ede4f76..29584fd 100644 --- a/src/Move1.java +++ b/src/Move1.java @@ -1,22 +1,70 @@ +import java.util.ArrayList; -public class Move { +public class Move1 implements Move{ //(x,y) current position, (x2,y2) position move to - int _x; - int _y; - int _x2; - int _y2; - boolean _b; - - public Move(int x, int y, int x2, int y2, boolean b){ - _x = x; - _y = y; - _x2 = x2; - _y2 = y2; - _b = b; + ArrayList moves; + public Move1(ArrayList moves){ + this.moves = moves; } - public void printMove(){ - System.out.println("("+this._x+","+this._y+"):("+this._x2+","+this._y2+")" ); + private int parseX(String move){ + return Integer.parseInt(move.split(":")[0]); + } + private int parseY(String move){ + return Integer.parseInt(move.split(":")[1]); + } + + public int[] captures(){ + return null; + } + + public ArrayList kills(){ + ArrayList captures = new ArrayList(); + for(int i = 0; i