PDA

View Full Version : [DIS]Caro?



ngtuankiet
04-10-2002, 16:31
Chương trình caro hả? Mình có làm cho 2 người chơi,lâu lắm rồi hồi mình mới biết về C thôi,nhưng không có dùng đồ họa nên xấu lắm và cũng viết rất đơn giản.
Mình đang định viết lại cho 1 ngừoi chơi và dùng cả đồ họa nữa nhưng không có nhiều thời gian.

madcat
08-10-2002, 14:49
tôi định post bài này, tôi cũng viết nó lúc mới sử dụng C

lgthanh
17-10-2002, 09:35
rat vui neu duoc xem

phoenix
13-11-2002, 22:22
hic, sao không thấy ai post lên hết vậy, tui cũng muốn được tham khảo chương trình caro đó

CrazyKing
14-11-2002, 01:01
02 người chơi thì đâu có gì để nói , tìm hiểu chút về socket là xong , vấn đề là 1 người chơi với máy !!!! là Hueristic đó mấy bác !!! Thành công hay không là vào thời điểm ban đầu đó !

phoenix
15-11-2002, 22:44
thì tui đang điên đầu với heuristic đây, có ai giúp tui 1 vài ý tường để hoàn tất chương trình chơi caro với máy ko?

bpmtri
19-11-2002, 09:03
Phoenix xêm thêm các bài viết trong forum này nè:

http://diendantinhoc.org/forum/?action=msg&msg=1023402262#1023402262

CrazyKing
19-11-2002, 20:01
Phoenix đã làm xong chưa ???

phoenix
20-11-2002, 00:14
phoenix vẫn chưa làm xong, crazyking có thể giúp phoenix ko? chỉ cho Phoenix cái cấu trúc dữ liệu thôi cũng được,

CrazyKing
22-11-2002, 11:52
to : phoenix
Quang vu gởi bài caro hay lắm !!! Phoenix có thể tham khảo từ đó !
Cấu trúc dữ liệu thì trên trang bptri giới thiệu !!!

vo_danh_khach
05-12-2002, 12:28
hic hic hic
nói tới nói lui, chăng thấy ai post cai code cả. chỉ toàn nói chuyện đâu đâu.
tôi đợi cái code đó lâu lắm rui đó

vo_danh_khach
05-12-2002, 12:36
cuối cung cũng thấy 1 cai link sang DDTH.org chứ có thấy post ở đây đâu, chảng lẽ copy sang??

bpmtri
05-12-2002, 13:01
Hic, vậy tui xin mạn phép copy cái source Caro viết bằng C++ bên đó qua đây luôn nha. Code này là của bạn Boy-4-eyes bên diendantinhoc.org.



/*TestCaro.cpp*/
#include <conio.h>
#include <dos.h>

#define SIZE 16
#define EXSIZE (SIZE+2)
#define HUM 0
#define COM 1
#define EMPTY 2
#define NONE 3


#define INF 10000
#define WIN 5000
#define BONUS 100
#define MAXDEPTH 20
#define DEPTH 4

/* ASCCI code of special keys */
#define Up 72
#define Down 80
#define Left 75
#define Right 77
#define Enter 13
#define Esc 27
#define F1 59
#define F2 60
#define F3 61
#define F4 62
#define UndoMv 8

#define EMPTY2SIDE ((Board[me]==EMPTY)&&(Board[ms]==EMPTY))

/* Define new types are used in this program */
//typedef unsigned char bool;
typedef unsigned char byte;
typedef unsigned int word;

/* Refer to each direction */
const byte Direct[5] = {EXSIZE,EXSIZE-1,1,EXSIZE+1,0};

const byte *pDirect = Direct;
const BOARDSIZE = EXSIZE*EXSIZE;

#define VERTICAL 0
#define HORIZONTAL 2
/* Queue Class*/
typedef int QUEUE_ENTRY;
typedef unsigned char ERRORCODE;
typedef enum BOOL {FALSE = 0,TRUE = 1};

const int MAX_SIZE = 32;

class Queue
{
public:
Queue();
~Queue();
public:
void Append(const QUEUE_ENTRY &item);
QUEUE_ENTRY Retrieve();
void Reset();
protected:
int count;
int out_pos;
QUEUE_ENTRY entry[MAX_SIZE];
};

