首页 > 编程语言 >【C++】<图形库> 三人成棋(面向对象写法)

【C++】<图形库> 三人成棋(面向对象写法)

时间:2024-05-28 20:58:56浏览次数:14  
标签:int C++ 玩家 --- Player 图形库 成棋 include mouse

 目录

一、游戏需求

二、程序架构

三、代码实现

四、实现效果

五、已知BUG


一、游戏需求

构建一个五子棋游戏,在自定义棋盘宽度和高度的基础上,实现三人对战功能,并且能判定谁输谁赢。


二、程序架构

(1) 对象分析:

【1】 需要一个棋盘(ChessBoard)类来绘制棋盘。

【2】有三人对战,用白棋、黑棋和黄棋区分。因此,需要构建白棋玩家、黑棋玩家和黄棋玩家。另外,每个玩家下的棋子用vector容器来装。每个玩家还应该具有判定自己是否赢得比赛的方法。由于vector容器和相关方法只有略微不同,可以先构建一个玩家基类(Player),再派生出白棋(WhitePlayer)、黑棋(BlackPlayer)和黄棋(YellowPlayer)玩家类。

【3】需要创建棋子类(ChessPiece),有坐标和颜色属性。当不同的玩家落子时,白棋、黑棋和黄棋玩家类会创建各自颜色的棋子。

【4】玩家根据鼠标点击来落子,因此需要一个鼠标类(Mouse)来返回鼠标信息。

【5】菜单类(Menu)将主要的逻辑封装好,便于在main()中调用。

(2) 文件构成:

有main.cpp、ChessBoard.cpp、Player.cpp(将涉及玩家的类都放于此)、ChessPiece.cpp、Mouse.cpp、Menu.cpp,还有对应的头文件。


三、代码实现

【1】main.cpp:

#include <iostream>
#include <graphics.h>
#include "ChessBoard.h"
#include "Menu.h"
#include "Mouse.h"
#include "Player.h"

/**************************************************************
  *说明:【1】若使用win11系统,需修改相关设置才能正常运行
  *	        设置-->系统-->开发者选项-->终端-->windows控制台主机
  *     【2】在创建棋盘对象时,可以自定义棋盘的宽度和高度
  ************************************************************/

int main()
{
	//创建相关对象
	ChessBoard board;	//棋盘对象
	Menu menu;			//菜单对象
	Mouse mouse;		//鼠标对象
	WhitePlayer wp;		//白棋玩家
	BlackPlayer bp;		//黑棋玩家
	YellowPlayer yp;	//黄棋玩家

	while (1) {
		//显示主交互界面
		int choice = menu.mainInterface();
		
		//根据choice显示不同界面
		switch (choice) {
		case '1'://游戏对战
			menu.startGame(mouse, board, wp, bp, yp);
			break;
		case '2'://游戏介绍
			menu.introInterface();
			break;
		case '0'://退出游戏
			return 0;
		}
	}
	return 0;
}

【2】Player.h:

#pragma once
#include <vector>
#include <algorithm>
#include "ChessPiece.h"
#include "Mouse.h"
#include "ChessBoard.h"


/***********************************************************
  * @类名:	Player
  * @摘要:	玩家基类(抽象类)
  * @作者:	柯同学
  * @注意:	派生类必须重写generatePiece方法
  *********************************************************/
class Player{
private:
	std::vector<ChessPiece> pieces;	//保存棋子的动态数组

public:
	virtual ~Player() {}			//虚析构函数:防止内存泄漏

	std::vector<ChessPiece>& getPieces();	//返回棋子动态数组引用

	virtual void generatePiece(Mouse& mouse, Player& p1, Player& p2) = 0;	//纯虚函数:玩家落子

	bool isWin(ChessBoard& board);	//判断当前玩家是否赢
};


/***********************************************************
  * @类名:	WhitePlayer
  * @摘要:	白玩家类(继承Player)
  * @作者:	柯同学
  * @注意:	generatePiece下白棋
  *********************************************************/
class BlackPlayer;
class YellowPlayer;
class WhitePlayer : public Player{
public:
	void generatePiece(Mouse& mouse, Player& p1, Player& p2) override;
};


/***********************************************************
  * @类名:	BlackPlayer
  * @摘要:	黑玩家类(继承Player)
  * @作者:	柯同学
  * @注意:	generatePiece下黑棋
  *********************************************************/
