Linux下基于c++的简单五子棋小游戏
目录
一、五子棋项目介绍
1.游戏规则
2.五指棋界面显示
二、 VT100简介
1.VT100控制码
2.前景颜色(字体颜色)设置
3. 背景颜色设置
三、配置头文件
四、棋子对象设计
1.棋子的抽象类
2.白棋子类
3.黑棋子类
五、棋盘对象设计
六、棋手对象设计
1.棋手抽象类
2.黑棋手类
3.白棋手类
七、按键控制
1.光标类
2.按键键类
八、裁判对象设计
九、游戏类
十、主函数
一、五子棋项目介绍
1.游戏规则
五子棋是我国古代传统的黑白棋种之一,黑白双方依次落子,任意一方在棋盘上形成横向、纵向、斜向的连续相同颜色的五颗棋子的一方胜。
2.五指棋界面显示
此次项目将不使用任何图形库进行开发,所有显示内容都是以字符形式进行显示,为了让整个五子棋项目显示的界面更加漂亮,这里我们使用VT100终端控制码进行输出。效果如下
二、 VT100简介
VT100是一个终端类型定义,VT100控制码是用来在终端扩展显示的代码。主要用来在终端上任意坐标用不同的颜色显示字符。所有的控制符是\033或\e打头(即ESC的ASCII码)用输出字符语句来输出。可以在命令行用echo命令,或者在c程序中用printf来输出VT100的控制字符。
1.VT100控制码
2.前景颜色(字体颜色)设置
3. 背景颜色设置
注意:字体颜色可以和背景颜色一起设置,例如:\033[44;37m表示将背景颜色设置为蓝色,字体颜色设为白色。
注意:
1.在终端上面,坐标系的原点为左上角,水平向右为x轴正方向坐标垂直向下为y轴正方向坐标
2.在输出完内容结束的时候,一定要记得使用\033[0m关闭属性,否则会影响终端正常输出
三、配置头文件
#ifndef CONFIG_HPP
#define CONFIG_HPP#define BLACK 0x1 //黑色
#define WHITE 0x2 //白色
#define BLACK_COLOR "\033[37;40m[♀]\033[0m" //黑棋颜色配置
#define WHITE_COLOR "\033[47;30m[♀]\033[0m" //白棋颜色配置
#define LINE 21 //棋盘宽21
#define COLUMN 21 //棋盘长21
#define CHESS_BOARD_FILE "ChessBoard.txt" //棋盘文件配置
#define CHESS_BOARD_COLOR "\033[43;37m" //棋盘颜色配置
#define LINE_INTERVAL 2 //宽距
#define COLUMN_INTERVAL 4 //长距#define X_MAX 81 //最大x坐标
#define Y_MAX 41 //最大y坐标#define X_CENTER 41 //棋盘中心点的x坐标
#define Y_CENTER 21 //棋盘中心点的y坐标
#endif
四、棋子对象设计
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 //获取棋子的x坐标{return x;}int getY() const //获取棋子的y坐标{return y;}char getColor() const //获取棋子的颜色{return color;}
private:int x; //棋子的x坐标int y; //棋子的y坐标char color; //棋子的颜色
};
#endif
2.白棋子类
#ifndef WHITECHESS_HPP
#define WHITECHESS_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); //因为棋子我们设的棋子占3个坐标所以将光标移动到白棋子坐标前打印白棋子printf("\033[%d;%dH",getY(),getX()); //打印完后将光标重新定位到棋子的位置;}
};#endif
3.黑棋子类
#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);//因为棋子我们设的棋子占3个坐标所以将光标移动到黑棋子坐标前打印黑棋子printf("\033[%d;%dH",getY(),getX());}
};#endif
五、棋盘对象设计
因为棋盘只有一个说以我们这里采用单例的设计模式
#ifndef CHESSBOARD_HPP
#define CHESSBOARD_HPP#include "Chess.hpp"
#include <cstdio>class ChessBoard
{
public:static ChessBoard *getInstance() //实例化棋盘{return cb;}void show(){char buf[1024]={0};FILE *fp = fopen(CHESS_BOARD_FILE,"r");//打开棋盘文件if(fp == NULL){perror("Fall to fopen");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; //求出棋子在棋盘上的Y坐标int column = (chess->getX() -1) / COLUMN_INTERVAL;//求出棋子在棋盘上X坐标if(isValidPostion(line,column)){this->chess[line][column] =chess;//将棋子储存在指针数组中chess->show(); //打印该棋子curLine = line; //获取当前棋子在棋盘上的Y坐标用于判断胜利curColumn = column;//获取当前棋子在棋盘上X坐标用于判断胜利return true;}return false;}bool isValidColorChess(int line,int column,char color)//判断坐标的棋子是否存在且颜色是否等于color{if(line >= LINE || line < 0 || column >= COLUMN || column < 0){return false;}Chess *ch = chess[line][column];if(ch == NULL){return false;}if(ch->getColor()!= color){return false;}return true;}int getCurLine() const//获取截止于当前最后一颗棋子的y坐标{return curLine;}int getCurColumn() const//获取截止于当前最后一颗棋子的x坐标{return curColumn;}
private:ChessBoard(): curLine(-1),curColumn(-1)//将截止于当前最后一颗棋子的坐标设为(-1,-1)不存在{for (int i=0;i < LINE; ++i) //将存储棋子的指针数组初始化{for(int j=0;j < COLUMN; ++j){chess[i][j] = NULL;}}}~ChessBoard(){for (int i=0;i < LINE; ++i) //因为棋子是new出来的所以析构函数里要释放掉棋子的空间{for(int j=0;j < COLUMN; ++j){if(chess[i][j] != NULL){delete chess[i][j];chess[i][j] = NULL;}}}}static ChessBoard *cb;Chess *chess[LINE][COLUMN]; //一个棋子类型的指针数组,用来存储棋子。int curLine; //截止于当前最后一颗棋子的y坐标int curColumn; //截止于当前最后一颗棋子的x坐标
};
ChessBoard *ChessBoard::cb = new ChessBoard;
#endif
六、棋手对象设计
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 getNmae() 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空格键,用来控制落子
1.光标类
#ifndef CURSOR_HPP
#define CURSOR_HPP#include "Config.hpp"
#include <iostream>
#include <cstdio>using namespace std;class Cursor
{
public:Cursor() : x(X_CENTER),y(Y_CENTER){show();}void show() const //打印光标{printf("\033[%d;%dH",y,x);}void moveUp() //光标上移{if((y - LINE_INTERVAL) <= 0){return ;}y -= LINE_INTERVAL;show();}void moveDown() //光标下移{if((y + LINE_INTERVAL) > Y_MAX){return ;}y += LINE_INTERVAL;show();}void moveLeft() //光标左移{if((x - COLUMN_INTERVAL) <= 0){return ;}x -= COLUMN_INTERVAL;show();}void moveRight() //光标右移{if((x + COLUMN_INTERVAL) > X_MAX){return ;}x += COLUMN_INTERVAL;show();}int getX() const //获取光标x坐标{return x;}int getY() const //获取光标y坐标{return y;}void moveCenter() //将光标定位在棋盘中间{x = X_CENTER;y = Y_CENTER;show();}
private:int x; //光标的x坐标int y; //光标的y坐标
};
#endif
2.按键键类
#ifndef KEYHANDLE_HPP
#define KEYHANDLE_HPP#include "Cursor.hpp"
#include "Player.hpp"
#include <termios.h>
#include <unistd.h>class KeyHandle
{
public:KeyHandle(){system("stty -icanon") //关闭回车确认system("stty -echo") //关闭回显}~KeyHandle(){system("stty icanon") //开启回车确认system("stty echo") //开启回显}bool waitPlayerPlaceChess(Player *player) //按键操作{char key = 0;//用于接收按键的变量bool ret = false;while(1){key=getchar();//接收按键switch(key){case 'w':case 'W':cursor.moveUp();//当按键是w或W的时候光标上移break;case 's':case 'S':cursor.moveDown();//当按键是s或S的时候光标上移break;case 'a':case 'A':cursor.moveLeft();//当按键是a或A的时候光标上移break;case 'd':case 'D':cursor.moveRight();//当按键是d或D的时候光标上移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();//获取截止至当前最后一颗棋子的y坐标int curColumn = cb->getCurColumn(); //获取截止于当前最后一颗棋子的x坐标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;}}bool isDirectionWin(int line,int column,char color,int x,int y)//判断棋子胜利各个方向上的是否满足获胜条件,x=1,y=0横向方向,x=0,y=1竖直方向,x=1,y=1右斜方向,x=1,y=-1左斜方向{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)//判断是否有5课以上的子{return true;}return false;}
};
#endif
九、游戏类
#ifndef GOBANG_HPP
#define GOBANG_HPP
#include "WhitePlayer.hpp"
#include "BlackPlayer.hpp"
#include "ChessBoard.hpp"
#include "KeyHandle.hpp"
#include "Arbitration.hpp"class Gobang
{
public:Gobang(string BlackPlayerName,string WhitePlayerName)//传入黑棋手名和白棋手明{player[0] = new BlackPlayer(BlackPlayerName);//初始化黑棋手player[1] = new WhitePlayer(WhitePlayerName);//初始化白棋手}~Gobang(){delete player[0]; //释放黑棋手delete player[1]; //释放白棋手}void game(){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[43;H" << player[i]->getNmae() << "获得胜利!";//胜利则输出对应的棋手获得胜利break;}}if (isWin) //胜利则结束游戏{break;}}}private:Player *player[2]; //棋手类的指针数组,来存储两个棋手Arbitration arb; //裁判对象用来判断胜利KeyHandle keyHandle; //按键操作对象
};
#endif
十、主函数
#include "Gobang.hpp"
int main(int argc, const char *argv[])
{cout << "\033[2J";//清空终端ChessBoard::getInstance()->show();//打印棋盘string BlackPlayerName("张三");//黑棋手名为张三string WhitePlayerName("李四");//白棋手名为李四Gobang gobang(BlackPlayerName,WhitePlayerName);//游戏类对象gobang.game();//开始游戏cout << "\033[0m\033[45;0H";return 0;
}
Linux下基于c++的简单五子棋小游戏相关推荐
- php 设计五子棋游戏,基于js+canvas实现五子棋小游戏
本文实例为大家分享了js+canvas实现五子棋小游戏的具体代码,供大家参考,具体内容如下 效果展示: 源码展示: 五子棋 * { margin: 0; padding: 0; } body { ma ...
- C语言---简单五子棋小游戏
效果图如下: 设计思路: 棋盘设计为15×15格,初始状态光标在棋盘的中央,白棋先走,轮流落子,当一方连成五子或下满棋盘时,游戏结束(连成五子的一方获胜,下满棋盘为和棋).当游戏一方胜利后显示胜利信息 ...
- c语言编写五子棋小游戏ppt,C语言实现简单五子棋小游戏
五子棋简单功能实现,供大家参考,具体内容如下 游戏功能演示 代码如下: #include #include #include #include // 棋盘 char board[15][15]; // ...
- 超级简单五子棋小游戏(含代码)
五子棋简单功能实现 游戏功能演示 代码如下: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> ...
- 基于 Blazor 开发五子棋小游戏
今天是农历五月初五,端午节.在此,祝大家端午安康! 端午节是中华民族古老的传统节日之一.端午也称端五,端阳.此外,端午节还有许多别称,如:午日节.重五节.五月节.浴兰节.女儿节.天中节.地腊.诗人节. ...
- 基于深度学习的一款五子棋小游戏
今天分享一个基于深度学习而开发的AI小游戏 简单介绍 这一款基于深度学习的五子棋小游戏的界面是使用Unity开发的,而网络结构是使用keras搭建的. 环境 笔者的环境如下 操作系统 windows ...
- linux使用flask设计网站,linux下Flask框架搭建简单网页
开始安装FLASK需要创建一个虚拟环境,虚拟环境可以不干扰正在使用的系统环境,避免影响,并且也不需要完全的root权限,更加安全可靠. 搭建环境 Python3.4 进入到microblog目录下创建 ...
- 基于flask的五子棋小游戏
基于flask的五子棋小游戏 前言 首先说明一下,本人方向是java后端,只因老师布置了一个作业,要用flask来做一个五子棋,没办法被逼上梁山,程序不太美观,但是应付作业还是够了的. 废话不 ...
- 基于c++EGE图形库编写的五子棋小游戏
基于c++EGE图形库编写的五子棋小游戏 EGE图形库 新手推荐使用 EGE(Easy Graphics Engine),是windows下的简易绘图库,是一个类似BGI(graphics.h)的面向 ...
最新文章
- 20151210小问题2
- leetcode —— 206. 反转链表
- 7种主流案例,告诉你调度器架构设计通用法则(干货!)
- azure云数据库_Azure SQL数据库中的高级数据安全性–数据发现和分类
- 【思路题】【多校第一场】【1001.OO’s Sequence】
- 『不再迷茫 - 正则表达式』JS正则要点梳理 持续更新
- Javascript作用域、闭包原理以及性能问题
- iOS10 拍照崩溃问题
- Padavan启用ipv6并允许公网访问内网
- 微信小程序往数组中添加元素对象
- ag-gird 多层表头文字居中
- 【易社投研资讯】销量一日暴增数倍,上海加码外牌限行,新能源车换购需求迎新一轮释放,哪些公司或将受益?
- 关于ubuntu系统的scp服务提示Permission denied
- Python批量下载无版权图片
- 《Primes is in P》学习笔记
- $.ajax传递数组的两种方式
- shell命令之cd切换目录
- 常用数据挖掘工具简介
- JS和CSS的引入/写入位置应该放在哪里?
- AC/DC、DC/DC转换器知识
热门文章
- Python+Selenium自动化测试详细教程
- Unity标准开发实例——Shuriken粒子系统06
- 资料分享:PyTorch中文版官方教程来啦(附下载)
- HTTPS报文分析(Wireshark)
- 「小技巧」如何让IGV更快的加载GTF和GFF注释文件
- 中小河流水文监测系统、水文遥测系统、水文监测
- crontab定时时钟同步,输出重定向 1 * * * * /usr/sbin/ntpdate x.x.x.x > /dev/null 2>1
- OCZ Colossus 3.5寸固态硬盘正式发布 最大1TB
- 程序员七夕情人节表白代码
- 头歌Educoder云计算与大数据——实验三 分布式文件系统HDFS