Queue::Queue()
{
count = 0;
out_pos = 0;
}
Queue::~Queue()
{
}
void Queue::Reset()
{
count = 0;
out_pos = 0;
}
void Queue::Append(const QUEUE_ENTRY &item)
{
entry[count++] = item;
if (count == MAX_SIZE) count = 0;
}

QUEUE_ENTRY Queue::Retrieve()
{
QUEUE_ENTRY temp = entry[out_pos++];
if (out_pos == MAX_SIZE) out_pos = 0;
return temp;
}
//////////End of Queue Class///////////
typedef struct {
int Forward[2];
int Back[2];
} *PPatternType,PatternType;

class SavePatternType:public Queue
{
public:
SavePatternType();
void Restore();
void Reset();
void Append(QUEUE_ENTRY &item);
protected:
int nPos;
int *SavePos[MAX_SIZE];
};
void SavePatternType::SavePatternType()
{
nPos = 0;
Queue::Reset();
}
void SavePatternType::Reset()
{
nPos = 0;
Queue::Reset();
}
void SavePatternType::Restore()
{
for (int i = 0;i < nPos;i++)
*SavePos[i] = Retrieve();
}
void SavePatternType::Append(QUEUE_ENTRY &item)
{
SavePos[nPos++] = &item;
Queue::Append(item);
}
PatternType Pattern[BOARDSIZE][4];
SavePatternType SavePattern[2];

//{0,15,15,15,15,15,15,15,15,15,7,3,1,0,0}}};
int FLookUpTable[31][4] =
{{0,0,0,0},{2,0,0,0},{0,0,0,0},{5,4,0,0},{6,0,0,0} ,{0,6,0,0},
{0,0,0,0},{11,9,8,0},{12,10,0,0},{13,0,10,0},{14,0 ,0,0},
{0,13,12,0},{0,14,0,0},{0,0,14,0},{0,0,0,0},{23,19 ,17,16},
{24,20,18,0},{25,21,0,18},{26,22,0,0},{27,0,21,20} ,{28,0,22,0},
{29,0,0,22},{30,0,0,0},{0,27,25,24},{0,28,26,0},{0 ,29,0,26},
{0,30,0,0},{0,0,29,28},{0,0,30,0},{0,0,0,30},{0,0, 0,0}};
int ELookUpTable[31][4] =
{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,1,0,0},{0,0,0,0} ,{0,2,0,0},
{0,0,0,0},{0,1,3,0},{0,1,0,0},{0,0,4,0},{0,0,0,0},
{0,2,6,0},{0,2,0,0},{0,0,6,0},{0,0,0,0},{0,1,3,7},
{0,1,3,0},{0,1,0,8},{0,1,0,0},{0,0,4,9},{0,0,4,0},
{0,0,0,10},{0,0,0,0},{0,2,5,11},{0,2,5,0},{0,2,0,1 2},
{0,2,0,0},{0,0,6,13},{0,0,6,0},{0,0,0,14},{0,0,0,0 }};
int EnemyLineTable[31][31] ={
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//0
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//1
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,4,5},//2
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//3
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//4
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,4,5},//5
{0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//6
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//7
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//8
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//9
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//0
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,4,5},//1
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,4,5},//2
{0,0,0,0,0,0,4,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,4,3,5},//3
{0,0,4,0,0,4,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,4,4 ,0,3,0,3,3,5},//4
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//5
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//6
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//7
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//8
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//9
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//0
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//1
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//2
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0 ,0,3,3,3,4,5},//3
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,4,5},//4
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,3,0,3,3,5},//5
{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 ,3,3,3,3,3,5},//6
{0,0,0,0,0,0,4,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,3,0 ,0,3,4,3,3,5},//7
{3,3,3,3,3,3,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3 ,3,3,3,3,3,5},//8
{3,3,4,3,3,4,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4 ,3,3,3,3,3,5},//9
{5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ,5,5,5,5,5,5}};//0

