1. 程式人生 > >五子棋的核心演算法

五子棋的核心演算法

五子棋是一種受大眾廣泛喜愛的遊戲,其規則簡單,變化多端,非常富有趣味性和消遣性。這裡設計和實現了一個人機對下的五子棋程式,採用了博弈樹的方法,應用了剪枝和最大最小樹原理進行搜尋發現最好的下子位置。介紹五子棋程式的資料結構、評分規則、勝負判斷方法和搜尋演算法過程。

一、相關的資料結構
  關於盤面情況的表示,以連結串列形式表示當前盤面的情況,目的是可以允許使用者進行悔棋、回退等操作。
  CList StepList;
  其中Step結構的表示為:

  struct Step
  {
    int m; //m,n表示兩個座標值
    int n;
    char side; //side表示下子方
  };
以陣列形式儲存當前盤面的情況,
目的是為了在顯示當前盤面情況時使用:
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];

  其中FIVE_MAX_LINE表示盤面最大的行數。

  同時由於需要在遞迴搜尋的過程中考慮時間和空間有效性,只找出就當前情況來說相對比較好的幾個盤面,而不是對所有的可下子的位置都進行搜尋,這裡用變數CountList來表示當前搜尋中可以選擇的所有新的盤面情況物件的集合:

CList CountList;
  其中類CBoardSituiton為:
class CBoardSituation
{
CList StepList; //每一步的列表
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
struct Step machineStep;   //機器所下的那一步
double value; //該種盤面狀態所得到的分數
}

二、評分規則
  對於下子的重要性評分,需要從六個位置來考慮當前棋局的情況,分別為:-,¦,/,/,//,//


  實際上需要考慮在這六個位置上某一方所形成的子的佈局的情況,對於在還沒有子的地方落子以後的當前局面的評分,主要是為了說明在這個地方下子的重要性程度,設定了一個簡單的規則來表示當前棋面對機器方的分數。

  基本的規則如下:

判斷是否能成5, 如果是機器方的話給予100000分,如果是人方的話給予-100000 分;
判斷是否能成活4或者是雙死4或者是死4活3,如果是機器方的話給予10000分,如果是人方的話給予-10000分;
判斷是否已成雙活3,如果是機器方的話給予5000分,如果是人方的話給予-5000 分;
判斷是否成死3活3,如果是機器方的話給予1000分,如果是人方的話給予-1000 分;
判斷是否能成死4,如果是機器方的話給予500分,如果是人方的話給予-500分;
判斷是否能成單活3,如果是機器方的話給予200分,如果是人方的話給予-200分;
判斷是否已成雙活2,如果是機器方的話給予100分,如果是人方的話給予-100分;
判斷是否能成死3,如果是機器方的話給予50分,如果是人方的話給予-50分;
判斷是否能成雙活2,如果是機器方的話給予10分,如果是人方的話給予-10分;
判斷是否能成活2,如果是機器方的話給予5分,如果是人方的話給予-5分;
判斷是否能成死2,如果是機器方的話給予3分,如果是人方的話給予-3分。

  實際上對當前的局面按照上面的規則的順序進行比較,如果滿足某一條規則的話,就給該局面打分並儲存,然後退出規則的匹配。注意這裡的規則是根據一般的下棋規律的一個總結,在實際執行的時候,使用者可以新增規則和對評分機制加以修正。

三、勝負判斷
  實際上,是根據當前最後一個落子的情況來判斷勝負的。實際上需要從四個位置判斷,以該子為出發點的水平,豎直和兩條分別為 45度角和135度角的線,目的是看在這四個方向是否最後落子的一方構成連續五個的棋子,如果是的話,就表示該盤棋局已經分出勝負。具體見下面的圖示:


四、搜尋演算法實現描述
  注意下面的核心的演算法中的變數currentBoardSituation,表示當前機器最新的盤面情況, CountList表示第一層子節點可以選擇的較好的盤面的集合。核心的演算法如下:
void MainDealFunction()
{
value=-MAXINT; //對初始根節點的value賦值
CalSeveralGoodPlace(currentBoardSituation,CountList);
//該函式是根據當前的盤面情況來比較得到比較好的可以考慮的幾個盤面的情況,可以根據實際的得分情況選取分數比較高的幾個盤面,也就是說在第一層節點選擇的時候採用貪婪演算法,直接找出相對分數比較高的幾個形成第一層節點,目的是為了提高搜尋速度和防止堆疊溢位。
pos=CountList.GetHeadPosition();
CBoardSituation* pBoard;
for(i=0;ivalue=Search(pBoard,min,value,0);
Value=Select(value,pBoard->value,max);
//取value和pBoard->value中大的賦給根節點
}
for(i=0;ivalue)
//找出那一個得到最高分的盤面
{
  currentBoardSituation=pBoard;
  PlayerMode=min; //當前下子方改為人
  Break;
}
}

  其中對於Search函式的表示如下:實際上核心的演算法是一個剪枝過程,其中在這個搜尋過程中相關的四個引數為:(1)當前棋局情況;(2)當前的下子方,可以是機器(max)或者是人(min);(3)父節點的值oldValue;(4)當前的搜尋深度depth。

