mimimax for Tictactoe

MiniMax is another way of impleneting a simple AI for TicTacToe. Here is the code. 

 

package com.tictactoe;

public class Point {
    int x;
    int y;
    Point(int x, int y){
        this.x=x;
        this.y=y;
    }
    public String toString(){
        return " ("+x+","+y+") ";
    }

}
package com.tictactoe;

import java.util.ArrayList;
import java.util.List;

/*
 * 2 for human player
 * 1 for computer player
 */
public class Node {
    Node parent;
    Point position;
    int player;
    int score;
    int status;
    static final int STATUS_PLAYING=1;
    static final int STATUS_HUMAN_WIN=2;
    static final int STATUS_HUMAN_LOSE=3;
    static final int STATUS_DRAW=4;
    
    Node(Node parent, int player){
        this.parent=parent;
        this.player=player;
    }
    
    int nodeStatus(){
        return this.status;
    }
    
    void checkStatus(){
        int N=TicTacToe.N;
        int g[][]=new int[N][N];
        Node e=this;
        while(e.parent!=null){
            g[e.position.x][e.position.y]=e.player;
            e=e.parent;
        }
        g[e.position.x][e.position.y]=e.player;
        for(int i=0;i<N;i++){
            if((g[i][0]==1 && g[i][1]==1 && g[i][2]==1)||(g[0][i]==1&&g[1][i]==1&&g[2][i]==1)){
                this.status=Node.STATUS_HUMAN_LOSE;
                return;
            }
            if((g[i][0]==2 && g[i][1]==2 && g[i][2]==2)||(g[0][i]==2&&g[1][i]==2&&g[2][i]==2)){
                this.status=Node.STATUS_HUMAN_WIN;
                return;
            }
        }
        if((g[0][0]==1&&g[1][1]==1&&g[2][2]==1)||(g[0][2]==1&&g[1][1]==1&&g[2][0]==1)){
            this.status=Node.STATUS_HUMAN_LOSE;
            return;
        }
        if((g[0][0]==2&&g[1][1]==2&&g[2][2]==2)||(g[0][2]==2&&g[1][1]==2&&g[2][0]==2)){
            this.status=Node.STATUS_HUMAN_WIN;
            return;
        }
        int k=0;
        for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(g[i][j]==0) k++;
        if(k==0){
            this.status=Node.STATUS_DRAW;
            return;
        }
        this.status=Node.STATUS_PLAYING;
    }
    
    boolean isTerminal(){
        checkStatus();
        if(this.status!=Node.STATUS_PLAYING) return true;
        else return false;
    }
    
    List<Node> getChildren(){
        int i,j;
        int N=TicTacToe.N;
        int g[][]=new int[N][N];
        Node e=this;
        while(e.parent!=null){
            g[e.position.x][e.position.y]=e.player;
            e=e.parent;
        }
        g[e.position.x][e.position.y]=e.player;
        List<Node> list=new ArrayList<Node>();
        for(i=0;i<N;i++){
            for(j=0;j<N;j++){
                if(g[i][j]==0){
                    Node node=new Node(this, 3-this.player);
                    Point p=new Point(i,j);
                    node.position=p;
                    list.add(node);
                }
            }
        }
        return list;
    }
    void display(){
        int i,j;
        int N=TicTacToe.N;
        int g[][]=new int[N][N];
        Node e=this;
        while(e.parent!=null){
            g[e.position.x][e.position.y]=e.player;
            e=e.parent;
        }
        g[e.position.x][e.position.y]=e.player;
        System.out.println("Player is: "+this.player+" Game status: "+this.status+" playing at"+this.position);
        for(i=0;i<N;i++, System.out.println()){
            for(j=0;j<N;j++)
                System.out.print(g[i][j]+" ");
        }
    }
}
package com.tictactoe;

import java.util.Scanner;

public class TicTacToe {
    static final int N=3;
    int board[][];
    int miniMax(Node node, int player){
        if(node.isTerminal()){
            if(node.status==Node.STATUS_DRAW) return 0;
            if(node.status==Node.STATUS_HUMAN_LOSE) return 1;
            if(node.status==Node.STATUS_HUMAN_WIN) return -1;
            System.out.println("terminal but playing?");
            return 0;
        } else{
            if(player==1){
                int v=Integer.MIN_VALUE;
                for(Node e: node.getChildren()){
                    v=Math.max(v, miniMax(e,3-player));
                }
                return v;
            } else {
                int v=Integer.MAX_VALUE;
                for(Node e: node.getChildren()){
                    v=Math.min(v, miniMax(e,3-player));
                }
                return v;
            }
        }
        
    }
    
    boolean isGameOver(){
        int g[][]=board;
        for(int i=0;i<N;i++){
            if((g[i][0]==1 && g[i][1]==1 && g[i][2]==1)||(g[0][i]==1&&g[1][i]==1&&g[2][i]==1)){
                return true;
            }
            if((g[i][0]==2 && g[i][1]==2 && g[i][2]==2)||(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)||(g[0][2]==1&&g[1][1]==1&&g[2][0]==1)){
            return true;
        }
        if((g[0][0]==2&&g[1][1]==2&&g[2][2]==2)||(g[0][2]==2&&g[1][1]==2&&g[2][0]==2)){
            return true;
        }
        int k=0;
        for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(g[i][j]==0) k++;
        if(k==0){
            return true;
        }
        return false;
    }
    void displayBoard(){
        int i,j;
        for(i=0;i<N;i++){
            for(j=0;j<N;j++){
                System.out.print(board[i][j]+" ");
            }
            System.out.println();
        }
    }
    void play(){
        System.out.println("2 for Human, 1 for Computer.");
        Scanner sc=new Scanner(System.in);
        int x;
        int y;
        
        board=new int[N][N];
        int currentplayer=2;
        Node root=null;
        while(isGameOver()==false){
            if(currentplayer==2){
                do {
                    System.out.println("Huam play first, input a position to play");
                    x=sc.nextInt();
                    y=sc.nextInt();
                }while(!(x>=0&&x<N&&y>=0&&y<N));
                board[x][y]=2;
                System.out.println("Now board is:");
                
                Node node=new Node(root, 2);
                node.position=new Point(x,y);
                node.checkStatus();
                node.display();
                currentplayer=1;
                root=node;
            } else {
                Node sNode=null;
                int maxScore=Integer.MIN_VALUE;
                for(Node e: root.getChildren()){
                    int s=miniMax(e,2);
                    if(maxScore<s){
                        sNode=e;
                        maxScore=s;
                    }
                }
                System.out.println("Computer select max score:"+maxScore);
                board[sNode.position.x][sNode.position.y]=1;
                sNode.checkStatus();
                sNode.display();
                root=sNode;
                currentplayer=2;
            }
        }
        sc.close();
    }
    
    public static void main(String args[]){
        TicTacToe tt=new TicTacToe();
        tt.play();
        System.out.println("End Game");
    }

}

 

posted @ 2015-08-17 13:38  xxx's blog  阅读(505)  评论(0编辑  收藏  举报