📄 oai.cpp
字号:
// OAI.cpp: implementation of the COAI class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MfcPo.h"
#include "OAI.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
COAI::COAI()
{
searchmethod = 0; //negamax
ordermove = TRUE;
depth = 6; //default search depth of 6
eg_empty = 15; //end-game search of 15 moves
new_board(); //setup board initial positions
}
COAI::~COAI()
{
}
int COAI::set_up_legal_moves(move_st *move_struct, int who)
{
int move_no = 0;
int i=0;
for(int x=0; x<8; x++)
for (int y=0;y<8;y++){
if (!board[x][y]){ //a stone already exits
int move_effect = 1;
//check up
if ((y>=2) && (board[x][y-1]==-who)){
for (i=y-2; i>=0; i--){
if (board[x][i]==-who) continue;
if (board[x][i]== who)
for (int j=y-1; j!=i;j--){
move_struct->disk_turned[move_no][move_effect].x = x;
move_struct->disk_turned[move_no][move_effect].y = j;
move_effect++;
}
break;
} //close of i for-loop
} //close of up check
//check up-right
if ((x<=5) && (y>=2) && (board[x+1][y-1]==-who)){
for (i=2; ((x+i)<8) && ((y-i)>=0); i++){
if (board[x+i][y-i]==-who) continue;
if (board[x+i][y-i]== who)
for (int j=1; j!=i;j++){
move_struct->disk_turned[move_no][move_effect].x = x+j;
move_struct->disk_turned[move_no][move_effect].y = y-j;
move_effect++;
}
break;
}
}
//check right
if ((x<=5) && (board[x+1][y]==-who)){
for (i=x+2; i<8; i++){
if (board[i][y]==-who) continue;
if (board[i][y]== who)
for (int j=x+1; j!=i;j++){
move_struct->disk_turned[move_no][move_effect].x = j;
move_struct->disk_turned[move_no][move_effect].y = y;
move_effect++;
}
break;
}
}
//check bottom-right
if ((x<=5) && (y<=5) && (board[x+1][y+1]==-who)){
for (i=2;((x+i)<8) && ((y+i)<8); i++){
if (board[x+i][y+i]==-who) continue;
if (board[x+i][y+i]== who)
for (int j=1; j!=i; j++){
move_struct->disk_turned[move_no][move_effect].x = x+j;
move_struct->disk_turned[move_no][move_effect].y = y+j;
move_effect++;
}
break;
}
}
//check bottom
if ((y<=5) && (board[x][y+1]==-who)){
for (i=y+2; i<8; i++){
if (board[x][i]==-who) continue;
if (board[x][i]== who)
for (int j=y+1; j!=i;j++){
move_struct->disk_turned[move_no][move_effect].x = x;
move_struct->disk_turned[move_no][move_effect].y = j;
move_effect++;
}
break;
}
}
//check bottom-left
if ((x>1) && (y<=5) && (board[x-1][y+1]==-who)){
for (i=2;((x-i)>=0) && ((y+i)<8); i++){
if (board[x-i][y+i]==-who) continue;
if (board[x-i][y+i]== who)
for (int j=1; j!=i; j++){
move_struct->disk_turned[move_no][move_effect].x = x-j;
move_struct->disk_turned[move_no][move_effect].y = y+j;
move_effect++;
}
break;
}
}
//check left
if ((x>1) && (board[x-1][y]==-who)){
for (i=x-2; i>=0; i--){
if (board[i][y]==-who) continue;
if (board[i][y]== who)
for (int j=x-1; j!=i;j--){
move_struct->disk_turned[move_no][move_effect].x = j;
move_struct->disk_turned[move_no][move_effect].y = y;
move_effect++;
}
break;
}
}
//check left-upper
if ((x>1) && (y>1) && (board[x-1][y-1]==-who)){
for (i=2;((x-i)>=0) && ((y-i)>=0); i++){
if (board[x-i][y-i]==-who) continue;
if (board[x-i][y-i]== who)
for (int j=1; j!=i; j++){
move_struct->disk_turned[move_no][move_effect].x = x-j;
move_struct->disk_turned[move_no][move_effect].y = y-j;
move_effect++;
}
break;
}
}
if (move_effect>1){
//valid move
move_struct->disk_turned[move_no][0].x = x;
move_struct->disk_turned[move_no][0].y = y;
//termination
move_struct->disk_turned[move_no][move_effect].x = -1;
move_struct->disk_turned[move_no][move_effect].y = -1;
move_no++;
}
} //close of not stone
} //close of y for-loop
move_struct->disk_turned[move_no][0].x = -1;
move_struct->disk_turned[move_no][0].y = -1;
move_struct->no_legal_moves = move_no;
return move_no;
}
int COAI::disk_difference(int to_play)
{
int me=0,you=0;
for (int i=0; i<8; i++){
for (int j=0; j<8; j++){
if (board[i][j]==to_play)
me++;
else if (board[i][j]==-to_play)
you++;
}
}
return me-you;
}
void COAI::order_moves(move_st *move_struct, int *move_order)
{
//simple search to get score for every moves
int i=0;
move_order_search = TRUE;
for(i=0; i<move_struct->no_legal_moves;i++){
play_move(move_struct, i);
to_play = -to_play;
eval_table[i] = -search(START_ALPHA, START_BETA, 1);
to_play = -to_play;
undo_move(move_struct, i);
}
move_order_search = FALSE;
//sort move order
for(i=0; i<move_struct->no_legal_moves; i++){
int max = -1000000L;
int max_move;
for (int j=0; j<move_struct->no_legal_moves;j++)
if (eval_table[j]>max){
max = eval_table[j];
max_move = j;
}
move_order[i] = max_move;
eval_table[max_move] = -1000000L;
}
}
void COAI::play_move(move_st *move_struct, int movenum)
{
for (int i=0; move_struct->disk_turned[movenum][i].x >=0; i++)
board[move_struct->disk_turned[movenum][i].x][move_struct->disk_turned[movenum][i].y] = to_play;
total_disks++;
}
void COAI::play_move(int who, int x, int y)
{
int i;
board[x][y] = who;
//check up
if ((y>=2) && (board[x][y-1]==-who)){
for (i=y-2; i>=0; i--){
if (board[x][i]== who){
for (int j=y-1; j!=i;j--)
board[x][j] = who;
break;
}
else if (board[x][i]== EMPTY)
break;
} //close of for
} //close of if
//check up-right
if ((x<=5) && (y>=2) && (board[x+1][y-1]==-who)){
for (i=2; ((x+i)<8) && ((y-i)>=0); i++){
if (board[x+i][y-i]== who){
for (int j=1; j!=i;j++)
board[x+j][y-j] = who;
break;
}
else if (board[x+i][y-i]==EMPTY)
break;
}
}
//check right
if ((x<=5) && (board[x+1][y]==-who)){
for (i=x+2; i<8; i++){
if (board[i][y]== who){
for (int j=x+1; j!=i;j++)
board[j][y]= who;
break;
}
else if (board[i][y] == EMPTY)
break;
}
}
//check bottom-right
if ((x<=5) && (y<=5) && (board[x+1][y+1]==-who)){
for (i=2;((x+i)<8) && ((y+i)<8); i++){
if (board[x+i][y+i]== who){
for (int j=1; j!=i; j++)
board[x+j][y+j] = who;
break;
}
else if (board[x+i][y+i]==EMPTY)
break;
}
}
//check bottom
if ((y<=5) && (board[x][y+1]==-who)){
for (i=y+2; i<8; i++){
if (board[x][i]== who){
for (int j=y+1; j!=i;j++)
board[x][j] = who;
break;
}
else if (board[x][i]==EMPTY)
break;
}
}
//check bottom-left
if ((x>1) && (y<=5) && (board[x-1][y+1]==-who)){
for (i=2;((x-i)>=0) && ((y+i)<8); i++){
if (board[x-i][y+i]== who){
for (int j=1; j!=i; j++)
board[x-j][y+j] = who;
break;
}
else if (board[x-i][y+i]==EMPTY)
break;
}
}
//check left
if ((x>1) && (board[x-1][y]==-who)){
for (i=x-2; i>=0; i--){
if (board[i][y]== who){
for (int j=x-1; j!=i; j--)
board[j][y] = who;
break;
}
else if (board[i][y]==EMPTY)
break;
}
}
//check left-upper
if ((x>1) && (y>1) && (board[x-1][y-1]==-who)){
for (i=2;((x-i)>=0) && ((y-i)>=0); i++){
if (board[x-i][y-i] == who){
for (int j=1; j!=i; j++)
board[x-j][y-j] = who;
break;
}
else if (board[x-i][y-i] == EMPTY)
break;
}
}
total_disks++;
}
void COAI::undo_move(move_st *move_struct, int movenum)
{
board[move_struct->disk_turned[movenum][0].x][move_struct->disk_turned[movenum][0].y] = EMPTY;
for (int i=1; move_struct->disk_turned[movenum][i].x >= 0; i++)
board[move_struct->disk_turned[movenum][i].x][move_struct->disk_turned[movenum][i].y] = -to_play;
total_disks--;
}
int COAI::corner(int who)
{
pos start[4] = {{0,0},{0,7},{7,0},{7,7}};
int to_return = 0;
int i,j,k;
for (i=0; i<4; i++){ //4 corners
if (start[i].x ==0) //j,k is the edge near corner
j = start[i].x + 1; //horizontal
else
j = start[i].x - 1;
if (start[i].y ==0)
k = start[i].y + 1; //vertical
else
k = start[i].y - 1;
if (board[start[i].x][start[i].y]==who){ //our disk at corner
to_return += 30;
if (board[start[i].x][k]==who)
to_return += 5;
if (board[j][start[i].y]==who)
to_return += 5;
}
else if (board[start[i].x][start[i].y]==-who){ //opponent disk at corner
to_return -=30;
if (board[start[i].x][k]==-who)
to_return -= 5;
if (board[j][start[i].y]==who)
to_return -= 5;
}
else{ //corner is empty
/* if (board[start[i].x][k]==who)
to_return -= 5;
if (board[j][start[i].y]==who)
to_return -= 5;*/
if (board[j][k]==who)
to_return -= 10;
else if (board[j][k]==-who)
to_return += 5;
}
}
return to_return;
}
int COAI::mobility(int who)
{
int to_return = 0;
for (int i=0; i<8; i++)
for (int j=0; j<8; j++)
if (is_legal(who, i, j))
to_return++;
return to_return;
}
bool COAI::is_legal(int who, int x, int y)
{
if (board[x][y])
return FALSE;
int i;
//check up
if ((y>=2) && (board[x][y-1]==-who)){
for (i=y-2; i>=0; i--){
if (board[x][i]== who)
return TRUE;
else if(board[x][i]==EMPTY)
break;
}
}
//check up-right
if ((x<=5) && (y>=2) && (board[x+1][y-1]==-who)){
for (i=2; ((x+i)<8) && ((y-i)>=0); i++){
if (board[x+i][y-i]== who)
return TRUE;
else if (board[x+i][y-i] == EMPTY)
break;
}
}
//check right
if ((x<=5) && (board[x+1][y]==-who)){
for (i=x+2; i<8; i++){
if (board[i][y]== who)
return TRUE;
else if (board[i][y] == EMPTY)
break;
}
}
//check bottom-right
if ((x<=5) && (y<=5) && (board[x+1][y+1]==-who)){
for (i=2;((x+i)<8) && ((y+i)<8); i++){
if (board[x+i][y+i]== who)
return TRUE;
else if (board[x+i][y+i] == EMPTY)
break;
}
}
//check bottom
if ((y<=5) && (board[x][y+1]==-who)){
for (i=y+2; i<8; i++){
if (board[x][i] == who)
return TRUE;
else if (board[x][i] == EMPTY)
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -