A naive AI for TicTacToe
TicTacToe 是一个很简单的棋盘游戏, 正因为如此, 即使是最直接的实现方式通常也能被很高效的执行。 下面是我自己写的一个简单的深度优先搜索的AI。
貌似这是一个And/OR Tree ?
package jp.co.worksap.global; import java.util.Arrays; import java.util.Scanner; class Position{ int x; int y; public Position(int x, int y){ this.x=x; this.y=y; } } public class TicTacToe { static final int N=3; int grid[][]=new int [N][N]; int curPlayer=0; boolean isOver=false; Scanner sc; boolean flag; void initialize(){ int i; for(i=0;i<N;i++ ){ Arrays.fill(grid[i], 0); } sc=new Scanner(System.in); } boolean gameDetection(int g[][]){ int i; for(i=0;i<N;i++){ if(g[i][0]==1&&g[i][1]==1&&g[i][2]==1) return true; if(g[i][0]==2&&g[i][1]==2&&g[i][2]==2) return true; if(g[0][i]==1&&g[1][i]==1&&g[2][i]==1) return true; if(g[0][i]==2&&g[1][i]==2&&g[2][i]==2) return true; } if(g[0][0]==1&&g[1][1]==1&&g[2][2]==1) return true; if(g[0][0]==2&&g[1][1]==2&&g[2][2]==2) return true; if(g[0][2]==1&&g[1][1]==1&&g[2][0]==1) return true; if(g[0][2]==2&&g[1][1]==2&&g[2][0]==2) return true; return false; } void play(int player){ if(player==1){ Position posi=dfs_planning(); grid[posi.x][posi.y]=1; } else if(player==2){ //human player for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ System.out.print(grid[i][j]+" "); } System.out.println(); } System.out.println("Input (x,y) to play: "); do{ int x=sc.nextInt(); int y=sc.nextInt(); if(x>=0&&x<N&&y>=0&&y<N&&grid[x][y]==0){ grid[x][y]=2; if(gameDetection(grid)){ System.out.println("Game over. human win."); } break; } else System.out.print("Not valid position to play"); } while(true); System.out.println("Now computer's turn."); } } Position dfs_planning(){ int g2[][]=new int[N][N]; int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++){ g2[i][j]=grid[i][j]; } } for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(g2[i][j]==0){ flag=false; g2[i][j]=1; flag=couldLose(g2, 2); if(flag==false){ return new Position(i,j); } else System.out.println(i+", "+j+" is not possible."); g2[i][j]=0; } } } System.out.println("returning null"); return null; } boolean willLose(int g[][]){ int i; for(i=0;i<N;i++){ if(g[i][0]+g[i][1]+g[i][2]==4 && g[i][0]*g[i][1]*g[i][2]==0) return true; if(g[0][i]+g[1][i]+g[2][i]==4 && g[0][i]*g[1][i]*g[2][i]==0) return true; } if(g[0][0]+g[1][1]+g[2][2]==4 && g[0][0]*g[1][1]*g[2][2]==0) return true; if(g[0][2]+g[1][1]+g[2][0]==4 && g[0][2]*g[1][1]*g[2][0]==0) return true; return false; } boolean willWin(int g[][]){ int i; for(i=0;i<N;i++){ if((g[i][0]==1&&g[i][1]==1&&g[i][2]==0)||(g[i][0]==1&&g[i][1]==0&&g[i][2]==1) ||(g[i][0]==0&&g[i][1]==1&&g[i][2]==1)) return true; if((g[0][i]==1&&g[1][i]==1&&g[2][i]==0)||(g[0][i]==1&&g[1][i]==0&&g[2][i]==1) ||(g[0][i]==0&&g[1][i]==1&&g[2][i]==1)) return true; } if((g[0][0]==1 &&g[1][1]==1 && g[2][2]==0) || (g[0][0]==1&&g[1][1]==0&&g[2][2]==1) || (g[0][0]==0&&g[1][1]==1&&g[2][2]==1)) return true; if((g[0][2]==1 &&g[1][1]==1 && g[2][0]==0) ||(g[0][2]==1&&g[1][1]==0&&g[2][0]==1) ||(g[0][2]==0&&g[1][1]==1&&g[2][0]==1)) return true; return false; } boolean couldLose(int g2[][], int player){ int i,j,k; k=0; for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(g2[i][j]==0) k++; } } if(k==0) return false; else { if(player==1){ if(willWin(g2))return false; boolean res=true; for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(g2[i][j]==0){ g2[i][j]=player; res&=couldLose(g2, 3-player); g2[i][j]=0; } } } return res; } else{ if(willLose(g2)) { return true; } boolean res=false; for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(g2[i][j]==0){ g2[i][j]=player; res|=couldLose(g2, 3-player); g2[i][j]=0; } } } return res; } } } static int fact(int n){ if(n==1) return 1; else return n*fact(n-1); } public static void main(String args[]){ TicTacToe ttt=new TicTacToe(); ttt.initialize(); ttt.curPlayer=2; while(ttt.gameDetection(ttt.grid)==false){ ttt.play(ttt.curPlayer); ttt.curPlayer=3-ttt.curPlayer; } System.out.println("GAME END"); for(int i=0;i<N;i++){ for(int j=0;j<N;j++)System.out.print(ttt.grid[i][j]+" "); System.out.println(); } ttt.sc.close(); } }