class BlackPlayer : public Player {
public:
	void generatePiece(Mouse& mouse, Player& p1, Player& p2) override;
};


/***********************************************************
  * @类名:	YellowPlayer
  * @摘要:	黄玩家类(继承Player)
  * @作者:	柯同学
  * @注意:	generatePiece下黄棋
  *********************************************************/
class YellowPlayer : public Player {
public:
	void generatePiece(Mouse& mouse, Player& p1, Player& p2) override;
};

【3】Player.cpp:

#include "Player.h"


/***********************************************************
  * @函数名:Player::getPieces
  * @功  能:返回棋子动态数组的引用
  * @参  数:无
  * @返回值:棋子动态数组的引用
  *********************************************************/
std::vector<ChessPiece>& Player::getPieces() {
	return this->pieces; 
}


/***********************************************************
  * @函数名:Player::isWin
  * @功  能:判断当前玩家是否赢得游戏
  * @参  数:board---棋盘对象
  * @返回值:true---赢得游戏,false---没赢游戏
  *********************************************************/
bool Player::isWin(ChessBoard& board) {
	/* 得到最近一次下的棋子 */
	ChessPiece lastChess;
	if (pieces.size() > 0) {
		lastChess = pieces[pieces.size() - 1];
	}
	/* 获胜情况1:左右五连 */
	int leftWinFlag = 0;//胜利标志:4则赢
	std::vector<ChessPiece>::iterator p;
	for (int i = -4; i <= 4; ++i) {
		//越界则跳过
		if ((lastChess.getX() + i * BOARD_INTERVAL < 0) ||
			(lastChess.getX() + i * BOARD_INTERVAL > board.getWidth())) {
			continue;
		}
		//查找连续相连的棋子
		ChessPiece targetChess(lastChess.getX() + i * BOARD_INTERVAL, lastChess.getY(), lastChess.getColor());
		p = std::find(pieces.begin(), pieces.end(), targetChess);
		if (p != pieces.end()) {
			leftWinFlag++;
		}
		else {
			leftWinFlag = 0;
		}
		//胜利
		if (leftWinFlag >= 5)
			return true;
	}

	/* 获胜情况2:上下五连 */
	int upWinFlag = 0;
	for (int i = -4; i <= 4; ++i) {
		//越界则跳过
		if ((lastChess.getY() + i * BOARD_INTERVAL < 0) ||
			(lastChess.getY() + i * BOARD_INTERVAL > board.getWidth())) {
			continue;
		}
		//查找连续相连的棋子
		ChessPiece targetChess(lastChess.getX(), lastChess.getY() + i * BOARD_INTERVAL, lastChess.getColor());
		p = std::find(pieces.begin(), pieces.end(), targetChess);
		if (p != pieces.end()) {
			upWinFlag++;
		}
		else {
			upWinFlag = 0;
		}
		//胜利
		if (upWinFlag >= 5)
			return true;
	}

	/* 获胜情况3:左上--右下(斜右)五连 */
	int diarightWinFlag = 0;
	for (int i = -4; i <= 4; ++i) {
		//越界则跳过
		if ((lastChess.getY() + i * BOARD_INTERVAL < 0) ||
			(lastChess.getY() + i * BOARD_INTERVAL > board.getWidth())) {
			continue;
		}
		//查找连续相连的棋子
		ChessPiece targetChess(lastChess.getX() + i * BOARD_INTERVAL, lastChess.getY() - i * BOARD_INTERVAL, lastChess.getColor());
		p = std::find(pieces.begin(), pieces.end(), targetChess);
		if (p != pieces.end()) {
			diarightWinFlag++;
		}
		else {
			diarightWinFlag = 0;
		}
		//胜利
		if (diarightWinFlag >= 5)
			return true;
	}

	/* 获胜情况4:左下--右上(斜左)五连 */
	int dialeftWinFlag = 0;
	for (int i = -4; i <= 4; ++i) {
		//越界则跳过
		if ((lastChess.getY() + i * BOARD_INTERVAL < 0) ||
			(lastChess.getY() + i * BOARD_INTERVAL > board.getWidth())) {
			continue;
		}
		//查找连续相连的棋子
		ChessPiece targetChess(lastChess.getX() + i * BOARD_INTERVAL, lastChess.getY() + i * BOARD_INTERVAL, lastChess.getColor());
		p = std::find(pieces.begin(), pieces.end(), targetChess);
		if (p != pieces.end()) {
			dialeftWinFlag++;
		}
		else {
			dialeftWinFlag = 0;
		}
		//胜利
		if (dialeftWinFlag >= 5)
			return true;
	}
	return false;
}


