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();
    }
}

 

posted @ 2015-08-10 08:08  xxx's blog  阅读(509)  评论(0编辑  收藏  举报