基于C++的五子棋项目

news/2024/10/17 18:14:09/

一、五子棋项目介绍

1.游戏规则

五子棋是我国古代传统的黑白棋种之一,黑白双方依次落子,任意一方在棋盘上形成横向、纵向、斜向的连续相同颜色的五颗棋子的一方为胜。

2.完成界面显示

此次项目将不使用任何图形库进行开发,所有显示的内容都是以字符的形式进行显示。

二、棋子对象

1.棋子类

关于棋子类我们可以做如下几点思考:
由于黑棋和白棋的显示是不同的,棋子类的显示方法是不知道如何实现的,所以它是一个抽象类。每棵棋子在棋盘的不同位置存放,所以它应该包含棋子在屏幕上面的具体坐标。
每颗棋子都有自己的颜色,所以它应该包含颜色。

棋子类代码如下:

#ifndef CHESS_HPP
#define CHESS_HPP#include <iostream>
#include <cstdio>using namespace std;class Chess
{
public:Chess(int x,int y,char color) : x(x),y(y),color(color){}virtual ~Chess() {}virtual void show() = 0;int getX() const{return x;}int getY() const{return y;}char getColor() const{return color;}
private:int x;int y;char color;
};#endif

2.黑棋类

黑棋类应该继承棋子类,然后实现棋子类的void show(void) const函数,在这个函数中显示黑色棋子。

黑棋类代码如下:

