1. 程式人生 > >象棋和五子棋AI的開發(一)

象棋和五子棋AI的開發(一)

剛出來工作的時候,用C++做過一個五子棋的AI,那時候已基本達到了自己戰勝不了電腦的水平。當然,自己的水平相當有限,不能以此作為標準。最近心血來潮,想做一款象棋的,看了一些資料之後,發現五子棋也可以再寫一遍。於是就使用C#做了象棋和五子棋的AI,都達到了自己無法戰勝的水平。

一開始,我以為五子棋更簡單一些,畢竟象棋的走法更復雜,但做下來發現,其實五子棋是更復雜、計算量更大的一個棋類。

程式的內容很大一部分參考了《PC遊戲程式設計(人機博弈)》這本書,在閱讀本博文之前,請先了解書裡的內容。我不打算重複書裡講過的內容,只會講一些自己的特色。

一、基本資料型別的定義

程式沒有以效率至上為原則,充分地考慮了易讀性,所以程式碼看起來還是比較容易理解的。

一些基本的資料型別:

/// <summary>
/// 棋子顏色
/// </summary>
public enum ChessColor
{
    無,
    黑,
    紅,
    白,
    藍
}

/// <summary>
/// 棋子型別
/// </summary>
public enum ChessType
{
    空,
    卒,
    象,
    士,
    炮,
    馬,
    車,
    將,
    有
}

/// <summary>
/// 棋子結構
/// </summary>
public class Chess
{
    public Chess()
    {
        color = ChessColor.無;
        type = ChessType.空;
    }

    public Chess(ChessColor c, ChessType t)
    {
        color = c;
        type = t;
    }

    public void Set(ChessColor c, ChessType t)
    {
        color = c;
        type = t;
    }

    public ChessColor color;
    public ChessType type;
}

/// <summary>
/// 移動類棋走步結構
/// </summary>
public class Step : IComparable
{
    public Step(int fr, int fc, int tr, int tc)
    {
        FromRow = fr;
        FromCol = fc;
        ToRow = tr;
        ToCol = tc;
    }

    public int FromRow;
    public int FromCol;
    public int ToRow;
    public int ToCol;

    /// <summary>
    /// 走步價值
    /// </summary>
    public int value;
    public int CompareTo(object obj)
    {
        return (obj as Step).value - value;
    }
}

/// <summary>
/// 單放類棋走步結構
/// </summary>
public class Put : IComparable
{
    public Put(int tr, int tc, ChessColor c)
    {
        ToRow = tr;
        ToCol = tc;
        Color = c;
    }

    public int ToRow;
    public int ToCol;
    public ChessColor Color;

    /// <summary>
    /// 走步價值
    /// </summary>
    public int value;
    public int CompareTo(object obj)
    {
        return (obj as Put).value - value;
    }
}

整個棋盤用一個二維陣列表示,board[Row,Col],它的每一格都是一個Chess型別,而Chess包括了顏色和棋子型別兩個屬性。在象棋裡面,顏色是紅和黑,型別有將、象、馬、車等;在五子棋裡面,顏色是白和黑,型別只有空和有。

象棋和五子棋的走步結構也並不一樣,象棋是由一個位置移動到另一個位置,而五子棋是直接放棋子在某一個空位上。我們還能注意到,結構裡有一個走步價值的屬性。它是排序用的,在歷史啟發演算法裡使用。