/***********************************************************
  * @函数名:createNonDUP(中介函数)
  * @功  能:生成不重复的棋
  * @参  数:my---当前对象
  * @参  数:bplay---黑棋玩家
  * @参  数:yplay---白棋玩家
  * @参  数:target---目标棋子
  * @参  数:mouse---鼠标对象
  * @返回值:无
  *********************************************************/
void createNonDUP(Player& my, Player& bplay, Player& yplay, ChessPiece& target, Mouse& mouse) {
	//查找三个玩家的棋库中是否有target的坐标
	std::vector<ChessPiece>::iterator wp, bp, yp;
	wp = find(my.getPieces().begin(), my.getPieces().end(), target);
	bp = find(bplay.getPieces().begin(), bplay.getPieces().end(), target);
	yp = find(yplay.getPieces().begin(), yplay.getPieces().end(), target);
	//不存在重复的棋就加入对应容器,并绘制
	if (wp == my.getPieces().end() && bp == bplay.getPieces().end()
		&& yp == yplay.getPieces().end())
	{
		my.getPieces().push_back(target);
		setfillcolor(target.getColor());
		fillcircle(target.getX(), target.getY(), PIECE_RADIUS);
		mouse.setClickTotal(mouse.getClickTotal() + 1);
	}
}


/***********************************************************
  * @函数名:WhitePlayer::generatePiece
  * @功  能:白玩家:下白棋,并将棋子对象加入vector容器中
  * @参  数:mouse---鼠标对象
  * @参  数:p1---其他玩家
  * @参  数:p2---其他玩家
  * @返回值:无
  *********************************************************/
void WhitePlayer::generatePiece(Mouse& mouse, Player& p1, Player& p2) {
	if (mouse.detectClick()) {
		//创建棋对象,设置颜色为白色
		ChessPiece cp(mouse.getMouseMesg().x, mouse.getMouseMesg().y, WHITE);
		cp.fixChessPiece();
		//生成不重复的棋子,并绘制
		createNonDUP(*this, p1, p2, cp, mouse);
	}
}


/***********************************************************
  * @函数名:BlackPlayer::generatePiece
  * @功  能:黑玩家:下黑棋,并将棋子对象加入vector容器中
  * @参  数:mouse---鼠标对象
  * @参  数:p1---其他玩家
  * @参  数:p2---其他玩家
  * @返回值:无
  *********************************************************/
void BlackPlayer::generatePiece(Mouse& mouse, Player& p1, Player& p2) {
	if (mouse.detectClick()) {
		//创建棋对象,设置颜色为黑色
		ChessPiece cp(mouse.getMouseMesg().x, mouse.getMouseMesg().y, BLACK);
		cp.fixChessPiece();
		//生成不重复的棋子,并绘制
		createNonDUP(*this, p1, p2, cp, mouse);
	}
}


/***********************************************************
  * @函数名:YellowPlayer::generatePiece
  * @功  能:黄玩家:下黄棋,并将棋子对象加入vector容器中
  * @参  数:mouse---鼠标对象
  * @参  数:p1---其他玩家
  * @参  数:p2---其他玩家
  * @返回值:无
  *********************************************************/
void YellowPlayer::generatePiece(Mouse& mouse, Player& p1, Player& p2) {
	if (mouse.detectClick()) {
		//创建棋对象,设置颜色为黄色
		ChessPiece cp(mouse.getMouseMesg().x, mouse.getMouseMesg().y, YELLOW);
		cp.fixChessPiece();
		//生成不重复的棋子,并绘制
		createNonDUP(*this, p1, p2, cp, mouse);
	}
}

【4】ChessPiece.h:

#pragma once
#include <graphics.h>
#include "Mouse.h"
#include "ChessBoard.h"
#define PIECE_RADIUS	5	//棋子半径


/***********************************************************
  * @类名:	ChessPiece
  * @摘要:	棋子类
  * @作者:	柯同学
  * @注意:	默认棋子为白色
  *********************************************************/
