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"

 

posted @ 2015-06-07 20:04  Daniel_Yi  阅读(824)  评论(0编辑  收藏  举报