double Search(CBoardSituation&
board,int mode,double oldvalue,int depth)
{
CList m_DeepList;
if(deptholdvalue))==   TRUE)
    {
      if(mode==max)
        value=select(value,search(successor
      Board,min,value,depth+1),max);
      else
        value=select(value,search(successor
        Board,max,value,depth+1),min);
    }
    return value;
}
else
{
if ( goal(board)<>0)
//這裡goal(board)<>0表示已經可以分出勝負
return goal(board);
else
return evlation(board);
    }
  }

  注意這裡的goal(board)函式是用來判斷當前盤面是否可以分出勝負,而evlation(board)是對當前的盤面從機器的角度進行打分。

  下面是Select函式的介紹,這個函式的主要目的是根據 PlayerMode情況,即是機器還是使用者來返回節點的應有的值。

double Select(double a,double b,int mode)
{
if(a>b && mode==max)¦¦ (a< b && mode==min)
return a;
else
return b;
}

五、小結
  在Windows作業系統下,用VC++實現了這個人機對戰的五子棋程式。和國內許多隻是採用規則或者只是採用簡單遞迴而沒有剪枝的那些程式相比,在智力上和時間有效性上都要好於這些程式。同時所討論的方法和設計過程為使用者設計其他的遊戲(如象棋和圍棋等)提供了一個參考。

相關推薦

五子棋核心演算法

五子棋是一種受大眾廣泛喜愛的遊戲,其規則簡單,變化多端,非常富有趣味性和消遣性。這裡設計和實現了一個人機對下的五子棋程式,採用了博弈樹的方法,應用了剪枝和最大最小樹原理進行搜尋發現最好的下子位置。介紹五子棋程式的資料結構、評分規則、勝負判斷方法和搜尋演算法過程。 一、相關的資料結構   關於盤面情況的表示,以

分享《Python機器學習—預測分析核心演算法》高清中文版PDF+高清英文版PDF+原始碼

下載:https://pan.baidu.com/s/1sfaOZmuRj14FWNumGQ5ahw 更多資料分享:http://blog.51cto.com/3215120 《Python機器學習—預測分析核心演算法》高清中文版PDF+高清英文版PDF+原始碼高清中文版,338頁,帶目錄和書籤,文字能夠

Python機器學習——預測分析核心演算法 pdf 下載

機器學習關注於預測,其核心是一種基於數學和演算法的技術,要掌握該技術,需要對數學及統計概念有深入理解,能夠熟練使用R 語言或者其他程式語言。    本書通過集中介紹兩類可以進行有效預測的機器學習演算法,展示瞭如何使用Python 程式語言完成機器學習任務,從而降低機器學習難度,使機器

WF曲速未來:區塊鏈核心演算法之Paxos演算法

Paxos演算法解決的問題是在一個可能發生訊息可能會延遲、丟失、重複的分散式系統中如何就某個值達成一致,保證不論發生以上任何異常,都不會破壞決議的一致性。 先帶你會看一下libpaxos3的程式碼: 第一步獲取和編譯LibPaxos3所需的基本步驟: 執行示例  

KMP演算法模板 - 構建next最長字首陣列 與 kmp核心演算法

#include <iostream> #include <string> using namespace std; //構建next最長字首陣列 int* getNextArray(const string &sub) { if(sub.length() ==