class ChessPiece {
private:
	int x;		//横坐标
	int y;		//纵坐标
	int color;	//白色、黑色、黄色(分别对应白玩家、黑玩家、黄玩家)
public:
	ChessPiece(int x = 0, int y = 0, int color = WHITE) : x(x), y(y), color(color) {}

	bool operator==(const ChessPiece& cp);	//比较两个棋子坐标是否相等

	void setColor(int color);			//设置棋子颜色

	void setXY(int x, int y);			//设置棋子坐标

	int getX() { return x; }			//获取棋子x坐标

	int getY() { return y; }			//获取棋子y坐标

	int getColor() { return color; }	//获取棋子颜色

	void fixChessPiece();				//修正棋子坐标,并绘制棋子
};

【5】ChessPiece.cpp:

#include "ChessPiece.h"


/***********************************************************
  * @函数名:operator==
  * @功  能:==运算符重载:比较两个棋子的坐标是否相等
  * @参  数:cp---另一个棋子
  * @返回值:无
  *********************************************************/
bool ChessPiece::operator==(const ChessPiece& cp) {
	if (this->x == cp.x && this->y == cp.y)
		return true;
	return false;
}


/***********************************************************
  * @函数名:setColor
  * @功  能:设置棋子颜色
  * @参  数:color---棋子的颜色
  * @返回值:无
  *********************************************************/
void ChessPiece::setColor(int color) {
	this->color = color;
}


/***********************************************************
  * @函数名:setXY
  * @功  能:设置棋子坐标
  * @参  数:x---棋子的横坐标
  * @参  数:y---棋子的纵坐标
  * @返回值:无
  *********************************************************/
void ChessPiece::setXY(int x, int y) {
	this->x = x;
	this->y = y;
}


/***********************************************************
  * @函数名:createChessPiece
  * @功  能:修正棋子坐标
  * @参  数:无
  * @返回值:无
  *********************************************************/
void ChessPiece::fixChessPiece() {
	if (this->x >= 0 && this->y >= 0) {//范围合理
		if (this->x % BOARD_INTERVAL > BOARD_INTERVAL / 2) {
			int i;
			for (i = 0; i * BOARD_INTERVAL < this->x; i++);
			this->x = i * BOARD_INTERVAL;
		}
		else {
			this->x -= this->x % BOARD_INTERVAL;
		}
		if (this->y % BOARD_INTERVAL > BOARD_INTERVAL / 2) {
			int i;
			for (i = 0; i * BOARD_INTERVAL < this->y; i++);
			this->y = i * BOARD_INTERVAL;
		}
		else {
			this->y -= this->y % BOARD_INTERVAL;
		}
	}
	else {//坐标越界
		this->x = 0;
		this->y = 0;
	}
}

【6】ChessBoard.h:

#pragma once
#include <iostream>
#include <graphics.h>

#define BOARD_INTERVAL	20	//网格的间隔

/***********************************************************
  * @类名:	ChessBoard
  * @摘要:	棋盘类
  * @作者:	柯同学
  * @注意:	默认宽度和高度为400,400
  *********************************************************/
class ChessBoard {
private:
	int width;		//棋盘宽度
	int height;		//棋盘高度
public:
	ChessBoard(int w = 400, int h = 400) : width(w), height(h) {}

	void setWidth(int width);	//设置棋盘宽度

	void setHeight(int height);	//设置棋盘高度

	int getWidth();				//获取棋盘宽度

	int getHeight();			//获取棋盘高度

	void showBoard();			//绘制棋盘网格
};

【7】ChessBoard.cpp:

#include "ChessBoard.h"


/***********************************************************
  * @函数名:setWidth
  * @功  能:设置棋盘宽度
  * @参  数:width---要设置的属性
  * @返回值:无
  *********************************************************/
void ChessBoard::setWidth(int width) {
	this->width = width;
}


/***********************************************************
  * @函数名:setHeight
  * @功  能:设置棋盘高度
  * @参  数:height---要设置的属性
  * @返回值:无
  *********************************************************/
void ChessBoard::setHeight(int height) {
	this->height = height;
}


/***********************************************************
  * @函数名:getWidth
  * @功  能:获取棋盘宽度
  * @参  数:无
  * @返回值:棋盘的宽度
  *********************************************************/
int ChessBoard::getWidth() {
	return width;
}


/***********************************************************
  * @函数名:getHeight
  * @功  能:获取棋盘高度
  * @参  数:无
  * @返回值:棋盘的高度
  *********************************************************/
