廢話不講,直入主題。
在StdAfx.h檔案中添加
#define SIZE 15 //棋盤是15*15
#define CHESS_WHITE ‘W’ //白棋
#define CHESS_BLACK ‘B’ //黑棋
#define SPACE ‘ ‘ //空位置
#define CHESS_COMPUTER ‘B’ //這裡程式中設定計算機執黑(計算機沒你聰明嘛)
核心類如下:
class CFiveChess
{
protected:
charm_cArr[SIZE][SIZE];//存放棋盤的棋子資訊,'B'表示黑棋,'W'表示白棋,' '(空格)表示未知
intm_nCurrentX,m_nCurrentY;//目前棋子下落點的坐标,沒下一步就以該點判斷是否赢棋,這樣能夠起到很大的優化效果
public:
CFiveChess();//構造函數
intm_nCount;//記錄已經下了多少步棋,下滿225步就和棋
voidInitArr(); //初始化棋盤
voidSetArr(int row,int col,char cPlayer);//給m_cArr[row][col]設定值
charGetArr(int row,int col);//讀取m_cArr[row][col]的值
voidSetCurrentPoint(int row,int col);//設定目前下落點
charJudegeWin(char cChessFlag);//判斷cChessFlag(黑白棋标志)棋是否赢了
//下面是人機對戰的核心成員
protected:
intcomputer[SIZE][SIZE],people[SIZE][SIZE];//記錄每個未下過棋子的點的價值,取價值最大點下,利用貪心的思想
//為了加入幾種有政策的下法,隻能将下面的棋型放在類中聲明了
//對各種棋型的數量進行統計
//分别是成5,活4,沖4,活3,沖3,活2,沖2,活1,沖1(死5,死4,死3,死2,死1沒必要統計),準活3,準沖3,準沖4(命名一點都不專業)
intcheng5,huo4,chong4,huo3,chong3,huo2,chong2,huo1,chong1,zhunhuo3,zhunchong3,zhunchong4;//每下一步都要統計這些棋型的數量,以便計算機能夠做出最優決策
public:
intm_nGrade;//人機對戰的3種等級,這個可以略掉,加着玩玩的
intm_CX,m_CY;//計算機的落棋點
voidComputerPlay(char cComputer,char cPeople);//計算機下棋,第一個參數表示計算機執哪種棋,第二個參數表示人執的棋
voidSearch(int row,int col,char cChessFlag,int state[SIZE][SIZE]);//行,列,棋的黑白标志,價值數組
intPracticalScore(int num[],int border[][2],char cChessFlag);//4個方向上相連的數量,兩端是否為空格,棋子标志;兩端隻有一個空格就是“沖”棋型,兩個空格就是“活”棋型,沒有就是“死”棋型,這些都影響這個點對于計算機下棋的價值
};
//我下五子棋的時候也不喜歡什麼什麼禁手規則,很多人也不知道,是以在這裡不設定有禁手和無禁手了,一律計算機執黑。其實禁手規則的設定很簡單,執黑者有三三,四四,三四四和長連禁手。這裡可以根據上面添加的棋型的數量來判斷即可,例如,可構成兩個活3的點就是三三禁手,黑棋是不能下這個點的,那麼可在調用完函數後将這個點的價值設為0即可。
//人機對弈,AI算法必須保證如下條件,其他的可以根據個人的下棋想法來添加相應代碼
上面是類部分的介紹,對于其成員函數的介紹就不做多解釋了,人人對弈的很簡單,下面介紹人機對弈的函數以及加入的相關政策性選擇法。
//以下是人機對戰函數
void CFiveChess::ComputerPlay(charcComputer,char cPeople)
{
intmaxComputer=0,maxPeople=0;//計算機和人的狀态矩陣的最大值
//(即maxComputer是計算機最有價值點的值,maxPeople是人最有價值點的值,初始化為0
intnRow,nCol;
intcx,cy,px,py;
for(nRow=0;nRow<SIZE;nRow++)//初始化價值數組
for(nCol=0;nCol<SIZE;nCol++)
computer[nRow][nCol]=people[nRow][nCol]=0;
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
if(m_cArr[nRow][nCol]==SPACE)//取未知點來搜尋,求得該點的價值
{
Search(nRow,nCol,cComputer,computer);
Search(nRow,nCol,cPeople,people);
}
//3種等級,一種是比較人機各自的最大值後再取其中的最大值,另兩種是把人機的相加然後取其最大值
if(m_nGrade==1)
{
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
{
if(computer[nRow][nCol]>maxComputer)//找出computer的最大值點
{
maxComputer=computer[nRow][nCol];
cx=nRow;
cy=nCol;
}
if(people[nRow][nCol]>maxPeople)//找出people的最大值點
{
maxPeople=people[nRow][nCol];
px=nRow;
py=nCol;
}
}
if(maxComputer>=maxPeople)
{
m_CX=cx;
m_CY=cy;
}
else
{
m_CX=px;
m_CY=py;
}
}
if(m_nGrade==2 || m_nGrade==3)
{
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
computer[nRow][nCol]+=people[nRow][nCol];
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
if(computer[nRow][nCol]>maxComputer)
{
maxComputer=computer[nRow][nCol];
m_CX=nRow;
m_CY=nCol;
}
}
//經過上述步驟後,m_cArr[m_CX][m_CY]是最有價值的一點,好不容易選出來的,計算機将在這一點落子
}
//下面是搜尋函數,對點(row,col)的各個方向搜尋,統計添加棋型的數量
void CFiveChess::Search(int row,intcol,char cChessFlag,int state[SIZE][SIZE])
{
charAnother;//另一方
intnum[4],border[4][2];//—,|,\,/,四個方向
intmax=0,temp=0;//max為該點m_cArr[row][col]的最大價值
inti,j;
if(cChessFlag==CHESS_BLACK)
Another=CHESS_WHITE;
else
Another=CHESS_BLACK;
//橫向
border[0][0]=border[0][1]=1;//初始化必須為1,因為下面沒有判斷邊界
num[0]=0;
//右
for(i=col+1;i<SIZE;i++)
{
if(m_cArr[row][i]==cChessFlag)
{
num[0]++;
continue;
}
if(m_cArr[row][i]==Another)
{
border[0][1]=1;
break;
}
if(m_cArr[row][i]==SPACE)
{
border[0][1]=0;
break;
}
}
//左
for(i=col-1;i>=0;i--)
{
if(m_cArr[row][i]==cChessFlag)
{
num[0]++;
continue;
}
if(m_cArr[row][i]==Another)
{
border[0][0]=1;
break;
}
if(m_cArr[row][i]==SPACE)
{
border[0][0]=0;
break;
}
}
//縱向
border[1][0]=border[1][1]=1;num[1]=0;
//上
for(i=row-1;i>=0;i--)
{
if(m_cArr[i][col]==cChessFlag)
{
num[1]++;
continue;
}
if(m_cArr[i][col]==Another)
{
border[1][0]=1;
break;
}
if(m_cArr[i][col]==SPACE)
{
border[1][0]=0;
break;
}
}
//下
for(i=row+1;i<SIZE;i++)
{
if(m_cArr[i][col]==cChessFlag)
{
num[1]++;
continue;
}
if(m_cArr[i][col]==Another)
{
border[1][1]=1;
break;
}
if(m_cArr[i][col]==SPACE)
{
border[1][1]=0;
break;
}
}
//'\'方向
border[2][0]=border[2][1]=1;num[2]=0;
//上
for(i=row-1,j=col-1;i>=0&& j>=0;i--,j--)
{
if(m_cArr[i][j]==cChessFlag)
{
num[2]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[2][0]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[2][0]=0;
break;
}
}
//下
for(i=row+1,j=col+1;i<SIZE&& j<SIZE;i++,j++)
{
if(m_cArr[i][j]==cChessFlag)
{
num[2]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[2][1]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[2][1]=0;
break;
}
}
//'/'方向
border[3][0]=border[3][1]=1;num[3]=0;
//上
for(i=row-1,j=col+1;i>=0&& j<SIZE;i--,j++)
{
if(m_cArr[i][j]==cChessFlag)
{
num[3]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[3][0]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[3][0]=0;
break;
}
}
//下
for(i=row+1,j=col-1;i<SIZE&& j>=0;i++,j--)
{
if(m_cArr[i][j]==cChessFlag)
{
num[3]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[3][1]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[3][1]=0;
break;
}
}
cheng5=huo4=chong4=huo3=chong3=huo2=chong2=huo1=chong1=zhunhuo3=zhunchong3=zhunchong4=0;//放在這裡初始化
//為了讓計算機下棋有政策一點,将下面幾種棋型也加入
//B表示cChessFlag,W表示Another,S表示空格,X為價值統計點(假設落子點)
//棋型1,2 将 S B B S X S和 S X S B B S 當做準活3處理
//棋型3,4 将 W B B S X S和 S X S B B W 當做準沖3處理
//棋型5,6 将 W B B B S X和 X S B B B W 當做準沖4處理
//棋型7,8 将 S X B S B S和 S B S B X S 當做準活3處理
//棋型9,10 将 S B X S B S和 S B S X B S 當做準活3處理
//棋型11,12将 W B X B S B和 B S B X B W 當做準沖4處理
// 棋型13,14将 W B B X S B和 B S X B B W 當做準沖4處理
//一個準活3的價值小于活3,兩個準活3的價值等于兩個活3
//一個準沖3的價值小于沖3,兩個準沖3的價值等于兩個沖3
//一個準沖4的價值微小于沖4,兩個準沖4等于兩個沖4
//
//下面的代碼敲的糾結死人,NND,一不小心就錯了,寫完這些政策後,調試的最好方法就是和計算機多下幾盤棋,其實計算機的落子點是确定的,可以人為的計算出來。
//橫
if(col-4>=0&& col+1<SIZE) //棋型1
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col-1]==SPACE && m_cArr[row][col-2]==cChessFlag
&&m_cArr[row][col-3]==cChessFlag && m_cArr[row][col-4]==SPACE)
zhunhuo3++;
if(col-1>=0&& col+4<SIZE)//棋型2
if(m_cArr[row][col-1]==SPACE&& m_cArr[row][col+1]==SPACE && m_cArr[row][col+2]==cChessFlag
&&m_cArr[row][col+3]==cChessFlag && m_cArr[row][col+4]==SPACE)
zhunhuo3++;
if(col-4>=0&& col+1<SIZE) //棋型3
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col-1]==SPACE && m_cArr[row][col-2]==cChessFlag
&&m_cArr[row][col-3]==cChessFlag && m_cArr[row][col-4]==Another)
zhunchong3++;
if(col-1>=0&& col+4<SIZE)//棋型4
if(m_cArr[row][col-1]==SPACE&& m_cArr[row][col+1]==SPACE && m_cArr[row][col+2]==cChessFlag
&&m_cArr[row][col+3]==cChessFlag && m_cArr[row][col+4]==Another)
zhunchong3++;
if(col-5>=0&& col<SIZE)//棋型5
if(m_cArr[row][col-1]==SPACE&& m_cArr[row][col-2]==cChessFlag &&m_cArr[row][col-3]==cChessFlag
&&m_cArr[row][col-4]==cChessFlag && m_cArr[row][col-5]==Another)
zhunchong4++;
if(col>=0&& col+5<SIZE)//棋型6
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col+2]==cChessFlag &&m_cArr[row][col+3]==cChessFlag
&&m_cArr[row][col+4]==cChessFlag && m_cArr[row][col+5]==Another)
zhunchong4++;
if(col-1>=0&& col+4<SIZE) //棋型7
if(m_cArr[row][col+4]==SPACE&& m_cArr[row][col+3]==cChessFlag && m_cArr[row][col+2]==SPACE
&&m_cArr[row][col+1]==cChessFlag && m_cArr[row][col-1]==SPACE)
zhunhuo3++;
if(col-4>=0&& col+1<SIZE) //棋型8
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col-1]==cChessFlag && m_cArr[row][col-2]==SPACE
&&m_cArr[row][col-3]==cChessFlag && m_cArr[row][col-4]==SPACE)
zhunhuo3++;
if(col-2>=0&& col+3<SIZE)//棋型9
if(m_cArr[row][col-2]==SPACE&& m_cArr[row][col-1]==cChessFlag && m_cArr[row][col+1]==SPACE
&&m_cArr[row][col+2]==cChessFlag && m_cArr[row][col+3]==SPACE)
zhunhuo3++;
if(col-3>=0&& col+2<SIZE)//棋型10
if(m_cArr[row][col-3]==SPACE&& m_cArr[row][col-2]==cChessFlag && m_cArr[row][col-1]==SPACE
&&m_cArr[row][col+1]==cChessFlag && m_cArr[row][col+2]==SPACE)
zhunhuo3++;
if(col-2>=0&& col+3<SIZE)//棋型11
if(m_cArr[row][col-2]==Another&& m_cArr[row][col-1]==cChessFlag &&m_cArr[row][col+1]==cChessFlag
&&m_cArr[row][col+2]==SPACE && m_cArr[row][col+3]==cChessFlag)
zhunchong4++;
if(col-3>=0&& col+2<SIZE)//棋型12
if(m_cArr[row][col-3]==cChessFlag&& m_cArr[row][col-2]==SPACE && m_cArr[row][col-1]==cChessFlag
&&m_cArr[row][col+1]==cChessFlag && m_cArr[row][col+2]==Another)
zhunchong4++;
if(col-3>=0&& col+2<SIZE)//棋型13
if(m_cArr[row][col-3]==Another&& m_cArr[row][col-2]==cChessFlag &&m_cArr[row][col-1]==cChessFlag
&&m_cArr[row][col+1]==SPACE && m_cArr[row][col+2]==cChessFlag)
zhunchong4++;
if(col-2>=0&& col+3<SIZE) //棋型14
if(m_cArr[row][col-2]==cChessFlag&& m_cArr[row][col-1]==SPACE && m_cArr[row][col+1]==cChessFlag
&&m_cArr[row][col+2]==cChessFlag && m_cArr[row][col+3]==Another)
zhunchong4++;
//豎
if(row-4>=0&& row+1<SIZE) //棋型1
if(m_cArr[row+1][col]==SPACE&& m_cArr[row-1][col]==SPACE && m_cArr[row-2][col]==cChessFlag
&&m_cArr[row-3][col]==cChessFlag && m_cArr[row-4][col]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE)//棋型2
if(m_cArr[row-1][col]==SPACE&& m_cArr[row+1][col]==SPACE && m_cArr[row+2][col]==cChessFlag
&&m_cArr[row+3][col]==cChessFlag && m_cArr[row+4][col]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE) //棋型3
if(m_cArr[row+1][col]==SPACE&& m_cArr[row-1][col]==SPACE && m_cArr[row-2][col]==cChessFlag
&&m_cArr[row-3][col]==cChessFlag && m_cArr[row-4][col]==Another)
zhunchong3++;
if(row-1>=0&& row+4<SIZE)//棋型4
if(m_cArr[row-1][col]==SPACE&& m_cArr[row+1][col]==SPACE && m_cArr[row+2][col]==cChessFlag
&&m_cArr[row+3][col]==cChessFlag && m_cArr[row+4][col]==Another)
zhunchong3++;
if(row-5>=0&& row<SIZE)//棋型5
if(m_cArr[row-1][col]==SPACE&& m_cArr[row-2][col]==cChessFlag &&m_cArr[row-3][col]==cChessFlag
&&m_cArr[row-4][col]==cChessFlag && m_cArr[row-5][col]==Another)
zhunchong4++;
if(row>=0&& row+5<SIZE)//棋型6
if(m_cArr[row+1][col]==SPACE&& m_cArr[row+2][col]==cChessFlag &&m_cArr[row+3][col]==cChessFlag
&&m_cArr[row+4][col]==cChessFlag && m_cArr[row+5][col]==Another)
zhunchong4++;
if(row-1>=0&& row+4<SIZE)//棋型7
if(m_cArr[row-1][col]==SPACE&& m_cArr[row+1][col]==cChessFlag && m_cArr[row+2][col]==SPACE
&&m_cArr[row+3][col]==cChessFlag && m_cArr[row+4][col]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE)//棋型8
if(m_cArr[row-4][col]==SPACE&& m_cArr[row-3][col]==cChessFlag && m_cArr[row-2][col]==SPACE
&&m_cArr[row-1][col]==cChessFlag && m_cArr[row+1][col]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE)//棋型9
if(m_cArr[row-2][col]==SPACE&& m_cArr[row-1][col]==cChessFlag && m_cArr[row+1][col]==SPACE
&&m_cArr[row+2][col]==cChessFlag && m_cArr[row+3][col]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE)//棋型10
if(m_cArr[row-3][col]==SPACE&& m_cArr[row-2][col]==cChessFlag && m_cArr[row-1][col]==SPACE
&&m_cArr[row+1][col]==cChessFlag && m_cArr[row+2][col]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE)//棋型11
if(m_cArr[row-2][col]==Another&& m_cArr[row-1][col]==cChessFlag &&m_cArr[row+1][col]==cChessFlag
&&m_cArr[row+2][col]==SPACE && m_cArr[row+3][col]==cChessFlag)
zhunchong4++;
if(row-3>=0&& row+2<SIZE)//棋型12
if(m_cArr[row-3][col]==cChessFlag&& m_cArr[row-2][col]==SPACE && m_cArr[row-1][col]==cChessFlag
&&m_cArr[row+1][col]==cChessFlag && m_cArr[row+2][col]==Another)
zhunchong4++;
if(row-3>=0&& row+2<SIZE)//棋型13
if(m_cArr[row-3][col]==Another&& m_cArr[row-2][col]==cChessFlag &&m_cArr[row-1][col]==cChessFlag
&&m_cArr[row+1][col]==SPACE && m_cArr[row+2][col]==cChessFlag)
zhunchong4++;
if(row-2>=0&& row+3<SIZE)//棋型14
if(m_cArr[row-2][col]==cChessFlag&& m_cArr[row-1][col]==SPACE && m_cArr[row+1][col]==cChessFlag
&&m_cArr[row+2][col]==cChessFlag && m_cArr[row+3][col]==Another)
zhunchong4++;
//'\'
if(row-4>=0&& row+1<SIZE && col-4>=0 && col+1<SIZE) //棋型1
if(m_cArr[row+1][col+1]==SPACE&& m_cArr[row-1][col-1]==SPACE &&m_cArr[row-2][col-2]==cChessFlag
&&m_cArr[row-3][col-3]==cChessFlag && m_cArr[row-4][col-4]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE && col-1>=0 && col+4<SIZE)//棋型2
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row+1][col+1]==SPACE &&m_cArr[row+2][col+2]==cChessFlag
&&m_cArr[row+3][col+3]==cChessFlag && m_cArr[row+4][col+4]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE && col-4>=0 && col+1<SIZE) //棋型3
if(m_cArr[row+1][col+1]==SPACE&& m_cArr[row-1][col-1]==SPACE &&m_cArr[row-2][col-2]==cChessFlag
&&m_cArr[row-3][col-3]==cChessFlag && m_cArr[row-4][col-4]==Another)
zhunchong3++;
if(row-1>=0&& row+4<SIZE && col-1>=0 && col+4<SIZE)//棋型4
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row+1][col+1]==SPACE &&m_cArr[row+2][col+2]==cChessFlag
&&m_cArr[row+3][col+3]==cChessFlag && m_cArr[row+4][col+4]==Another)
zhunchong3++;
if(row-5>=0&& row<SIZE && col-5>=0 && col<SIZE)//棋型5
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row-2][col-2]==cChessFlag &&m_cArr[row-3][col-3]==cChessFlag
&&m_cArr[row-4][col-4]==cChessFlag && m_cArr[row-5][col-5]==Another)
zhunchong4++;
if(row>=0&& row+5<SIZE && col>=0 && col+5<SIZE)//棋型6
if(m_cArr[row+1][col+1]==SPACE&& m_cArr[row+2][col+2]==cChessFlag &&m_cArr[row+3][col+3]==cChessFlag
&&m_cArr[row+4][col+4]==cChessFlag && m_cArr[row+5][col+5]==Another)
zhunchong4++;
if(row-1>=0&& row+4<SIZE && col-1>=0 && col+4<SIZE)//棋型7
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row+1][col+1]==cChessFlag &&m_cArr[row+2][col+2]==SPACE
&&m_cArr[row+3][col+3]==cChessFlag && m_cArr[row+4][col+4]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE && col-4>=0 && col+1<SIZE)//棋型8
if(m_cArr[row-4][col-4]==SPACE&& m_cArr[row-3][col-3]==cChessFlag &&m_cArr[row-2][col-2]==SPACE
&&m_cArr[row-1][col-1]==cChessFlag && m_cArr[row+1][col+1]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE && col-2>=0 && col+3<SIZE)//棋型9
if(m_cArr[row-2][col-2]==SPACE&& m_cArr[row-1][col-1]==cChessFlag &&m_cArr[row+1][col+1]==SPACE
&&m_cArr[row+2][col+2]==cChessFlag && m_cArr[row+3][col+3]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE && col-3>=0 && col+2<SIZE)//棋型10
if(m_cArr[row-3][col-3]==SPACE&& m_cArr[row-2][col-2]==cChessFlag &&m_cArr[row-1][col-1]==SPACE
&&m_cArr[row+1][col+1]==cChessFlag && m_cArr[row+2][col+2]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE && col-2>=0 && col+3<SIZE)//棋型11
if(m_cArr[row-2][col-2]==Another&& m_cArr[row-1][col-1]==cChessFlag &&m_cArr[row+1][col+1]==cChessFlag
&&m_cArr[row+2][col+2]==SPACE && m_cArr[row+3][col+3]==cChessFlag)
zhunchong4++;
if(row-3>=0&& row+2<SIZE && col-3>=0 && col+2<SIZE)//棋型12
if(m_cArr[row-3][col-3]==cChessFlag&& m_cArr[row-2][col-2]==SPACE &&m_cArr[row-1][col-1]==cChessFlag
&&m_cArr[row+1][col+1]==cChessFlag && m_cArr[row+2][col+2]==Another)
zhunchong4++;
if(row-3>=0&& row+2<SIZE && col-3>=0 && col+2<SIZE)//棋型13
if(m_cArr[row-3][col-3]==Another&& m_cArr[row-2][col-2]==cChessFlag &&m_cArr[row-1][col-1]==cChessFlag
&&m_cArr[row+1][col+1]==SPACE && m_cArr[row+2][col+2]==cChessFlag)
zhunchong4++;
if(row-2>=0&& row+3<SIZE && col-2>=0 && col+3<SIZE)//棋型14
if(m_cArr[row-2][col-2]==cChessFlag&& m_cArr[row-1][col-1]==SPACE &&m_cArr[row+1][col+1]==cChessFlag
&&m_cArr[row+2][col+2]==cChessFlag && m_cArr[row+3][col+3]==Another)
zhunchong4++;
//'/'
if(row-1>=0&& row+4<SIZE && col-4>=0 && col+1<SIZE) //棋型1
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row+1][col-1]==SPACE &&m_cArr[row+2][col-2]==cChessFlag
&&m_cArr[row+3][col-3]==cChessFlag && m_cArr[row+4][col-4]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE && col-1>=0 && col+4<SIZE)//棋型2
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row-1][col+1]==SPACE &&m_cArr[row-2][col+2]==cChessFlag
&&m_cArr[row-3][col+3]==cChessFlag && m_cArr[row-4][col+4]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE && col-4>=0 && col+1<SIZE) //棋型3
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row+1][col-1]==SPACE &&m_cArr[row+2][col-2]==cChessFlag
&&m_cArr[row+3][col-3]==cChessFlag && m_cArr[row+4][col-4]==Another)
zhunchong3++;
if(row-4>=0&& row+1<SIZE && col-1>=0 && col+4<SIZE)//棋型4
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row-1][col+1]==SPACE &&m_cArr[row-2][col+2]==cChessFlag
&&m_cArr[row-3][col+3]==cChessFlag && m_cArr[row-4][col+4]==Another)
zhunchong3++;
if(row>=0&& row+5<SIZE && col-5>=0 && col<SIZE)//棋型5
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row+2][col-2]==cChessFlag && m_cArr[row+3][col-3]==cChessFlag
&&m_cArr[row+4][col-4]==cChessFlag && m_cArr[row+5][col-5]==Another)
zhunchong4++;
if(row-5>=0&& row<SIZE && col>=0 && col+5<SIZE)//棋型6
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row-2][col+2]==cChessFlag && m_cArr[row-3][col+3]==cChessFlag
&&m_cArr[row-4][col+4]==cChessFlag && m_cArr[row-5][col+5]==Another)
zhunchong4++;
if(row-4>=0&& row+1<SIZE && col-1>=0 && col+4<SIZE)//棋型7
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row-1][col+1]==cChessFlag && m_cArr[row-2][col+2]==SPACE
&&m_cArr[row-3][col+3]==cChessFlag && m_cArr[row-4][col+4]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE && col-4>=0 && col+1<SIZE)//棋型8
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row+1][col-1]==cChessFlag && m_cArr[row+2][col-2]==SPACE
&&m_cArr[row+3][col-3]==cChessFlag && m_cArr[row+4][col-4]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE && col-2>=0 && col+3<SIZE)//棋型9
if(m_cArr[row-3][col+3]==SPACE&& m_cArr[row-2][col+2]==cChessFlag && m_cArr[row-1][col+1]==SPACE
&&m_cArr[row+1][col-1]==cChessFlag && m_cArr[row+2][col-2]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE && col-3>=0 && col+2<SIZE)//棋型10
if(m_cArr[row-2][col+2]==SPACE&& m_cArr[row-1][col+1]==cChessFlag && m_cArr[row+1][col-1]==SPACE
&&m_cArr[row+2][col-2]==cChessFlag && m_cArr[row+3][col-3]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE && col-2>=0 && col+3<SIZE)//棋型11
if(m_cArr[row-3][col+3]==cChessFlag&& m_cArr[row-2][col+2]==SPACE &&m_cArr[row-1][col+1]==cChessFlag
&&m_cArr[row+1][col-1]==cChessFlag && m_cArr[row+2][col-2]==Another)
zhunchong4++;
if(row-2>=0&& row+3<SIZE && col-3>=0 && col+2<SIZE)//棋型12
if(m_cArr[row-2][col+2]==Another&& m_cArr[row-1][col+1]==cChessFlag &&m_cArr[row+1][col-1]==cChessFlag
&&m_cArr[row+2][col-2]==SPACE && m_cArr[row+3][col-3]==cChessFlag)
zhunchong4++;
if(row-2>=0&& row+3<SIZE && col-3>=0 && col+2<SIZE)//棋型13
if(m_cArr[row-2][col+2]==cChessFlag&& m_cArr[row-1][col+1]==SPACE &&m_cArr[row+1][col-1]==cChessFlag
&&m_cArr[row+2][col-2]==cChessFlag && m_cArr[row+3][col-3]==Another)
zhunchong4++;
if(row-3>=0&& row+2<SIZE && col-2>=0 && col+3<SIZE)//棋型14
if(m_cArr[row-3][col+3]==Another&& m_cArr[row-2][col+2]==cChessFlag &&m_cArr[row-1][col+1]==cChessFlag
&&m_cArr[row+1][col-1]==SPACE && m_cArr[row+2][col-2]==cChessFlag)
zhunchong4++;
/
temp=PracticalScore(num,border,cChessFlag);
max+=temp;
if(max>state[row][col])
state[row][col]=max;
}
//下面是實際的評分函數,并統計基本棋型
int CFiveChess::PracticalScore(intnum[],int border[][2],char cChessFlag)
{
inti;
for(i=0;i<4;i++)
{
if(num[i]>=4)//成5
{
cheng5++;break;//隻需一個成5就行
}
if(num[i]==3&& border[i][0]==0 && border[i][1]==0)
{
huo4++;break;
}
elseif(num[i]==3 && (border[i][0]&&border[i][1])==0 )
chong4++;
if(num[i]==2&& border[i][0]==0 && border[i][1]==0)
huo3++;
elseif(num[i]==2 && (border[i][0]&&border[i][1])==0)
chong3++;
if(num[i]==1&& border[i][0]==0 && border[i][1]==0)
huo2++;
elseif(num[i]==1 && (border[i][0]&&border[i][1])==0)
chong2++;
if(num[i]==0&& border[i][0]==0 && border[i][1]==0)
huo1++;
elseif(num[i]==0 && (border[i][0]&&border[i][1])==0)
chong1++;
}
//計算機和人的棋局評分标準不同,應該偏向計算機,例如,計算機和人同時都可以成5的時候,應該保證執行計算機成5,
//為了防止玩家赢了一盤後再根據原有的棋路走棋必赢,是以對于分值較小的的棋型采用随機化處理其分值
//共3個等級,最高一個等級強調防守(和前兩個等級隻改變一點點,盡管勝率差不多,但下起來精彩一些,呵呵,切忌,防守不能過度,過猶不及啊)
intmax=1; //若為0則會産生bug,下到隻有幾個空格時,這些空格的分值有可能都為0,以緻計算機在重複的點落子,是以将空格的價值設為1較好
if(cChessFlag==CHESS_COMPUTER)//計算機
{
if(cheng5>0)
max+=5000000;
if(huo4>0)
max+=200000;
if(huo3>0&& chong4>0)
max+=200000;
if(huo3>0&& zhunchong4>0)
max+=200000;
if(zhunhuo3>0&& zhunchong4>0)
max+=200000;
if(chong4>1)
max+=200000;
if(zhunchong4>1)
max+=200000;
if(huo3>1)
max+=8000;
if(zhunhuo3>1)
max+=8000;
if(huo3>0&& zhunhuo3>0)
max+=8000;
if(chong4>0)
max+=505;
if(zhunchong4>0&& m_nGrade==3)//
max+=507;
elseif(zhunchong4>0)
max+=503;
if(huo3>0)
max+=500;
if(zhunhuo3>0)
max+=495;
if(huo2>1)
max+=200;
if(huo2>0&& chong3>0)
max+=120;
if(chong3>1)
max+=70;
if(zhunchong3>1)
max+=70;
if(huo2>0)
max+=(22+rand()%5);
if(chong3>0)
max+=(20+rand()%5);
if(zhunchong3>0)
max+=(17+rand()%5);
if(chong2>1)
max+=(15+rand()%5);
if(chong2>0)
max+=(9+rand()%5);
if(chong1>0)
max+=3;
}
else//人
{
if(cheng5>0)
max+=1000000;
if(huo4>0)
max+=40000;
if(huo3>0&& chong4>0)
max+=40000;
if(huo3>0&& zhunchong4>0)
max+=40000;
if(zhunhuo3>0&& zhunchong4>0)
max+=40000;
if(chong4>1)
max+=40000;
if(zhunchong4>1)
max+=40000;
if(huo3>1)
max+=1900;
if(zhunhuo3>1)
max+=1900;
if(huo3>0&& zhunhuo3>0)
max+=1900;
if(huo3>0&& m_nGrade==3)//
max+=500;
elseif(huo3>0)
max+=450;
if(zhunhuo3>0&& m_nGrade==3)//
max+=495;
elseif(zhunhuo3>0)
max+=445;
if(chong4>0)
max+=350;
if(zhunchong4>0&& m_nGrade==3)//
max+=352;
elseif(zhunchong4>0)
max+=349;
if(huo2>1)
max+=150;
if(huo2>0 && chong3>0)
max+=110;
if(chong3>1&& m_nGrade==3)//
max+=70;
elseif(chong3>1)
max+=60;
if(zhunchong3>1)
max+=60;
if(huo2>0)
max+=(16+rand()%5);
if(chong3>0)
max+=(15+rand()%5);
if(zhunchong3>0)
max+=(12+rand()%5);
if(chong2>1)
max+=(10+rand()%5);
if(chong2>0)
max+=(8+rand()%5);
if(chong1>0)
max+=2;
}
returnmax;
}
//上面的分值配置設定一般是前面大的1/4略小,為什麼要這樣設定呢?那是因為下棋的最佳政策是:即使這點可構成4個活三(最多4個),也不如另一點可構成1個活4強,因為構成活4後隻需一步就可赢棋,構成4個活三的話還需要兩步才能赢,萬一下這兩步的過程中由于某些原因而讓對手赢了呢,每下一步棋勢都是會發生變化的。其他的類推……
看完上面的文字之後,或許你已經有了基本的思路了,現在你可以自己嘗試去寫了,如果要參考,下面是代碼的下載下傳位址。
五子棋(人人和人機對弈):http://download.csdn.net/detail/aihahaheihei/4076078
另外附上幾個完全原創的代碼
俄羅斯方塊:http://download.csdn.net/detail/aihahaheihei/4076057
電腦(計算表達式的):http://download.csdn.net/detail/aihahaheihei/4076071
貪吃蛇:http://download.csdn.net/detail/aihahaheihei/4076048
上面的程式都是基于MFC的。
請記住,學會與人分享自己的資源……
本着學習的精神,基本的已經說完了。
弱弱的再吱一聲:如果你做的五子棋幾盤就被别人下赢了,你的面子往何處放?哥實在不能這樣,好歹還得再泡MM的,是以我就給五子棋的添加了個遞歸深搜并模拟玩家下棋(也可通過遞歸實作,當然得剪枝,否則電腦承受不了這麼大的運算量),固然棋力強大了很多,相信大家都會dfs深度遞歸搜尋,代碼我就不上傳了。其實還可以利用多線程技術來更深度的遞歸搜尋,隻是很複雜,本人能力有限,不扯了。
以上僅獻給已逝去的青春。