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"