• C++的简单“五子棋”游戏,只是核心代码,资源代码未添加


    ChessBoard.h

     1 #ifndef __CHESS_BOARD_H__
     2 #define __CHESS_BOARD_H__
     3 
     4 #include "DataStruct.h"
     5 
     6 #define COL_WIDTH 45
     7 #define ROW_WIDTH 45
     8 
     9 class CChessBoard : public CWnd
    10 {
    11 private:
    12     CBitmap  m_bitBlackChess, m_bitWhiteChess;
    13     CBitmap  m_bitChessBoard;
    14     CBitmap  m_motive[8]; 
    15     int      m_iMotiveNumber;
    16     bool     m_bPlayMotive;
    17     int      m_iMotivex, m_iMotivey;
    18     // Construction
    19 public:
    20     board_type m_oChessBoard;
    21     CChessBoard();
    22     
    23 public:
    24     void NewGame();
    25     void MoveBack();
    26     void PlayMotive(int row, int col, UINT8 obcolor);
    27 
    28 public:
    29     virtual BOOL Create(RECT &rect, CWnd * pParentWnd, UINT nID);
    30 
    31 public:
    32     virtual ~CChessBoard();
    33     
    34 
    35 protected:
    36     //{{AFX_MSG(CChessBoard)
    37     afx_msg void OnPaint();
    38     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    39     afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    40     //}}AFX_MSG
    41     afx_msg void OnComRun(WPARAM wParam, LPARAM lParam);
    42     afx_msg void OnTranChess(WPARAM wParam, LPARAM lParam);
    43     DECLARE_MESSAGE_MAP()
    44 };
    45 
    46 #endif

    DataStruct.h

     1 #ifndef __DATA_STRUCT_H__
     2 #define __DATA_STRUCT_H__
     3 
     4 typedef unsigned char UINT8;
     5 typedef unsigned short UINT16; 
     6 typedef short        INT16;
     7 typedef char         INT8;
     8 
     9 #define BOARD_COLS 8
    10 #define BOARD_ROWS 8
    11 typedef struct
    12 {
    13     UINT8 board[BOARD_ROWS+2][BOARD_COLS+2];
    14 }board_type;
    15 
    16 typedef UINT16 move_key_type; 
    17 
    18 typedef struct
    19 {
    20     board_type    board;
    21     UINT16        movepos;
    22     INT16         value;
    23 }tree_node_type;
    24 
    25 
    26 #define   CHESS_NONE     0x00
    27 #define   CHESS_BLACK    0x01
    28 #define   CHESS_WHITE    0x02
    29 #define   CHESS_BORDER   0xFF
    30 
    31 #define   BD_PROTECTED   0x80
    32 #define   FD_PROTECTED   0x40
    33 #define   H_PROTECTED    0x20
    34 #define   V_PROTECTED    0x10
    35 
    36 #define   THITHER_COLOR(color)  ((~color)&0x03)
    37 
    38 
    39 #define   INITIAL_VALUE  (32767)
    40 
    41 #define   STEP_MONMENT1  10
    42 #define   STEP_MONMENT2  48
    43 
    44 #define LEVEL_LOW  0
    45 #define LEVEL_NOR  1
    46 #define LEVEL_HIGH 2
    47 //游戏难度等级
    48 extern  UINT8 g_iGameLevel; //游戏难度等级
    49 extern  UINT8 g_bStart;        //游戏开始标志
    50 
    51 #define   USER_PASS     1
    52 #define   COMPUTER_PASS 2
    53 #define   GAME_OVER     4
    54 
    55 #define  WM_TRANCHESS  (WM_USER+10)
    56 /*可一次吃掉的最多的子的个数*/
    57 #define MAX_AFFECTED_PIECES 19
    58 
    59 extern UINT8   computer_side;
    60 extern UINT8   cur_step;
    61 extern UINT16  step_array[64];
    62 
    63 extern INT16 calc_board_status(board_type *board_ptr, UINT8 obcolor);
    64 extern void init_board(board_type *board_ptr);
    65 extern void computer_play(board_type *board_ptr, HWND hwnd);
    66 extern  UINT8 do_move_chess(board_type *board_ptr, UINT16 movepos, UINT8 obcolor, HWND hwnd);
    67 extern void get_chess_score(board_type *board_ptr, UINT16 &iWscore, UINT16 &iBscore);
    68 
    69 #endif

    HelpDlg.h

     1 #if !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)
     2 #define AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_
     3 
     4 #if _MSC_VER > 1000
     5 #pragma once
     6 #endif // _MSC_VER > 1000
     7 // HelpDlg.h : header file
     8 //
     9 
    10 /////////////////////////////////////////////////////////////////////////////
    11 // CHelpDlg dialog
    12 
    13 class CHelpDlg : public CDialog
    14 {
    15 // Construction
    16 public:
    17     CHelpDlg(CWnd* pParent = NULL);   // standard constructor
    18 
    19 // Dialog Data
    20     //{{AFX_DATA(CHelpDlg)
    21     enum { IDD = IDD_HELP };
    22         // NOTE: the ClassWizard will add data members here
    23     //}}AFX_DATA
    24 
    25 
    26 // Overrides
    27     // ClassWizard generated virtual function overrides
    28     //{{AFX_VIRTUAL(CHelpDlg)
    29     protected:
    30     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    31     //}}AFX_VIRTUAL
    32 
    33 // Implementation
    34 protected:
    35 
    36     // Generated message map functions
    37     //{{AFX_MSG(CHelpDlg)
    38     virtual void OnOK();
    39     //}}AFX_MSG
    40     DECLARE_MESSAGE_MAP()
    41 };
    42 
    43 //{{AFX_INSERT_LOCATION}}
    44 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    45 
    46 #endif // !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)

    Othello.h

     1 // Othello.h : main header file for the OTHELLO application
     2 //
     3 
     4 #if !defined(AFX_OTHELLO_H__09373553_CD5E_4C18_9F3D_0A728D2E52CA__INCLUDED_)
     5 #define AFX_OTHELLO_H__09373553_CD5E_4C18_9F3D_0A728D2E52CA__INCLUDED_
     6 
     7 #if _MSC_VER > 1000
     8 #pragma once
     9 #endif // _MSC_VER > 1000
    10 
    11 #ifndef __AFXWIN_H__
    12     #error include 'stdafx.h' before including this file for PCH
    13 #endif
    14 
    15 #include "resource.h"        // main symbols
    16 
    17 /////////////////////////////////////////////////////////////////////////////
    18 // COthelloApp:
    19 // See Othello.cpp for the implementation of this class
    20 //
    21 
    22 class COthelloApp : public CWinApp
    23 {
    24 public:
    25     COthelloApp();
    26 
    27 // Overrides
    28     // ClassWizard generated virtual function overrides
    29     //{{AFX_VIRTUAL(COthelloApp)
    30     public:
    31     virtual BOOL InitInstance();
    32     //}}AFX_VIRTUAL
    33 
    34 // Implementation
    35 
    36     //{{AFX_MSG(COthelloApp)
    37         // NOTE - the ClassWizard will add and remove member functions here.
    38         //    DO NOT EDIT what you see in these blocks of generated code !
    39     //}}AFX_MSG
    40     DECLARE_MESSAGE_MAP()
    41 };
    42 
    43 
    44 /////////////////////////////////////////////////////////////////////////////
    45 
    46 //{{AFX_INSERT_LOCATION}}
    47 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    48 
    49 #endif // !defined(AFX_OTHELLO_H__09373553_CD5E_4C18_9F3D_0A728D2E52CA__INCLUDED_)

    OthelloDlg.h

     1 // OthelloDlg.h : header file
     2 //
     3 
     4 #if !defined(AFX_OTHELLODLG_H__DAC0C8C2_DDB6_4DA7_A56E_440CDF9A626B__INCLUDED_)
     5 #define AFX_OTHELLODLG_H__DAC0C8C2_DDB6_4DA7_A56E_440CDF9A626B__INCLUDED_
     6 
     7 #if _MSC_VER > 1000
     8 #pragma once
     9 #endif // _MSC_VER > 1000
    10 
    11 /////////////////////////////////////////////////////////////////////////////
    12 // COthelloDlg dialog
    13 
    14 #include "ChessBoard.h"
    15 
    16 class COthelloDlg : public CDialog
    17 {
    18 // Construction
    19 public:
    20     void GameStart();
    21     void PlayBackMusic(BOOL bCheck);
    22     void InitMenu();
    23     COthelloDlg(CWnd* pParent = NULL);    // standard constructor
    24 
    25     int  m_nBlackCount;    //黑子个数
    26     int  m_nWhiteCount;    //白子个数
    27     CChessBoard  m_chess;//棋盘对象
    28 
    29 // Dialog Data
    30     //{{AFX_DATA(COthelloDlg)
    31     enum { IDD = IDD_OTHELLO_DIALOG };
    32         // NOTE: the ClassWizard will add data members here
    33     //}}AFX_DATA
    34 
    35     // ClassWizard generated virtual function overrides
    36     //{{AFX_VIRTUAL(COthelloDlg)
    37     protected:
    38     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    39     //}}AFX_VIRTUAL
    40 
    41 // Implementation
    42 protected:
    43     HICON m_hIcon;
    44 
    45     // Generated message map functions
    46     //{{AFX_MSG(COthelloDlg)
    47     virtual BOOL OnInitDialog();
    48     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    49     afx_msg void OnPaint();
    50     afx_msg HCURSOR OnQueryDragIcon();
    51     afx_msg void OnAbout();
    52     afx_msg void OnExitGame();
    53     afx_msg void OnGameStart();
    54     afx_msg void OnHelp();
    55     afx_msg void OnLevelHigh();
    56     afx_msg void OnLevelLow();
    57     afx_msg void OnLevelNor();
    58     afx_msg void OnPlayMusic();
    59     afx_msg void OnBackBtn();
    60     //}}AFX_MSG
    61     afx_msg void OnRecalc(WPARAM wParam, LPARAM lParam);
    62     DECLARE_MESSAGE_MAP()
    63 };
    64 
    65 //{{AFX_INSERT_LOCATION}}
    66 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    67 
    68 #endif // !defined(AFX_OTHELLODLG_H__DAC0C8C2_DDB6_4DA7_A56E_440CDF9A626B__INCLUDED_)

    Resource.h

     1 //{{NO_DEPENDENCIES}}
     2 // Microsoft Developer Studio generated include file.
     3 // Used by Othello.rc
     4 //
     5 #define IDM_ABOUTBOX                    0x0010
     6 #define IDD_ABOUTBOX                    100
     7 #define IDS_ABOUTBOX                    101
     8 #define ID_CHESSBOARD                   101
     9 #define IDD_OTHELLO_DIALOG              102
    10 #define IDR_MAINFRAME                   128
    11 #define IDD_HELP                        130
    12 #define IDR_MAIN_MENU                   132
    13 #define IDB_TURN1                       134
    14 #define IDB_TURN2                       135
    15 #define IDB_TURN3                       136
    16 #define IDB_TURN4                       137
    17 #define IDB_TURN5                       138
    18 #define IDB_TURN6                       139
    19 #define IDB_BLACKCHESS                  140
    20 #define IDB_CHESSBOARD                  141
    21 #define IDB_WHITECHESS                  142
    22 #define IDC_STATUS                      1000
    23 #define IDC_BLACK_COUNT                 1001
    24 #define IDC_WHITE_COUNT                 1002
    25 #define IDC_BACK_BTN                    1003
    26 #define IDR_GAME_START                  32771
    27 #define IDR_EXIT_GAME                   32772
    28 #define IDR_PLAY_MUSIC                  32773
    29 #define IDR_LEVEL_HIGH                  32774
    30 #define IDR_LEVEL_NOR                   32775
    31 #define IDR_LEVEL_LOW                   32776
    32 #define IDR_HELP                        32777
    33 #define IDR_ABOUT                       32778
    34 
    35 // Next default values for new objects
    36 // 
    37 #ifdef APSTUDIO_INVOKED
    38 #ifndef APSTUDIO_READONLY_SYMBOLS
    39 #define _APS_NEXT_RESOURCE_VALUE        143
    40 #define _APS_NEXT_COMMAND_VALUE         32779
    41 #define _APS_NEXT_CONTROL_VALUE         1004
    42 #define _APS_NEXT_SYMED_VALUE           101
    43 #endif
    44 #endif

    StdAfx.h

     1 // stdafx.h : include file for standard system include files,
     2 //  or project specific include files that are used frequently, but
     3 //      are changed infrequently
     4 //
     5 
     6 #if !defined(AFX_STDAFX_H__0F6DA0D4_2DD7_4BB6_82C5_0E64F3D63B2D__INCLUDED_)
     7 #define AFX_STDAFX_H__0F6DA0D4_2DD7_4BB6_82C5_0E64F3D63B2D__INCLUDED_
     8 
     9 #if _MSC_VER > 1000
    10 #pragma once
    11 #endif // _MSC_VER > 1000
    12 
    13 #define VC_EXTRALEAN        // Exclude rarely-used stuff from Windows headers
    14 
    15 #include <afxwin.h>         // MFC core and standard components
    16 #include <afxext.h>         // MFC extensions
    17 #include <afxdisp.h>        // MFC Automation classes
    18 #include <afxdtctl.h>        // MFC support for Internet Explorer 4 Common Controls
    19 #ifndef _AFX_NO_AFXCMN_SUPPORT
    20 #include <afxcmn.h>            // MFC support for Windows Common Controls
    21 #endif // _AFX_NO_AFXCMN_SUPPORT
    22 
    23 #define UM_RECALC  (WM_USER+100)
    24 #define UM_COMRUN   (UM_RECALC +1)  
    25 
    26 //{{AFX_INSERT_LOCATION}}
    27 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    28 
    29 #endif // !defined(AFX_STDAFX_H__0F6DA0D4_2DD7_4BB6_82C5_0E64F3D63B2D__INCLUDED_)

    ChessBoard.cpp

      1 // ChessBoard1.cpp : implementation file
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "ChessBoard.h"
      6 #include "resource.h"
      7 
      8 #ifdef _DEBUG
      9 #define new DEBUG_NEW
     10 #undef THIS_FILE
     11 static char THIS_FILE[] = __FILE__;
     12 #endif
     13 
     14 UINT8 g_bStart = 0;
     15 
     16 /////////////////////////////////////////////////////////////////////////////
     17 // CChessBoard
     18 CChessBoard::CChessBoard()
     19 {
     20     m_iMotiveNumber=0;
     21     m_iMotivex = m_iMotivey=0;
     22     m_bPlayMotive = FALSE; 
     23     init_board(&m_oChessBoard);
     24 }
     25 
     26 CChessBoard::~CChessBoard()
     27 {
     28 }
     29 
     30 
     31 BEGIN_MESSAGE_MAP(CChessBoard, CWnd)
     32     //{{AFX_MSG_MAP(CChessBoard)
     33     ON_WM_PAINT()
     34     ON_WM_LBUTTONDOWN()
     35     ON_WM_CREATE()
     36     //}}AFX_MSG_MAP
     37     ON_MESSAGE(UM_COMRUN, OnComRun)
     38     ON_MESSAGE(WM_TRANCHESS, OnTranChess)
     39 END_MESSAGE_MAP()
     40 //////////////////////////////////////////////////////////////////////////
     41 //延时函数
     42 //////////////////////////////////////////////////////////////////////////
     43 void delay(INT32 millisecond)
     44 {
     45     clock_t start = clock();
     46     do
     47     { 
     48         MSG msg;
     49         if (::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) 
     50         { 
     51             if ( !AfxGetApp()->PumpMessage()) 
     52             { 
     53             ::PostQuitMessage(0); 
     54              return;
     55             } 
     56         } 
     57     }while(clock()<start+millisecond);
     58 }
     59 //////////////////////////////////////////////////////////////////////////
     60 //悔棋函数
     61 //////////////////////////////////////////////////////////////////////////
     62 void CChessBoard::MoveBack()
     63 {
     64     if(cur_step<2)
     65     {//如果当前步骤下于2,说明没有开始游戏
     66         return;
     67     }
     68    UINT8 comside = computer_side;
     69    UINT8 step = cur_step;
     70    INT16 movearray[64];
     71    //把下棋步骤数组中的数据复制到移动数组中
     72    memcpy(movearray, step_array, 64*sizeof(INT16));
     73    init_board(&m_oChessBoard);
     74    computer_side = comside;
     75    UINT8 col= CHESS_BLACK;
     76    for(int i=0; i<step-2; i++, col = ~col & 3)
     77    {
     78         do_move_chess(&m_oChessBoard, movearray[i], col, 0);
     79    }
     80    OnPaint();
     81    Invalidate(); 
     82 }
     83 //////////////////////////////////////////////////////////////////////////
     84 //改变棋子接口函数
     85 //////////////////////////////////////////////////////////////////////////
     86 void CChessBoard::OnTranChess(WPARAM wParam, LPARAM lParam)
     87 {
     88     int row = wParam/10-1;
     89     int col = wParam%10-1;
     90     CRect r(col*COL_WIDTH+22, row*ROW_WIDTH+22,
     91             col*COL_WIDTH+COL_WIDTH+22, row*ROW_WIDTH+ROW_WIDTH+22);
     92 
     93     m_bPlayMotive = FALSE; 
     94     OnPaint(); 
     95     InvalidateRect(&r);
     96 
     97     if((lParam>>16) !=0)
     98          PlayMotive(row, col, UINT8(lParam));
     99 }
    100 //////////////////////////////////////////////////////////////////////////
    101 //由电脑人工智能下棋
    102 //////////////////////////////////////////////////////////////////////////
    103 void CChessBoard::OnComRun(WPARAM wParam, LPARAM lParam)
    104 {
    105     computer_play(&m_oChessBoard, m_hWnd); 
    106     UINT16 wscore, bscore;
    107     get_chess_score(&m_oChessBoard, wscore, bscore);
    108     GetParent()->SendMessage(UM_RECALC, WPARAM(wscore|0x80000000), LPARAM(bscore)); 
    109 }
    110 //////////////////////////////////////////////////////////////////////////
    111 //新游戏
    112 //////////////////////////////////////////////////////////////////////////
    113 void CChessBoard::NewGame()
    114 {
    115     if(cur_step >0)
    116     {
    117         if(MessageBox("开始新游戏吗?", "黑白棋", 
    118             MB_YESNO|MB_ICONQUESTION) == IDYES)
    119         {
    120            g_bStart = 1;
    121            init_board(&m_oChessBoard);
    122            Invalidate(); 
    123         }
    124     }
    125 }
    126 //////////////////////////////////////////////////////////////////////////
    127 //窗口建立函数
    128 //////////////////////////////////////////////////////////////////////////
    129 BOOL CChessBoard::Create(RECT &rect, CWnd *pParentWnd, UINT nID)
    130 {
    131     CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|
    132                                               CS_HREDRAW|CS_VREDRAW,
    133                                               0, (HBRUSH)CBrush(RGB(0,0,255)), 0);
    134      rect.right = rect.left + 380+3;
    135     rect.bottom = rect.top +380+3;
    136     if(!CWnd::CreateEx(WS_EX_CLIENTEDGE, szClassName, _T(""),
    137                         WS_CHILD|WS_VISIBLE|WS_TABSTOP, rect, 
    138                         pParentWnd, nID, NULL)) //WS_EX_CLIENTEDGE
    139 
    140            return FALSE;
    141     UpdateWindow();
    142     m_bitBlackChess.LoadBitmap(IDB_BLACKCHESS);
    143     m_bitChessBoard.LoadBitmap(IDB_CHESSBOARD);
    144     m_bitWhiteChess.LoadBitmap(IDB_WHITECHESS);
    145 
    146     m_motive[0].LoadBitmap(IDB_WHITECHESS); 
    147     m_motive[1].LoadBitmap(IDB_TURN1);
    148     m_motive[2].LoadBitmap(IDB_TURN2); 
    149     m_motive[3].LoadBitmap(IDB_TURN3); 
    150     m_motive[4].LoadBitmap(IDB_TURN4); 
    151     m_motive[5].LoadBitmap(IDB_TURN5); 
    152     m_motive[6].LoadBitmap(IDB_TURN6); 
    153     m_motive[7].LoadBitmap(IDB_BLACKCHESS); 
    154 
    155     return TRUE;
    156 }
    157 //////////////////////////////////////////////////////////////////////////
    158 //播放棋子翻动动画
    159 //////////////////////////////////////////////////////////////////////////
    160 void CChessBoard::PlayMotive(int row, int col, UINT8 obcolor)
    161 {
    162     m_iMotivex = col*COL_WIDTH+24;
    163     m_iMotivey = row*COL_WIDTH+24;
    164     CRect r(m_iMotivex, m_iMotivey, 
    165         m_iMotivex+COL_WIDTH, 
    166         m_iMotivey +ROW_WIDTH);
    167     m_bPlayMotive = TRUE; 
    168     if(obcolor == CHESS_BLACK)
    169     {//把棋子从白面向黑面翻转
    170         for(m_iMotiveNumber =0; m_iMotiveNumber<8; m_iMotiveNumber++)
    171         {
    172             OnPaint();
    173             InvalidateRect(&r); 
    174             delay(50);
    175         }
    176     }
    177     else
    178     {//把棋子从黑面向白面翻转
    179         for(m_iMotiveNumber =7; m_iMotiveNumber>=0; m_iMotiveNumber--)
    180         {
    181             OnPaint();
    182             InvalidateRect(&r); 
    183             delay(50);
    184         }
    185     }
    186     m_bPlayMotive = FALSE;
    187 }
    188 //////////////////////////////////////////////////////////////////////////
    189 //窗口绘图函数
    190 //////////////////////////////////////////////////////////////////////////
    191 void CChessBoard::OnPaint() 
    192 {
    193 
    194     CPaintDC dc(this); 
    195     CDC imgdc;
    196     imgdc.CreateCompatibleDC(&dc);
    197     imgdc.SelectObject(&m_bitChessBoard); 
    198     dc.BitBlt(0, 0, 380, 380, &imgdc,0,0,SRCCOPY);      
    199     if(m_bPlayMotive)
    200     {
    201         imgdc.SelectObject(&m_motive[m_iMotiveNumber]);  
    202         dc.BitBlt(m_iMotivex, m_iMotivey, 39, 39, &imgdc, 0, 0, SRCCOPY);
    203         return;
    204     }
    205   
    206     for(int i=0; i<BOARD_ROWS; i++)
    207     {
    208         for(int j=0; j<BOARD_COLS; j++)
    209         {
    210             if(m_oChessBoard.board[i+1][j+1] == CHESS_BLACK)
    211             {
    212                 imgdc.SelectObject(&m_bitBlackChess); 
    213                 dc.BitBlt(j*COL_WIDTH+24, i*ROW_WIDTH+24, 39, 39, &imgdc,0,0,SRCCOPY);
    214             }
    215             else if(m_oChessBoard.board[i+1][j+1] == CHESS_WHITE)
    216             {
    217                 imgdc.SelectObject(&m_bitWhiteChess); 
    218                 dc.BitBlt(j*COL_WIDTH+24, i*ROW_WIDTH+24, 39, 39, &imgdc,0,0,SRCCOPY);
    219             }
    220         }
    221     }
    222 }
    223 //////////////////////////////////////////////////////////////////////////
    224 //鼠标左键响应函数
    225 //////////////////////////////////////////////////////////////////////////
    226 void CChessBoard::OnLButtonDown(UINT nFlags, CPoint point) 
    227 {
    228 
    229     BYTE row = (point.y-22)/ROW_WIDTH+1;
    230     BYTE col = (point.x-22)/COL_WIDTH+1;
    231 
    232     if(do_move_chess(&m_oChessBoard, row*10+col, ~computer_side&3, m_hWnd))
    233     {
    234         UINT16 wscore, bscore;
    235         get_chess_score(&m_oChessBoard, wscore, bscore);
    236         GetParent()->SendMessage(UM_RECALC, WPARAM(wscore), LPARAM(bscore)); 
    237         PostMessage(UM_COMRUN);
    238     }
    239     else
    240     {
    241         MessageBeep(MB_OK);
    242     }
    243 
    244     CWnd::OnLButtonDown(nFlags, point);
    245 }
    246 
    247 int CChessBoard::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    248 {
    249     if (CWnd::OnCreate(lpCreateStruct) == -1)
    250         return -1;
    251     
    252     EndWaitCursor();
    253     return 0;
    254 }

    dispose.cpp

      1 #include "stdafx.h"
      2 #include "dataStruct.h"
      3 
      4 UINT8   computer_side = CHESS_BLACK;
      5 UINT8   max_depth = 4;
      6 
      7 UINT8   cur_depth = 0;
      8 
      9 UINT8   cur_step =0;
     10 UINT16   step_array[64];
     11 
     12 UINT8   g_iGameLevel = LEVEL_LOW; //游戏难度等级
     13 const  UINT8 depth1[]={6, 7, 8};
     14 const  UINT8 depth2[]={5, 6, 7};
     15 
     16 /*找出所有在水平方向受保护的obcolor方的棋子,并累计分数*/
     17 INT16 scan_horiz_aixes(board_type *board_ptr, UINT8 obcolor)
     18 {
     19     /*扫描8个水平方向*/
     20     INT16 score=0;
     21     UINT8 *cur_ptr, *stop_ptr;
     22     UINT8  piece[4][2];
     23     UINT8 count=0, tmpscore;
     24     UINT8 bFull;
     25     for(UINT8 row=1; row<9; row++)
     26     {
     27         tmpscore = (row == 1 || row == 8) ? 10:2;
     28         cur_ptr = &board_ptr->board[row][1];
     29         stop_ptr= &board_ptr->board[row][9];
     30         bFull = TRUE;
     31         count=0;
     32         while(cur_ptr < stop_ptr)
     33         {
     34             if(*cur_ptr == obcolor)
     35             {
     36                 piece[count][0]  = cur_ptr - &board_ptr->board[row][0];
     37                 while(*cur_ptr == obcolor)
     38                     cur_ptr ++;
     39                 piece[count++][1] = cur_ptr - &board_ptr->board[row][0];
     40             }
     41             if(!*cur_ptr)
     42                 bFull = FALSE; 
     43             cur_ptr++;
     44         }
     45         while(count--)
     46         {
     47             UINT8 nums = (piece[count][1]-piece[count][0]);
     48             if(bFull || piece[count][0]==1 || piece[count][1] == 9)
     49                 score += nums;
     50             if(piece[count][0]==1 || piece[count][1] == 9)
     51                 score += tmpscore;
     52             else if(!bFull && (piece[count][0] == 2 || piece[count][1] == 8) && (row == 1 || row == 8))
     53                 score -= tmpscore;
     54         }
     55     }
     56     
     57     return score;
     58 }
     59 
     60 /*找出所有在垂直方向受保护的obcolor方的棋子,并累计分数*/
     61 INT16 scan_vertical_aixes(board_type *board_ptr, UINT8 obcolor)
     62 {
     63     INT16 score=0;
     64     UINT8 *cur_ptr, *stop_ptr;
     65     UINT8  piece[4][2];
     66     UINT8 count=0, tmpscore;
     67     UINT8 bFull;
     68     for(UINT8 col=1; col<9; col++)
     69     {
     70         tmpscore = (col == 1 || col == 8) ? 10:2;
     71         cur_ptr = &board_ptr->board[1][col];
     72         stop_ptr= &board_ptr->board[9][col];
     73         bFull = TRUE;
     74         count=0;
     75         while(cur_ptr < stop_ptr)
     76         {
     77             if(*cur_ptr == obcolor)
     78             {
     79                 piece[count][0]  = (cur_ptr - &board_ptr->board[0][col])/10;
     80                 while(*cur_ptr == obcolor)
     81                     cur_ptr += 10;
     82                 piece[count++][1] = (cur_ptr - &board_ptr->board[0][col])/10;
     83             }
     84             if(!*cur_ptr)
     85                 bFull = FALSE;
     86             cur_ptr += 10;
     87         }
     88         while(count--)
     89         {
     90             UINT8 nums = (piece[count][1]-piece[count][0]);
     91             if(bFull || piece[count][0]==1 || piece[count][1] == 9)
     92                 score += nums;
     93             if(piece[count][0]==1 || piece[count][1] == 9)
     94                 score += tmpscore;
     95             else if(!bFull && (piece[count][0] == 2 || piece[count][1] == 8) && (col == 1 || col == 8))
     96                 score -= (tmpscore<<1);
     97         }
     98     }
     99        return score;
    100 }
    101 
    102 /*找出所有在右上到左下方向受保护的obcolor方的棋子,并累计分数*/
    103 INT16 scan_fd_aixes(board_type *board_ptr, UINT8 obcolor)
    104 {
    105     INT16 score =0;
    106     UINT8 *cur_ptr, *stop_ptr, *base_ptr;
    107     UINT8  piece[4][2];
    108     UINT8 count=0, tmpscore;
    109     UINT8 bFull;
    110     for(INT8 aixes = -5; aixes <= 5; aixes++)
    111     {
    112         tmpscore = (aixes == 0) ? 10:2;
    113         if(aixes <=0)
    114         {
    115             base_ptr = cur_ptr = &board_ptr->board[1][8+aixes];
    116             stop_ptr = &board_ptr->board[9+aixes][0];
    117         }
    118         else
    119         {
    120             base_ptr = cur_ptr = &board_ptr->board[aixes+1][8];
    121             stop_ptr= &board_ptr->board[9][aixes];
    122         }
    123         bFull = TRUE;
    124         count=0;
    125         while(cur_ptr < stop_ptr)
    126         {
    127             if(*cur_ptr == obcolor)
    128             {
    129                 piece[count][0]  = cur_ptr - board_ptr->board[0];
    130                 while(*cur_ptr == obcolor)
    131                     cur_ptr += 9;
    132                 piece[count++][1] = cur_ptr- board_ptr->board[0];
    133             }
    134             if(!*cur_ptr)
    135                 bFull = FALSE;
    136             cur_ptr += 9;
    137         }
    138         while(count--)
    139         {
    140             UINT8 nums = (piece[count][1]-piece[count][0])/9;
    141             BOOL  toborder = (piece[count][0] == base_ptr - board_ptr->board[0] || 
    142                 piece[count][1] == stop_ptr - board_ptr->board[0]);
    143             if(bFull || toborder)
    144                 score += nums;
    145             
    146             if((aixes == 1 || aixes == -1) && toborder)
    147                 score -= tmpscore;
    148             /*如果是这块棋到达边界*/
    149             else if(toborder)
    150                 score += tmpscore;
    151             /*如果有棋在角边上,则扣分*/
    152             else if(!bFull && (piece[count][0] == 27 ||
    153                 piece[count][1] == 81))
    154                 score -= (tmpscore<<1);
    155         }
    156     }
    157     
    158     /*如果角边有棋子,扣分*/
    159     if(board_ptr->board[1][1] == obcolor)
    160         score += 10;
    161     else 
    162     {
    163         if(board_ptr->board[1][2] == obcolor)
    164             score -=2;
    165         if(board_ptr->board[2][1] == obcolor)
    166             score -=2;
    167         if(board_ptr->board[2][2]== obcolor)
    168             score -=2;
    169     }
    170     
    171     if(board_ptr->board[8][8] == obcolor)
    172         score +=10;
    173     else
    174     {
    175         if(board_ptr->board[7][8]  == obcolor)
    176             score -=2;
    177         if(board_ptr->board[8][7]== obcolor)
    178             score -=2;
    179         if(board_ptr->board[7][7]== obcolor)
    180             score -= 2;
    181     }    
    182     return score;
    183 }
    184 /*找出所有在左上到右下方向受保护的obcolor方的棋子,并累计分数*/
    185 INT16 scan_bd_aixes(board_type *board_ptr,  UINT8 obcolor)
    186 {
    187     
    188     INT16 score =0;
    189     UINT8 *cur_ptr, *stop_ptr, *base_ptr;
    190     UINT8  piece[4][2];
    191     UINT8 count=0, tmpscore;
    192     UINT8 bFull;
    193     for(INT8 aixes = -5; aixes <= 5; aixes++)
    194     {
    195         tmpscore = (aixes == 0) ? 10:2;
    196         if(aixes <=0)
    197         {
    198             base_ptr = cur_ptr = &board_ptr->board[1-aixes][1];
    199             stop_ptr = &board_ptr->board[9][9+aixes];
    200         }
    201         else
    202         {
    203             base_ptr = cur_ptr = &board_ptr->board[1][aixes+1];
    204             stop_ptr= &board_ptr->board[9-aixes][9];
    205         }
    206         bFull = TRUE;
    207         count=0;
    208         while(cur_ptr < stop_ptr)
    209         {
    210             if(*cur_ptr == obcolor)
    211             {
    212                 piece[count][0]  = cur_ptr - board_ptr->board[0];
    213                 while(*cur_ptr == obcolor)
    214                     cur_ptr += 11;
    215                 piece[count++][1] = cur_ptr- board_ptr->board[0];
    216             }
    217             if(!*cur_ptr)
    218                 bFull = FALSE;
    219             cur_ptr += 11;
    220         } 
    221         while(count--)
    222         {
    223             UINT8 nums = (piece[count][1]-piece[count][0])/11;
    224             BOOL  toborder = (piece[count][0] == base_ptr - board_ptr->board[0] || 
    225                 piece[count][1] == stop_ptr - board_ptr->board[0]);
    226             if(bFull || toborder)
    227                 score += nums;
    228             /*如果角边有棋子,扣分*/
    229             if((aixes == 1 || aixes == -1) && toborder)
    230                 score -= tmpscore;
    231             /*如果是这块棋到达边界*/
    232             else if(toborder)
    233                 score += tmpscore;
    234             /*如果有棋在角边上,则扣分, 主对角线方向*/
    235             else if(!bFull && (piece[count][0] == 22 ||
    236                 piece[count][1] == 88))
    237                 score -= (tmpscore<<1);
    238         }
    239     }
    240     
    241     /*如果角边有棋子,扣分*/
    242     if(board_ptr->board[1][8] == obcolor)
    243         score += 10;
    244     else 
    245     {
    246         if(board_ptr->board[1][7] == obcolor)
    247             score -=2;
    248         if(board_ptr->board[2][8] == obcolor)
    249             score -=2;
    250         if(board_ptr->board[2][7]== obcolor)
    251             score -=2;
    252     }
    253     
    254     if(board_ptr->board[8][1] == obcolor)
    255         score +=10;
    256     else
    257     {
    258         if(board_ptr->board[7][1]  == obcolor)
    259             score -=2;
    260         if(board_ptr->board[8][2]== obcolor)
    261             score -=2;
    262         if(board_ptr->board[7][2]== obcolor)
    263             score -= 2;
    264     } 
    265     return score;
    266 }
    267 
    268 INT16 sample_calc_board_status(board_type *board_ptr, UINT8 obcolor)
    269 {
    270     INT16 score=0;
    271     UINT8 *ptr = &board_ptr->board[1][1];
    272     UINT8 *stop = &board_ptr->board[8][9]; 
    273     UINT8 tmpcol = ~obcolor &0x03;
    274     while(ptr<stop)
    275     {
    276         if(*ptr == obcolor)
    277             score++;
    278         else if(*ptr == tmpcol)
    279             score--;
    280         ptr++;
    281     }
    282     return score;
    283 }
    284 
    285 /*计算棋局board_ptr的状态分*/
    286 INT16 calc_board_status(board_type *board_ptr, UINT8 obcolor)
    287 {
    288     INT16 score=0;
    289     score += scan_horiz_aixes(board_ptr,  obcolor);
    290     score += scan_vertical_aixes(board_ptr, obcolor);
    291     score += scan_bd_aixes(board_ptr, obcolor);
    292     score += scan_fd_aixes(board_ptr, obcolor);
    293     UINT8 tmpcol = ~obcolor & 0x03 ;
    294     if(board_ptr->board[1][1] == tmpcol)
    295         score -= 44;
    296     if(board_ptr->board[8][8] == tmpcol)
    297         score -= 44;
    298     if(board_ptr->board[1][8] == tmpcol)
    299         score -= 44;
    300     if(board_ptr->board[8][1] == tmpcol)
    301         score -= 44;
    302     return score;
    303 }
    304 
    305 /*从start_pos出发找到一个可下子的点,返回受影响的子的个数,
    306 affected_list存放受影响的棋格的指针,第一个指针为落子的点*/
    307 const INT16 delta_array[8] = {-11, 11, -9, 9, -1, 1, -10, 10};
    308 INT16 find_move(board_type *board_ptr, INT16 start_pos, 
    309                 UINT8 obcolor, INT16 *affected_list)
    310 {
    311     UINT8 *cel_ptr = board_ptr->board[0] + start_pos;
    312     UINT8 *stop_ptr = &board_ptr->board[8][9], *p;
    313     INT16 *aff_ptr = affected_list+1, *hold_aff;
    314     UINT8 aixes;
    315     UINT8 thithercolor = THITHER_COLOR(obcolor);
    316     while(1)
    317     {
    318         /*找到一个空格子*/
    319         while(*cel_ptr) 
    320             if(++cel_ptr>=stop_ptr)
    321                 return 0;
    322             /*检查在8个方向上是否能吃掉对方的棋子,并记录被吃掉棋子的下标*/
    323             for(aixes =0;aixes<8; aixes++)
    324             {
    325                 hold_aff = aff_ptr;
    326                 p = cel_ptr + delta_array[aixes];
    327                 while(*p == thithercolor)
    328                 {
    329                     *aff_ptr++ = p - board_ptr->board[0];
    330                     p+= delta_array[aixes];
    331                 }
    332                 if(*p != obcolor)
    333                     aff_ptr = hold_aff;
    334             }
    335             /*如果cel_ptr对应的点可以吃掉对方的子*/
    336             if(aff_ptr - affected_list > 1) 
    337             {
    338                 *affected_list = cel_ptr - board_ptr->board[0];
    339                 return (aff_ptr - affected_list);
    340             }
    341             cel_ptr++;
    342     }
    343 }
    344 
    345 void init_board(board_type *board_ptr)
    346 {
    347     memset(board_ptr, 0, sizeof(board_type));
    348     /*init boarder*/
    349     memset(board_ptr->board[0], 0xff, 10);
    350     memset(board_ptr->board[9], 0xff, 10);
    351     for(int i=0; i<9; i++)
    352     {
    353         board_ptr->board[i][0] = board_ptr->board[i][9] =0xff;
    354     }
    355     
    356     /*init chess*/
    357     board_ptr->board[4][4] = board_ptr->board[5][5] = CHESS_WHITE;
    358     board_ptr->board[4][5] = board_ptr->board[5][4] = CHESS_BLACK;
    359     cur_step = 0;
    360     computer_side = CHESS_WHITE;
    361 }   
    362 
    363 /*从棋盘的一个状态出发,扩展此结点,并返回此结点的部分回溯值*/
    364 void extend_node_one(tree_node_type *node_ptr, tree_node_type *parent_ptr,UINT8 obcolor)
    365 {
    366     tree_node_type childnode;
    367     INT16 affected_list[MAX_AFFECTED_PIECES];
    368     INT16 start_pos = 11, num;
    369     num = find_move(&node_ptr->board, start_pos, obcolor, affected_list);
    370     /*如果是终局状态,则返回状态估值函数的值*/
    371     if(++cur_depth == max_depth || num==0 )
    372     {
    373         /*如果已方PASS但没到棋局结束,要扣分*/
    374         node_ptr->value = calc_board_status(&node_ptr->board, computer_side);
    375         if(!num)
    376         {
    377             /*如果双方都没棋下*/
    378             if(!find_move(&node_ptr->board, 11, ~obcolor&0x03, affected_list)) 
    379                 return;
    380             
    381             if(obcolor == computer_side)
    382             {
    383                 node_ptr->value -= 15;
    384                 return ;
    385             }
    386             node_ptr->value += 15;
    387         }
    388         return;           
    389     }
    390     /*初始化回溯值*/ 
    391     node_ptr->value = (obcolor == computer_side)? -INITIAL_VALUE : INITIAL_VALUE;
    392     memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
    393     while(num)
    394     {
    395         while(num--)
    396             childnode.board.board[0][affected_list[num]] = obcolor;
    397         /*递归计算部分回溯值*/
    398         UINT8 depth = cur_depth;
    399         extend_node_one(&childnode, node_ptr, (~obcolor)&0x03);
    400         cur_depth = depth;
    401         /*如果此结点是棋手一方,则部分回溯值是子结点中最大的一个*/
    402         if(obcolor == computer_side)
    403         {
    404             if(childnode.value > node_ptr->value)
    405             {
    406                 node_ptr->value = childnode.value; 
    407                 node_ptr->movepos = affected_list[0];
    408             }
    409         }
    410         /*如果是对手一方,部分回溯值是子结点中最小的一个*/ 
    411         else
    412         {
    413             if(childnode.value < node_ptr->value)
    414             {
    415                 node_ptr->value = childnode.value;
    416                 node_ptr->movepos = affected_list[0];
    417             }
    418         }
    419         /* α-β裁减的判断   在考虑轮到棋手下棋的一个亲节点及轮到对手下棋的一个子节点时,
    420         如果该子节点的数值已经小于或等于其亲节点的回溯值,
    421         那么就不需要对该节点或者其后续节点做更多的处理了。
    422         计算的过程可以直接返回到亲节点上。
    423         */
    424         /*在考虑轮到对手下棋的一个亲节点及轮到棋手下棋的一个子节点时,
    425         如果该子节点的部分回溯值已经大于或等于其亲节点的部分回溯值,
    426         那么就不需要对该子节点或者其后裔节点做更多的处理了。
    427         计算过程可以直接返回到亲节点上。*/
    428         if(parent_ptr)
    429         {
    430             if(obcolor != computer_side)
    431             {
    432                 /*α裁减*/
    433                 if(node_ptr->value <= parent_ptr->value)
    434                     return;
    435             }
    436             else
    437             {
    438                 /*β裁减*/
    439                 if(node_ptr->value >= parent_ptr->value)
    440                     return;
    441             }
    442         }
    443         /*找到下一个可落子的点*/
    444         start_pos = affected_list[0]+1;
    445         memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
    446         num = find_move(&childnode.board, start_pos, obcolor, affected_list);
    447     }
    448     return;
    449 }
    450 
    451 
    452 void extend_node_two(tree_node_type *node_ptr, tree_node_type *parent_ptr,UINT8 obcolor)
    453 {
    454     tree_node_type childnode;
    455     INT16 affected_list[MAX_AFFECTED_PIECES];
    456     INT16 start_pos = 11, num;
    457     num = find_move(&node_ptr->board, start_pos, obcolor, affected_list);
    458     /*如果是终局状态,则返回状态估值函数的值*/
    459     if(!num)
    460     {
    461         /*如果已方PASS但没到棋局结束,要扣分*/
    462         node_ptr->value = sample_calc_board_status(&node_ptr->board, computer_side);
    463         /*如果双方都没棋下*/
    464         if(!find_move(&node_ptr->board, 11, ~obcolor&0x03, affected_list)) 
    465             return;
    466         
    467         if(obcolor == computer_side)
    468         {
    469             node_ptr->value -= 10;
    470             return;
    471         }
    472         node_ptr->value += 10;
    473         return;
    474     }
    475     /*初始化回溯值*/ 
    476     node_ptr->value = (obcolor == computer_side)? -INITIAL_VALUE : INITIAL_VALUE;
    477     memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
    478     while(num)
    479     {
    480         while(num--)
    481             childnode.board.board[0][affected_list[num]] = obcolor;
    482         /*递归计算部分回溯值*/
    483         UINT8 depth = cur_depth;
    484         extend_node_two(&childnode, node_ptr, (~obcolor)&0x03);
    485         cur_depth = depth;
    486         /*如果此结点是棋手一方,则部分回溯值是子结点中最大的一个*/
    487         if(obcolor == computer_side)
    488         {
    489             if(childnode.value > node_ptr->value)
    490             {
    491                 node_ptr->value = childnode.value; 
    492                 node_ptr->movepos = affected_list[0];
    493             }
    494         }
    495         /*如果是对手一方,部分回溯值是子结点中最小的一个*/ 
    496         else
    497         {
    498             if(childnode.value < node_ptr->value)
    499             {
    500                 node_ptr->value = childnode.value;
    501                 node_ptr->movepos = affected_list[0];
    502             }
    503         }
    504         /* α-β裁减的判断   在考虑轮到棋手下棋的一个亲节点及轮到对手下棋的一个子节点时,
    505         如果该子节点的数值已经小于或等于其亲节点的回溯值,
    506         那么就不需要对该节点或者其后续节点做更多的处理了。
    507         计算的过程可以直接返回到亲节点上。
    508         */
    509         /*在考虑轮到对手下棋的一个亲节点及轮到棋手下棋的一个子节点时,
    510         如果该子节点的部分回溯值已经大于或等于其亲节点的部分回溯值,
    511         那么就不需要对该子节点或者其后裔节点做更多的处理了。
    512         计算过程可以直接返回到亲节点上。*/
    513         if(parent_ptr)
    514         {
    515             if(obcolor != computer_side)
    516             {
    517                 /*α裁减*/
    518                 if(node_ptr->value <= parent_ptr->value)
    519                     return;
    520             }
    521             else
    522             {
    523                 /*β裁减*/
    524                 if(node_ptr->value >= parent_ptr->value)
    525                     return ;
    526             }
    527         }
    528         /*找到下一个可落子的点*/
    529         start_pos = affected_list[0]+1;
    530         memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
    531         num = find_move(&childnode.board, start_pos, obcolor, affected_list);
    532     }
    533     return;
    534 }
    535 
    536 void get_chess_score(board_type *board_ptr, UINT16 &iWscore, UINT16 &iBscore)
    537 {
    538     iWscore =0; iBscore =0;
    539     for(INT16 i=1; i<=BOARD_ROWS; i++)
    540         for(INT16 j=1; j<=BOARD_COLS; j++)
    541         {
    542             if(board_ptr->board[i][j]  == CHESS_BLACK)
    543                 iBscore++;
    544             else  if(board_ptr->board[i][j] == CHESS_WHITE)
    545                 iWscore++;
    546         }
    547 }
    548 
    549 void game_over(board_type *board_ptr, HWND hwnd)
    550 {
    551     UINT16 wscore, bscore;
    552     char strcomwin[]="虽然你很历害,但我还是赢了你!";
    553     char struserwin[]="让你一次,下次你可没这么走运了!";
    554     char strdogfall[]="我没好好下,你才有机会平局!";
    555     char *text;
    556     get_chess_score(board_ptr, wscore, bscore);
    557 
    558     g_bStart = 0;
    559     
    560     if(computer_side == CHESS_WHITE)
    561     {
    562         if(wscore > bscore)
    563         {
    564             text = strcomwin;
    565         }
    566         else if(wscore <bscore)
    567         {
    568             text = struserwin;
    569         }
    570         else
    571         {
    572             text = strdogfall;
    573         }
    574     }
    575     else
    576     {
    577         if(wscore > bscore)
    578             text = struserwin;            
    579         else if(wscore <bscore)
    580             text = strcomwin;
    581         else text = strdogfall;
    582     }
    583     MessageBox(hwnd,  text, "黑白棋", MB_OK|MB_ICONINFORMATION);
    584 }
    585 
    586 void computer_play(board_type *board_ptr, HWND hwnd)
    587 {
    588     cur_depth =0;
    589     tree_node_type node;
    590     INT16 affected_list[MAX_AFFECTED_PIECES];
    591 start:
    592     memcpy(&node.board, board_ptr, sizeof(board_type));
    593     node.movepos =0;
    594     if(cur_step>= STEP_MONMENT2)
    595     {
    596         extend_node_two(&node, NULL, computer_side);
    597     }
    598     else if(cur_step > STEP_MONMENT1)
    599     {
    600         max_depth = depth2[g_iGameLevel];
    601         extend_node_one(&node, NULL, computer_side);
    602     }
    603     else 
    604     {
    605         max_depth = depth1[g_iGameLevel];
    606         extend_node_one(&node, NULL, computer_side);
    607     }
    608     
    609     if(!do_move_chess(board_ptr, node.movepos, computer_side, hwnd))
    610     {
    611         if(!find_move(board_ptr, 11, (~computer_side)&0x03, affected_list))
    612         {
    613             game_over(board_ptr, hwnd);
    614             return;
    615         }
    616         else
    617         {
    618             MessageBox(hwnd,"我没棋下了,你再走一步!", "黑白棋", MB_OK|MB_ICONINFORMATION);
    619             return;
    620         }
    621     }
    622     else
    623     { 
    624         if(!find_move(board_ptr, 11, (~computer_side)&0x03, affected_list))
    625         {
    626             if(!find_move(board_ptr, 11, computer_side, affected_list))
    627             {
    628                 game_over(board_ptr, hwnd); 
    629                 return;
    630             }
    631             else
    632             {
    633                 
    634                 MessageBox(hwnd ,"你没棋下了,我再走一步!", "黑白棋", MB_OK|MB_ICONINFORMATION);
    635                 
    636                 goto start;
    637             }
    638             
    639         }
    640     }
    641 } 
    642 
    643 UINT8 do_move_chess(board_type *board_ptr, UINT16 movepos, UINT8 obcolor, HWND hwnd)
    644 {
    645     INT16 affected_list[MAX_AFFECTED_PIECES];
    646     INT16 num = find_move(board_ptr, movepos, obcolor, affected_list);
    647     if(!num || affected_list[0] != movepos)
    648         return 0; 
    649     for(int i=0; i<num; i++)
    650     {
    651         board_ptr->board[0][affected_list[i]] = obcolor;
    652         if(hwnd)
    653             ::SendMessage(hwnd, WM_TRANCHESS, WPARAM(affected_list[i]),LPARAM(i<<16|obcolor));
    654     }
    655     step_array[cur_step++] = movepos;
    656     
    657     return 1;
    658 }

    HelpDlg.cpp

     1 // HelpDlg.cpp : implementation file
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "Othello.h"
     6 #include "HelpDlg.h"
     7 
     8 #ifdef _DEBUG
     9 #define new DEBUG_NEW
    10 #undef THIS_FILE
    11 static char THIS_FILE[] = __FILE__;
    12 #endif
    13 
    14 /////////////////////////////////////////////////////////////////////////////
    15 // CHelpDlg dialog
    16 
    17 
    18 CHelpDlg::CHelpDlg(CWnd* pParent /*=NULL*/)
    19     : CDialog(CHelpDlg::IDD, pParent)
    20 {
    21     //{{AFX_DATA_INIT(CHelpDlg)
    22         // NOTE: the ClassWizard will add member initialization here
    23     //}}AFX_DATA_INIT
    24 }
    25 
    26 
    27 void CHelpDlg::DoDataExchange(CDataExchange* pDX)
    28 {
    29     CDialog::DoDataExchange(pDX);
    30     //{{AFX_DATA_MAP(CHelpDlg)
    31         // NOTE: the ClassWizard will add DDX and DDV calls here
    32     //}}AFX_DATA_MAP
    33 }
    34 
    35 
    36 BEGIN_MESSAGE_MAP(CHelpDlg, CDialog)
    37     //{{AFX_MSG_MAP(CHelpDlg)
    38     //}}AFX_MSG_MAP
    39 END_MESSAGE_MAP()
    40 
    41 /////////////////////////////////////////////////////////////////////////////
    42 // CHelpDlg message handlers
    43 
    44 void CHelpDlg::OnOK() 
    45 {
    46     // TODO: Add extra validation here
    47     
    48     CDialog::OnOK();
    49 }

    Othello.cpp

     1 // Othello.cpp : Defines the class behaviors for the application.
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "Othello.h"
     6 #include "OthelloDlg.h"
     7 
     8 #ifdef _DEBUG
     9 #define new DEBUG_NEW
    10 #undef THIS_FILE
    11 static char THIS_FILE[] = __FILE__;
    12 #endif
    13 
    14 /////////////////////////////////////////////////////////////////////////////
    15 // COthelloApp
    16 
    17 BEGIN_MESSAGE_MAP(COthelloApp, CWinApp)
    18     //{{AFX_MSG_MAP(COthelloApp)
    19         // NOTE - the ClassWizard will add and remove mapping macros here.
    20         //    DO NOT EDIT what you see in these blocks of generated code!
    21     //}}AFX_MSG
    22     ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    23 END_MESSAGE_MAP()
    24 
    25 /////////////////////////////////////////////////////////////////////////////
    26 // COthelloApp construction
    27 
    28 COthelloApp::COthelloApp()
    29 {
    30     // TODO: add construction code here,
    31     // Place all significant initialization in InitInstance
    32 }
    33 
    34 /////////////////////////////////////////////////////////////////////////////
    35 // The one and only COthelloApp object
    36 
    37 COthelloApp theApp;
    38 
    39 /////////////////////////////////////////////////////////////////////////////
    40 // COthelloApp initialization
    41 
    42 BOOL COthelloApp::InitInstance()
    43 {
    44     AfxEnableControlContainer();
    45 
    46     // Standard initialization
    47     // If you are not using these features and wish to reduce the size
    48     //  of your final executable, you should remove from the following
    49     //  the specific initialization routines you do not need.
    50 
    51 #ifdef _AFXDLL
    52     Enable3dControls();            // Call this when using MFC in a shared DLL
    53 #else
    54     Enable3dControlsStatic();    // Call this when linking to MFC statically
    55 #endif
    56 
    57     COthelloDlg dlg;
    58     m_pMainWnd = &dlg;
    59     int nResponse = dlg.DoModal();
    60     if (nResponse == IDOK)
    61     {
    62         // TODO: Place code here to handle when the dialog is
    63         //  dismissed with OK
    64     }
    65     else if (nResponse == IDCANCEL)
    66     {
    67         // TODO: Place code here to handle when the dialog is
    68         //  dismissed with Cancel
    69     }
    70 
    71     // Since the dialog has been closed, return FALSE so that we exit the
    72     //  application, rather than start the application's message pump.
    73     return FALSE;
    74 }

    OthelloDlg.cpp

      1 // OthelloDlg.cpp : implementation file
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "Othello.h"
      6 #include "OthelloDlg.h"
      7 
      8 #include "HelpDlg.h"
      9 
     10 #include <mmsystem.h>
     11 
     12 #include "DataStruct.h"
     13 
     14 #ifdef _DEBUG
     15 #define new DEBUG_NEW
     16 #undef THIS_FILE
     17 static char THIS_FILE[] = __FILE__;
     18 #endif
     19 
     20 /////////////////////////////////////////////////////////////////////////////
     21 // CAboutDlg dialog used for App About
     22 
     23 class CAboutDlg : public CDialog
     24 {
     25 public:
     26     CAboutDlg();
     27 
     28 // Dialog Data
     29     //{{AFX_DATA(CAboutDlg)
     30     enum { IDD = IDD_ABOUTBOX };
     31     //}}AFX_DATA
     32 
     33     // ClassWizard generated virtual function overrides
     34     //{{AFX_VIRTUAL(CAboutDlg)
     35     protected:
     36     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
     37     //}}AFX_VIRTUAL
     38 
     39 // Implementation
     40 protected:
     41     //{{AFX_MSG(CAboutDlg)
     42     //}}AFX_MSG
     43     DECLARE_MESSAGE_MAP()
     44 };
     45 
     46 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
     47 {
     48     //{{AFX_DATA_INIT(CAboutDlg)
     49     //}}AFX_DATA_INIT
     50 }
     51 
     52 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
     53 {
     54     CDialog::DoDataExchange(pDX);
     55     //{{AFX_DATA_MAP(CAboutDlg)
     56     //}}AFX_DATA_MAP
     57 }
     58 
     59 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
     60     //{{AFX_MSG_MAP(CAboutDlg)
     61         // No message handlers
     62     //}}AFX_MSG_MAP
     63 END_MESSAGE_MAP()
     64 
     65 /////////////////////////////////////////////////////////////////////////////
     66 // COthelloDlg dialog
     67 
     68 COthelloDlg::COthelloDlg(CWnd* pParent /*=NULL*/)
     69     : CDialog(COthelloDlg::IDD, pParent)
     70 {
     71     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
     72     m_nBlackCount = 0;
     73     m_nWhiteCount = 0;
     74 }
     75 
     76 void COthelloDlg::DoDataExchange(CDataExchange* pDX)
     77 {
     78     CDialog::DoDataExchange(pDX);
     79 }
     80 
     81 BEGIN_MESSAGE_MAP(COthelloDlg, CDialog)
     82     //{{AFX_MSG_MAP(COthelloDlg)
     83     ON_WM_SYSCOMMAND()
     84     ON_WM_PAINT()
     85     ON_WM_QUERYDRAGICON()
     86     ON_COMMAND(IDR_ABOUT, OnAbout)
     87     ON_COMMAND(IDR_EXIT_GAME, OnExitGame)
     88     ON_COMMAND(IDR_GAME_START, OnGameStart)
     89     ON_COMMAND(IDR_HELP, OnHelp)
     90     ON_COMMAND(IDR_LEVEL_HIGH, OnLevelHigh)
     91     ON_COMMAND(IDR_LEVEL_LOW, OnLevelLow)
     92     ON_COMMAND(IDR_LEVEL_NOR, OnLevelNor)
     93     ON_COMMAND(IDR_PLAY_MUSIC, OnPlayMusic)
     94     ON_BN_CLICKED(IDC_BACK_BTN, OnBackBtn)
     95     //}}AFX_MSG_MAP
     96     ON_MESSAGE(UM_RECALC, OnRecalc)
     97 END_MESSAGE_MAP()
     98 
     99 /////////////////////////////////////////////////////////////////////////////
    100 // COthelloDlg message handlers
    101 
    102 void COthelloDlg::OnRecalc(WPARAM wParam, LPARAM lParam)
    103 {
    104     CString strStatus;
    105     CString strCount;
    106     if(wParam & 0x80000000)
    107     {
    108         strStatus.Format(" 我找到一步好棋,现该你了!"); 
    109         
    110     }
    111     else
    112     {
    113         strStatus.Format("我正在想,你别急!"); 
    114     }
    115     strCount.Format(" 黑子:%02d ", UINT(lParam));
    116     SetDlgItemText(IDC_STATUS, strStatus); 
    117     SetDlgItemText(IDC_BLACK_COUNT, strCount);
    118     strCount.Format(" 白子:%02d ", (wParam&0xFFFF));
    119     SetDlgItemText(IDC_WHITE_COUNT, strCount);
    120 }
    121 
    122 BOOL COthelloDlg::OnInitDialog()
    123 {
    124     CDialog::OnInitDialog();
    125 
    126     // Add "About..." menu item to system menu.
    127 
    128     // IDM_ABOUTBOX must be in the system command range.
    129     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    130     ASSERT(IDM_ABOUTBOX < 0xF000);
    131 
    132     CMenu* pSysMenu = GetSystemMenu(FALSE);
    133     if (pSysMenu != NULL)
    134     {
    135         CString strAboutMenu;
    136         strAboutMenu.LoadString(IDS_ABOUTBOX);
    137         if (!strAboutMenu.IsEmpty())
    138         {
    139             pSysMenu->AppendMenu(MF_SEPARATOR);
    140             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    141         }
    142     }
    143 
    144     SetIcon(m_hIcon, TRUE);            // Set big icon
    145     SetIcon(m_hIcon, FALSE);        // Set small icon
    146     
    147     InitMenu();
    148 
    149     g_iGameLevel = LEVEL_LOW;
    150 
    151     SetDlgItemText(IDC_STATUS, "欢迎来玩黑白棋!");
    152 
    153     m_chess.Create(CRect(5,5, 30,30), this, ID_CHESSBOARD);
    154     
    155     return TRUE;  // return TRUE  unless you set the focus to a control
    156 }
    157 
    158 void COthelloDlg::OnSysCommand(UINT nID, LPARAM lParam)
    159 {
    160     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    161     {
    162         CAboutDlg dlgAbout;
    163         dlgAbout.DoModal();
    164     }
    165     else
    166     {
    167         CDialog::OnSysCommand(nID, lParam);
    168     }
    169 }
    170 
    171 // If you add a minimize button to your dialog, you will need the code below
    172 //  to draw the icon.  For MFC applications using the document/view model,
    173 //  this is automatically done for you by the framework.
    174 
    175 void COthelloDlg::OnPaint() 
    176 {
    177     if (IsIconic())
    178     {
    179         CPaintDC dc(this); // device context for painting
    180 
    181         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    182 
    183         // Center icon in client rectangle
    184         int cxIcon = GetSystemMetrics(SM_CXICON);
    185         int cyIcon = GetSystemMetrics(SM_CYICON);
    186         CRect rect;
    187         GetClientRect(&rect);
    188         int x = (rect.Width() - cxIcon + 1) / 2;
    189         int y = (rect.Height() - cyIcon + 1) / 2;
    190 
    191         // Draw the icon
    192         dc.DrawIcon(x, y, m_hIcon);
    193     }
    194     else
    195     {
    196         CDialog::OnPaint();
    197     }
    198 
    199     CString strCount;
    200     strCount.Format(" 黑子:%02d ", m_nBlackCount);
    201     SetDlgItemText(IDC_BLACK_COUNT, strCount);
    202     strCount.Format(" 白子:%02d ", m_nWhiteCount);
    203     SetDlgItemText(IDC_WHITE_COUNT, strCount);
    204 }
    205 
    206 // The system calls this to obtain the cursor to display while the user drags
    207 //  the minimized window.
    208 HCURSOR COthelloDlg::OnQueryDragIcon()
    209 {
    210     return (HCURSOR) m_hIcon;
    211 }
    212 
    213 void COthelloDlg::OnAbout() 
    214 {
    215     CAboutDlg dlg;            //创建关于对话框类对象
    216     dlg.DoModal();            //弹出关于对话框
    217 }
    218 
    219 void COthelloDlg::OnExitGame() 
    220 {
    221     CDialog::OnCancel();    //调用基类退出函数
    222 }
    223 
    224 void COthelloDlg::OnGameStart() 
    225 {
    226     GameStart();            //调用游戏开始接口函数    
    227 }
    228 
    229 void COthelloDlg::OnHelp() 
    230 {
    231     CHelpDlg dlg;            //创建帮助对话框类对象
    232     dlg.DoModal();            //弹出帮助对话框
    233 }
    234 
    235 void COthelloDlg::OnLevelHigh() 
    236 {
    237     CWnd*   pMain   =   AfxGetMainWnd();   
    238     CMenu*   pMenu   =   pMain->GetMenu();
    239     //判断播放音乐菜单当前状态
    240     BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_LEVEL_HIGH, MF_CHECKED);
    241     
    242     if( !bCheck )
    243     {
    244         pMenu->CheckMenuItem(IDR_LEVEL_HIGH, 
    245                     MF_BYCOMMAND | MF_CHECKED);
    246         pMenu->CheckMenuItem(IDR_LEVEL_LOW,
    247                     MF_BYCOMMAND | MF_UNCHECKED);
    248         pMenu->CheckMenuItem(IDR_LEVEL_NOR, 
    249                     MF_BYCOMMAND | MF_UNCHECKED);
    250         g_iGameLevel = LEVEL_HIGH;
    251     }
    252 }
    253 
    254 void COthelloDlg::OnLevelLow() 
    255 {
    256     CWnd*   pMain   =   AfxGetMainWnd();   
    257     CMenu*   pMenu   =   pMain->GetMenu();
    258     //判断播放音乐菜单当前状态
    259     BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_LEVEL_LOW, MF_CHECKED);
    260     
    261     if( !bCheck )
    262     {
    263         pMenu->CheckMenuItem(IDR_LEVEL_HIGH, 
    264             MF_BYCOMMAND | MF_UNCHECKED);
    265         pMenu->CheckMenuItem(IDR_LEVEL_LOW,
    266             MF_BYCOMMAND | MF_CHECKED);
    267         pMenu->CheckMenuItem(IDR_LEVEL_NOR, 
    268             MF_BYCOMMAND | MF_UNCHECKED);
    269         g_iGameLevel = LEVEL_LOW;
    270     }
    271 }
    272 
    273 void COthelloDlg::OnLevelNor() 
    274 {
    275     CWnd*   pMain   =   AfxGetMainWnd();   
    276     CMenu*   pMenu   =   pMain->GetMenu();
    277     //判断播放音乐菜单当前状态
    278     BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_LEVEL_NOR, MF_CHECKED);
    279     
    280     if( !bCheck )
    281     {
    282         pMenu->CheckMenuItem(IDR_LEVEL_HIGH, 
    283             MF_BYCOMMAND | MF_UNCHECKED);
    284         pMenu->CheckMenuItem(IDR_LEVEL_LOW,
    285             MF_BYCOMMAND | MF_UNCHECKED);
    286         pMenu->CheckMenuItem(IDR_LEVEL_NOR, 
    287             MF_BYCOMMAND | MF_CHECKED);
    288         g_iGameLevel = LEVEL_NOR;
    289     }
    290 }
    291 
    292 void COthelloDlg::OnPlayMusic() 
    293 {
    294     CWnd*   pMain   =   AfxGetMainWnd();   
    295     CMenu*   pMenu   =   pMain->GetMenu();
    296     //判断播放音乐菜单当前状态
    297     BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_PLAY_MUSIC, MF_CHECKED);
    298     
    299     if(g_bStart)
    300     {
    301         if(bCheck)
    302         {
    303             pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_UNCHECKED);
    304         }
    305         else
    306         {
    307             pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_CHECKED);
    308         }
    309         
    310         PlayBackMusic(!bCheck);            //调用播放背景音乐功能函数
    311     }
    312     
    313 }
    314 
    315 void COthelloDlg::InitMenu()
    316 {
    317 //初始化菜单
    318     CWnd*   pMain   =   AfxGetMainWnd();   
    319     CMenu*   pMenu  =   pMain->GetMenu();
    320     pMenu->CheckMenuItem(IDR_LEVEL_LOW, MF_BYCOMMAND | MF_CHECKED);
    321     pMenu->CheckMenuItem(IDR_LEVEL_HIGH, MF_BYCOMMAND | MF_UNCHECKED);
    322     pMenu->CheckMenuItem(IDR_LEVEL_NOR, MF_BYCOMMAND | MF_UNCHECKED);
    323     pMenu->CheckMenuItem(IDR_PLAY_MUSIC,MF_BYCOMMAND| MF_UNCHECKED);
    324 }
    325 
    326 void COthelloDlg::PlayBackMusic(BOOL bCheck)
    327 {
    328     if(bCheck)
    329     {                                //播放指定音乐文件
    330         sndPlaySound("music.wav",SND_ASYNC); 
    331     }
    332     else
    333     {                                //停止播放
    334         sndPlaySound(NULL,SND_PURGE); 
    335     }
    336 }
    337 
    338 void COthelloDlg::GameStart()
    339 {
    340     m_nBlackCount = 2;
    341     m_nWhiteCount = 2;
    342     m_chess.NewGame();
    343 }
    344 
    345 void COthelloDlg::OnBackBtn() 
    346 {
    347     m_chess.MoveBack();
    348 }

    StdAfx.cpp

    1 // stdafx.cpp : source file that includes just the standard includes
    2 //    Othello.pch will be the pre-compiled header
    3 //    stdafx.obj will contain the pre-compiled type information
    4 
    5 #include "stdafx.h"
  • 相关阅读:
    费马定理
    JAVA大数模板
    扩展KMP模板
    KMP算法模板
    2018暑假遗留题目
    线段树模板(含区间最大(小)值)
    [USACO18OPEN]Out of Sorts G
    几道背包题
    两个有关素数的算法
    German Collegiate Programming Contest 2015 F. Divisions
  • 原文地址:https://www.cnblogs.com/yixianyong/p/4558994.html
Copyright © 2020-2023  润新知