int FriendLineTable[31][31] ={

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0 ,0,5,0,0,8,0},//0
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//1
{0,0,0,0,0,0,0,0,0,0,5,0,7,8,0,0,0,0,0,0,0,5,0,0,0 ,7,0,8,0,0,0},//2
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//3
{0,0,0,0,0,0,7,0,0,1,0,0,0,7,0,0,0,0,0,1,1,0,3,0,0 ,0,5,7,7,0,0},//4
{0,0,0,0,0,6,8,0,0,4,5,6,7,9,0,0,0,0,0,4,0,5,0,6,6 ,7,0,9,0,0,0},//5
{0,0,0,0,7,8,0,0,0,7,0,8,0,0,0,0,0,0,0,7,7,0,0,8,8 ,0,0,0,0,0,0},//6
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//7
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//8
{0,1,0,1,1,4,7,1,1,1,1,4,0,7,0,1,1,1,1,1,1,1,3,4,4 ,0,5,7,7,0,0},//9
{0,0,5,0,0,5,0,0,0,1,0,5,5,0,0,0,0,0,0,1,1,2,3,5,5 ,5,5,0,7,0,0},//0
{0,0,0,0,0,6,8,0,0,4,5,6,7,9,0,0,0,0,0,4,0,5,0,6,6 ,7,0,0,0,0,0},//1
{0,0,7,0,0,7,0,0,0,0,5,7,7,0,0,0,0,0,0,0,0,5,0,7,7 ,7,7,0,0,0,0},//2
{0,6,8,6,7,9,0,6,6,7,0,9,0,0,0,6,6,6,6,7,7,0,0,9,9 ,0,0,0,0,0,0},//3
{0,8,0,8,0,0,0,8,8,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0 ,0,0,0,0,0,0},//4
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//5
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//6
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//7
{0,0,0,0,0,0,0,0,0,1,0,0,0,6,8,0,0,0,0,1,1,2,3,0,0 ,4,5,6,7,9,0},//8
{0,1,0,1,1,4,7,1,1,1,1,4,0,7,0,1,1,1,1,1,1,1,3,4,4 ,0,5,7,7,0,0},//9
{0,1,0,1,1,0,7,1,1,1,1,0,0,7,0,1,1,1,1,1,1,1,3,0,0 ,0,5,7,7,0,0},//0
{0,2,5,2,0,5,0,2,2,1,2,5,5,0,0,2,2,2,2,1,1,0,3,5,5 ,5,5,0,7,0,0},//1
{3,3,0,3,3,0,0,3,3,3,3,0,0,0,0,3,3,3,3,3,3,3,3,0,0 ,0,5,0,7,0,0},//2
{0,0,0,0,0,6,8,0,0,4,5,6,7,9,0,0,0,0,0,4,0,5,0,6,6 ,7,0,9,0,0,0},//3
{0,0,0,0,0,6,8,0,0,4,5,6,7,9,0,0,0,0,0,4,0,5,0,6,0 ,7,0,0,0,0,0},//4
{0,4,7,4,0,7,0,4,4,0,5,7,7,0,0,4,4,4,4,0,0,5,0,7,7 ,7,7,0,0,0,0},//5
{5,5,0,5,5,0,0,5,5,5,5,0,7,0,0,5,5,5,5,5,5,5,5,0,0 ,7,0,0,0,0,0},//6
{0,6,8,6,7,9,0,6,6,7,0,0,0,0,0,6,6,6,6,7,7,0,0,9,0 ,0,0,0,0,0,0},//7
{0,7,0,7,7,0,0,7,7,7,7,0,0,0,0,7,7,7,7,7,7,7,7,0,0 ,0,0,0,0,0,0},//8
{8,9,0,9,0,0,0,9,9,0,0,0,0,0,0,9,9,9,9,0,0,0,0,0,0 ,0,0,0,0,0,0},//9
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0}};//0

char *StTable[31] ={" ","* ","O ","** ","*O ","O* ","OO ",
"*** ","**O ","*O* ","*OO ","O** ","O*O ","OO* ","OOO ","****","***O",
"**O*","**OO","*O**","*O*O","*OO*","*OOO","O***","O**O","O*O*","O*OO",
"OO**","OO*O","OOO*","OOOO"};

