C++小游戏--五子棋--性能优化与详解代码

该五子棋游戏代码基于本人另一篇小游戏井字棋的代码进行独立改进完成的。链接如下:C++小游戏--井字棋--代码

主要改进了对游戏胜负情况判断函数的写法,以及棋子落盘的坐标计算。

具体代码如下(可直接照搬):

#include <iostream>
#include <graphics.h>
#include <string>

//棋盘数组
char board_data[15][15];
char current_piece = 'W';

bool CheckWin(char c) {
	// 检查水平方向、垂直方向和两条对角线的连续五子
	for (size_t i = 0; i < 15; i++) {
		for (size_t j = 0; j < 15; j++) {
			// 水平方向
			if (j + 4 < 15) {
				bool win = true;
				for (size_t k = 0; k < 5; k++) {
					if (board_data[i][j + k] != c) {
						win = false;
						break;
					}
				}
				if (win) return true;
			}

			// 垂直方向
			if (i + 4 < 15) {
				bool win = true;
				for (size_t k = 0; k < 5; k++) {
					if (board_data[i + k][j] != c) {
						win = false;
						break;
					}
				}
				if (win) return true;
			}

			// 主对角线
			if (i + 4 < 15 && j + 4 < 15) {
				bool win = true;
				for (size_t k = 0; k < 5; k++) {
					if (board_data[i + k][j + k] != c) {
						win = false;
						break;
					}
				}
				if (win) return true;
			}

			// 副对角线
			if (i >= 4 && j + 4 < 15) {
				bool win = true;
				for (size_t k = 0; k < 5; k++) {
					if (board_data[i - k][j + k] != c) {
						win = false;
						break;
					}
				}
				if (win) return true;
			}
		}
	}
	return false;
}

bool CheckDraw() { //判断平局
	for (size_t i = 0; i < 15; i++) {
		for (size_t j = 0; j < 15; j++) {
			if (board_data[i][j] == '-')
				return false;
		}
	}
	return true;
}

void DrawBoard() { //绘制棋盘
	for(int i=80;i<921;i+=60)//用循环画棋盘线
	{
		line(80, i, 920, i);
		line(i, 80, i, 920);
	}
	setfillcolor(WHITE);
	solidcircle(500, 500, 6);//独立绘制五个定位点
	solidcircle(260, 260, 6);
	solidcircle(740, 260, 6);
	solidcircle(260, 740, 6);
	solidcircle(740, 740, 6);
}

void DrawPiece() { //绘制棋子
	for (size_t i = 0; i < 15; i++) {
		for (size_t j = 0; j < 15; j++) {
			switch (board_data[i][j])
			{
			case 'W':
				setfillcolor(WHITE);
				solidcircle(60 * j + 80, 60 * i + 80, 20);
				break;
			case 'B':
				setfillcolor(BLACK);
				fillcircle(60 * j + 80, 60 * i + 80, 20);
				break;
			case '-':
				break;
			}
		}
	}
}

void DrawTipText() { //绘制信息
	static TCHAR str[64];
	_stprintf_s(str, _T("当前棋子(W为白子,B为黑子):%c"), current_piece);

	settextcolor(RGB(225, 170, 40));
	outtextxy(1, 1, str);
}

int main() {
	initgraph(1000, 1000);
	for (size_t i = 0; i < 15; i++) {
		for (size_t j = 0; j < 15; j++) {
			board_data[i][j] = '-';
		}
	}
	bool running = true;
	ExMessage msg;

	BeginBatchDraw();//创建渲染缓冲区

	while (running)
	{
		DWORD start_time = GetTickCount(); //性能优化

		while (peekmessage(&msg)) { //接收控制信息
			if (msg.message == WM_LBUTTONDOWN)
			{
				int x = msg.x;
				int y = msg.y;
				//计算点击的网格位置
				int index_x = (x - 50) / 60;
				int index_y = (y - 50) / 60;

				if (index_x >= 0 && index_x < 15 && index_y >= 0 && index_y < 15) {
					if (board_data[index_y][index_x] == '-')
					{
						board_data[index_y][index_x] = current_piece;

						current_piece = (current_piece == 'W') ? 'B' : 'W';
                        //三目运算符
					}
				}
			}
		}
		setbkcolor(RGB(119, 69, 19));
		cleardevice();//清理画布

		DrawBoard();
		DrawPiece();
		DrawTipText();

		FlushBatchDraw();

		if (CheckWin('W'))
		{
			MessageBox(GetHWnd(), _T("白子 win!"), _T("Game Over"), MB_OK);
			running = false;
		}
		else if (CheckWin('B'))
		{
			MessageBox(GetHWnd(), _T("黑子 win!"), _T("Game Over"), MB_OK);
			running = false;
		}
		else if (CheckDraw())
		{
			MessageBox(GetHWnd(), _T("Draw!"), _T("Game Over"), MB_OK);
			running = false;
		}

		DWORD end_time = GetTickCount();
		DWORD delta_time = end_time - start_time;
		if (delta_time < (1000 / 60))
		{
			Sleep(1000 / 60 - delta_time);//动态休眠,程序保持在60帧的情况下优化内存使用
		}
	}

	EndBatchDraw();
}

// MainFrm.cpp : implementation of the CMainFrame class // #include "stdafx.h" #include "五子棋.h" #include "MainFrm.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HCURSOR m_hcursor; ///////////////////////////////////////////////////////////////////////////// // CMainFrame IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_SETCURSOR() //}}AFX_MSG_MAP END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; ///////////////////////////////////////////////////////////////////////////// // CMainFrame construction/destruction CMainFrame::CMainFrame() { // TODO: add member initialization code here } CMainFrame::~CMainFrame() { } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics #ifdef _DEBUG void CMainFrame::AssertValid() const { CFrameWnd::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CFrameWnd::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default BOOL br = CFrameWnd::OnSetCursor( pWnd, nHitTest,message) ; if(star==1) { if(flag==1) { m_hcursor= AfxGetApp()->LoadCursor(IDC_hei); SetCursor(m_hcursor); br = TRUE; } else if(flag==2) { m_hcursor= AfxGetApp()->LoadCursor(IDC_bai); SetCursor(m_hcursor); br = TRUE; } } return br; // return CFrameWnd::OnSetCursor(pWnd, nHitTest, message); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值