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