int ChessBoard::getHeight() {
	return height;
}


/***********************************************************
  * @函数名:showBoard
  * @功  能:绘制棋盘并显示
  * @参  数:无
  * @返回值:无
  *********************************************************/
void ChessBoard::showBoard() {
	std::cout << width << " " << height << std::endl;
	for (int i = 0; i <= width; i += BOARD_INTERVAL) {
		line(0, i, width, i);//横线
		line(i, 0, i, height);//竖线
	}
}

【8】Mouse.h:

#pragma once
#include <graphics.h>
#include <iostream>
#include "ChessPiece.h"

/***********************************************************
  * @类名:	Mouse
  * @摘要:	鼠标类
  * @作者:	柯同学
  * @注意:	无
  *********************************************************/
class Mouse {
private:
	ExMessage mouseMesg;	//鼠标信息,包含坐标、点击的键
	int clickTotal;			//鼠标有效点击次数
public:
	Mouse() : clickTotal(0) {}		//无参构造:鼠标次数初始化为0

	void setClickTotal(int num);	//设置鼠标点击次数

	int getClickTotal();			//获取鼠标点击次数

	ExMessage& getMouseMesg();		//获取鼠标信息

	bool detectClick();				//返回鼠标是否被点击
};

【9】mouse.cpp:

#include "Mouse.h"


/***********************************************************
  * @函数名:setClickTotal
  * @功  能:设置鼠标有效点击次数
  * @参  数:num---要设置的次数
  * @返回值:无
  *********************************************************/
void Mouse::setClickTotal(int num) {
	this->clickTotal = num;
}


/***********************************************************
  * @函数名:getClickTotal
  * @功  能:获取鼠标有效点击次数
  * @参  数:无
  * @返回值:鼠标有效点击次数
  *********************************************************/
int Mouse::getClickTotal() {
	return this->clickTotal;
}


/***********************************************************
  * @函数名:getMouseMesg
  * @功  能:获取鼠标信息:包含点击的坐标、鼠标键
  * @参  数:无
  * @返回值:鼠标信息
  *********************************************************/
ExMessage& Mouse::getMouseMesg() {
	return this->mouseMesg;
}


/***********************************************************
  * @函数名:detectClick
  * @功  能:返回鼠标是否被点击
  * @参  数:无
  * @返回值:true---鼠标被点击,false---鼠标没有被点击
  *********************************************************/
bool Mouse::detectClick() {
	if (peekmessage(&this->mouseMesg) && this->mouseMesg.message == WM_LBUTTONDOWN) {//鼠标左击
		return true;
	}
	return false;
}

【10】Menu.h:

#pragma once
#include <iostream>
#include <graphics.h>
#include <conio.h>
#include "ChessBoard.h"
#include "Mouse.h"
#include "Player.h"


/***********************************************************
  * @类名:	Menu
  * @摘要:	菜单类
  * @作者:	柯同学
  * @注意:	无
  *********************************************************/
class Menu {
/*************以下为Menu内部调用的函数***********************/
private:
	void multiPlayerPK(Mouse& mouse,		//哪个玩家落子
						WhitePlayer& wp,
						BlackPlayer& bp,
						YellowPlayer& yp);	

	void multiPlayerWin(ChessBoard& board,	//哪个玩家获胜
						WhitePlayer& wp,
						BlackPlayer& bp,
						YellowPlayer& yp);	

/*************以下为menu对外开放的函数**********************/
public:
	int mainInterface();					//主界面显示

	void introInterface();					//游戏介绍界面

	void startGame(Mouse& mouse, ChessBoard& board, 
				   WhitePlayer& wp, BlackPlayer& bp,
				   YellowPlayer& yp);		//三人对战界面
};

【11】Menu.cpp:

#include "Menu.h"


/***********************************************************
  * @函数名:mainInterface
  * @功  能:游戏主界面
  * @参  数:无
  * @返回值:无
  *********************************************************/
