zoukankan      html  css  js  c++  java
  • 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");
        }
    
    }
  • 相关阅读:
    使用 VBRichClient 库
    提取文件夹目录的办法
    编程语言转换
    解决linux服务器上matplotlib中文显示乱码问题
    动态规划 53:Maximum Subarray,152:Maximum Subarray,266. Palindrome Permutation 回文全排列
    动态规划:494,576
    ResourceExhaustedError 解决方案
    周赛138场
    leetcode 115
    leetcode 372
  • 原文地址:https://www.cnblogs.com/gaoqichao/p/4736388.html
Copyright © 2011-2022 走看看