智能五子棋基本思路
前些天閑時寫的,在學數據結構的時拿來練手的.沒技術含量,最有技術含量的AI部分,我是看別人(園子里叫二十四生的)的算法改的.剛弄了一下午小程序弄不過去,頭疼,現無聊的緊,閑著發著玩.當消遣
主要發下AI核心算法.有興趣的同學用VB,VC.VC#都可以一起做著玩.保持對編程的興趣.其它沒了.
一,說下五子棋的原理:5子成一線即贏.
所以可以這樣做,當一子落下時,判斷該子是否成5子,下面的代碼說的很清楚了
????????///?當一棋子落子時檢查該色子是否勝利
????????///?</summary>
????????///?<param?name="chessPoint">落子位置</param>
????????///?<param?name="color">棋子色</param>
????????///?<returns>bool</returns>
????????///?把棋子分8個方向計算
????????///?2????3?????4
????????///?1????x,y???5
????????///?8?????7????6
????????public?bool?CheckeWin(ChessPoint?chessPoint,?CheckerColor?color)??//檢查是否勝利
????????{
????????????int?X?=?chessPoint.X;
????????????int?Y?=?chessPoint.Y;
????????????int?times?=?1;
????????????int?tempX?=?X?-?1;
????????????int?tempY?=?Y;
????????????/**///檢查?1?方向//
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?1,?color))
????????????????{
????????????????????times++;
????????????????????tempX--;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????/**/////檢查?5??方向////
????????????tempX?=?X?+?1;
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?5,?color))
????????????????{
????????????????????times++;
????????????????????tempX++;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????if?(times?>=?5)
????????????????return?true;
????????????/**/////1-5?方向檢查完畢
????????????times?=?1;
????????????tempX?=?X;
????????????tempY?=?Y?-?1;
????????????/**///檢查?3?方向////
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?3,?color))
????????????????{
????????????????????times++;
????????????????????tempY--;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????/**///檢查?7?方向
????????????tempY?=?Y?+?1;
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?7,?color))
????????????????{
????????????????????times++;
????????????????????tempY++;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????if?(times?>=?5)
????????????????return?true;
????????????/**//3-7?方向檢查完畢////
????????????times?=?1;
????????????tempX?=?X?-?1;
????????????tempY?=?Y?-?1;
????????????/**////檢查?2?方向
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?2,?color))
????????????????{
????????????????????times++;
????????????????????tempX--;
????????????????????tempY--;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????tempX?=?X?+?1;
????????????tempY?=?Y?+?1;
????????????/**//檢查?6?方向/
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?6,?color))
????????????????{
????????????????????times++;
????????????????????tempX++;
????????????????????tempY++;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????if?(times?>=?5)
????????????????return?true;
????????????/**/2-6方向檢查完畢////
????????????times?=?1;
????????????tempX?=?X?+?1;
????????????tempY?=?Y?-?1;
????????????/**////檢查?4?方向
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?4,?color))
????????????????{
????????????????????times++;
????????????????????tempX++;
????????????????????tempY--;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????tempX?=?X?-?1;
????????????tempY?=?Y?+?1;
????????????/**////檢查?8?方向/
????????????while?(true)
????????????{
????????????????if?(NextHasChecker(tempX,?tempY,?8,?color))
????????????????{
????????????????????times++;
????????????????????tempX--;
????????????????????tempY++;
????????????????????continue;
????????????????}
????????????????else
????????????????????break;
????????????}
????????????if?(times?>=?5)
????????????????return?true;
????????????return?false;???//默認返回False
????????}
???????檢查1.2.3.4.5.6.7.8?方向是否有該色的子#region??檢查1.2.3.4.5.6.7.8?方向是否有該色的子
???????public?bool?NextHasChecker(int?x,?int?y,?int?direction,?CheckerColor?color)
???????{
???????????switch?(direction)
???????????{
???????????????case?1:
???????????????????if?(x?<?0)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?5:
???????????????????if?(x?>?14)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?3:
???????????????????if?(y?<?0)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?7:
???????????????????if?(y?>?14)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?2:
???????????????????if?(x?<?0?||?y?<?0)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?6:
???????????????????if?(x?>?14?||?y?>?14)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?4:
???????????????????if?(x?>?14?||?y?<?0)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????case?8:
???????????????????if?(x?<?0?||?y?>?14)?return?false;
???????????????????if?(GoBang[x,?y]?!=?null?&&?GoBang[x,?y].CheckColor?==?color)
???????????????????????return?true;
???????????????????else
???????????????????????return?false;
???????????????default:
???????????????????return?false;
???????????}
???????}
???????#endregion????????????//檢查1.2.3.4.5.6.7.8?方向是否有該色的子
(二),這樣只是達到判斷勝否的目的.做一個單機版的五子棋.要求有個電腦和你玩.那么就是個AI的問題,COMPUTER,根椐盤上的棋子作出相應的攻守.
一個稍微簡單點的AI,也是我能理解的AI思路.當電腦下子時,遞歸或循環棋盤上每一個未下子的位置,對每個位置下子進行打分,比如當電腦色棋面上有三子已成一線,且成"活三"必勝局面,那么在此位置下子應當是得分比較高的點,或者當對手的成"活三","雙三","禁手"的點,在那點電腦下子也應當是得分比較高的,其次是成二子,成一子..依次分配合理的權值.最后把權值相加,取得分最高點著子.所以不同情況的權值的取大小直接影響到電腦對該位置落子認可度.當然我沒有,要很多的測試才能得出,下面給一個別人的權值計算公式,相對合理.
? ?? ?? ???//找自己的取勝點(10000)
? ?? ?? ???int w1 = 100000;
? ?? ?? ???//找對手的取勝點(50000)
? ?? ?? ???int w2 = 50000;
? ?? ?? ???//找自己的三個相連的點(10000)
? ?? ?? ???int w3 = 10000;
? ?? ?? ???//找對手的三個相連的點(5000)
? ?? ?? ???int w4 = 5000;
? ?? ?? ???//找自己的兩個相連的點(1000)
? ?? ?? ???int w5 = 1000;
? ?? ?? ???//找對手的兩個相連的點(500)
? ?? ?? ???int w6 = 500;
? ?? ?? ???//找自己的相連的點(100)
? ?? ?? ???int w7 = 100;
? ?? ?? ???//找對方的相連的點(50)
? ?? ?? ???int w8 = 50;
? ?? ?? ???//找自己的失敗點
? ?? ?? ???int w9 = -1000000;
(三),明白了COMPUTER找最佳落子位置原理后就是計算棋盤上落子的分值的時候了.
前面已說過.一個棋子在盤中有四個方向,水平,豎值,兩個方向斜,前面說是1.2.3.4.5.6.7.8那么也就是計算這4個方向的棋子的連子數,我給出參考算法:
從四個方向檢測,連子個數#region?從四個方向檢測,連子個數
????????/**////?<summary>
????????///?正東正西檢測與m,n點棋子相同的棋子個數
????????///?</summary>
????????///?<param?name="m"></param>
????????///?<param?name="n"></param>
????????///?<param?name="arrchessboard"></param>
????????///?<returns>如果返回負值則表示改方向在無子可下</returns>
????????public?static?int?Xnum(int?m,?int?n,?Checker[,]?arrchessboard,CheckerColor?color)
????????{
????????????//檢查是否無子可下(當flag=2時表示無子可下)
????????????int?flag?=?0;
????????????//連子個數
????????????int?num?=?1;
????????????//正東方向檢查(x+)
????????????int?i?=?m?+?1;
????????????//不超出棋格
????????????while?(i?<?15)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[i,?n]?!=?null?&&?arrchessboard[i,?n].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i++;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//正東方向超出棋格
????????????if?(i?==?15)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//正東方向有別的子不可在下
????????????????if?(arrchessboard[i,?n]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????//正西方向檢查(x-)
????????????i?=?m?-?1;
????????????while?(i?>=?0)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[i,?n]?!=?null?&&?arrchessboard[i,?n].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i--;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//正西方向超出棋格
????????????if?(i?==?-1)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//正西方向有別的子不可在下
????????????????if?(arrchessboard[i,?n]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????if?(flag?==?2)
????????????{
????????????????return?-num;
????????????}
????????????else
????????????{
????????????????if?(flag?==?1?&&?num?==?3)
????????????????{
????????????????????//連子數為3時有一邊不能下就不是活三
????????????????????return?-num;
????????????????}
????????????????else
????????????????{
????????????????????return?num;
????????????????}
????????????}
????????}
????????/**////?<summary>
????????///?正南正北方向檢測
????????///?</summary>
????????///?<param?name="m"></param>
????????///?<param?name="n"></param>
????????///?<param?name="arrchessboard"></param>
????????///?<returns>如果返回負值則表示改方向在無子可下</returns>
??????public?static?int?Ynum(int?m,?int?n,?Checker[,]?arrchessboard,?CheckerColor?color)
????????{
????????????//檢查是否無子可下(當flag=2時表示無子可下)
????????????int?flag?=?0;
????????????//連子個數
????????????int?num?=?1;
????????????//正南方向檢查(y+)
????????????int?i?=?n?+?1;
????????????while?(i?<?15)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[m,i]?!=?null?&&?arrchessboard[m,?i].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i++;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//正南方向超出棋格
????????????if?(i?==?15)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//正南方向有別的子不可在下
????????????????if?(arrchessboard[m,?i]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????//正北方向檢查(y-)
????????????i?=?n?-?1;
????????????while?(i?>=?0)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[m,i]?!=?null?&&?arrchessboard[m,?i].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i--;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//正北方向超出棋格
????????????if?(i?==?-1)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//正北方向有別的子不可在下
????????????????if?(arrchessboard[m,?i]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????if?(flag?==?2)
????????????{
????????????????return?-num;
????????????}
????????????else
????????????{
????????????????if?(flag?==?1?&&?num?==?3)
????????????????{
????????????????????//連子數為3時有一邊不能下就不是活三
????????????????????return?-num;
????????????????}
????????????????else
????????????????{
????????????????????return?num;
????????????????}
????????????}
????????}
????????/**////?<summary>
????????///?西北東南方向檢查
????????///?</summary>
????????///?<param?name="m"></param>
????????///?<param?name="n"></param>
????????///?<param?name="arrchessboard"></param>
????????///?<returns>如果返回負值則表示改方向在無子可下</returns>
??????public?static?int?YXnum(int?m,?int?n,?Checker[,]?arrchessboard,?CheckerColor?color)
????????{
????????????//檢查是否無子可下(當flag=2時表示無子可下)
????????????int?flag?=?0;
????????????//連子個數
????????????int?num?=?1;
????????????//東南方向(x+,y+)
????????????int?i?=?m?+?1;
????????????int?j?=?n?+?1;
????????????//不超出棋格
????????????while?(i?<?15?&&?j?<?15)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[i,j]?!=?null?&&?arrchessboard[i,?j].CheckColor==?color)
????????????????{
????????????????????num++;
????????????????????i++;
????????????????????j++;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//東南方向超出棋格
????????????if?(i?==?15?||?j?==?15)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//東南方向有別的子不可在下
????????????????if?(arrchessboard[i,?j]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????//西北方向(x-,y-)
????????????i?=?m?-?1;
????????????j?=?n?-?1;
????????????//不超出棋格
????????????while?(i?>=?0?&&?j?>=?0)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[i,?j]?!=?null?&&?arrchessboard[i,?j].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i--;
????????????????????j--;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//西北方向超出棋格
????????????if?(i?==?-1?||?j?==?-1)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//西北方向有別的子不可在下
????????????????if?(arrchessboard[i,?j]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????if?(flag?==?2)
????????????{
????????????????return?-num;
????????????}
????????????else
????????????{
????????????????if?(flag?==?1?&&?num?==?3)
????????????????{
????????????????????//連子數為3時有一邊不能下就不是活三
????????????????????return?-num;
????????????????}
????????????????else
????????????????{
????????????????????return?num;
????????????????}
????????????}
????????}
????????/**////?<summary>
????????///?西南東北方向檢查
????????///?</summary>
????????///?<param?name="m"></param>
????????///?<param?name="n"></param>
????????///?<param?name="arrchessboard"></param>
????????///?<returns>如果返回負值則表示改方向在無子可下</returns>
??????public?static?int?XYnum(int?m,?int?n,?Checker[,]?arrchessboard,?CheckerColor?color)
????????{
????????????//檢查是否無子可下(當flag=2時表示無子可下)
????????????int?flag?=?0;
????????????//連子個數
????????????int?num?=?1;
????????????//西南方向(x-,y+)
????????????int?i?=?m?-?1;
????????????int?j?=?n?+?1;
????????????//不超出棋格
????????????while?(i?>=?0?&&?j?<?15)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[i,?j]?!=?null?&&?arrchessboard[i,?j].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i--;
????????????????????j++;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//西南方向超出棋格
????????????if?(i?==?-1?||?j?==?15)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//西南方向有別的子不可在下
????????????????if?(arrchessboard[i,?j]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????//東北方向(x+,y-)
????????????i?=?m?+?1;
????????????j?=?n?-?1;
????????????//不超出棋格
????????????while?(i?<?15?&&?j?>=?0)
????????????{
????????????????//前方的棋子與m,n點不同時跳出循環
????????????????if?(arrchessboard[i,?j]?!=?null?&&?arrchessboard[i,?j].CheckColor?==?color)
????????????????{
????????????????????num++;
????????????????????i++;
????????????????????j--;
????????????????}
????????????????else
????????????????{
????????????????????break;
????????????????}
????????????}
????????????//東北方向超出棋格
????????????if?(i?==?15?||?j?==?-1)
????????????{
????????????????flag++;
????????????}
????????????else
????????????{
????????????????//東北方向有別的子不可在下
????????????????if?(arrchessboard[i,?j]?!=?null)
????????????????{
????????????????????flag++;
????????????????}
????????????}
????????????if?(flag?==?2)
????????????{
????????????????return?-num;
????????????}
????????????else
????????????{
????????????????if?(flag?==?1?&&?num?==?3)
????????????????{
????????????????????//連子數為3時有一邊不能下就不是活三
????????????????????return?-num;
????????????????}
????????????????else
????????????????{
????????????????????return?num;
????????????????}
????????????}
????????}
????????#endregion
(四),上面是對一點計算如果在該處落子時得分,設四個數組,就是那四個方向的連子數*相應權值
?????????? arrf[0]
?????????? arrf[1]
?????????? arrf[2]
?????????? arrf[3]
那么找最高分就是一個循環或遞歸的過程,不多說.
找到該點坐標,落子.交換棋子色,人下子,COMPUTER下子,...只到有5子有人成功.
我用C#,VS2005完整解決方案放下,關于人工智能,何其深奧,已此簡單的算法基礎我對AI有一點初步認識.
?
轉載于:https://www.cnblogs.com/solo/archive/2007/01/09/616068.html
總結
- 上一篇: 卖不动了 全球安卓平板市场份额破新低:1
- 下一篇: 阳奉阴违(转载)