int Menu::mainInterface() {
	initgraph(800, 600);
	setbkcolor(WHITE);
	cleardevice();
	settextstyle(70, 0, "Arial");
	settextcolor(BLACK);
	outtextxy(150, 120, "小游戏:三人成棋");
	setlinecolor(BLACK);
	settextstyle(50, 0, "Arial");
	outtextxy(280, 250, "1.开始游戏");
	outtextxy(280, 350, "2.游戏介绍");
	outtextxy(280, 450, "0.退出游戏");
	int keyNum = -1;
	while (1) {
		if (_kbhit()) {
			keyNum = _getch();
			if (keyNum == '1' || keyNum == '2' || keyNum == '0')
				break;
		}
	}
	closegraph();
	return keyNum;
}


/***********************************************************
  * @函数名:introInterface
  * @功  能:游戏介绍的界面
  * @参  数:无
  * @返回值:无
  *********************************************************/
void Menu::introInterface() {
	initgraph(800, 600, 0);
	setbkcolor(WHITE);
	cleardevice();
	settextstyle(70, 0, "Arial");
	settextcolor(BLACK);
	outtextxy(0, 0, "游戏介绍:");
	settextstyle(50, 0, "Arial");
	outtextxy(0, 100, "【1】游戏人数:三人");
	outtextxy(0, 200, "【2】下棋顺序:白棋、黑棋、黄棋");
	outtextxy(0, 300, "【3】返回提示:默认按0返回");
	outtextxy(0, 400, "【4】其他说明:基本已实现,但仍有bug");
	outtextxy(450, 500, "按0返回主菜单!");
	while (!_kbhit() || _getch() != '0');
	closegraph();
}


/***********************************************************
  * @函数名:startGame
  * @功  能:三人对战界面
  * @参  数:mouse---鼠标对象
  * @参  数:board---棋盘对象
  * @参  数:wp---白棋玩家
  * @参  数:bp---黑棋玩家
  * @参  数:yp---黄棋玩家
  * @返回值:无
  *********************************************************/
void Menu::startGame(Mouse& mouse, ChessBoard& board, WhitePlayer& wp, 
					 BlackPlayer& bp, YellowPlayer& yp) 
{
	//创建窗口,显示棋盘
	initgraph(board.getWidth(), board.getHeight(), 0);
	setbkcolor(RGB(245, 222, 181));
	setlinecolor(BLACK);
	cleardevice();
	board.showBoard();
	//主循环
	while (!_kbhit() || _getch() != '0') {//按'0'退出程序
		//玩家落子
		multiPlayerPK(mouse, wp, bp, yp);
		//玩家胜负判定
		multiPlayerWin(board, wp, bp, yp);
	}
	closegraph();
}


/***********************************************************
  * @函数名:multiPlayerPK
  * @功  能:确定哪个玩家落子,根据鼠标有效点击次数
  * @参  数:mouse---鼠标对象
  * @参  数:wp---白棋玩家
  * @参  数:bp---黑棋玩家
  * @参  数:yp---黄棋玩家
  * @返回值:无
  *********************************************************/
void Menu::multiPlayerPK(Mouse& mouse, WhitePlayer& wp, 
						 BlackPlayer& bp, YellowPlayer& yp)
{
	if (mouse.getClickTotal() % 3 == 0) {
		wp.generatePiece(mouse, bp, yp);//白棋落子
	}
	else if (mouse.getClickTotal() % 3 == 1) {
		bp.generatePiece(mouse, wp, yp);//黑棋落子
	}
	else {
		yp.generatePiece(mouse, wp, bp);//黄棋落子
	}
		
}


/***********************************************************
  * @函数名:multiPlayerWin
  * @功  能:确定哪个玩家获胜
  * @参  数:board---棋盘对象
  * @参  数:wp---白棋玩家
  * @参  数:bp---黑棋玩家
  * @参  数:yp---黄棋玩家
  * @返回值:无
  *********************************************************/
void Menu::multiPlayerWin(ChessBoard& board, WhitePlayer& wp, 
						  BlackPlayer& bp, YellowPlayer& yp) 
{
	if (wp.isWin(board)) {
		cleardevice();
		settextcolor(BLACK);
		settextstyle(30, 0, "Arial");
		outtextxy(25, board.getHeight() / 2 - 30, "白棋获胜!按0返回主界面!");
	}
	else if (bp.isWin(board)) {
		cleardevice();
		settextcolor(BLACK);
		settextstyle(30, 0, "Arial");
		outtextxy(25, board.getHeight() / 2 - 30, "黑棋获胜!按0返回主界面!");
	}
	else if (yp.isWin(board)) {
		cleardevice();
		settextcolor(BLACK);
		settextstyle(30, 0, "Arial");
		outtextxy(25, board.getHeight() / 2 - 30, "黄棋获胜!按0返回主界面!");
	}
}


