吴昊品游戏核心算法 Round 5 —— 五子棋(无禁手)后台的判胜负AI(bfs+queue容器)(HDOJ 2699)...
五子棋的歷史
?
?
連子棋類游戲起源很早,在四千年前的兩河文明就有古西亞連棋。
五子棋則咸信是流傳于古中國的傳統(tǒng)棋種之一,至今仍在民間廣泛流傳,規(guī)則相當(dāng)簡單。或許因沒有形成一套獨立完整的棋種理論及文化內(nèi)涵,更無制定公平完善的規(guī)則來解決黑白平衡問題,一直沒有得到發(fā)展,所以沒有像圍棋、象棋等傳統(tǒng)棋類流傳廣泛,導(dǎo)致缺少可考古的棋具,也沒像直棋、方棋等鄉(xiāng)土棋類記載在地方縣志、古人筆記等文獻。
五子棋在傳入日本后,被日本人發(fā)揚光大,自1899年日本棋士黒巖涙香證明了原始規(guī)則的五子棋先下必勝后,五子棋邁入一條不斷改良的道路,經(jīng)過數(shù)十年的修改、驗證、再修改,最終發(fā)展出加入禁手的五子棋,并經(jīng)過公開征名,稱為連珠(RENJU),因此規(guī)則在日本成型,又稱為日式規(guī)則或連珠規(guī)則。原始規(guī)則在中國依然有人在玩,也被稱為無禁規(guī)則、自由規(guī)則,有軟件可驗證黑手必勝(這個稍后再證明)。
連珠規(guī)則禁止先下的黑棋下出雙活三、雙四、長連(超過五子以上的連線)下出則判敗,此舉限制黑棋的取勝方式,白棋則增加逼迫黑子下出禁手來取勝的手 段,使黑棋的優(yōu)勢稍稍減少。不過禁手也許對初學(xué)者來說是一種障礙,但下久后會發(fā)現(xiàn),禁手使得雙方棋手必需更加精準(zhǔn)的掌握棋子的落點,增加了連珠的技術(shù)性、 復(fù)雜性及趣味性。
又過了幾十年,人們發(fā)現(xiàn)單單加入禁手,尚無法完全平衡黑棋一子之先的優(yōu)勢,因此在國際比賽使用的“RIF規(guī)則”,在連珠規(guī)則的基礎(chǔ)上,又加入了三手交換及五手兩打,算第一個可以真正合乎公平競技的職業(yè)規(guī)則。
? Problem——該問題,是用一串二維數(shù)組裝載的字符串,用.表示空,用W表示白棋,用B表示黑棋,來判斷目前的局面中的當(dāng)前走棋的一方是否贏了整盤棋。
? Solve:
?/*
?? 該程序可以判定當(dāng)前的一方是否獲勝,如果暫時沒有獲勝或者已經(jīng)告負,本
?? 程序會有相應(yīng)的輸出。
?? AI的策略基本上和連連看的相似,也用的是queue容器+BFS
?? (1)判斷當(dāng)前局勢,利用目前棋盤上黑子和白子的數(shù)量進行比較
?? (2)五子連環(huán)必須是恰好有五個子,也就是說,沿端點方向上的點應(yīng)該是空格的
?? (3)表面上是八個方向,實際上考慮到對稱性,四個方向即可
?? (4)在for循環(huán)的條件判斷上加上flag,找到一例,即可退出循環(huán)
?*/
?
??2??#include<queue>//STL里面的queue容器
??3??using?namespace?std;
??4??
??5??struct?Node?//每個點有一個坐標(biāo),最大連通數(shù)以及方向
??6??{
??7????char?x,y,time,dirc;
??8????bool?no_stone;???????
??9??};
?10??
?11??char?map[15][15],c;//定義一個二維數(shù)組,表示棋盤,c表示現(xiàn)在輪到誰
?12??
?13??int?dir[4][2]={{0,1},{1,0},{1,-1},{1,1}};//四個方向
?14??
?15??//BFS搜索,和之前的連連看類似
?16??bool?bfs(int?x,int?y)
?17??{
?18????queue<Node>?Q;
?19????Node?first,next;
?20????int?i;???
?21????first.x=x;
?22????first.y=y;
?23????first.no_stone=false;
?24????first.time=1;
?25????first.dirc=-1;
?26????Q.push(first);
?27????
?28????while(!Q.empty())
?29????{
?30??????first=Q.front();
?31??????Q.pop();
?32??????//從第一個點開始,保證有且僅有五個是連在一起的,用no_stone標(biāo)識沒有多連
?33??????if(first.time==5&&first.no_stone)
?34??????{
?35????????return?true;?????????????????????????????????
?36??????}?????????????
?37??????for(i=0;i<4;i++)
?38??????{
?39????????//初始方向不確定
?40????????if(first.dirc==-1||first.dirc==i)
?41????????{
?42??????????next.x=first.x+dir[i][0];
?43??????????next.y=first.y+dir[i][1];
?44??????????if(next.x>=0&&next.x<15&&next.y>=0&&next.y<15)
?45??????????{
?46????????????next.dirc=i;
?47????????????next.time=first.time+1;
?48????????????//唯獨不標(biāo)識對手的棋子,自己的棋子和空棋子用no_stone區(qū)分
?49????????????if(map[next.x][next.y]==c)??????????????????????????????
?50????????????{
?51??????????????next.no_stone=first.no_stone;
?52??????????????Q.push(next);????????????????????????????????????????????????????????
?53????????????}??????????????
?54????????????else?if(map[next.x][next.y]=='.'&&!first.no_stone)
?55????????????{
?56??????????????next.no_stone=true;
?57??????????????Q.push(next);?????
?58????????????}??
?59??????????}?????????????????????????????????
?60????????}????????????????
?61??????}?????
?62????}??
?63????return?false;
?64??}
?65??
?66??int?main()
?67??{
?68????int?T;
?69????scanf("%d",&T);
?70????while(T--)
?71????{
?72??????int?i,j;
?73??????int?white_num=0,black_num=0;
?74??????getchar();?//讀入一個回車鍵
?75??????for(i=0;i<15;i++)
?76??????{
?77????????gets(map[i]);?????????????????
?78??????}??????????
?79??????for(i=0;i<15;i++)
?80??????{
?81????????for(j=0;j<15;j++)
?82????????{
?83??????????if(map[i][j]=='W')
?84??????????{
?85????????????white_num++;??????????????????
?86??????????}?????????????
?87??????????else?if(map[i][j]=='B')
?88??????????{
?89????????????black_num++;?????
?90??????????}?????
?91????????}????????????????
?92??????}
?93??????//記錄黑白棋子的數(shù)量,主要是判斷當(dāng)前下棋方是黑還是白
?94??????if(black_num>white_num)
?95??????{
?96????????c='W';???????????????????????
?97??????}
?98??????else
?99??????{
100????????c='B';????
101??????}
102??????bool?flag=true;
103??????//只要找到一個“五子連”就可以了
104??????for(i=0;i<15&&flag;i++)
105??????{
106????????for(j=0;j<15&&flag;j++)
107????????{
108??????????if(map[i][j]==c)
109??????????{
110????????????flag=!bfs(i,j);????????????????
111??????????}???????????????????????
112????????}???????????????????????
113??????}
114??????if(flag)?printf("NO\n");
115??????else?printf("YES\n");
116????}
117????return?0;????
118??}
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/tuanzang/archive/2013/02/27/2935770.html
總結(jié)
以上是生活随笔為你收集整理的吴昊品游戏核心算法 Round 5 —— 五子棋(无禁手)后台的判胜负AI(bfs+queue容器)(HDOJ 2699)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: access查询出生日期格式转换_从身份
- 下一篇: geoserver native JAI