//////////////////////////////////
////////// Main class //////////
class Board {
word Board[BOARDSIZE];
int Score[2];
int FLevel;
int TLevel;
int BestMove[2];
int Searching;
word side,xside,lose;
word NewMove;
word col,row;
word Move;
BOOL GameOver;
public:
Board();
~Board();
void InitNewGame();
void DrawBoard();
void UpdateBoard();
void UpdateMove();
void UpdateScore(int Move);
void KeyStroke();
void GetHumanMove();
void GetComputerThink();
void PrintWin();
void MoveTo(word);
void Undo(int Move);
int Search();
void Play();
};

void Board::UpdateScore(int Move) {
int Step,
Points,
me,
ms,
*eScore = &Score[xside],
*fScore = &Score[side],
PLine[2],
nDirect = 0,
Update3 = 0;
Board[Move] = side;
SavePattern[side].Reset();
SavePattern[xside].Reset();

pDirect = Direct;
PatternType pPattern;
while ((Step = *pDirect++)!=0){

pPattern = Pattern[Move][nDirect];
PLine[side] = FriendLineTable[pPattern.Back[side]][pPattern.Forward[side]];
PLine[xside] = EnemyLineTable[pPattern.Back[xside]][pPattern.Forward[xside]];

if (PLine[xside] == 5)
if (FLevel==xside){
*eScore -= BONUS+4;
FLevel = EMPTY;
}
if (PLine[xside] == 4)
if (FLevel==xside){
*eScore -= BONUS+2;
FLevel = EMPTY;
}
if (PLine[xside] == 3)
if (TLevel == xside){
*eScore -= BONUS;
if (*eScore < BONUS-5) TLevel = EMPTY;
}
if (PLine[xside]) *eScore -= 1;
Points = 1;
if (Searching) {
me = ms = Move;
while (Board[me+=Step] == side) Points++;
while (Board[ms-=Step] == side) Points++;
}
else{
int i;
int fEEnemy = 0,
fEFriend = 0,
fCountable = 1,
*pPFriend,*pPEnemy,
nPos;
me = Move + Step;nPos = me;
for (i = 0;(i < 4)||fCountable;i++){
pPFriend = &Pattern[nPos][nDirect].Back[side];
pPEnemy = &Pattern[nPos][nDirect].Back[xside];
if (Board[nPos] == side){
if (fCountable){
Points++;
me = nPos + Step;
}
fEFriend = 1;
}
else
if (Board[nPos] == xside){
fEEnemy = 1;
fCountable = 0;
}
else
if (Board[nPos] == EMPTY){
fCountable = 0;
SavePattern[side].Append(*pPFriend);
SavePattern[xside].Append(*pPEnemy);
if (fEEnemy == 0)
*pPFriend = FLookUpTable[*pPFriend][i];
if (fEFriend == 0)
*pPEnemy = ELookUpTable[*pPEnemy][i];
}
else break;
if (fEEnemy&&fEFriend) break;
nPos += Step;
}
fEEnemy = 0;fEFriend = 0;fCountable = 1;
ms = Move - Step;nPos = ms;
for (i = 0;(i < 4)||fCountable;i++){
pPFriend = &Pattern[nPos][nDirect].Forward[side];
pPEnemy = &Pattern[nPos][nDirect].Forward[xside];
if (Board[nPos] == side){
if (fCountable){
Points++;
ms = nPos - Step;
}
fEFriend = 1;
}
else
if (Board[nPos] == xside){
fEEnemy = 1;
fCountable = 0;
}
else
if (Board[nPos] == EMPTY){
fCountable = 0;
SavePattern[side].Append(*pPFriend);
SavePattern[xside].Append(*pPEnemy);
if (fEEnemy == 0)
*pPFriend = FLookUpTable[*pPFriend][i];
if (fEFriend == 0)
*pPEnemy = ELookUpTable[*pPEnemy][i];
}
else break;
if (fEEnemy&&fEFriend) break;
nPos -= Step;
}
}//End searching
if (Points==5){
*fScore += WIN;
GameOver = TRUE;
return;
}
else
switch (Points){
case 4:
if (FLevel != xside){
if (PLine[side] == 9){
*fScore += WIN/2;
GameOver = TRUE;
}
else
if (PLine[side] == 8)
*fScore += BONUS+2;
BestMove[0] = Board[me];
BestMove[1] = Board[ms];
FLevel = side;
}
else
*fScore += Points-(Board[me]!=EMPTY)-(Board[ms]!=EMPTY);
break;
case 3:
if (PLine[side] == 7){
if (FLevel!=xside){
FLevel = side;
*fScore += BONUS;
}
}
else
if (PLine[side] == 6) Update3++;
*fScore += 2-(Board[me]!=EMPTY)-(Board[ms]!=EMPTY);
break;
case 2:
if (PLine[side] == 5){
if (FLevel!=xside){
FLevel = side;
*fScore += BONUS+1;
}
}
else
if (EMPTY2SIDE){
if (PLine[side] == 4) Update3++;
*fScore += 1;
}
break;
case 1:
if (PLine[side] == 3){
if (FLevel!=xside){
FLevel = side;
*fScore+=BONUS;
}
}
else if (PLine[side] == 2) Update3++;
else if (PLine[side] == 1) *fScore += 1;
break;
} //switch
nDirect++;
}//while

if (Update3&&(FLevel != xside))
if ((TLevel!=xside)||(FLevel==side)){
if (TLevel == xside) {
*eScore-=BONUS;
*fScore+=BONUS;
}
TLevel = side;
while (Update3--) *fScore+=BONUS;
}
}
void Board::Undo(int Move)
{
if (Board[Move] == EMPTY) return;
MoveTo(Move);
cprintf(".");
side = xside;xside = 1-side;

Board[Move] = EMPTY;
SavePattern[side].Restore();
SavePattern[xside].Restore();
}
int Board::Search()
{
int Best = -INF;
int SaveScore[2];
int SaveLevel[2];
int Value;

if ((FLevel == side)&&GameOver) {
if (BestMove[0] == EMPTY)
NewMove = BestMove[0];
else NewMove = BestMove[1];
return WIN;
}
SaveScore[0] = Score[0];
SaveScore[1] = Score[1];
SaveLevel[0] = FLevel;
SaveLevel[1] = TLevel;
Searching = 1;
for (int i = 0;i < BOARDSIZE;i++) {
if (Board[i] == EMPTY) {
UpdateScore(i);
Board[i] = EMPTY;
if (GameOver) GameOver = FALSE;
Value = Score[side]-Score[xside];

if (Value > Best) {
Best = Value;
NewMove = i;
}
Score[0] = SaveScore[0];
Score[1] = SaveScore[1];
FLevel = SaveLevel[0];
TLevel = SaveLevel[1];
}
}
Searching = 0;
return Best;
}
Board::Board() {
int i,j;
textmode(0x01);
textattr(0x0F);
for (i = 0;i < EXSIZE;i++)
for (j = 0;j < EXSIZE;j++)
Board[i*EXSIZE+j] = NONE;
}