四、实现效果

五、已知BUG

由于时间原因,已有的BUG在未来有时间后再修改:

【1】一局游戏下完后,从主菜单进来可能会停留在上次下棋后的界面。

【2】游戏输赢判定后,点击屏幕依然能下棋。

标签:int,C++,玩家,---,Player,图形库,成棋,include,mouse
From: https://blog.csdn.net/weixin_46249470/article/details/139201755

相关文章

  • c++ vector 正确释放内存
     今天在看微博的时候,有人提出了一个对于Vector内存泄露的疑问( Link)。博主采用Vector存储一些数据,但是发现在执行clear()之后内存并没有释放,于是怀疑产生了内存泄露。随后有人回复:“vector的clear不影响capacity,你应该swap一个空的vector。”开始并不知道回复......
  • C++实现获取设备管理器中的设备信息
     C++实现获取设备管理器中的设备信息,基本调用了windowsAPI函数,除此之外,还引用了setupapi.lib库,代码如下所示://PrintDeviceInfo.cpp:定义控制台应用程序的入口点。//#include<stdio.h>#include<locale.h>#include<Windows.h>#include<setupapi.h>#pragmacomm......
  • C++实现删除打印机副本功能
     我们要实现此功能,首先需要获取到打印机的名称,其次是将获取到的打印机名称依次删除。一、获取打印机副本名称1.我们获取打印机副本名称,可以使用windowsAPI中的EnumPrinters函数,该函数可以枚举出我们电脑中的打印机设备信息,该函数使用方法如下:DWORDFlags=PRINTER_ENU......
  • C++实现dll文件的显示调用
    我们实现dll文件的显示调用,主要分为三个步骤:创建DLL、导出函数、使用DLL。其中离不开WindowsAPI函数,使用到了LoadLibrary、GetProcAddress、 FreeLibrary等,以下是一个简单的示例程展示整个过程。:1.创建DLLMyLibrary.h//MyLibrary.h#ifndefMY_LIBRARY_H#defineMY_LI......
  • C++跨平台库boost和Poco的编译
    PrerequisitesCMake3.5ornewerAC++17compiler(VisualC++2022,GCC8.0,Clang5,ornewer)在window下编译依赖的三方库编译POCO$gitclone-bmasterhttps://github.com/pocoproject/poco.git$cdpoco$mkdircmake-build$cdcmake-build$cmake..$cma......
  • C++17 链接 C++11 lib 出现重复定义
    C++11实现staticconstexpr是按照conststatic实现的,需要在.cpp中定义://tmp.hclassStatisTest{public:staticconstexprconstcharliteral[]="xxxliteral";};//tmp.cc#include"tmp.h"constcharStatisTest::literal[];//compile......
  • 阿赵UE引擎C++编程学习笔记——文件夹操作和文件读写
      大家好,我是阿赵。  这次学习一下在UE里面使用C++的API操作文件读写和文件夹操作。一、UE引擎获取相关路径  获取到路径一般是相对路径,使用FPaths::ConvertRelativePathToFull转换后,可以获得完整的绝对路径。FStringcontentDir=FPaths::ProjectContentDir();......
  • 《C++primer》第八章课后习题
    练习8.1istream&abc(istream&is){ strings; is>>s; cout<<s; s.clear(); returnis;}练习8.2abc(cin);练习8.3答:输入类型与i不符,或者输入结束标识练习8.4vector<string>s;voidabc(strings1){ strings2; ifstreamin(s1); while(getline(......
  • 《C++primer》读书笔记---第八章:IO库
    8.1IO类下表列出的是一些IO类型:  为了支持使用宽字符的语言,标准库定义了一组类型和对象来操纵wchar_t类型的数据。宽字符版本的类型和函数的名字以一个w开始,例如,wcin、wcout、wcerr是分别对应cin、cout、cerr的宽字符类型。注:IO对象无拷贝或赋值ofstreamout1,out2;......
  • C++二进制文件的读写
    二进制文件的读取:voidTransformSession::generateData(conststd::string&filePath,std::vector<uint8_t>&data){std::ifstreamifs(filePath,std::ios::binary);if(!ifs){SPDLOG_ERROR("failedtoopenreadfile:{}",filePath);......