• 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 }
  • 相关阅读:
    批处理学习总结
    深搜广搜
    罗塔的一篇回忆埃尔德什的文字
    一个有意思的东西(挖坑)
    人格风骨出尘俗 道德文章传后人(转载)
    2015年数学日历
    一道关于将弧翻折的问题
    努力要做的是理解,而不是死记硬背
    在博客中使用align*环境
    测试TeX代码的网址
  • 原文地址:https://www.cnblogs.com/fanerna/p/5406329.html
Copyright © 2020-2023  润新知