Board::~Board() {
textmode(C80);
}

void Board::InitNewGame() {
int i,j;
GameOver = FALSE;
side = COM;xside = HUM;
FLevel = EMPTY;
TLevel = EMPTY;
Score[0] = 0;
Score[1] = 0;
Move = (SIZE/2+1)*(EXSIZE+1);
for (i = 1;i <= SIZE;i++)
for (j = 1;j <= SIZE;j++){
Board[i*EXSIZE+j] = EMPTY;
for (int k = 0;k < 4;k++)
for (int iside = 0;iside < 2;iside++){
Pattern[i*EXSIZE+j][k].Back[iside] = 15;
Pattern[i*EXSIZE+j][k].Back[iside] = 15;
Pattern[i*EXSIZE+j][k].Forward[iside] = 15;
Pattern[i*EXSIZE+j][k].Forward[iside] = 15;
}
}
}

void Board::DrawBoard() {
byte i,j;
for (i = 1;i <= SIZE;i++) {
gotoxy(1,i);
for (j = 1;j <= SIZE;j++) cprintf(".");
cprintf("%d",i);
};
gotoxy(1,i);
for (j = 1;j <= SIZE;j++) cprintf("%d",j%10);
}

void Board::UpdateBoard() {
MoveTo(Move);
if (side==1) cprintf("X");
else if (side==0) cprintf("O");
side = xside;xside =1-side;
}

void Board::UpdateMove() {
Board[Move] = side;
UpdateScore(Move);
}

void Board::GetComputerThink() {
gotoxy(1,24);clreol();
cprintf("Value: %d",Search());
Move = NewMove;
}

void Board::MoveTo(word move) {
gotoxy(move % EXSIZE,move / EXSIZE);
}
void ViewPattern(int Move,int Direct){
gotoxy(1,20);cprintf("String Table(O): ");
for (int i = 3;i >= 0;i--)
cprintf("%c",StTable[Pattern[Move][Direct].Back[0]][i]);
cprintf("|%s",StTable[Pattern[Move][Direct].Forward[0]]);
gotoxy(1,21);cprintf("String Table(X): ");
for (i = 3;i >= 0;i--)
cprintf("%c",StTable[Pattern[Move][Direct].Back[1]][i]);
cprintf("|%s",StTable[Pattern[Move][Direct].Forward[1]]);
}

void Board::KeyStroke() {
byte k;
int nDirect = 0;
gotoxy(20,1);clreol();cprintf("%d",Move);
MoveTo(Move);
int LastMove = Move;
while(TRUE) {
if (kbhit()) {
k = getch();
if (!k) k = getch();
switch (k) {
case Up :if (Move/EXSIZE > 1) Move -= Direct[VERTICAL];
else Move = (SIZE-1)*EXSIZE+Move;break;
case Down :if (Move/EXSIZE < SIZE) Move += Direct[VERTICAL];
else Move = Move-(SIZE-1)*EXSIZE;break;
case Left :if (Move % EXSIZE > 1) Move -= Direct[HORIZONTAL];
else Move = Move+EXSIZE-3;break;
case Right :if (Move % EXSIZE < SIZE) Move += Direct[HORIZONTAL];
else Move = Move-EXSIZE+3;break;
case Esc :lose = EMPTY;return;
case Enter :if (Board[Move] == EMPTY) return;
case F1 :nDirect = 0;break;
case F2 :nDirect = 1;break;
case F3 :nDirect = 2;break;
case F4 :nDirect = 3;break;
case UndoMv :Undo(LastMove);break;
}
gotoxy(20,1);clreol();cprintf("%d",Move);
gotoxy(1,19);cprintf("|/-\ Direct %d",nDirect);
ViewPattern(Move,nDirect);
MoveTo(Move);
}
}
}

void Board::GetHumanMove() {
KeyStroke();
}

void Board::Play() {
InitNewGame();
DrawBoard();
int First = 1;
while (TRUE) {
lose = xside;
if (side == HUM) GetHumanMove();
else GetComputerThink();
if (First){
First = 0;
Move = (SIZE/2+1)*(EXSIZE+1);
}
Searching = 0;
UpdateMove();
UpdateBoard();
gotoxy(1,23);clreol();cprintf("FL: %d TL: %d",FLevel,TLevel);
cprintf("| Hum & My score: %d|%d",Score[HUM],Score[COM]);
delay(100);
if (GameOver||(lose==EMPTY)) {
PrintWin();
return;
}
}
}

void Board::PrintWin() {
char Mess[3][50] = {"YOU LOSE!",
"YOU WIN!",
"WHY DO YOU QUIT EARLY?"};
byte i = 0,j = 0;
while (!kbhit()) {
gotoxy(1,25);
for (i = 0;(Mess[lose][i]!='\0');i++) {
if ((i == j)&&(Mess[lose][i]!=' ')) textcolor(WHITE);
else textcolor(DARKGRAY);
cprintf("%c",Mess[lose][i]);
};
if (j == i) j = 0;else j++;
}
}

/* M A I N */

int main(void) {
Board Caro;
Caro.Play();
return 0;
}

nmd
16-12-2002, 01:28
(* the minimax value of n, searched to depth d.
* If the value is less than min, returns min.
* If greater than max, returns max. *)
fun minimax(n: node, d: int, min: int, max: int): int =
if leaf(n) or depth=0 return evaluate(n)
if n is a max node
v := min
for each child of n
v' := minimax (child,d-1,v,max)
if v' > v, v:= v'
if v > max return max
return v
if n is a min node
v := max
for each child of n
v' := minimax (child,d-1,min,v)
if v' < v, v:= v'
if v < min return min
return v


Trong đoạn này thì với bài Caro, for each child of n nên làm sao? Nghĩa là các con của nó nên xác định, giới hạn trong khoảng nào để xét it nhất?