| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 774 人关注过本帖
标题:[求助]tictactoe源代码读不懂
只看楼主 加入收藏
williamschw
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2006-6-2
收藏
 问题点数:0 回复次数:0 
[求助]tictactoe源代码读不懂

#pragma warning (disable: 4786)

#include "Matrix.h"

#ifdef USE_DOT_H
#include <iostream.h>
#else
#include <iostream>
#if !defined( __BORLANDC__ ) || __BORLANDC__ >= 0x0530
using namespace std; // Seems to be a Borland 5.0 bug
#endif
#endif


#ifndef SAFE_STL
#include <map>
#include <functional>
using namespace std;
#else
#include "map.h"
#include "functional.h"
#include "StartConv.h"
#endif


struct Position
{
matrix<int> board;

Position( ) : board( 3, 3 ) { }
Position( const matrix<int> & theBoard ) : board( theBoard ) { }

bool operator< ( const Position & rhs ) const;
};

// Comparison operator, guarantees a total order.
bool Position::operator<( const Position & rhs ) const
{
for( int i = 0; i < 3; i++ )
for( int j = 0; j < 3; j++ )
if( board[ i ][ j ] != rhs.board[ i ][ j ] )
return board[ i ][ j ] < rhs.board[ i ][ j ];

return false;
}

typedef map<Position,int,less<Position> > MapType;
typedef MapType::const_iterator MapItr;

class TicTacToe
{
public:
enum Side { HUMAN, COMPUTER, EMPTY };
enum PositionVal { HUMAN_WIN, DRAW, UNCLEAR, COMPUTER_WIN };

TicTacToe( ) : board( 3, 3 ) { clearBoard( ); } // Constructor

// Find optimal move
int chooseMove( Side d, int & bestRow, int & bestColumn,
int alpha = HUMAN_WIN, int beta = COMPUTER_WIN, int depth = 0 );
// Play move, including checking legality
bool playMove( Side s, int row, int column );

// Simple supporting routines
void clearBoard( );
void getMove( );
bool boardIsFull( ) const;
bool isAWin( Side s ) const;

const matrix<int> & getBoard( ) const
{ return board; }

int getTransSize( ) const { return transpositions.size( ); }

private:
MapType transpositions;

matrix<int> board;

// Play a move, possible claering a square. No checks.
void place( int row, int column, int piece = EMPTY )
{ board[ row ][ column ] = piece; }

// Test if a square is empty.
bool squareIsEmpty( int row, int column ) const
{ return board[ row ][ column ] == EMPTY; }

// Compute static value of current position (win, draw, etc.)
int positionValue( ) const;
};

// Return the static value of the current position.
int TicTacToe::positionValue( ) const
{
return isAWin( COMPUTER ) ? COMPUTER_WIN :
isAWin( HUMAN ) ? HUMAN_WIN :
boardIsFull( ) ? DRAW : UNCLEAR;
}

// Routine to compute optimal tic-tac-toe move.
int TicTacToe::chooseMove( Side s, int & bestRow, int & bestColumn,
int alpha, int beta, int depth )
{
Side opp; // The other side
int reply; // Value of opponent's reply
int dc; // Placeholder
int simpleEval; // Result of an immediate evaluation
Position thisPosition = board;
int value;
static const int TABLE_DEPTH = 5; // Max depth placed in Trans. table

if( ( simpleEval = positionValue( ) ) != UNCLEAR )
return simpleEval;

if( depth == 0 )
transpositions = MapType( ); // makeEmpty

else if( depth >= 3 && depth <= TABLE_DEPTH )
{
MapItr itr = transpositions.find( thisPosition );
if( itr != transpositions.end( ) )
return (*itr).second;
}

if( s == COMPUTER )
{
opp = HUMAN; value = alpha;
}
else
{
opp = COMPUTER; value = beta;
}

for( int row = 0; row < 3; row++ )
for( int column = 0; column < 3; column++ )
if( squareIsEmpty( row, column ) )
{
place( row, column, s );
reply = chooseMove( opp, dc, dc, alpha, beta, depth + 1 );
place( row, column, EMPTY );
if( s == COMPUTER && reply > value ||
s == HUMAN && reply < value )
{
if( s == COMPUTER )
alpha = value = reply;
else
beta = value = reply;

bestRow = row; bestColumn = column;
if( alpha >= beta )
goto Done; // Refutation
}
}

Done:
if( depth <= TABLE_DEPTH )
transpositions[ thisPosition ] = value;
return value;
}

