Tic-Tac-Toe游戏

 1 //用来存储一步的类
 2  final class Best {
 3     
 4      int  row;
 5      int  column;
 6      int val;
 7      
 8      
 9      public    Best(int  v)
10      {
11          this(v,0,0);
12      }
13      public   Best(int   v,int r,int c)
14      {
15          val=v;
16          row=r;
17          column=c;
18      }
19 }
//position类
final  class Position {
	private   int    [][]board;
	
	public   Position  (int  [][]  theBoard)
	{
		board=new   int [3][3];
		for(int i=0;i<3;i++)
			for(int j=0;j<3;j++)
				board[i][j]=theBoard[i][j];
				                     
	}
	public  boolean  equals(Object  rhs)
	{
		if(!(rhs  instanceof  Position))
			return  false;
		//Position  other=(Position)hrs;
		
		
		for(int i=0;i<3;i++)
          for(int j=0;j<3;j++)
        	  if(board[i][j]!=((Position)rhs).board[i][j])
        		  return  false;
		return  true;
	}
public int  hashCode()
{
	int  hashVal=0;
	
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			hashVal=hashVal*4+board[i][j];
	
	return  hashVal;
}
}

  

  1 import java.awt.Frame;
  2 import java.awt.Panel;
  3 import java.awt.Button;
  4 import java.awt.GridLayout;
  5 
  6 import java.awt.event.WindowAdapter;
  7 import java.awt.event.ActionListener;
  8 import java.awt.event.ActionEvent;
  9 import java.awt.event.WindowEvent;
 10 
 11 public class TicTacMain extends Frame
 12 {
 13     /**
 14      * 
 15      */
 16     private static final long serialVersionUID = -1712977983195809884L;
 17 
 18     public TicTacMain( )
 19     {
 20         add( new TicTacPanel( ) );
 21         
 22         addWindowListener( new WindowAdapter( ) 
 23         {
 24             public void windowClosing( WindowEvent event ) 
 25             {
 26                 System.exit( 0 );
 27             }                 
 28         } );
 29     }
 30     
 31     
 32     public static void main( String [ ] args )
 33     {
 34         Frame f = new TicTacMain( );
 35         f.pack( );
 36         f.setVisible( true );
 37     }
 38 
 39     private static class TicTacPanel extends Panel implements ActionListener
 40     {
 41         public TicTacPanel( )
 42         {
 43             setLayout( new GridLayout( 3, 3 ) );
 44             for( int i = 0; i < 3; i++ )
 45                for( int j = 0; j < 3; j++ )
 46                {
 47                    squares[ i ][ j ] = new Button( );
 48                    add( squares[ i ][ j ] );
 49                    squares[ i ][ j ].addActionListener( this );
 50                }
 51                
 52                
 53             resetBoard( );
 54         }
 55 
 56         public void resetBoard( )
 57         {
 58             t = new TicTacToe( );
 59             for( int i = 0; i < 3; i++ )
 60                for( int j = 0; j < 3; j++ )
 61                {
 62                    squares[ i ][ j ].setLabel( "" );
 63                    squares[ i ][ j ].setEnabled( true );
 64                }
 65         }
 66 
 67         private int gameNum = 0;
 68 
 69         public void doCompMove( boolean thinkAboutIt )
 70         {
 71             Best compMove;
 72 
 73             if( thinkAboutIt )
 74                 compMove = t.chooseMove( TicTacToe.COMPUTER );
 75             else
 76             {
 77                 compMove = new Best( 0, gameNum % 3, gameNum / 3 );
 78                 gameNum = ( gameNum + 1 ) % 9;
 79             }
 80 
 81             System.out.println( " ROW = " + compMove.row +
 82                                 " COL = " + compMove.column );
 83 
 84             squares[ compMove.row ][ compMove.column ].setLabel( computerSide );
 85             squares[ compMove.row ][ compMove.column ].setEnabled( false );
 86             t.playMove( TicTacToe.COMPUTER, compMove.row, compMove.column );
 87         }
 88 
 89         public boolean resetIfDone( boolean condition, String message, boolean compMoves )
 90         {
 91             if( condition )
 92             {
 93                 System.out.println( message );
 94                 System.out.println( "Restarting..." );
 95                 resetBoard( );
 96                 if( compMoves )
 97                 {
 98                     System.out.println( "I go first..." );
 99                     computerSide = "X";
100                     humanSide = "O";
101                     doCompMove( false );
102                 }
103                 else
104                 {
105                     humanSide = "X";
106                     computerSide = "O";
107                     System.out.println( "You go first..." );
108                 }
109             }
110             return condition;
111         }
112 
113 
114         public void actionPerformed( ActionEvent evt )
115         {
116             if( evt.getSource( ) instanceof Button )
117             {
118                 ( (Button)evt.getSource( ) ).setLabel( humanSide );
119                 ( (Button)evt.getSource( ) ).setEnabled( false );
120 
121                 for( int i = 0; i < 3; i++ )
122                     for( int j = 0; j < 3; j++ )
123                         if( evt.getSource( ) == squares[ i ][ j ] )
124                             t.playMove( TicTacToe.HUMAN, i, j );
125 
126                 if( resetIfDone( t.boardIsFull( ), "DRAW", true ) )
127                     return;
128                 doCompMove( true );           
129                 resetIfDone( t.isAWin( TicTacToe.COMPUTER ), "I WIN!!", true );
130                 resetIfDone( t.boardIsFull( ), "DRAW", false );
131 
132                 return;
133             }
134         }
135 
136         private Button [ ][ ]  squares = new Button[ 3 ][ 3 ];
137         private TicTacToe t;
138         private String computerSide = "O";
139         private String humanSide    = "X";
140     }
141 }
  1 package s2;
  2 
  3 //结合了置换表和剪枝的TicTacToe类
  4 import  java.util.Map;
  5 import  java.util.HashMap;
  6 //TicTacToe类的框架
  7  class TicTacToe {
  8      public  static  final  int   HUMAN=0;
  9      public  static  final  int  COMPUTER=1;
 10      public  static   final  int   EMPTY=2;
 11      
 12      public  static  final  int   HUMAN_WIN=0;
 13      public  static   final   int     DRAW=1;
 14      public  static  final   int     UNCLEAR=2;
 15      public  static   final   int    COMPUTER_WIN=3;
 16     
 17      public     TicTacToe()
 18      {
 19             clearBoard();
 20             
 21      }
 22      
 23      
 24     private   Map<Position,Integer>transpositions=new   HashMap<Position,Integer>();
 25     public  Best    chooseMove(int  size)
 26     {
 27         return  chooseMove(size,HUMAN_WIN,COMPUTER_WIN,0);
 28     }
 29            //Find  optional  move
 30     private  Best  chooseMove(int side,int  alpha,int beta,int  depth)
 31     {
 32         int  opp;
 33         Best   reply;
 34     
 35         int simpleEval; 
 36         Position   thisPosition=new  Position(board);
 37         int  tableDepth=5;
 38         int  bestRow=0;
 39         int bestColumn=0;
 40         int value;
 41         
 42         
 43         
 44         
 45         if((simpleEval=positionValue())!=UNCLEAR)
 46             return  new   Best(simpleEval);
 47         if(depth==0)
 48             transpositions.clear();
 49         else if(depth>3&&depth<=tableDepth)
 50         {
 51             Integer  lookupVal=transpositions.get(thisPosition);
 52             if(lookupVal!=null)
 53                 return  new   Best(lookupVal);
 54         }
 55         if(side==COMPUTER)
 56         {
 57             opp=HUMAN;
 58             value=alpha;
 59         }
 60         else 
 61         {
 62             opp=COMPUTER;
 63             value=beta;
 64         }
 65         
 66         Outer:
 67             for(int row =0;row<3;row++)
 68                 for(int  column=0;column<3;column++)
 69                     if(squareIsEmpty(row,column))
 70                     {
 71                         place(row,column,side);
 72                         reply=chooseMove(opp,alpha,beta,depth+1);
 73                         place(row,column,EMPTY);
 74                         if(side==COMPUTER&&reply.val>value||side==HUMAN&&reply.val<value)
 75                         {
 76                             if(side==COMPUTER)
 77                                 alpha=value=reply.val;
 78                             else
 79                                 beta=value=reply.val;
 80                             
 81                             
 82                             bestRow=row;
 83                             bestColumn=column;
 84                             if(alpha>=beta)
 85                                 break  Outer;    //Refution
 86                         }
 87                     }
 88         if(depth<=tableDepth)
 89             transpositions.put(thisPosition,value);
 90              return   new   Best(value,bestRow,bestColumn);
 91         
 92             
 93     }
 94     private   int    positionValue()   /*估算位置的程序,根据棋盘上的情况返回HUMAN_WINDRAWCOMPUTER_WINUNCLEAR*
 95     所使用的策略是最大最小值策略*/
 96     {
 97         return   isAWin(COMPUTER)?COMPUTER_WIN:
 98                  isAWin(HUMAN)    ?HUMAN_WIN:
 99                  boardIsFull()   ?DRAW   :UNCLEAR;
100         
101     }
102     public   boolean     playMove(int row,int column,int side)
103     {
104         if( row < 0 || row >= 3 || column < 0 || column >= 3||board[row][column]!=EMPTY)
105             return  false;
106         board[ row ][ column ] = side;
107         return true;
108     }
109     public   void   clearBoard()
110     {
111           for( int i = 0; i < 3; i++ )
112                 for( int j = 0;j<3;j++)
113                     board[i][j]=EMPTY;
114     }
115     public  boolean  boardIsFull()
116     {
117          for( int row = 0; row < 3; row++ )
118                 for( int column = 0; column < 3; column++ )
119                     if( board[ row ][ column ] == EMPTY )
120                         return false;
121             return true;
122     }
123     public   boolean  isAWin(int  side)
124     {
125          int row, column;
126 
127          /* Look for all in a row */
128      for( row = 0; row < 3; row++ )
129      {
130          for( column = 0; column < 3; column++ )
131              if( board[ row ][ column ] != side )
132                  break;
133          if( column >= 3 )
134              return true;
135      }
136 
137      /* Look for all in a column */
138      for( column = 0; column < 3; column++ )
139      {
140          for( row = 0; row < 3; row++ )
141              if( board[ row ][ column ] != side )
142                  break;
143          if( row >= 3 )
144              return true;
145      }
146 
147      /* Look on diagonals */
148      if( board[ 1 ][ 1 ] == side && board[ 2 ][ 2 ] == side
149             && board[ 0 ][ 0 ] == side )
150          return true;
151 
152      if( board[ 0 ][ 2 ] == side && board[ 1 ][ 1 ] == side
153             && board[ 2 ][ 0 ] == side )
154          return true;
155 
156      return false;
157     }
158     private     void    place(int  row,int  column,int  piece)
159     {
160         board[row][column]=piece;
161         //Test   if   a  square   is  Empty
162     }
163     public   boolean  squareIsEmpty(int  row,int  column)
164     {
165         return  board[row][column]==EMPTY;
166         
167     }
168         private  int  [][]board=new  int[3][3];    //创建一个网格
169 }
原文地址:https://www.cnblogs.com/fanerna/p/5406329.html