#ifndef BLACKCHESS_HPP
#define BLACKCHESS_HPP#include "Chess.hpp"
#include "Config.hpp"class BlackChess : public Chess
{
public:BlackChess(int x,int y) : Chess(x,y,BLACK){}void show(){printf("\033[%d;%dH%s",getY(),getX()-1,BLACK_COLOR);printf("\033[%d;%dH",getY(),getX());//光标归位}
};#endif

3.白棋类

 白棋类应该继承棋子类,然后实现棋子类的void show(void) const函数,在这个函数中显示白色棋子。

白棋类代码如下:

#ifndef WHITE_HPP
#define WHITE_HPP#include "Chess.hpp"
#include "Config.hpp"class WhiteChess : public Chess
{
public:WhiteChess(int x,int y) : Chess(x,y,WHITE){}void show(){printf("\033[%d;%dH%s",getY(),getX()-1,WHITE_COLOR);printf("\033[%d;%dH",getY(),getX());//光标归位}
};#endif

 三、棋盘对象

棋盘对象只有—个,我们可以使用单例模式来设计

1.显示棋盘

棋盘已经在chessBoard.txt文件中存放,只需要将这个文件中的棋盘读取出来然后在终端上面显示就可以了。


链接:https://pan.baidu.com/s/113G9XCGdn1F0SKX_z6h1IQ   提取码:eoks

 2.存放棋子

整个棋盘有15行和15列构成,我们把每个棋子都看成是一个对象,我们只需要记录这些对象的首地址就可以了,可以用一个二维的指针数组存放。

3.落子位置是否有效

如果落子位置已经有棋子了则返回false ,如果落子位置没有棋子则返回true 。

棋盘类代码如下:

#ifndef CHESSBOARD_HPP
#define CHESSBOARD_HPP#include "Chess.hpp"
#include "Config.hpp"
#include <errno.h>
#include <cstring>class ChessBoard
{
public:static ChessBoard* getInstance(){return cb;}void show(){char buf[1024] = {0};FILE *fp = fopen(CHESS_BOARD_FILE,"r");if(fp == NULL){fprintf(stderr,"Fail to open ChessBoard.txt: %s\n",strerror(errno));return ;}cout << "\033[1;1H" << CHESS_BOARD_COLOR;while(fgets(buf,sizeof(buf),fp) != NULL){fputs(buf,stdout);}fclose(fp);cout << "\033[0m";}bool isValidPostion(int line,int column){if(line >= LINE || line < 0 || column >= COLUMN || column < 0){return false;}return chess[line][column] == NULL ? true : false;}bool placeChess(Chess *chess){int line = (chess->getY() - 1)/LINE_INTERVAL;int column = (chess->getX() - 1)/COLUMN_INTERVAL;if(isValidPostion(line,column)){this->chess[line][column] = chess;chess->show();curLine = line;curColumn = column;return true;}return false;}bool isValidColorChess(int line,int column,char color){if(line < 0 || line >= LINE || column < 0 || column >= COLUMN){return false;}Chess *ch = chess[line][column];if(ch == NULL){return false;}if(ch->getColor() != color){return false;}return true;}int getCurLine() const{return curLine;}int getCurColumn() const{return curColumn;}private:ChessBoard() : curLine(-1),curColumn(-1){for(int i = 0; i < LINE; ++i){for(int j = 0; j < COLUMN; ++j){chess[i][j] = NULL;}}}~ChessBoard(){}static ChessBoard *cb;Chess *chess[LINE][COLUMN];int curLine;int curColumn;
};ChessBoard *ChessBoard::cb = new ChessBoard;#endif

四、棋手对象

五子棋游戏中有两个玩家,一个玩家下黑旗,一个玩家下白旗。每个玩家至少包含以下成员:

1.玩家的名字 2.玩家下棋的棋子颜色  3.在棋盘落子的方法

1.玩家类

#ifndef PLAYER_HPP
#define PLAYER_HPP#include<iostream>using namespace std;class Player
{
public:Player(const string &name,char color) : name(name),color(color){}virtual ~Player() {}char getColor() const{return color;}string getName() const{return name;}virtual bool placeChess(int x, int y) = 0;private:string name;char color;
};#endif

2.黑棋玩家类

#ifndef BLACKPLAYER_HPP
#define BLACKPLAYER_HPP#include "Player.hpp"
#include "Config.hpp"
#include "ChessBoard.hpp"
#include "BlackChess.hpp"class BlackPlayer : public Player
{
public:BlackPlayer(const string &name) : Player(name,BLACK){}bool placeChess(int x,int y){BlackChess *bc = new BlackChess(x,y);if(!ChessBoard::getInstance()->placeChess(bc)){delete bc;return false;}return true;}
};#endif

3.白棋玩家类

#ifndef WHITEPLAYER_HPP
#define WHITEPLAYER_HPP#include "Player.hpp"
#include "Config.hpp"
#include "ChessBoard.hpp"
#include "WhiteChess.hpp"class WhitePlayer : public Player
{
public:WhitePlayer(const string &name) : Player(name,WHITE){}bool placeChess(int x,int y){WhiteChess *bc = new WhiteChess(x,y);if(!ChessBoard::getInstance()->placeChess(bc)){delete bc;return false;}return true;}
};#endif

五、按键方向控制类

在五子棋项目中,我们通过W/A/S/D/Space五个按键来做控制,这五个按键的功能如下;
W将光标向前移动,即将当前光标y轴坐标-2
S将光标向后移动,即将当前光标y轴坐标+2
A将光标向左移动,即将当前光标x轴坐标 - 4
D将光标向右移动,即将当前光标x轴坐标+4
Space空格键,用来控制落子

终端属性设置:

方向类代码如下:
 

#ifndef KEYHANDLE_HPP
#define KEYHANDLE_HPP#include "Cursor.hpp"
#include "Player.hpp"
#include <termios.h>
#include <unistd.h>
#include <cstdlib>class KeyHandle
{
public:KeyHandle(){
#if 0struct termios attr;tcgetattr(0,&attr);attr.c_lflag &= ~(ICANON | ECHO);tcsetattr(0,TCSANOW,&attr);
#elsesystem("stty -icanon");system("stty -echo");
#endif}~KeyHandle(){
#if 0struct termios attr;tcgetattr(0,&attr);attr.c_lflag |= (ICANON | ECHO);tcsetattr(0,TCSANOW,&attr);
#elsesystem("stty icanon");system("stty echo");
#endif}bool waitPlayerPlaceChess(Player *player){char key = '\0';bool ret = false;while(1){key = getchar();switch(key){case 'w':case 'W':cursor.moveUp();break;case 's':case 'S':cursor.moveDown();break;case 'a':case 'A':cursor.moveLeft();break;case 'd':case 'D':cursor.moveRight();break;case ' ':ret = player->placeChess(cursor.getX(),cursor.getY());break;}if(ret){break;}}}private:Cursor cursor;};#endif

 六、裁判类

给出当前可以落子的棋手是谁
判断当前在棋盘上落子的棋子是否构成了五颗相同的棋子(赢棋)显示获得胜利的棋手

裁判类代码如下:

#ifndef ARBITRATION_HPP
#define ARBITRATION_HPP#include "ChessBoard.hpp"class Arbitration
{
public:bool isWin(char color){ChessBoard *cb = ChessBoard::getInstance();int curLine = cb->getCurLine();int curColumn = cb->getCurColumn();bool ret = false;ret = isDirectionWin(curLine,curColumn,color,1,0);if(ret){return true;}ret = isDirectionWin(curLine,curColumn,color,0,1);if(ret){return true;}ret = isDirectionWin(curLine,curColumn,color,1,1);if(ret){return true;}ret = isDirectionWin(curLine,curColumn,color,1,-1);if(ret){return true;}return false;}bool isDirectionWin(int line,int column,char color,int x,int y){ChessBoard *cb = ChessBoard::getInstance();int count = 1;for(int i = 1; i < 5; ++i){bool ret = cb->isValidColorChess(line + (i * y),column + (i * x),color);if(!ret){break;}++count;}for(int i = 1; i < 5; ++i){bool ret = cb->isValidColorChess(line - (i * y),column - (i * x),color);if(!ret){break;}++count;}if(count >= 5){return true;}return false;}
};#endif

主函数代码如下:

#include "BlackPlayer.hpp"
#include "WhitePlayer.hpp"
#include "ChessBoard.hpp"
#include "KeyHandle.hpp"
#include "Arbitration.hpp"int main(int argc, const char *argv[])
{cout << "\033[2J";ChessBoard::getInstance()->show();KeyHandle KeyHandle;Arbitration arb;Player *player[2];player[0] = new BlackPlayer("张三");player[1] = new WhitePlayer("李四");bool isWin = false;while(1){for(int i = 0; i < 2; ++i){KeyHandle.waitPlayerPlaceChess(player[i]);isWin = arb.isWin(player[i]->getColor());if(isWin){cout << "\033[32;0H" << player[i]->getName() << "获得胜利";break;}}if(isWin){break;}}delete player[0];delete player[1];cout << "\033[0m\033[35;0H";return 0;
}

宏定义类代码如下:

#ifndef CONFIG_HPP
#define CONFIG_HPP#define BLACK 0x1
#define WHITE 0x0#define BLACK_COLOR "\033[31;40m[♚]"
#define WHITE_COLOR "\033[36;47m[♛]"#define LINE 15
#define COLUMN 15#define CHESS_BOARD_FILE "ChessBoard.txt"
#define CHESS_BOARD_COLOR "\033[45;37m"#define LINE_INTERVAL 2
#define COLUMN_INTERVAL 4#define X_MAX 57
#define Y_MAX 29#define X_CENTER 29
#define Y_CENTER 15#endif

运行效果如下:

 


http://www.ppmy.cn/news/563052.html

相关文章

五子棋的设计与实现

术&#xff1a;Java等 摘要&#xff1a; 五子棋是一种两人对弈的纯策略型棋类游戏&#xff0c;非常容易上手&#xff0c;老少皆宜。为了更好的推广五子棋&#xff0c;研究简单的人工智能方式&#xff0c;运用Java开发五子棋游戏。主要包含了人机对战&#xff0c;棋盘初始化&…

五子棋-完美解决闪屏问题版-新增悔棋功能(C++实现)

在学C的时候&#xff0c;在做课设的时候做了一个五子棋课设&#xff0c;当时选这个就是觉得挺好玩的&#xff0c;想理解一下游戏是如何实现的&#xff0c;然后就入了这个坑。。。这个我没有用图形化界面来实现&#xff0c;完全是使用字符来实现。然后没有用图形化界面的最大的问…

C++、easyx组合的界面版五子棋(适合新手)

C、easyx组合的五子棋界面版&#xff08;适合新手&#xff09; 点击进入五子棋控制台版本 文章目录 C、easyx组合的五子棋界面版&#xff08;适合新手&#xff09;前言效果图一、游戏规则二、实现逻辑1.绘制棋盘2.落子2.1 鼠标坐标的获取2.2 绘制棋子 三、输赢判定算法四、其…

Windows编程 简易五子棋

简易五子棋&#xff0c;望指正 #include <windows.h> #include<commctrl.h> #define SIZE 20 UINT IDC_BUTTON1200; HWND hwnd; HPEN penbackCreatePen(PS_SOLID,1,RGB(0,0,0)); HPEN penback2CreatePen(PS_SOLID,1,RGB(255,255,255)); HBRUSH brushbackCreateSo…

课程设计-单机版五子棋游戏-Java

一. 项目简介&#xff1a; 五子棋是全国智力运动会竞技项目之一&#xff0c;是一种两人对弈的纯策略型棋类游戏。五子棋的玩法是&#xff1a;双方分别使用黑白两色的棋子&#xff0c;下在棋盘直线与横线的交叉点上&#xff0c;先形成五子连线者获胜。五子棋的棋具与围棋通用…

五子棋人机对弈代码——java版

算法是穷举递归法&#xff0c;只不过用java重新写了一遍 import java.awt.Color;import java.awt.Container;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseEvent;import java.awt.event.Mou…

c++五子棋人机版

五子棋游戏人机版&#xff1a; 电脑实现了阻挡对方连续的棋子 #include<iostream> #include<iomanip> using namespace std; #include<stdlib.h> #include<time.h> /*class PerPlayer { public:int m;int n;int person(); }; PerPlayer pp;class CompP…

五子棋程序设计实现技术文档

五子棋程序设计实现文档 文章目录 五子棋程序设计实现文档前言一、运行截图二、基本思路1.实现过程2.落子3.悔棋4.人机对战的实现1.机器人落子逻辑**2.改进胜负判断方法3.计算目标点的权值(白棋ai使用)4.计算目标点的权值(黑棋ai使用)** 4.扩展功能1.智能“提示”功能 前言 博…