// Play a move. Return true if move is legal; return false otherwise.
bool TicTacToe::playMove( Side s, int row, int column )
{
if( row < 0 || row >= 3 || column < 0 || column >= 3
|| board[ row ][ column ] != EMPTY )
return false;
board[ row ][ column ] = s;
return true;
}

// Clear the board.
void TicTacToe::clearBoard( )
{
for( int row = 0; row < 3; row++ )
for( int column = 0; column < 3; column++ )
board[ row ][ column ] = EMPTY;
}

// Return true if board is full; return false otherwise.
bool TicTacToe::boardIsFull( ) const
{
for( int row = 0; row < 3; row++ )
for( int column = 0; column < 3; column++ )
if( board[ row ][ column ] == EMPTY )
return false;
return true;
}

// Return true if current position is a win for side s.
// Return false otherwise.
bool TicTacToe::isAWin( Side s ) const
{
int row, column;

// Look for all in a row
for( row = 0; row < 3; row++ )
{
for( column = 0; column < 3; column++ )
if( board[ row ][ column ] != s )
break;
if( column >= 3 )
return true;
}

// Look for all in a column
for( column = 0; column < 3; column++ )
{
for( row = 0; row < 3; row++ )
if( board[ row ][ column ] != s )
break;
if( row >= 3 )
return true;
}

// Look on diagonals
if( board[ 1 ][ 1 ] == s && board[ 2 ][ 2 ] == s
&& board[ 0 ][ 0 ] == s )
return true;

if( board[ 0 ][ 2 ] == s && board[ 1 ][ 1 ] == s
&& board[ 2 ][ 0 ] == s )
return true;

return false;
}


// From here downward, we have non-class functions to play the game.
void printBoard( const TicTacToe & obj, char compSide, char humanSide )
{
const matrix<int> & b = obj.getBoard( );
cout << "---" << endl;
for( int row = 0; row < 3; row++ )
{
for( int col = 0; col < 3; col++ )
if( b[ row ][ col ] == TicTacToe::COMPUTER )
cout << compSide;
else if( b[ row ][ col ] == TicTacToe::HUMAN )
cout << humanSide;
else
cout << ' ';
cout << endl;
}
cout << "---" << endl;
}

void doCompMove( TicTacToe & t, bool firstMove )
{
static int gameNum = 0;
int bestRow, bestCol, bestVal;

if( !firstMove )
t.chooseMove( TicTacToe::COMPUTER, bestRow, bestCol );
else
{
gameNum++;
bestRow = gameNum % 3; bestCol = gameNum / 3;
}

cout << "Transposition table size is: " << t.getTransSize( ) << endl;
cout << "Computer plays: ROW = " << bestRow << " COL = " << bestCol << endl;
t.playMove( TicTacToe::COMPUTER, bestRow, bestCol );
}

void playGame( bool compGoesFirst )
{
TicTacToe t;
char compSide, humanSide;
int row, col;

if( compGoesFirst )
{
compSide = 'x'; humanSide = 'o';
doCompMove( t, true );
}
else
{
compSide = 'o'; humanSide = 'x';
}

while( !t.boardIsFull( ) )
{
do
{
printBoard( t, compSide, humanSide );
cout << endl << "Enter row and col (starts at 0): ";
cin >> row >> col;
} while( !t.playMove( TicTacToe::HUMAN, row, col ) );

cout << endl;
printBoard( t, compSide, humanSide );
cout << endl;

if( t.isAWin( TicTacToe::HUMAN ) )
{
cout << "Human wins!!" << endl;
break;
}
if( t.boardIsFull( ) )
{
cout << "Draw!!" << endl;
break;
}

doCompMove( t, false );
if( t.isAWin( TicTacToe::COMPUTER ) )
{
cout << "Computer wins!!" << endl;
break;
}
if( t.boardIsFull( ) )
{
cout << "Draw!!" << endl;
break;
}
}
printBoard( t, compSide, humanSide );
}

int main( )
{
bool compGoesFirst = false;
char again;

cout << "Welcome to TIC-TAC-TOE" << endl;

while( true )
{
playGame( compGoesFirst );
cout << "Play again (y/n)? ";
cin >> again;
if( again == 'n' )
break;
compGoesFirst = !compGoesFirst;
}

return 0;
}

#include "EndConv.h"


主要是choosemove 部分的内容,希望牛人能给出点解释,谢谢,在线等

搜索更多相关主题的帖子: 源代码 tictactoe 
2006-06-02 20:49
快速回复:[求助]tictactoe源代码读不懂
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.039451 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved