通过在控制台输出字符来实现一个中国象棋小游戏实际上是很简单的,也非常有趣。游戏是人人对战模式,实现后的效果如下:

代码思路很简单,就是创建好各个游戏对象的类,然后用一个管理类来实现游戏规则就可以了。但是这里我想说因为中国象棋的棋子种类和数量是固定的,可以视为稳定的代码(不会再扩展),继而整个程序都是稳定的,这里我认为就不需要使用多态或策略模式,使用多态是为了隔离程序中的稳定代码和变化代码,当代码全部为稳定时就不需要用,否则反而会变的麻烦。下面直接上代码:

Point类

#ifndef POINT_H
#define POINT_H
#include<iostream>
using namespace std;
//坐标类
class Point
{
public:Point(int x = 0, int y = 0) : m_x(x), m_y(y) {};~Point() {};Point& operator=(const Point &p){m_x = p.m_x;m_y = p.m_y;return *this;}bool operator==(const Point &p)const {if (m_x == p.m_x&&m_y == p.m_y)return true;else return false;}void Set(const int x, const int y) { m_x = x; m_y = y; }void SetX(const int x) { m_x = x; }void SetY(const int y) { m_y = y; }int GetX() const { return m_x; }int GetY()const { return m_y; }private:int m_x;int m_y;
};
#endif

Chess类

#ifndef CHESS_H
#define CHESS_H#include"Point.h"enum ChessCamp//棋子阵营(红绿两方)
{RED,GREEN
};enum ChessType//棋子种类
{MA,SHUAI,CHE,PAO,SHI,BING,XIANG
};class Chess
{
public:Chess(ChessType type, ChessCamp camp, Point position) :m_type(type),m_camp(camp),m_position(position){}~Chess(){}Point GetPosition()const { return m_position; }void SetPosition(const Point& newposition) { m_position = newposition; }ChessType GetType()const { return m_type; }ChessCamp GetCamp()const { return m_camp; }private:ChessType m_type;ChessCamp m_camp;Point m_position;};#endif // !CHESS_H

ChessBoard(棋盘)类