Raft演算法(zookeeper核心演算法

轉自: https://www.cnblogs.com/mindwind/p/5231986.html Leslie Lamport 在三十多年前發表的論文《拜占庭將軍問題》(參考[1])。 拜占庭位於如今的土耳其的伊斯坦布林,是東羅馬帝國的首都。由於當時拜占庭羅馬帝國

核心演算法掌握要求《演算法導論》

第一部分  基礎(Foundations) 第一章 計算中演算法的角色(The Role of Algorithms in Computing) 第二章 開始(Getting Started) 第三章 函式的增長率(Growth of Functions)

rsync的核心演算法

rsync是unix/linux下同步檔案的一個高效演算法,它能同步更新兩處計算機的檔案與目錄,並適當利用查詢檔案中的不同塊以減少資料傳輸。rsync中一項與其他大部分類似程式或協定中所未見的重要特性是映象是隻對有變更的部分進行傳送。rsync可拷貝/顯示目錄屬性,以及拷貝檔案,並可選擇性的壓縮以及遞迴

淺談感測器融合的核心演算法

“有夢的人很多,能實現的太少。 這個世界從不缺比你更努力的人。 我們是不是把生活說得太辛苦了,而已經忘了要好好生活了 想法越簡單,越不容易實現。” 2018年,L3等級的自動駕駛汽車陸續出現在市場上。 奧迪的第一款L3自動駕駛汽車奧迪A8旗艦轎車,也是全球首款達

QT簡易計算器--表示式計算核心演算法(二)

概述:上篇我主要介紹了用QT做計算器的整個流程,這次主要就是分析一下,計算器表示式計算的演算法部分。因為也找了很多別人寫的程式碼,但大多都是隻支援個位數的加減乘除,小數也不支援,所以就在原有框架上,修改,優化,讓其滿足我想要的功能。 1,表示式計算思路。

消除遊戲的核心演算法

1.通過自定義事件從點選的物件類裡面丟擲當前點選的物件的座標 cc.eventManager.dispatchCustomEvent(USER_CLICK_SHRED_EVERT, that.arrayIndex); 2.然後獲取到座標後進行處理 cc.eventManage

雙舵輪AGV里程計、運動控制核心演算法

        舵輪AGV可以通過調整兩個舵輪的角度及速度,可以使小車在不轉動車頭的情況下實現變道,轉向等動作,甚至可以實現沿任意點為半徑的轉彎運動,有很強的靈活性。 因此在AGV行業,這種驅動方式應用很廣,但是目前能做好控制的廠家並不多。國內比較好的廠家主要有瀋陽新鬆機器人、蘇州華曉精密、上海同普,還有部分

感知機核心演算法的兩種理解!

一.感知機模型 f(x)=sign(w⋅x+b) 感知機是一種線性分類模型,屬於判別模型. 二. 感知機學習策略 損失函式 L(w,b)=−∑xi∈Myi(w⋅xi+b)

五子棋AI演算法簡易實現(一)

基礎篇 (1)勝負判定 五子棋的勝負判定的條件是其中一方下棋以後,橫線、豎線、右上斜線或者右下斜線任一方向出現五子相連,即可判定獲勝。此處用遞迴方法即可實現。 var is_win = false; var ModuleWinnerC

區塊鏈技術六大核心演算法

-----轉載2018-01-15 14:49技術/作業系統區塊鏈核心演算法一:拜占庭協定拜占庭的故事大概是這麼說的:拜占庭帝國擁有巨大的財富,周圍10個鄰邦垂誕已久,但拜占庭高牆聳立,固若金湯,沒有一個單獨的鄰邦能夠成功入侵。任何單個鄰邦入侵的都會失敗,同時也有可能自身被其

五子棋AI演算法第三篇-Alpha Beta剪枝

剪枝是必須的 上一篇講了極大極小值搜尋,其實單純的極大極小值搜尋演算法並沒有實際意義。 可以做一個簡單的計算,平均一步考慮 50 種可能性的話,思考到第四層,那麼搜尋的節點數就是 50^4 = 6250000,在我的酷睿I7的電腦上一秒鐘能計算的節點不超

五子棋AI演算法 Java實現

五子棋AI演算法 也算是一個典型的遊戲AI演算法,一些棋類的AI演算法都可以參考實現,下面是Java實現程式碼 棋盤抽象介面 import java.util.List;   publicinterface IChessboard {  

史上最具核心內容的五子棋核心程式碼------verision1.0

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*;  public class 五子棋2 extends JPanel {static int x=0,y

Python預測分析(1):關於預測的兩類核心演算法

    本書涉及的機器學習問題通常是指“函式逼近”問題。是有監督學習問題的一個子集。線性迴歸和邏輯迴歸是解決此類函式逼近問題最常見的演算法。函式逼近問題包含了各種領域中的分類問題和迴歸問題,如文字分類、搜尋響應、廣告放置、垃圾郵件過濾、使用者行為預測、診斷等。從廣義上說,本書

五子棋基礎演算法及勝利判定演算法(無AI)

這篇文章只是簡單的繪製了一個棋盤,通過輸入座標(格式舉例:3,4)來下棋,然後就是勝利判定演算法。我最剛開始的演算法會出現陣列越界問題,也就是說當棋子下在棋盤最靠邊的一圈時就會出現陣列越界異常,後來大改了一遍,解決了這個問題。下面是正確的程式碼: import java.i