回到主頁

人工智慧課程 黑白棋演算法程式設計

 

 

 

 

主畫面說明:

                    

觀看此執行畫面.

 

 

玩家可利用SPACE(空白鍵)鍵或點選檔案->新遊戲,就可進入所選的遊戲。

一、  開發環境:

(1) 軟體方面:

1、   Visual C++ 5.0

2、   Visual C++ SP2 以上

3、   聲音編輯使用微軟所附的錄音機應用程式編輯

4、   作業系統Win98,Win2000

 

(2)           硬體方面:

1、   CPUPentium II

2、   記憶體:96MB

3、   加速卡:S3 4M RAM

4、   3D音效卡

 

二、執行環境:

1)軟體方面:

1、作業系統:Windows2000Windows98Windows95

2)硬體方面:

1、   CPUPentium 133以上

2、   記憶體:64MB以上

3、   顯示卡:VGA 800X600 高彩16位元

4、    3D音效卡

 

三、黑白棋腳本設計

畫面說明:

此遊戲畫面右邊為輔助說明的區域,除了標題外還顯示目前的白子及黑子的數目、上一步棋子所下的位置、現在是該那一種顏色的棋子下。

遊戲畫面上邊有功能表及工具盒其功能是相同的,主要分為:

遊戲:重新開啟一個新遊戲。

設定:設黑子或白子開局及玩家、電腦的

棋子。

翻轉:棋子翻轉的快慢,共分五種速度。

操作:回上一步、上二步、顯示可下位置。

說明:關於。

                   

 

四、玩家操作說明:

1、新遊戲:

玩家可從選單按下遊戲->新遊戲開始玩

新遊戲,或由工具列選擇。

2、棋子的顏色選擇:

可從選單按下設定->選擇由黑子或白子開

局及玩家與電腦的設定。

3、棋子翻轉的速度:

可從選單按下翻轉à設定各種速度。

4、悔棋:

可從選單按下操作à選舉退一步或退二

步、或從工具列選擇。

5、顯示可下位置:

從選單按下操作à選擇可下位置。

 

五、黑白棋技術說明

專案為 Visual C++ 5.0 Service pack 2 下開發所以要執行此專案建議先將 Visual C++ 升級至目前最新的狀態,黑白棋規則是寫在 CChess 類別裡介面和遊戲流程是寫在 CBoard 類別裡然後專案程式會繼承 CBoard 類別得到一個 CUserBoard 類別裡面只有一個 ComputerAI 繼承的虛擬函式 只要演算法寫在此虛擬函式中即可函式會傳給目前棋盤狀態(一個 CChess 類別) 現在要走的顏色,可以走的點之坐標每一個可走座標可吃多少子經過演算法計算再將要走的座標回傳即可。 

 總之黑白棋規則及介面,是寫在 CBoard 類別裡,然後專案程式會繼承 CBoard 類別,得到一個 CUserBoard 類別,裡面只有一個 ComputerAI 繼承的虛擬函式,只要將演算法寫在此虛擬函式中即可,函式會告訴你目前下的顏色,及可走的點有哪些,經過演算法計算,再將要走的點回傳即可。此程式有反悔功能及取得目前剩餘秒數,在 ComputerAI 虛擬函式中,當然最簡單的人工智慧(AI),就是以吃最多子的位置優先下。

程式技巧主要說明如下:

/ Board.h: interface for the CBoard class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_BOARD_H__C59C16D9_278D_11D4_B7E2_CD495D617759__INCLUDED_)

#define AFX_BOARD_H__C59C16D9_278D_11D4_B7E2_CD495D617759__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

enum { BLACK = -1, EMPTY, WHITE };

enum { USER_COMPUTER = 1, USER_PLAYER, USER_NETPLAYER };

#define BOARD_WIDTH 8

#define BOARD_HEIGHT 8

#define IDT_COUNTDOWN 40000

class CTimerWnd;

class AFX_EXT_CLASS CBoard 

{

friend CTimerWnd;

private:

        CBitmap* m_pbmp_Memory;//黑白棋點陣圖

        CDC* m_pdc_Memory;//黑白棋點陣圖

        CBitmap* m_pbmp_Boarde;//黑白棋點陣圖

        CDC* m_pdc_Boarde;//黑白棋點陣圖

        CBitmap* m_pbmp_Chess;//黑白棋點陣圖

        CDC* m_pdc_Chess;//黑白棋點陣圖

        CBitmap* m_pbmp_ChessMask;//黑白棋點陣圖

        CDC* m_pdc_ChessMask;//黑白棋點陣圖

        CTimerWnd* m_pwndTimerWindow;//倒數視窗

        int m_iCountDown;//倒數秒數

        int m_iBlackCount;//黑子數目

        int m_iWhiteCount;//白子數目

        DWORD m_dwLastPoint;//最後下的點

        BOOL m_bIsGameOver;//是否已結束遊戲

        CString m_strProductName;//產品名稱

        CWnd* m_pWnd;//繪圖視窗

        BOOL m_bShowCanPlay;//是否要提示可下的點

        int m_iBlackUser;//黑子使用者

        int m_iWhiteUser;//白子使用者

        int m_iDelayAnimation;//延遲棋子翻轉的時間

        int m_iColor;//目前的顏色

