C++的简单“五子棋”游戏,只是核心代码,资源代码未添加
ChessBoard.h
#ifndef __CHESS_BOARD_H__
#define __CHESS_BOARD_H__ #include "DataStruct.h" #define COL_WIDTH 45
#define ROW_WIDTH 45 class CChessBoard : public CWnd
{
private:
CBitmap m_bitBlackChess, m_bitWhiteChess;
CBitmap m_bitChessBoard;
CBitmap m_motive[];
int m_iMotiveNumber;
bool m_bPlayMotive;
int m_iMotivex, m_iMotivey;
// Construction
public:
board_type m_oChessBoard;
CChessBoard(); public:
void NewGame();
void MoveBack();
void PlayMotive(int row, int col, UINT8 obcolor); public:
virtual BOOL Create(RECT &rect, CWnd * pParentWnd, UINT nID); public:
virtual ~CChessBoard(); protected:
//{{AFX_MSG(CChessBoard)
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
afx_msg void OnComRun(WPARAM wParam, LPARAM lParam);
afx_msg void OnTranChess(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
}; #endif
DataStruct.h
#ifndef __DATA_STRUCT_H__
#define __DATA_STRUCT_H__ typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef short INT16;
typedef char INT8; #define BOARD_COLS 8
#define BOARD_ROWS 8
typedef struct
{
UINT8 board[BOARD_ROWS+][BOARD_COLS+];
}board_type; typedef UINT16 move_key_type; typedef struct
{
board_type board;
UINT16 movepos;
INT16 value;
}tree_node_type; #define CHESS_NONE 0x00
#define CHESS_BLACK 0x01
#define CHESS_WHITE 0x02
#define CHESS_BORDER 0xFF #define BD_PROTECTED 0x80
#define FD_PROTECTED 0x40
#define H_PROTECTED 0x20
#define V_PROTECTED 0x10 #define THITHER_COLOR(color) ((~color)&0x03) #define INITIAL_VALUE (32767) #define STEP_MONMENT1 10
#define STEP_MONMENT2 48 #define LEVEL_LOW 0
#define LEVEL_NOR 1
#define LEVEL_HIGH 2
//游戏难度等级
extern UINT8 g_iGameLevel; //游戏难度等级
extern UINT8 g_bStart; //游戏开始标志 #define USER_PASS 1
#define COMPUTER_PASS 2
#define GAME_OVER 4 #define WM_TRANCHESS (WM_USER+10)
/*可一次吃掉的最多的子的个数*/
#define MAX_AFFECTED_PIECES 19 extern UINT8 computer_side;
extern UINT8 cur_step;
extern UINT16 step_array[]; extern INT16 calc_board_status(board_type *board_ptr, UINT8 obcolor);
extern void init_board(board_type *board_ptr);
extern void computer_play(board_type *board_ptr, HWND hwnd);
extern UINT8 do_move_chess(board_type *board_ptr, UINT16 movepos, UINT8 obcolor, HWND hwnd);
extern void get_chess_score(board_type *board_ptr, UINT16 &iWscore, UINT16 &iBscore); #endif
HelpDlg.h
#if !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)
#define AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HelpDlg.h : header file
// /////////////////////////////////////////////////////////////////////////////
// CHelpDlg dialog class CHelpDlg : public CDialog
{
// Construction
public:
CHelpDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data
//{{AFX_DATA(CHelpDlg)
enum { IDD = IDD_HELP };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA // Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHelpDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL // Implementation
protected: // Generated message map functions
//{{AFX_MSG(CHelpDlg)
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}; //{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)
Othello.h
// Othello.h : main header file for the OTHELLO application
// #if !defined(AFX_OTHELLO_H__09373553_CD5E_4C18_9F3D_0A728D2E52CA__INCLUDED_)
#define AFX_OTHELLO_H__09373553_CD5E_4C18_9F3D_0A728D2E52CA__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif #include "resource.h" // main symbols /////////////////////////////////////////////////////////////////////////////
// COthelloApp:
// See Othello.cpp for the implementation of this class
// class COthelloApp : public CWinApp
{
public:
COthelloApp(); // Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COthelloApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL // Implementation //{{AFX_MSG(COthelloApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_OTHELLO_H__09373553_CD5E_4C18_9F3D_0A728D2E52CA__INCLUDED_)
OthelloDlg.h
// OthelloDlg.h : header file
// #if !defined(AFX_OTHELLODLG_H__DAC0C8C2_DDB6_4DA7_A56E_440CDF9A626B__INCLUDED_)
#define AFX_OTHELLODLG_H__DAC0C8C2_DDB6_4DA7_A56E_440CDF9A626B__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 /////////////////////////////////////////////////////////////////////////////
// COthelloDlg dialog #include "ChessBoard.h" class COthelloDlg : public CDialog
{
// Construction
public:
void GameStart();
void PlayBackMusic(BOOL bCheck);
void InitMenu();
COthelloDlg(CWnd* pParent = NULL); // standard constructor int m_nBlackCount; //黑子个数
int m_nWhiteCount; //白子个数
CChessBoard m_chess;//棋盘对象 // Dialog Data
//{{AFX_DATA(COthelloDlg)
enum { IDD = IDD_OTHELLO_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA // ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COthelloDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL // Implementation
protected:
HICON m_hIcon; // Generated message map functions
//{{AFX_MSG(COthelloDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnAbout();
afx_msg void OnExitGame();
afx_msg void OnGameStart();
afx_msg void OnHelp();
afx_msg void OnLevelHigh();
afx_msg void OnLevelLow();
afx_msg void OnLevelNor();
afx_msg void OnPlayMusic();
afx_msg void OnBackBtn();
//}}AFX_MSG
afx_msg void OnRecalc(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
}; //{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_OTHELLODLG_H__DAC0C8C2_DDB6_4DA7_A56E_440CDF9A626B__INCLUDED_)
Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Othello.rc
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define ID_CHESSBOARD 101
#define IDD_OTHELLO_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_HELP 130
#define IDR_MAIN_MENU 132
#define IDB_TURN1 134
#define IDB_TURN2 135
#define IDB_TURN3 136
#define IDB_TURN4 137
#define IDB_TURN5 138
#define IDB_TURN6 139
#define IDB_BLACKCHESS 140
#define IDB_CHESSBOARD 141
#define IDB_WHITECHESS 142
#define IDC_STATUS 1000
#define IDC_BLACK_COUNT 1001
#define IDC_WHITE_COUNT 1002
#define IDC_BACK_BTN 1003
#define IDR_GAME_START 32771
#define IDR_EXIT_GAME 32772
#define IDR_PLAY_MUSIC 32773
#define IDR_LEVEL_HIGH 32774
#define IDR_LEVEL_NOR 32775
#define IDR_LEVEL_LOW 32776
#define IDR_HELP 32777
#define IDR_ABOUT 32778 // Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 143
#define _APS_NEXT_COMMAND_VALUE 32779
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
StdAfx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// #if !defined(AFX_STDAFX_H__0F6DA0D4_2DD7_4BB6_82C5_0E64F3D63B2D__INCLUDED_)
#define AFX_STDAFX_H__0F6DA0D4_2DD7_4BB6_82C5_0E64F3D63B2D__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT #define UM_RECALC (WM_USER+100)
#define UM_COMRUN (UM_RECALC +1) //{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__0F6DA0D4_2DD7_4BB6_82C5_0E64F3D63B2D__INCLUDED_)
ChessBoard.cpp
// ChessBoard1.cpp : implementation file
// #include "stdafx.h"
#include "ChessBoard.h"
#include "resource.h" #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif UINT8 g_bStart = ; /////////////////////////////////////////////////////////////////////////////
// CChessBoard
CChessBoard::CChessBoard()
{
m_iMotiveNumber=;
m_iMotivex = m_iMotivey=;
m_bPlayMotive = FALSE;
init_board(&m_oChessBoard);
} CChessBoard::~CChessBoard()
{
} BEGIN_MESSAGE_MAP(CChessBoard, CWnd)
//{{AFX_MSG_MAP(CChessBoard)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_MESSAGE(UM_COMRUN, OnComRun)
ON_MESSAGE(WM_TRANCHESS, OnTranChess)
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
//延时函数
//////////////////////////////////////////////////////////////////////////
void delay(INT32 millisecond)
{
clock_t start = clock();
do
{
MSG msg;
if (::PeekMessage( &msg, NULL, , , PM_NOREMOVE ) )
{
if ( !AfxGetApp()->PumpMessage())
{
::PostQuitMessage();
return;
}
}
}while(clock()<start+millisecond);
}
//////////////////////////////////////////////////////////////////////////
//悔棋函数
//////////////////////////////////////////////////////////////////////////
void CChessBoard::MoveBack()
{
if(cur_step<)
{//如果当前步骤下于2,说明没有开始游戏
return;
}
UINT8 comside = computer_side;
UINT8 step = cur_step;
INT16 movearray[];
//把下棋步骤数组中的数据复制到移动数组中
memcpy(movearray, step_array, *sizeof(INT16));
init_board(&m_oChessBoard);
computer_side = comside;
UINT8 col= CHESS_BLACK;
for(int i=; i<step-; i++, col = ~col & )
{
do_move_chess(&m_oChessBoard, movearray[i], col, );
}
OnPaint();
Invalidate();
}
//////////////////////////////////////////////////////////////////////////
//改变棋子接口函数
//////////////////////////////////////////////////////////////////////////
void CChessBoard::OnTranChess(WPARAM wParam, LPARAM lParam)
{
int row = wParam/-;
int col = wParam%-;
CRect r(col*COL_WIDTH+, row*ROW_WIDTH+,
col*COL_WIDTH+COL_WIDTH+, row*ROW_WIDTH+ROW_WIDTH+); m_bPlayMotive = FALSE;
OnPaint();
InvalidateRect(&r); if((lParam>>) !=)
PlayMotive(row, col, UINT8(lParam));
}
//////////////////////////////////////////////////////////////////////////
//由电脑人工智能下棋
//////////////////////////////////////////////////////////////////////////
void CChessBoard::OnComRun(WPARAM wParam, LPARAM lParam)
{
computer_play(&m_oChessBoard, m_hWnd);
UINT16 wscore, bscore;
get_chess_score(&m_oChessBoard, wscore, bscore);
GetParent()->SendMessage(UM_RECALC, WPARAM(wscore|0x80000000), LPARAM(bscore));
}
//////////////////////////////////////////////////////////////////////////
//新游戏
//////////////////////////////////////////////////////////////////////////
void CChessBoard::NewGame()
{
if(cur_step >)
{
if(MessageBox("开始新游戏吗?", "黑白棋",
MB_YESNO|MB_ICONQUESTION) == IDYES)
{
g_bStart = ;
init_board(&m_oChessBoard);
Invalidate();
}
}
}
//////////////////////////////////////////////////////////////////////////
//窗口建立函数
//////////////////////////////////////////////////////////////////////////
BOOL CChessBoard::Create(RECT &rect, CWnd *pParentWnd, UINT nID)
{
CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|
CS_HREDRAW|CS_VREDRAW,
, (HBRUSH)CBrush(RGB(,,)), );
rect.right = rect.left + +;
rect.bottom = rect.top ++;
if(!CWnd::CreateEx(WS_EX_CLIENTEDGE, szClassName, _T(""),
WS_CHILD|WS_VISIBLE|WS_TABSTOP, rect,
pParentWnd, nID, NULL)) //WS_EX_CLIENTEDGE return FALSE;
UpdateWindow();
m_bitBlackChess.LoadBitmap(IDB_BLACKCHESS);
m_bitChessBoard.LoadBitmap(IDB_CHESSBOARD);
m_bitWhiteChess.LoadBitmap(IDB_WHITECHESS); m_motive[].LoadBitmap(IDB_WHITECHESS);
m_motive[].LoadBitmap(IDB_TURN1);
m_motive[].LoadBitmap(IDB_TURN2);
m_motive[].LoadBitmap(IDB_TURN3);
m_motive[].LoadBitmap(IDB_TURN4);
m_motive[].LoadBitmap(IDB_TURN5);
m_motive[].LoadBitmap(IDB_TURN6);
m_motive[].LoadBitmap(IDB_BLACKCHESS); return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//播放棋子翻动动画
//////////////////////////////////////////////////////////////////////////
void CChessBoard::PlayMotive(int row, int col, UINT8 obcolor)
{
m_iMotivex = col*COL_WIDTH+;
m_iMotivey = row*COL_WIDTH+;
CRect r(m_iMotivex, m_iMotivey,
m_iMotivex+COL_WIDTH,
m_iMotivey +ROW_WIDTH);
m_bPlayMotive = TRUE;
if(obcolor == CHESS_BLACK)
{//把棋子从白面向黑面翻转
for(m_iMotiveNumber =; m_iMotiveNumber<; m_iMotiveNumber++)
{
OnPaint();
InvalidateRect(&r);
delay();
}
}
else
{//把棋子从黑面向白面翻转
for(m_iMotiveNumber =; m_iMotiveNumber>=; m_iMotiveNumber--)
{
OnPaint();
InvalidateRect(&r);
delay();
}
}
m_bPlayMotive = FALSE;
}
//////////////////////////////////////////////////////////////////////////
//窗口绘图函数
//////////////////////////////////////////////////////////////////////////
void CChessBoard::OnPaint()
{ CPaintDC dc(this);
CDC imgdc;
imgdc.CreateCompatibleDC(&dc);
imgdc.SelectObject(&m_bitChessBoard);
dc.BitBlt(, , , , &imgdc,,,SRCCOPY);
if(m_bPlayMotive)
{
imgdc.SelectObject(&m_motive[m_iMotiveNumber]);
dc.BitBlt(m_iMotivex, m_iMotivey, , , &imgdc, , , SRCCOPY);
return;
} for(int i=; i<BOARD_ROWS; i++)
{
for(int j=; j<BOARD_COLS; j++)
{
if(m_oChessBoard.board[i+][j+] == CHESS_BLACK)
{
imgdc.SelectObject(&m_bitBlackChess);
dc.BitBlt(j*COL_WIDTH+, i*ROW_WIDTH+, , , &imgdc,,,SRCCOPY);
}
else if(m_oChessBoard.board[i+][j+] == CHESS_WHITE)
{
imgdc.SelectObject(&m_bitWhiteChess);
dc.BitBlt(j*COL_WIDTH+, i*ROW_WIDTH+, , , &imgdc,,,SRCCOPY);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
//鼠标左键响应函数
//////////////////////////////////////////////////////////////////////////
void CChessBoard::OnLButtonDown(UINT nFlags, CPoint point)
{ BYTE row = (point.y-)/ROW_WIDTH+;
BYTE col = (point.x-)/COL_WIDTH+; if(do_move_chess(&m_oChessBoard, row*+col, ~computer_side&, m_hWnd))
{
UINT16 wscore, bscore;
get_chess_score(&m_oChessBoard, wscore, bscore);
GetParent()->SendMessage(UM_RECALC, WPARAM(wscore), LPARAM(bscore));
PostMessage(UM_COMRUN);
}
else
{
MessageBeep(MB_OK);
} CWnd::OnLButtonDown(nFlags, point);
} int CChessBoard::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -)
return -; EndWaitCursor();
return ;
}
dispose.cpp
#include "stdafx.h"
#include "dataStruct.h" UINT8 computer_side = CHESS_BLACK;
UINT8 max_depth = ; UINT8 cur_depth = ; UINT8 cur_step =;
UINT16 step_array[]; UINT8 g_iGameLevel = LEVEL_LOW; //游戏难度等级
const UINT8 depth1[]={, , };
const UINT8 depth2[]={, , }; /*找出所有在水平方向受保护的obcolor方的棋子,并累计分数*/
INT16 scan_horiz_aixes(board_type *board_ptr, UINT8 obcolor)
{
/*扫描8个水平方向*/
INT16 score=;
UINT8 *cur_ptr, *stop_ptr;
UINT8 piece[][];
UINT8 count=, tmpscore;
UINT8 bFull;
for(UINT8 row=; row<; row++)
{
tmpscore = (row == || row == ) ? :;
cur_ptr = &board_ptr->board[row][];
stop_ptr= &board_ptr->board[row][];
bFull = TRUE;
count=;
while(cur_ptr < stop_ptr)
{
if(*cur_ptr == obcolor)
{
piece[count][] = cur_ptr - &board_ptr->board[row][];
while(*cur_ptr == obcolor)
cur_ptr ++;
piece[count++][] = cur_ptr - &board_ptr->board[row][];
}
if(!*cur_ptr)
bFull = FALSE;
cur_ptr++;
}
while(count--)
{
UINT8 nums = (piece[count][]-piece[count][]);
if(bFull || piece[count][]== || piece[count][] == )
score += nums;
if(piece[count][]== || piece[count][] == )
score += tmpscore;
else if(!bFull && (piece[count][] == || piece[count][] == ) && (row == || row == ))
score -= tmpscore;
}
} return score;
} /*找出所有在垂直方向受保护的obcolor方的棋子,并累计分数*/
INT16 scan_vertical_aixes(board_type *board_ptr, UINT8 obcolor)
{
INT16 score=;
UINT8 *cur_ptr, *stop_ptr;
UINT8 piece[][];
UINT8 count=, tmpscore;
UINT8 bFull;
for(UINT8 col=; col<; col++)
{
tmpscore = (col == || col == ) ? :;
cur_ptr = &board_ptr->board[][col];
stop_ptr= &board_ptr->board[][col];
bFull = TRUE;
count=;
while(cur_ptr < stop_ptr)
{
if(*cur_ptr == obcolor)
{
piece[count][] = (cur_ptr - &board_ptr->board[][col])/;
while(*cur_ptr == obcolor)
cur_ptr += ;
piece[count++][] = (cur_ptr - &board_ptr->board[][col])/;
}
if(!*cur_ptr)
bFull = FALSE;
cur_ptr += ;
}
while(count--)
{
UINT8 nums = (piece[count][]-piece[count][]);
if(bFull || piece[count][]== || piece[count][] == )
score += nums;
if(piece[count][]== || piece[count][] == )
score += tmpscore;
else if(!bFull && (piece[count][] == || piece[count][] == ) && (col == || col == ))
score -= (tmpscore<<);
}
}
return score;
} /*找出所有在右上到左下方向受保护的obcolor方的棋子,并累计分数*/
INT16 scan_fd_aixes(board_type *board_ptr, UINT8 obcolor)
{
INT16 score =;
UINT8 *cur_ptr, *stop_ptr, *base_ptr;
UINT8 piece[][];
UINT8 count=, tmpscore;
UINT8 bFull;
for(INT8 aixes = -; aixes <= ; aixes++)
{
tmpscore = (aixes == ) ? :;
if(aixes <=)
{
base_ptr = cur_ptr = &board_ptr->board[][+aixes];
stop_ptr = &board_ptr->board[+aixes][];
}
else
{
base_ptr = cur_ptr = &board_ptr->board[aixes+][];
stop_ptr= &board_ptr->board[][aixes];
}
bFull = TRUE;
count=;
while(cur_ptr < stop_ptr)
{
if(*cur_ptr == obcolor)
{
piece[count][] = cur_ptr - board_ptr->board[];
while(*cur_ptr == obcolor)
cur_ptr += ;
piece[count++][] = cur_ptr- board_ptr->board[];
}
if(!*cur_ptr)
bFull = FALSE;
cur_ptr += ;
}
while(count--)
{
UINT8 nums = (piece[count][]-piece[count][])/;
BOOL toborder = (piece[count][] == base_ptr - board_ptr->board[] ||
piece[count][] == stop_ptr - board_ptr->board[]);
if(bFull || toborder)
score += nums; if((aixes == || aixes == -) && toborder)
score -= tmpscore;
/*如果是这块棋到达边界*/
else if(toborder)
score += tmpscore;
/*如果有棋在角边上,则扣分*/
else if(!bFull && (piece[count][] == ||
piece[count][] == ))
score -= (tmpscore<<);
}
} /*如果角边有棋子,扣分*/
if(board_ptr->board[][] == obcolor)
score += ;
else
{
if(board_ptr->board[][] == obcolor)
score -=;
if(board_ptr->board[][] == obcolor)
score -=;
if(board_ptr->board[][]== obcolor)
score -=;
} if(board_ptr->board[][] == obcolor)
score +=;
else
{
if(board_ptr->board[][] == obcolor)
score -=;
if(board_ptr->board[][]== obcolor)
score -=;
if(board_ptr->board[][]== obcolor)
score -= ;
}
return score;
}
/*找出所有在左上到右下方向受保护的obcolor方的棋子,并累计分数*/
INT16 scan_bd_aixes(board_type *board_ptr, UINT8 obcolor)
{ INT16 score =;
UINT8 *cur_ptr, *stop_ptr, *base_ptr;
UINT8 piece[][];
UINT8 count=, tmpscore;
UINT8 bFull;
for(INT8 aixes = -; aixes <= ; aixes++)
{
tmpscore = (aixes == ) ? :;
if(aixes <=)
{
base_ptr = cur_ptr = &board_ptr->board[-aixes][];
stop_ptr = &board_ptr->board[][+aixes];
}
else
{
base_ptr = cur_ptr = &board_ptr->board[][aixes+];
stop_ptr= &board_ptr->board[-aixes][];
}
bFull = TRUE;
count=;
while(cur_ptr < stop_ptr)
{
if(*cur_ptr == obcolor)
{
piece[count][] = cur_ptr - board_ptr->board[];
while(*cur_ptr == obcolor)
cur_ptr += ;
piece[count++][] = cur_ptr- board_ptr->board[];
}
if(!*cur_ptr)
bFull = FALSE;
cur_ptr += ;
}
while(count--)
{
UINT8 nums = (piece[count][]-piece[count][])/;
BOOL toborder = (piece[count][] == base_ptr - board_ptr->board[] ||
piece[count][] == stop_ptr - board_ptr->board[]);
if(bFull || toborder)
score += nums;
/*如果角边有棋子,扣分*/
if((aixes == || aixes == -) && toborder)
score -= tmpscore;
/*如果是这块棋到达边界*/
else if(toborder)
score += tmpscore;
/*如果有棋在角边上,则扣分, 主对角线方向*/
else if(!bFull && (piece[count][] == ||
piece[count][] == ))
score -= (tmpscore<<);
}
} /*如果角边有棋子,扣分*/
if(board_ptr->board[][] == obcolor)
score += ;
else
{
if(board_ptr->board[][] == obcolor)
score -=;
if(board_ptr->board[][] == obcolor)
score -=;
if(board_ptr->board[][]== obcolor)
score -=;
} if(board_ptr->board[][] == obcolor)
score +=;
else
{
if(board_ptr->board[][] == obcolor)
score -=;
if(board_ptr->board[][]== obcolor)
score -=;
if(board_ptr->board[][]== obcolor)
score -= ;
}
return score;
} INT16 sample_calc_board_status(board_type *board_ptr, UINT8 obcolor)
{
INT16 score=;
UINT8 *ptr = &board_ptr->board[][];
UINT8 *stop = &board_ptr->board[][];
UINT8 tmpcol = ~obcolor &0x03;
while(ptr<stop)
{
if(*ptr == obcolor)
score++;
else if(*ptr == tmpcol)
score--;
ptr++;
}
return score;
} /*计算棋局board_ptr的状态分*/
INT16 calc_board_status(board_type *board_ptr, UINT8 obcolor)
{
INT16 score=;
score += scan_horiz_aixes(board_ptr, obcolor);
score += scan_vertical_aixes(board_ptr, obcolor);
score += scan_bd_aixes(board_ptr, obcolor);
score += scan_fd_aixes(board_ptr, obcolor);
UINT8 tmpcol = ~obcolor & 0x03 ;
if(board_ptr->board[][] == tmpcol)
score -= ;
if(board_ptr->board[][] == tmpcol)
score -= ;
if(board_ptr->board[][] == tmpcol)
score -= ;
if(board_ptr->board[][] == tmpcol)
score -= ;
return score;
} /*从start_pos出发找到一个可下子的点,返回受影响的子的个数,
affected_list存放受影响的棋格的指针,第一个指针为落子的点*/
const INT16 delta_array[] = {-, , -, , -, , -, };
INT16 find_move(board_type *board_ptr, INT16 start_pos,
UINT8 obcolor, INT16 *affected_list)
{
UINT8 *cel_ptr = board_ptr->board[] + start_pos;
UINT8 *stop_ptr = &board_ptr->board[][], *p;
INT16 *aff_ptr = affected_list+, *hold_aff;
UINT8 aixes;
UINT8 thithercolor = THITHER_COLOR(obcolor);
while()
{
/*找到一个空格子*/
while(*cel_ptr)
if(++cel_ptr>=stop_ptr)
return ;
/*检查在8个方向上是否能吃掉对方的棋子,并记录被吃掉棋子的下标*/
for(aixes =;aixes<; aixes++)
{
hold_aff = aff_ptr;
p = cel_ptr + delta_array[aixes];
while(*p == thithercolor)
{
*aff_ptr++ = p - board_ptr->board[];
p+= delta_array[aixes];
}
if(*p != obcolor)
aff_ptr = hold_aff;
}
/*如果cel_ptr对应的点可以吃掉对方的子*/
if(aff_ptr - affected_list > )
{
*affected_list = cel_ptr - board_ptr->board[];
return (aff_ptr - affected_list);
}
cel_ptr++;
}
} void init_board(board_type *board_ptr)
{
memset(board_ptr, , sizeof(board_type));
/*init boarder*/
memset(board_ptr->board[], 0xff, );
memset(board_ptr->board[], 0xff, );
for(int i=; i<; i++)
{
board_ptr->board[i][] = board_ptr->board[i][] =0xff;
} /*init chess*/
board_ptr->board[][] = board_ptr->board[][] = CHESS_WHITE;
board_ptr->board[][] = board_ptr->board[][] = CHESS_BLACK;
cur_step = ;
computer_side = CHESS_WHITE;
} /*从棋盘的一个状态出发,扩展此结点,并返回此结点的部分回溯值*/
void extend_node_one(tree_node_type *node_ptr, tree_node_type *parent_ptr,UINT8 obcolor)
{
tree_node_type childnode;
INT16 affected_list[MAX_AFFECTED_PIECES];
INT16 start_pos = , num;
num = find_move(&node_ptr->board, start_pos, obcolor, affected_list);
/*如果是终局状态,则返回状态估值函数的值*/
if(++cur_depth == max_depth || num== )
{
/*如果已方PASS但没到棋局结束,要扣分*/
node_ptr->value = calc_board_status(&node_ptr->board, computer_side);
if(!num)
{
/*如果双方都没棋下*/
if(!find_move(&node_ptr->board, , ~obcolor&0x03, affected_list))
return; if(obcolor == computer_side)
{
node_ptr->value -= ;
return ;
}
node_ptr->value += ;
}
return;
}
/*初始化回溯值*/
node_ptr->value = (obcolor == computer_side)? -INITIAL_VALUE : INITIAL_VALUE;
memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
while(num)
{
while(num--)
childnode.board.board[][affected_list[num]] = obcolor;
/*递归计算部分回溯值*/
UINT8 depth = cur_depth;
extend_node_one(&childnode, node_ptr, (~obcolor)&0x03);
cur_depth = depth;
/*如果此结点是棋手一方,则部分回溯值是子结点中最大的一个*/
if(obcolor == computer_side)
{
if(childnode.value > node_ptr->value)
{
node_ptr->value = childnode.value;
node_ptr->movepos = affected_list[];
}
}
/*如果是对手一方,部分回溯值是子结点中最小的一个*/
else
{
if(childnode.value < node_ptr->value)
{
node_ptr->value = childnode.value;
node_ptr->movepos = affected_list[];
}
}
/* α-β裁减的判断 在考虑轮到棋手下棋的一个亲节点及轮到对手下棋的一个子节点时,
如果该子节点的数值已经小于或等于其亲节点的回溯值,
那么就不需要对该节点或者其后续节点做更多的处理了。
计算的过程可以直接返回到亲节点上。
*/
/*在考虑轮到对手下棋的一个亲节点及轮到棋手下棋的一个子节点时,
如果该子节点的部分回溯值已经大于或等于其亲节点的部分回溯值,
那么就不需要对该子节点或者其后裔节点做更多的处理了。
计算过程可以直接返回到亲节点上。*/
if(parent_ptr)
{
if(obcolor != computer_side)
{
/*α裁减*/
if(node_ptr->value <= parent_ptr->value)
return;
}
else
{
/*β裁减*/
if(node_ptr->value >= parent_ptr->value)
return;
}
}
/*找到下一个可落子的点*/
start_pos = affected_list[]+;
memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
num = find_move(&childnode.board, start_pos, obcolor, affected_list);
}
return;
} void extend_node_two(tree_node_type *node_ptr, tree_node_type *parent_ptr,UINT8 obcolor)
{
tree_node_type childnode;
INT16 affected_list[MAX_AFFECTED_PIECES];
INT16 start_pos = , num;
num = find_move(&node_ptr->board, start_pos, obcolor, affected_list);
/*如果是终局状态,则返回状态估值函数的值*/
if(!num)
{
/*如果已方PASS但没到棋局结束,要扣分*/
node_ptr->value = sample_calc_board_status(&node_ptr->board, computer_side);
/*如果双方都没棋下*/
if(!find_move(&node_ptr->board, , ~obcolor&0x03, affected_list))
return; if(obcolor == computer_side)
{
node_ptr->value -= ;
return;
}
node_ptr->value += ;
return;
}
/*初始化回溯值*/
node_ptr->value = (obcolor == computer_side)? -INITIAL_VALUE : INITIAL_VALUE;
memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
while(num)
{
while(num--)
childnode.board.board[][affected_list[num]] = obcolor;
/*递归计算部分回溯值*/
UINT8 depth = cur_depth;
extend_node_two(&childnode, node_ptr, (~obcolor)&0x03);
cur_depth = depth;
/*如果此结点是棋手一方,则部分回溯值是子结点中最大的一个*/
if(obcolor == computer_side)
{
if(childnode.value > node_ptr->value)
{
node_ptr->value = childnode.value;
node_ptr->movepos = affected_list[];
}
}
/*如果是对手一方,部分回溯值是子结点中最小的一个*/
else
{
if(childnode.value < node_ptr->value)
{
node_ptr->value = childnode.value;
node_ptr->movepos = affected_list[];
}
}
/* α-β裁减的判断 在考虑轮到棋手下棋的一个亲节点及轮到对手下棋的一个子节点时,
如果该子节点的数值已经小于或等于其亲节点的回溯值,
那么就不需要对该节点或者其后续节点做更多的处理了。
计算的过程可以直接返回到亲节点上。
*/
/*在考虑轮到对手下棋的一个亲节点及轮到棋手下棋的一个子节点时,
如果该子节点的部分回溯值已经大于或等于其亲节点的部分回溯值,
那么就不需要对该子节点或者其后裔节点做更多的处理了。
计算过程可以直接返回到亲节点上。*/
if(parent_ptr)
{
if(obcolor != computer_side)
{
/*α裁减*/
if(node_ptr->value <= parent_ptr->value)
return;
}
else
{
/*β裁减*/
if(node_ptr->value >= parent_ptr->value)
return ;
}
}
/*找到下一个可落子的点*/
start_pos = affected_list[]+;
memcpy(&childnode.board, &node_ptr->board, sizeof(board_type));
num = find_move(&childnode.board, start_pos, obcolor, affected_list);
}
return;
} void get_chess_score(board_type *board_ptr, UINT16 &iWscore, UINT16 &iBscore)
{
iWscore =; iBscore =;
for(INT16 i=; i<=BOARD_ROWS; i++)
for(INT16 j=; j<=BOARD_COLS; j++)
{
if(board_ptr->board[i][j] == CHESS_BLACK)
iBscore++;
else if(board_ptr->board[i][j] == CHESS_WHITE)
iWscore++;
}
} void game_over(board_type *board_ptr, HWND hwnd)
{
UINT16 wscore, bscore;
char strcomwin[]="虽然你很历害,但我还是赢了你!";
char struserwin[]="让你一次,下次你可没这么走运了!";
char strdogfall[]="我没好好下,你才有机会平局!";
char *text;
get_chess_score(board_ptr, wscore, bscore); g_bStart = ; if(computer_side == CHESS_WHITE)
{
if(wscore > bscore)
{
text = strcomwin;
}
else if(wscore <bscore)
{
text = struserwin;
}
else
{
text = strdogfall;
}
}
else
{
if(wscore > bscore)
text = struserwin;
else if(wscore <bscore)
text = strcomwin;
else text = strdogfall;
}
MessageBox(hwnd, text, "黑白棋", MB_OK|MB_ICONINFORMATION);
} void computer_play(board_type *board_ptr, HWND hwnd)
{
cur_depth =;
tree_node_type node;
INT16 affected_list[MAX_AFFECTED_PIECES];
start:
memcpy(&node.board, board_ptr, sizeof(board_type));
node.movepos =;
if(cur_step>= STEP_MONMENT2)
{
extend_node_two(&node, NULL, computer_side);
}
else if(cur_step > STEP_MONMENT1)
{
max_depth = depth2[g_iGameLevel];
extend_node_one(&node, NULL, computer_side);
}
else
{
max_depth = depth1[g_iGameLevel];
extend_node_one(&node, NULL, computer_side);
} if(!do_move_chess(board_ptr, node.movepos, computer_side, hwnd))
{
if(!find_move(board_ptr, , (~computer_side)&0x03, affected_list))
{
game_over(board_ptr, hwnd);
return;
}
else
{
MessageBox(hwnd,"我没棋下了,你再走一步!", "黑白棋", MB_OK|MB_ICONINFORMATION);
return;
}
}
else
{
if(!find_move(board_ptr, , (~computer_side)&0x03, affected_list))
{
if(!find_move(board_ptr, , computer_side, affected_list))
{
game_over(board_ptr, hwnd);
return;
}
else
{ MessageBox(hwnd ,"你没棋下了,我再走一步!", "黑白棋", MB_OK|MB_ICONINFORMATION); goto start;
} }
}
} UINT8 do_move_chess(board_type *board_ptr, UINT16 movepos, UINT8 obcolor, HWND hwnd)
{
INT16 affected_list[MAX_AFFECTED_PIECES];
INT16 num = find_move(board_ptr, movepos, obcolor, affected_list);
if(!num || affected_list[] != movepos)
return ;
for(int i=; i<num; i++)
{
board_ptr->board[][affected_list[i]] = obcolor;
if(hwnd)
::SendMessage(hwnd, WM_TRANCHESS, WPARAM(affected_list[i]),LPARAM(i<<|obcolor));
}
step_array[cur_step++] = movepos; return ;
}
HelpDlg.cpp
// HelpDlg.cpp : implementation file
// #include "stdafx.h"
#include "Othello.h"
#include "HelpDlg.h" #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif /////////////////////////////////////////////////////////////////////////////
// CHelpDlg dialog CHelpDlg::CHelpDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHelpDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHelpDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
} void CHelpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHelpDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
} BEGIN_MESSAGE_MAP(CHelpDlg, CDialog)
//{{AFX_MSG_MAP(CHelpDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////
// CHelpDlg message handlers void CHelpDlg::OnOK()
{
// TODO: Add extra validation here CDialog::OnOK();
}
Othello.cpp
// Othello.cpp : Defines the class behaviors for the application.
// #include "stdafx.h"
#include "Othello.h"
#include "OthelloDlg.h" #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif /////////////////////////////////////////////////////////////////////////////
// COthelloApp BEGIN_MESSAGE_MAP(COthelloApp, CWinApp)
//{{AFX_MSG_MAP(COthelloApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////
// COthelloApp construction COthelloApp::COthelloApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
} /////////////////////////////////////////////////////////////////////////////
// The one and only COthelloApp object COthelloApp theApp; /////////////////////////////////////////////////////////////////////////////
// COthelloApp initialization BOOL COthelloApp::InitInstance()
{
AfxEnableControlContainer(); // Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need. #ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif COthelloDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
} // Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
OthelloDlg.cpp
// OthelloDlg.cpp : implementation file
// #include "stdafx.h"
#include "Othello.h"
#include "OthelloDlg.h" #include "HelpDlg.h" #include <mmsystem.h> #include "DataStruct.h" #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif /////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About class CAboutDlg : public CDialog
{
public:
CAboutDlg(); // Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA // ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL // Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
} void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
} BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////
// COthelloDlg dialog COthelloDlg::COthelloDlg(CWnd* pParent /*=NULL*/)
: CDialog(COthelloDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_nBlackCount = ;
m_nWhiteCount = ;
} void COthelloDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
} BEGIN_MESSAGE_MAP(COthelloDlg, CDialog)
//{{AFX_MSG_MAP(COthelloDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDR_ABOUT, OnAbout)
ON_COMMAND(IDR_EXIT_GAME, OnExitGame)
ON_COMMAND(IDR_GAME_START, OnGameStart)
ON_COMMAND(IDR_HELP, OnHelp)
ON_COMMAND(IDR_LEVEL_HIGH, OnLevelHigh)
ON_COMMAND(IDR_LEVEL_LOW, OnLevelLow)
ON_COMMAND(IDR_LEVEL_NOR, OnLevelNor)
ON_COMMAND(IDR_PLAY_MUSIC, OnPlayMusic)
ON_BN_CLICKED(IDC_BACK_BTN, OnBackBtn)
//}}AFX_MSG_MAP
ON_MESSAGE(UM_RECALC, OnRecalc)
END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////
// COthelloDlg message handlers void COthelloDlg::OnRecalc(WPARAM wParam, LPARAM lParam)
{
CString strStatus;
CString strCount;
if(wParam & 0x80000000)
{
strStatus.Format(" 我找到一步好棋,现该你了!"); }
else
{
strStatus.Format("我正在想,你别急!");
}
strCount.Format(" 黑子:%02d ", UINT(lParam));
SetDlgItemText(IDC_STATUS, strStatus);
SetDlgItemText(IDC_BLACK_COUNT, strCount);
strCount.Format(" 白子:%02d ", (wParam&0xFFFF));
SetDlgItemText(IDC_WHITE_COUNT, strCount);
} BOOL COthelloDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon InitMenu(); g_iGameLevel = LEVEL_LOW; SetDlgItemText(IDC_STATUS, "欢迎来玩黑白棋!"); m_chess.Create(CRect(,, ,), this, ID_CHESSBOARD); return TRUE; // return TRUE unless you set the focus to a control
} void COthelloDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
} // If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework. void COthelloDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), ); // Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
} CString strCount;
strCount.Format(" 黑子:%02d ", m_nBlackCount);
SetDlgItemText(IDC_BLACK_COUNT, strCount);
strCount.Format(" 白子:%02d ", m_nWhiteCount);
SetDlgItemText(IDC_WHITE_COUNT, strCount);
} // The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR COthelloDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
} void COthelloDlg::OnAbout()
{
CAboutDlg dlg; //创建关于对话框类对象
dlg.DoModal(); //弹出关于对话框
} void COthelloDlg::OnExitGame()
{
CDialog::OnCancel(); //调用基类退出函数
} void COthelloDlg::OnGameStart()
{
GameStart(); //调用游戏开始接口函数
} void COthelloDlg::OnHelp()
{
CHelpDlg dlg; //创建帮助对话框类对象
dlg.DoModal(); //弹出帮助对话框
} void COthelloDlg::OnLevelHigh()
{
CWnd* pMain = AfxGetMainWnd();
CMenu* pMenu = pMain->GetMenu();
//判断播放音乐菜单当前状态
BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_LEVEL_HIGH, MF_CHECKED); if( !bCheck )
{
pMenu->CheckMenuItem(IDR_LEVEL_HIGH,
MF_BYCOMMAND | MF_CHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_LOW,
MF_BYCOMMAND | MF_UNCHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_NOR,
MF_BYCOMMAND | MF_UNCHECKED);
g_iGameLevel = LEVEL_HIGH;
}
} void COthelloDlg::OnLevelLow()
{
CWnd* pMain = AfxGetMainWnd();
CMenu* pMenu = pMain->GetMenu();
//判断播放音乐菜单当前状态
BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_LEVEL_LOW, MF_CHECKED); if( !bCheck )
{
pMenu->CheckMenuItem(IDR_LEVEL_HIGH,
MF_BYCOMMAND | MF_UNCHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_LOW,
MF_BYCOMMAND | MF_CHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_NOR,
MF_BYCOMMAND | MF_UNCHECKED);
g_iGameLevel = LEVEL_LOW;
}
} void COthelloDlg::OnLevelNor()
{
CWnd* pMain = AfxGetMainWnd();
CMenu* pMenu = pMain->GetMenu();
//判断播放音乐菜单当前状态
BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_LEVEL_NOR, MF_CHECKED); if( !bCheck )
{
pMenu->CheckMenuItem(IDR_LEVEL_HIGH,
MF_BYCOMMAND | MF_UNCHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_LOW,
MF_BYCOMMAND | MF_UNCHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_NOR,
MF_BYCOMMAND | MF_CHECKED);
g_iGameLevel = LEVEL_NOR;
}
} void COthelloDlg::OnPlayMusic()
{
CWnd* pMain = AfxGetMainWnd();
CMenu* pMenu = pMain->GetMenu();
//判断播放音乐菜单当前状态
BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_PLAY_MUSIC, MF_CHECKED); if(g_bStart)
{
if(bCheck)
{
pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_UNCHECKED);
}
else
{
pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_CHECKED);
} PlayBackMusic(!bCheck); //调用播放背景音乐功能函数
} } void COthelloDlg::InitMenu()
{
//初始化菜单
CWnd* pMain = AfxGetMainWnd();
CMenu* pMenu = pMain->GetMenu();
pMenu->CheckMenuItem(IDR_LEVEL_LOW, MF_BYCOMMAND | MF_CHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_HIGH, MF_BYCOMMAND | MF_UNCHECKED);
pMenu->CheckMenuItem(IDR_LEVEL_NOR, MF_BYCOMMAND | MF_UNCHECKED);
pMenu->CheckMenuItem(IDR_PLAY_MUSIC,MF_BYCOMMAND| MF_UNCHECKED);
} void COthelloDlg::PlayBackMusic(BOOL bCheck)
{
if(bCheck)
{ //播放指定音乐文件
sndPlaySound("music.wav",SND_ASYNC);
}
else
{ //停止播放
sndPlaySound(NULL,SND_PURGE);
}
} void COthelloDlg::GameStart()
{
m_nBlackCount = ;
m_nWhiteCount = ;
m_chess.NewGame();
} void COthelloDlg::OnBackBtn()
{
m_chess.MoveBack();
}
StdAfx.cpp
// stdafx.cpp : source file that includes just the standard includes
// Othello.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information #include "stdafx.h"
C++的简单“五子棋”游戏,只是核心代码,资源代码未添加的更多相关文章
- Leo-io 的C语言实现简单五子棋游戏观后感
源代码: /************************************************************** ** 文 件 名:wuziqi.cpp ** 功 能:扫 ...
- 用Java写的简单五子棋游戏(原创五子连珠算法)
源码jar包(已安装jdk环境可直接运行) 下载地址:http://download.csdn.net/detail/eguid_1/9532912 五子连珠算法为自创算法,对于五子棋该算法性能足以. ...
- 原生JS+Canvas实现五子棋游戏
一.功能模块 先看下现在做完的效果: 线上体验:https://wj704.github.io/five_game.html 主要功能模块为: 1.人机对战功能 2.悔棋功能 3.撤销悔棋功能 二.代 ...
- 基于Blazor写一个简单的五子棋游戏
写这个五子棋游戏,其实主要目的是想尝试一下微软新作Blazor.Blazor对于那些搞.NET的程序员,又想做一些前端工作,真的挺友好,不用一句JS就可搞定前端交互,美哉.现在已经有很流行的前端框架, ...
- java 五子棋游戏
五子棋游戏 一,1.五子棋的基本常识 与任何一种竞技棋一样,五子棋的每一局棋也分为三个阶段:开局,中局和残局. 五子棋的开始阶段称为开局,或称布局.其开局阶段是十分短暂的,大约在七着与十几着之间.在这 ...
- 信息安全系统设计基础课程实践:简单TUI游戏设计
简单TUI游戏设计 目 录 一 Curses库简介与基本开发方法 ...
- 自定义View实现五子棋游戏
成功的路上一点也不拥挤,因为坚持的人太少了. ---简书上看到的一句话 未来请假三天顺带加上十一回家结婚,不得不说真是太坑了,去年婚假还有10天,今年一下子缩水到了3天,只能赶着十一办事了. 最近还在 ...
- Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局
Android实训案例(八)--单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局 阿法狗让围棋突然就被热议了,鸿洋大神也顺势出了篇五子棋单机游戏的视频,我看到了就像膜拜膜拜,就 ...
- cocos2d-x游戏引擎核心之六——绘图原理和绘图技巧
一.OpenGL基础 游戏引擎是对底层绘图接口的包装,Cocos2d-x 也一样,它是对不同平台下 OpenGL 的包装.OpenGL 全称为 Open Graphics Library,是一个开放的 ...
随机推荐
- Java 调用 C++ (Java 调用 dll)康哥手把手教你
摘要: 本文原创,转载请注明地址 http://www.cnblogs.com/baokang/p/4979243.html 因为要做点图形处理的项目,需要在Java中调用dll库,所以开发的第一步是 ...
- ucenter用户登录过程
以用户登录为例介绍,其它注销,改密码,消息,头像,好友均类同. 从用户xxx在某一应用程序的login.php,输入用户名,密码讲起.先用uc_user_login函数到uc_server验证此用户和 ...
- phpcms
phpcms 织梦 帝国cms
- java16
1:List的子类(掌握) (1)List的子类特点 ArrayList: 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector: 底层数据结构是数组,查询快,增删慢 线程安全,效率低 ...
- Python演讲笔记1
参考: 1. The Clean Architecture in Python (Brandon Rhodes) 2. Python Best Practice Patterns (Vladimir ...
- 激活webstorm2016如何激活webstorm2016永久激活webstorm2016
没有那么麻烦,我这个方法是简单粗暴: 1.搜webstrom2016,最新的是2016.3 2.官方下载 3.断网,改本地时间,你打算用多久,就把本地时间往未来调多久 4.安装webstorm 5.一 ...
- mvc+webapi 单元测试
1.前言 现在这个项目已经有阶段性的模块完成了,所以就想着对这些模块进行单元测试,以保证项目的代码的质量.首先虽然标题是mvc+webapi实质上我只是对mvc进行的测试.用的时候vs的unit te ...
- 基于Netty4的HttpServer和HttpClient的简单实现
Netty的主页:http://netty.io/index.html 使用的Netty的版本:netty-4.0.23.Final.tar.bz2 ‐ 15-Aug-2014 (Stable, Re ...
- service 03 iis之服务器无访问权限
这两天在Service 03 的iis 6.0 里面配置一个aspx 的网站 ,总是遇到一个问题 401.2 无权限访问,于是去百度了一下好多的方法,基本上是关于设置匿名用户,打开IUSER用户 ...
- Winform实现用多线程、百度地图API解析某公司的物理地址
前言 作为一个很挫的C#新手总喜欢自己写点儿不着边际的东西,本人是个新手加菜鸟,写B/S的,工作中,任务完成了,空闲下来,总想继续学点儿什么,由此触发了本篇文章了.个人一直认为,.NET中,C/S所要 ...