#ifndef CHESSBOARD_H
#define CHESSBOARD_H#include<Windows.h>
#include"chess.h"class ChessBoard
{
public:bool m_isend;ChessBoard();~ChessBoard() {}void PrintBoard();void ChangeChess(const Point& spos, const Point& tpos);Chess* GetChess(const Point& pos)const{return m_allchess[pos.GetX()][pos.GetY()];}void Clear() {for (int i = 0; i < 10; i++){for (int j = 0; j < 9; j++){if (m_allchess[i][j] != nullptr) {delete m_allchess[i][j];m_allchess[i][j] = nullptr;}}}}private:Chess* m_allchess[10][9];
};
#endif 
#include"ChessBoard.h"ChessBoard::ChessBoard()
{m_isend = false;for (int i = 0; i < 10; i++){for (int j = 0; j < 9; j++)m_allchess[i][j] = nullptr;}//四个车m_allchess[0][0] = new Chess(CHE, GREEN, Point(0, 0));m_allchess[0][8] = new Chess(CHE, GREEN, Point(0, 8));m_allchess[9][0] = new Chess(CHE, RED, Point(9, 0));m_allchess[9][8] = new Chess(CHE, RED, Point(9, 8));//四个马m_allchess[0][1] = new Chess(MA, GREEN, Point(0, 1));m_allchess[0][7] = new Chess(MA, GREEN, Point(0, 7));m_allchess[9][1] = new Chess(MA, RED, Point(9, 1));m_allchess[9][7] = new Chess(MA, RED, Point(9, 7));//四个炮m_allchess[2][1] = new Chess(PAO, GREEN, Point(2, 1));m_allchess[2][7] = new Chess(PAO, GREEN, Point(2, 7));m_allchess[7][1] = new Chess(PAO, RED, Point(7, 1));m_allchess[7][7] = new Chess(PAO, RED, Point(7, 7));//两个帅m_allchess[0][4] = new Chess(SHUAI, GREEN, Point(0, 4));m_allchess[9][4] = new Chess(SHUAI, RED, Point(9, 4));//象m_allchess[0][2] = new Chess(XIANG, GREEN, Point(0, 2));m_allchess[0][6] = new Chess(XIANG, GREEN, Point(0, 6));m_allchess[9][2] = new Chess(XIANG, RED, Point(9, 2));m_allchess[9][6] = new Chess(XIANG, RED, Point(9, 6));//士m_allchess[0][3] = new Chess(SHI, GREEN, Point(0, 3));m_allchess[0][5] = new Chess(SHI, GREEN, Point(0, 5));m_allchess[9][3] = new Chess(SHI, RED, Point(9, 3));m_allchess[9][5] = new Chess(SHI, RED, Point(9, 5));//兵for (int i = 0; i <= 8; i += 2)m_allchess[3][i] = new Chess(BING, GREEN, Point(3, i));for (int i = 0; i <= 8; i += 2)m_allchess[6][i] = new Chess(BING, RED, Point(6, i));}void ChessBoard::PrintBoard()
{for (int i = 0; i < 10; i++){//输出上排坐标或河界if (i == 0 || i == 5){cout << "  ";for (int j = 0; j < 9; j++){if (i == 0)cout << j << " ";//上排坐标if (i == 5)cout << "一";//河界}cout << endl;}for (int j = 0; j < 9; j++){if (j == 0) cout << i << " ";//左排坐标if (m_allchess[i][j] == nullptr){if (i == 8 && j == 4 || i == 1 && j == 4)cout << "米";//九宫格else cout << "十";//没有棋子}else{//根据阵营设置颜色if (m_allchess[i][j]->GetCamp() == GREEN)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);if (m_allchess[i][j]->GetCamp() == RED)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);if (m_allchess[i][j]->GetType() == CHE)cout << "车";if (m_allchess[i][j]->GetType() == MA)cout << "马";if (m_allchess[i][j]->GetType() == SHUAI)cout << "帅";if (m_allchess[i][j]->GetType() == PAO)cout << "炮";if (m_allchess[i][j]->GetType() == XIANG)cout << "象";if (m_allchess[i][j]->GetType() == SHI)cout << "士";if (m_allchess[i][j]->GetType() == BING)cout << "兵";//恢复默认颜色(白色)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);}}cout << endl;}
}void ChessBoard::ChangeChess(const Point & spos, const Point & tpos)
{if (m_allchess[tpos.GetX()][tpos.GetY()] != nullptr){//如果把帅吃了,游戏结束if (m_allchess[tpos.GetX()][tpos.GetY()]->GetType() == SHUAI)m_isend = true;delete m_allchess[tpos.GetX()][tpos.GetY()];}m_allchess[tpos.GetX()][tpos.GetY()] = m_allchess[spos.GetX()][spos.GetY()];m_allchess[spos.GetX()][spos.GetY()] = nullptr;
}

GameManager类,控制核心玩法

#ifndef GameManager_H
#define GameManager_H
#include"ChessBoard.h"class GameManager
{
public:~GameManager() { m_chessboard.Clear(); }//严格意义上说单例模式析构应该为私有 但有时编译会出问题bool Move(const Point& startpos,const Point& targetpos);void ChangeCamp() {if (m_nowcamp == RED)m_nowcamp = GREEN;else m_nowcamp = RED;}ChessCamp GetCamp()const{ return m_nowcamp; }void Print(){  m_chessboard.PrintBoard();}bool IsEnd()const { return m_chessboard.m_isend; }static GameManager*Instance();//单例模式
private:ChessBoard m_chessboard;ChessCamp m_nowcamp;//单例模式 构造函数为私有GameManager(){m_nowcamp = RED;m_chessboard= ChessBoard();}bool JudgeMoveLegel(const Point& startpos,const Point& targetpos);//判断移动是否符合棋盘规定bool JudgeMoveChessRule(const Point& startpos,const Point& targetpos);//判断移动是否符合棋子的规则int JudgeChessBetween(const Point& startpos,const Point& targetpos);//返回两点之间棋子的数目bool JudgeCrossRiver(const Point&pos);//判断棋子是否过河
};
#endif // !GameManager_H
#include"GameManager.h"//单例模式
GameManager * GameManager::Instance()
{static GameManager instance;return &instance;
}bool GameManager::JudgeMoveLegel(const Point& startpos, const Point& targetpos)
{//若目标位置和起始位置相同,错误if (startpos == targetpos)return false;//如果起始选定位置没有棋子,或棋子阵营与当前玩家不一致,错误if (m_chessboard.GetChess(startpos) == nullptr ||m_chessboard.GetChess(startpos)->GetCamp() != m_nowcamp)return false;//如果目标位置越界,错误if (targetpos.GetX() < 0 || targetpos.GetX() > 9 ||targetpos.GetY() < 0 || targetpos.GetY() > 8)return false;//如果目标和起始是一个阵营,错误if (m_chessboard.GetChess(targetpos)!=nullptr&&m_chessboard.GetChess(startpos)->GetCamp() == m_chessboard.GetChess(targetpos)->GetCamp())return false;return true;
}bool GameManager::JudgeMoveChessRule(const Point& startpos, const Point& targetpos)
{//若是车if (m_chessboard.GetChess(startpos)->GetType() == CHE){if (startpos.GetX() == targetpos.GetX() || startpos.GetY() == targetpos.GetY())//目标和起始在一条直线上if (!JudgeChessBetween(startpos, targetpos))//中间没有棋子return true;}//若是炮else if (m_chessboard.GetChess(startpos)->GetType() == PAO){if (m_chessboard.GetChess(targetpos) == nullptr)//若不用吃子{if (startpos.GetX() == targetpos.GetX() || startpos.GetY() == targetpos.GetY())if (!JudgeChessBetween(startpos, targetpos))return true;}else //若要吃子{if (startpos.GetX() == targetpos.GetX() || startpos.GetY() == targetpos.GetY())if (JudgeChessBetween(startpos, targetpos) == 1)return true;}}//若是马else if (m_chessboard.GetChess(startpos)->GetType() == MA){int  tempx = targetpos.GetX() - startpos.GetX();int tempy = targetpos.GetY() - startpos.GetY();//若形成日字,并且没有憋马腿if (tempx*tempx + tempy*tempy == 5 &&m_chessboard.GetChess(Point(startpos.GetX() + tempx / 2, startpos.GetY() + tempy / 2)) == nullptr)return true;}//若是士else if (m_chessboard.GetChess(startpos)->GetType() == SHI){int tempx = targetpos.GetX() - startpos.GetX();int tempy = targetpos.GetY() - startpos.GetY();if ((tempx*tempx + tempy*tempy == 2) && (targetpos.GetY()<= 5) && (targetpos.GetY() >=3) && (targetpos.GetX() >= 7 || targetpos.GetX() <= 2))return true;}//若是帅else if (m_chessboard.GetChess(startpos)->GetType() == SHUAI){int tempx = targetpos.GetX() - startpos.GetX();int tempy = targetpos.GetY() - startpos.GetY();if ((tempx*tempx + tempy*tempy == 1) && (targetpos.GetY() <= 5) && (targetpos.GetY() >= 3) && (targetpos.GetX() >= 7 || targetpos.GetX() <= 2))return true;}//若是象else if (m_chessboard.GetChess(startpos)->GetType() == XIANG){int tempx = targetpos.GetX() - startpos.GetX();int tempy = targetpos.GetY() - startpos.GetY();//若形成田字,并且没有踩象眼if (tempx*tempx + tempy*tempy == 8 &&m_chessboard.GetChess(Point(startpos.GetX() + tempx / 2, startpos.GetY() + tempy / 2)) == nullptr)//没有将要过河if(m_chessboard.GetChess(startpos)->GetCamp() == RED&&targetpos.GetX() >4||m_chessboard.GetChess(startpos)->GetCamp() == GREEN&&targetpos.GetX() <5)return true;}//若是兵else if (m_chessboard.GetChess(startpos)->GetType() == BING){int    tempx = targetpos.GetX() - startpos.GetX();int tempy = targetpos.GetY() - startpos.GetY();if (tempx*tempx + tempy*tempy == 1)//走了一步{if (JudgeCrossRiver((startpos)))//若过河了return true;else //还没过河{//若是往前走if (m_chessboard.GetChess(startpos)->GetCamp() == RED&&tempx == -1 ||m_chessboard.GetChess(startpos)->GetCamp() == GREEN&&tempx == 1)return true;}}}return false;
}bool GameManager::Move(const Point& startpos, const Point& targetpos)
{if (JudgeMoveLegel(startpos, targetpos) && JudgeMoveChessRule(startpos, targetpos)){m_chessboard.ChangeChess(startpos, targetpos);return true;}else return false;
}int GameManager::JudgeChessBetween(const Point& startpos, const Point& targetpos)
{int num = 0;//若两点x轴相等if (startpos.GetX() == targetpos.GetX()){int x = startpos.GetX();if (startpos.GetY() > targetpos.GetY()){for (int i = targetpos.GetY() + 1; i < startpos.GetY(); i++){if (m_chessboard.GetChess(Point(x, i)) != nullptr)num++;}}else{for (int i = startpos.GetY() + 1; i < targetpos.GetY(); i++){if (m_chessboard.GetChess(Point(x, i)) != nullptr)num++;}}}//若两点y轴相等else if (startpos.GetY() == targetpos.GetY()){int y = startpos.GetY();if (startpos.GetX() > targetpos.GetX()){for (int i = targetpos.GetX() + 1; i < startpos.GetX(); i++){if (m_chessboard.GetChess(Point(i, y)) != nullptr)num++;}}else{for (int i = startpos.GetX() + 1; i < targetpos.GetX(); i++){if (m_chessboard.GetChess(Point(i, y)) != nullptr)num++;}}}return num;
}bool GameManager::JudgeCrossRiver(const Point & pos)
{if (m_chessboard.GetChess(pos)->GetCamp() == RED&&pos.GetX() < 5)return true;if (m_chessboard.GetChess(pos)->GetCamp() == GREEN&&pos.GetX() > 4)return true;return false;
}

main函数

#include"GameManager.h"
#define mymanager GameManager::Instance()int main()
{cout << "    中国象棋" <<  endl;cout << "****************" << endl << endl;cout << "  1.开始游戏" << endl << endl;cout << "    2.退出" << endl << endl;cout << "****************" << endl << endl;cout << "请输入选项:" << endl;int c(0);cin >> c;if (c == 1){mymanager->Print();while (1){if (mymanager->GetCamp() == RED)cout << "现在轮到红方" << endl;else cout << "现在轮到绿方" << endl;cout << "输入起始点和目标点:";int sx, sy, tx, ty;cin >> sx >> sy >> tx >> ty;if (mymanager->Move(Point(sx, sy), Point(tx, ty))){mymanager->Print();if (mymanager->IsEnd()){cout << "游戏结束!获胜方为:";if (mymanager->GetCamp() == RED)cout << "红方" << endl;else cout << "绿方" << endl;break;}mymanager->ChangeCamp();}else cout << "输入违法,请重新输入" << endl;}}if (c == 2)exit(0);cin.get();return 0;
}

谢谢观看:)

C++练习实例———中国象棋小游戏相关推荐

  1. 用html+css+js实现中国象棋小游戏开发项目

    用html+css+js中国象棋小游戏开发项目 最近刚学习完JS的相关课程,跟着老师做了两个小游戏项目,就已经抑制不住内心的小激动,想着要迫不及待的着手准备做一个网页小游戏--中国象棋 由于从小就比较 ...

  2. 网络中国象棋小游戏的实现

    开学了,去图书馆借了几本书,没有找到想要的C++网络编程,倒是找到了几本LINUX的书,以及一本<Visual C#经典游戏编程开发>.翻了翻发现里面有个可以联网对弈的中国象棋游戏,一直写 ...

  3. linux下中国象棋小游戏(粗糙版)

    第一篇博客,就把自己以前写的一个中国象棋的小游戏放上来.主要是寒假在家没事干,所以写个游戏打发时间.不过最后没起到作用,因为写了差不多了就不想写了,所以只花了两天的时间.最后寒假大部分时间还是在酱油. ...

  4. 初学 Qt 之从零开始的中国象棋小游戏(一)

    最近对 Qt 这个跨平台 C++ 图形应用程序框架很感兴趣,闲暇时间多学了一下,收获很多,也踩了不少坑,在这里记录一下,分享心得. Qt 的安装 安装 Qt 并不麻烦,就是网速有点慢.推荐使用国内镜像 ...

  5. Java实现单人版中国象棋小游戏的实现,具有时间设置,认输,悔棋,求和,自动判断输赢功能。

    说明:这个小游戏是小马猿用了一个多月,自己一边学习一边码出来的,接近3000行的代码,所有算法都是自己不断摸索得到的,作为小马猿第一个游戏成品,现在分享给各位小伙伴.如果伙伴们在使用这份代码发现有什么 ...

  6. 不愧是大厂牛人!用Java实现象棋小游戏(附超详细,超长究极无敌代码)

    本文实例为大家分享了java实现象棋小游戏的具体代码,供大家参考,具体内容如下 用Eclipse编写 java环境1.8jdk 代码如下 package xiangqi象棋; /***中国象棋Java ...

  7. 如何用Python开发象棋小游戏

    如何用Python开发象棋小游戏,源代码版本 人生苦短,我用Python! hello 大家好!我是Mark,一个姓马名克的中国人. 最近,我在CSDN当中看到了这一篇文章: 传送门 他详细地讲解了如 ...

  8. Pathon开发象棋小游戏

    因为参加了python学习竞赛,自学了python的一些基础语法,做了一个中国象棋的小游戏,作为参赛项目,开始之前专门在电脑上下载了一个象棋小游戏,研究了一下象棋规则以及一些按键,接下来就把这个象棋小 ...

  9. java象棋游戏用户特点_基于Java Swing的《中国象棋》游戏的设计与实现

    60 开发经验 3基金项目: 江西省自然科学基金资助项目(编号: 0411046); 江西省高性能计算技术重点实验室资助基金项目(No. JXHC20052003) ). 基于 Java Swing ...

最新文章

  1. 开源(Open Source)那些事儿 (一)
  2. java层 android_Android开发实践:Java层与Jni层的数组传递
  3. 【SSL】调用HTTPS://服务遇到错误:unable to find valid certification path to requested target
  4. 接口测试学习——jmeter分布式压测
  5. 串口与modem流量控制大全(2)
  6. oracle11g创建表空间大文件,oracle11g创建表空间 sql语法
  7. 福大计算机课程表,教学文件 - 福州大学电气工程与自动化学院
  8. 《算法竞赛进阶指南》 0x30 数学知识 数论 题目
  9. ideajdk升级_JDK升级为13
  10. T-SQL: Batches
  11. 实战React:ToDoList
  12. log4j日志级别配置详解
  13. 缩短bch码能用matlab,BCH码编译码matlab仿真.doc
  14. Android开发 入门篇(一)
  15. c语言一维高斯滤波器,高斯滤波简介,高斯滤波性质及应用
  16. 军事指挥系统时间同步解决方案
  17. matlab在常微分方程的应用,Matlab在常微分方程教学中的应用
  18. GitHub+JenKins集成Python自动化测试脚本
  19. Android OS历史版本
  20. 天蝎项目整机柜服务器技术规格,天蝎整机柜服务器技术规范2.5.doc

热门文章

  1. Effective C++ 3nd笔记——资源管理
  2. JavaScript有哪些内置对象
  3. android获取权限
  4. JAVA使用PGP对文件签名+验签
  5. 我没想到,做IT还有感动众生的机会
  6. 修改ntp服务器rac,RAC时间同步的两种方法【NTP时间同步服务器】
  7. HTML学习(二):关于几种简单的标签(下)
  8. Unity3D 优化总篇
  9. oracle一般监听配置文件,Oracle监听配置讲解
  10. 教育培训课件PPT模板