    int m_iSquare[BOARD_WIDTH][BOARD_HEIGHT];//黑白棋陣列 y,x

 

        void DestroyGameBitmap();//釋放黑白棋資源

        void DrawBoardFrame(CDC* pDC);//畫出棋盤

        void DrawLastPoint(CDC* pDC,BOOL bDraw);//畫出最後下的點

        void DrawCanPlayPoint(CDC* pDC);//畫出能下的點

        void DrawAnimationChess(CDC* pDC,int x,int y,int iColor);//畫出動態棋子

        void StepAnimationChess(CDC* pDC,int iIndex,int x,int y,int iColor);//畫出分解動態棋子

        void DrawStaticChess(CDC* pDC,int x,int y,int iColor);//畫出靜態棋子

        void DrawGameStatus(CDC* pDC);//畫出遊戲目前資訊

        void DoFlipChess(CDC* pDC,CPoint ptMove);//翻轉棋子

        void StartTimer();//開始計時器

        void KillTimer();//殺掉計時器

        int DoCountDown();//倒數一次

        void DoMove(CPoint ptMove,CDWordArray& dwaryResult);//移動一步

        int DoCheckLine(int iColor,CPoint ptMove,int iOffsetX,int iOffsetY,CDWordArray& dwaryResult);//確認某方向是否有子可吃

        BOOL CheckComputerAILegal(int iColor,CPoint ptMove);//檢查電腦 AI 傳回的座標是否合法

 

public:

        CBoard();

        ~CBoard();

 

        void SetDrawWindow(CWnd* pwnd);//設定繪圖視窗

        void SetShowCanPlay(BOOL bShow);//設定是否要提示可下的點

        BOOL GetShowCanPlay();//取得是否要提示可下的點

        int GetNowColor();//取得現在的顏色

        void SetDelayAnimation(int iSleep);//設定延遲棋子翻轉的時間

        void SetBlackUser(int iUser);//設定黑子使用者

        void SetWhiteUser(int iUser);//設定白子使用者

        int GetChess(int x,int y);//取得棋盤狀態

        BOOL IsEmpty(int x,int y);//某點是否是空的

        CPoint GetLastPoint();//取得最後走的點

        void ClearBoard(int iStartColor,int iBlackUser,int iWhiteUser);//清除資料開始一個新遊戲

        BOOL IsGameOver();//遊戲是否結束

        void LoadGameBitmap(CDC *pDC);//載入黑白棋資源

        void DrawBoardStatus(CDC* pDC);//畫出目前版面狀態

        void DrawGameOver(CDC* pDC);//畫出GameOver畫面

        void GameProcess(CDC* pDC);//遊戲流程控制

        CPoint CheckMouseDown(CDC* pDC,CPoint ptDown);//確認滑鼠輸入的點

 

        //某點是否可以走

        //iColor : 顏色

        //ptMove : 要走的點

        //dwaryResult : 可吃子的座標

        //return : 可吃子的數目

        int IsLegalMove(int iColor,CPoint ptMove,CDWordArray& dwaryResult);

 

        //是否還有點可走

        //iColor : 顏色

        //dwaryCanPlayResult : 可吃子的座標

        //return : 可吃子的數目 0= 無子可吃要 pass

        int CanPlayMove(int iColor,CDWordArray& dwaryCanPlayResult);

 

        //電腦思考模組

        //虛擬函式必須繼承,AI演算法寫在此函式中即可

        //iColor : 顏色

        //dwaryCanPlayResult : 可吃子的座標

        //return : 電腦決定要走的座標 (傳回的座標必須在合法可走的座標內,否則會有錯誤警告)

        virtual CPoint ComputerAI(int iColor,CDWordArray& dwaryCanPlayResult);

};

#endif // !defined(AFX_BOARD_H__C59C16D9_278D_11D4_B7E2_CD495D617759__INCLUDED_)

// UserBoard.h: interface for the CUserBoard class.

/////////////////////////////////////////////////////////////////////

#if !defined(AFX_USERBOARD_H__98FE00E1_26E0_11D4_B7E2_444553540000__INCLUDED_)

#define AFX_USERBOARD_H__98FE00E1_26E0_11D4_B7E2_444553540000__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "Board.h"

class CUserBoard : public CBoard 

{

public:

        CUserBoard();

        ~CUserBoard();

 

        virtual CPoint ComputerAI(int iColor,CDWordArray& dwaryCanPlayResult);

};

#endif // !defined(AFX_USERBOARD_H__98FE00E1_26E0_11D4_B7E2_444553540000__INCLUDED_)

CPoint CUserBoard::ComputerAI(int iColor,CDWordArray& dwaryCanPlayResult)

{

        CPoint ptMove;

        int x=-1,y=-1;

        //AI 開始

        CDWordArray dwaryResult;

        int iScore;

        int iCount = dwaryCanPlayResult.GetSize();

        for (int i=0; i<iCount; i++)

        {

                x = ptMove.x = HIWORD(dwaryCanPlayResult[i]);

                y = ptMove.y = LOWORD(dwaryCanPlayResult[i]);

                iScore = IsLegalMove(iColor,ptMove,dwaryResult);

                TRACE("%d ",iScore);

        }

        //AI 結束

        ptMove.x = x;

        ptMove.y = y;

        return ptMove;

}

 

回到主頁