当前位置:   article > 正文

C++项目1——五子棋游戏_c++五子棋

c++五子棋

参考视频

【C/C++】大一学年设计:五子棋(含GUI/网络/算法)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1V54y1D7pD?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click

目录

一、控制台版本

1.1 代码

1.2 实现效果

二、存储功能的实现

三、简化下棋的过程


一、控制台版本

1.1 代码

  1. #include <iostream>
  2. #include <stack>
  3. #include <fstream>
  4. #include <string>
  5. #define BLACK 1
  6. #define WHITE 2
  7. using namespace std;
  8. class ChessNode {
  9. public:
  10. ChessNode() {
  11. location_x = 0;
  12. location_y = 0;
  13. player_id = -1;
  14. }
  15. void SetLocation(int x, int y)
  16. {
  17. location_x = x;
  18. location_y = y;
  19. }
  20. void SetPlayerId(int id) {
  21. player_id = id;
  22. }
  23. void SetChessNode(int x, int y, int id) {
  24. location_x = x;
  25. location_y = y;
  26. player_id = id;
  27. }
  28. int GetLocationX()
  29. {
  30. return location_x;
  31. }
  32. int GetLocationY()
  33. {
  34. return location_y;
  35. }
  36. int GetPlayerId()
  37. {
  38. return player_id;
  39. }
  40. private:
  41. int location_x;
  42. int location_y;
  43. int player_id;
  44. };
  45. class CheckerBoard {
  46. public:
  47. CheckerBoard(int size)
  48. {
  49. this->Size = size;
  50. board = new ChessNode * [size + 2];
  51. for (int i = 0; i < size + 2; i++) {
  52. board[i] = new ChessNode[size + 2];
  53. for (int j = 0; j < size + 2; j++) {
  54. board[i][j].SetChessNode(i, j, -1);
  55. }
  56. }
  57. }
  58. ~CheckerBoard()
  59. {
  60. for (int i = 0; i < Size + 2; i++) {
  61. delete[] board[i];
  62. board[i] = nullptr;
  63. }
  64. delete board;
  65. board = nullptr;
  66. }
  67. void PlaceNode(int x, int y, int id)
  68. {
  69. if (board[x][y].GetPlayerId() != -1) {
  70. return;
  71. }
  72. if (x >= 1 && y >= 1 && x <= Size && y <= Size) {
  73. board[x][y].SetChessNode(x, y, id);
  74. AddStep(board[x][y]);
  75. }
  76. }
  77. void AddStep(ChessNode c) {
  78. route.push(c);
  79. }
  80. ChessNode ShowNode(int x, int y)
  81. {
  82. if (x >= 1 && y >= 1 && x <= Size && y <= Size) {
  83. return board[x][y];
  84. }
  85. return board[0][0];
  86. }
  87. ChessNode ShowRecentStep()
  88. {
  89. if (!route.empty()) {
  90. return route.top();
  91. }
  92. return board[0][0];
  93. }
  94. void RepentStep()
  95. {
  96. if (!route.empty()) {
  97. ChessNode tmp = route.top();
  98. board[tmp.GetLocationX()][tmp.GetLocationY()].SetChessNode(tmp.GetLocationX(), tmp.GetLocationY(), -1);
  99. route.pop();
  100. }
  101. }
  102. void Display()
  103. {
  104. cout << "\t";
  105. for (int i = 1; i <= Size; i++) {
  106. cout << i << "\t";
  107. }
  108. cout << endl;
  109. for (int i = 1; i <= Size; i++) {
  110. cout << i << "\t";
  111. for (int j = 1; j <= Size; j++) {
  112. if (board[i][j].GetPlayerId() == BLACK) {
  113. cout << "x\t";
  114. }
  115. else if (board[i][j].GetPlayerId() == WHITE) {
  116. cout << "o\t";
  117. }
  118. else {
  119. cout << "#\t";
  120. }
  121. }
  122. cout << endl;
  123. }
  124. }
  125. // 存储路径
  126. void StorageRoute() {
  127. while (!route.empty()) {
  128. route2.push(route.top());
  129. route.pop();
  130. }
  131. ofstream ofs;
  132. ofs.open("test.txt", ios::out);
  133. while (!route2.empty()) {
  134. ofs << char(route2.top().GetLocationX() + 48);
  135. ofs << " ";
  136. ofs << char(route2.top().GetLocationY() + 48);
  137. ofs << " ";
  138. ofs << char(route2.top().GetPlayerId() + 48);
  139. ofs << "\n";
  140. route2.pop();
  141. }
  142. ofs.close();
  143. }
  144. private:
  145. int Size;
  146. ChessNode** board;
  147. stack<ChessNode> route;
  148. stack<ChessNode> route2;
  149. };
  150. class Client {
  151. public:
  152. Client()
  153. {
  154. Size = 0;
  155. }
  156. void LoopRun()
  157. {
  158. int sig = -1;
  159. while (sig != 1) {
  160. cout << "\t\t五子棋游戏菜单" << endl;
  161. cout << "(1) 关闭客户端" << "\t\t" << "(2) 开始新的游戏" << endl;
  162. cout << "(3) 设置棋盘尺寸" << "\t" << "(4) 删除当前的游戏" << endl;
  163. cout << "(5) 进入当前的游戏" << "\t" << "(6) 查看游戏相关信息" << endl;
  164. cout << "(7) 当前游戏存档" << "\t" << "(8) 读取存档" << endl;
  165. cout << "输入数字并且回车: ";
  166. cin >> sig;
  167. cout << endl;
  168. if (sig == 2) {
  169. RunNewGame();
  170. }
  171. else if (sig == 3) {
  172. SetSize();
  173. }
  174. else if (sig == 4) {
  175. DeleteCheckerBoard_Max();
  176. }
  177. else if (sig == 5) {
  178. RunNowGame();
  179. }
  180. else if (sig == 6) {
  181. ShowGameInf();
  182. }
  183. else if (sig == 7) {
  184. StorageRouteMax();
  185. }
  186. else if (sig == 8) {
  187. ReadRoute();
  188. }
  189. cout << endl;
  190. cout << "-----------------------------------------------" << endl;
  191. }
  192. }
  193. bool JudgeSize()
  194. {
  195. if (Size == 0) {
  196. return true;
  197. }
  198. return false;
  199. }
  200. void DeleteCheckerBoard()
  201. {
  202. delete checkerboard;
  203. checkerboard = nullptr;
  204. }
  205. void DeleteCheckerBoard_Max()
  206. {
  207. StorageRouteMax();
  208. }
  209. void RunNewGame() {
  210. int x;
  211. int y;
  212. int id;
  213. DeleteCheckerBoard();
  214. if (JudgeSize()) {
  215. cout << "Size = 0,请设置棋盘尺寸" << endl;
  216. return;
  217. }
  218. checkerboard = new CheckerBoard(Size);
  219. checkerboard->Display();
  220. while (cin >> x >> y) {
  221. if (x > Size || y > Size || x < 1 || y < 1) {
  222. cout << "返回主菜单成功!" << endl;
  223. break;
  224. }
  225. if (checkerboard->ShowRecentStep().GetPlayerId() == -1) {
  226. id = BLACK;
  227. }
  228. else if (checkerboard->ShowRecentStep().GetPlayerId() == WHITE) {
  229. id = BLACK;
  230. }
  231. else if (checkerboard->ShowRecentStep().GetPlayerId() == BLACK) {
  232. id = WHITE;
  233. }
  234. else {
  235. cout << "程序出现了错误,请重新打开游戏" << endl;
  236. }
  237. checkerboard->PlaceNode(x, y, id);
  238. checkerboard->Display();
  239. if (JudgePlay()) {
  240. cout << "游戏胜利" << endl;
  241. }
  242. else {
  243. cout << "未出现赢家" << endl;
  244. }
  245. }
  246. }
  247. void RunNowGame() {
  248. int x;
  249. int y;
  250. int id;
  251. if (checkerboard == nullptr) {
  252. cout << "当前后台没有游戏在运行" << endl;
  253. return;
  254. }
  255. checkerboard->Display();
  256. while (cin >> x >> y >> id) {
  257. if (x > Size || y > Size || x < 1 || y < 1) {
  258. break;
  259. }
  260. checkerboard->PlaceNode(x, y, id);
  261. checkerboard->Display();
  262. }
  263. }
  264. void SetSize()
  265. {
  266. cout << "请输入需要的棋盘尺寸: ";
  267. cin >> Size;
  268. int x = 1;
  269. if (Size < 5) {
  270. while (x != 0) {
  271. if (Size < 5) {
  272. cout << " ->棋盘的大小太小为: " << Size << ",请重新设置" << endl;
  273. cout << " ->不进行设置,请输入0后回车" << endl;
  274. }
  275. else {
  276. break;
  277. }
  278. cout << "请重新输入需要的棋盘尺寸: ";
  279. cin >> Size;
  280. x = Size;
  281. }
  282. }
  283. cout << " ->棋盘的大小设置成功为: " << Size << endl;
  284. }
  285. void ShowGameInf()
  286. {
  287. cout << " 当前游戏尺寸: " << Size << endl;
  288. cout << " 游戏开发者: 胡安" << endl;
  289. cout << " 游戏版本: 1.0.0" << endl;
  290. cout << "当前是否有棋盘: ";
  291. if (checkerboard == nullptr) {
  292. cout << "no" << endl;
  293. }
  294. else {
  295. cout << "yes" << endl;
  296. }
  297. }
  298. // 用来判断是否是否五子连线的函数(深度优先搜索)
  299. bool JudgePlay()
  300. {
  301. ChessNode c;
  302. int id;
  303. int counter;
  304. for (int i = 5; i <= Size; i++) {
  305. for (int j = 5; j <= Size; j++) {
  306. c = checkerboard->ShowNode(i, j);
  307. id = c.GetPlayerId();
  308. if (id != 1 && id != 2) {
  309. continue;
  310. }
  311. counter = 1;
  312. while (counter < 5) {
  313. if (checkerboard->ShowNode(i - counter, j - counter).GetPlayerId() == id) {
  314. if (counter == 4) {
  315. return true;
  316. }
  317. }
  318. else {
  319. break;
  320. }
  321. counter++;
  322. }
  323. counter = 1;
  324. while (counter < 5) {
  325. if (checkerboard->ShowNode(i - counter, j).GetPlayerId() == id) {
  326. if (counter == 4) {
  327. return true;
  328. }
  329. }
  330. else {
  331. break;
  332. }
  333. counter++;
  334. }
  335. counter = 1;
  336. while (counter < 5) {
  337. if (checkerboard->ShowNode(i, j - counter).GetPlayerId() == id) {
  338. if (counter == 4) {
  339. return true;
  340. }
  341. }
  342. else {
  343. break;
  344. }
  345. counter++;
  346. }
  347. }
  348. }
  349. return false;
  350. }
  351. // 存储下棋路径的函数
  352. void StorageRouteMax() {
  353. if (checkerboard == nullptr) {
  354. cout << "没有棋盘,存储失败了" << endl;
  355. return;
  356. }
  357. checkerboard->StorageRoute();
  358. delete checkerboard;
  359. checkerboard = nullptr;
  360. cout << "棋盘路径已经被存储到文件中" << endl;
  361. }
  362. // 读取路径的函数
  363. void ReadRoute() {
  364. if (checkerboard != nullptr) {
  365. DeleteCheckerBoard();
  366. }
  367. Size = 10;
  368. checkerboard = new CheckerBoard(Size);
  369. ifstream ifs;
  370. ifs.open("test.txt", ios::in);
  371. if (!ifs.is_open())
  372. {
  373. cout << "test.txt文件,读取失败" << endl;
  374. return;
  375. }
  376. string xx;
  377. string yy;
  378. string dd;
  379. string buf;
  380. while (getline(ifs, buf))
  381. {
  382. xx = buf.substr(0, 1);
  383. int j = 0;
  384. string s = " ";
  385. for (int i = 0; i < size(buf); i++) {
  386. string s2 = buf.substr(i, 1);
  387. if (s.compare(s2) == 0)
  388. {
  389. j++;
  390. if (j == 1) {
  391. yy = buf.substr(i + 1, 1);
  392. }
  393. else if (j == 2) {
  394. dd = buf.substr(i + 1, 1);
  395. }
  396. }
  397. }
  398. int xxx = (int)(xx[0] - 48);
  399. int yyy = (int)(yy[0] - 48);
  400. int ddd = (int)(dd[0] - 48);
  401. checkerboard->PlaceNode(xxx, yyy, ddd);
  402. }
  403. ifs.close();
  404. cout << "棋盘路径已经被读取!如下图: " << endl;
  405. checkerboard->Display();
  406. }
  407. public:
  408. int Size;
  409. CheckerBoard* checkerboard;
  410. };
  411. int main(void)
  412. {
  413. Client* client = new Client;
  414. client->LoopRun();
  415. return 0;
  416. }

1.2 实现效果

 

二、存储功能的实现

这里弄好的功能丢掉了,就不重新再弄了,但是大致思路是下面这样的,下面的函数都是放到客户端类里面,然后使用 LoopRun 函数进行调用

  1. #include <iostream>
  2. #include <fstream>
  3. #include <stack>
  4. #include <string>
  5. using namespace std;
  6. class ChessNode {
  7. public:
  8. ChessNode(int x, int y, int id) {
  9. location_x = x;
  10. location_y = y;
  11. player_id = id;
  12. }
  13. public:
  14. int location_x;
  15. int location_y;
  16. int player_id;
  17. };
  18. class CheckerBoard {
  19. public:
  20. void AddStep(ChessNode c) {
  21. route.push(c);
  22. }
  23. public:
  24. stack<ChessNode> route;
  25. stack<ChessNode> route2;
  26. };
  27. int main(void)
  28. {
  29. CheckerBoard* b = new CheckerBoard;
  30. ChessNode n1(1, 1, 1);
  31. b->AddStep(n1);
  32. ChessNode n2(1, 2, 2);
  33. b->AddStep(n2);
  34. ChessNode n3(1, 3, 1);
  35. b->AddStep(n3);
  36. while (!b->route.empty()) {
  37. b->route2.push(b->route.top());
  38. b->route.pop();
  39. }
  40. ofstream ofs;
  41. ofs.open("test.txt", ios::out);
  42. while (!b->route2.empty()) {
  43. ofs << char(b->route2.top().location_x + 48);
  44. ofs << " ";
  45. ofs << char(b->route2.top().location_y + 48);
  46. ofs << " ";
  47. ofs << char(b->route2.top().player_id + 48);
  48. ofs << "\n";
  49. b->route2.pop();
  50. }
  51. ofs.close();
  52. // 2、创建流对象
  53. ifstream ifs;
  54. // 3、打开文件并判断文件是否打开成功
  55. ifs.open("test.txt", ios::in);
  56. if (!ifs.is_open())
  57. {
  58. cout << "文件打开失败" << endl;
  59. }
  60. string xx;
  61. string yy;
  62. string dd;
  63. // 4、读数据
  64. string buf;
  65. while (getline(ifs, buf))
  66. {
  67. // cout << buf << endl;
  68. xx = buf.substr(0, 1);
  69. int j = 0;
  70. string s = " ";
  71. for (int i = 0; i < size(buf); i++) {
  72. string s2 = buf.substr(i, 1);
  73. if (s.compare(s2) == 0)
  74. {
  75. j++;
  76. if (j == 1) {
  77. yy = buf.substr(i + 1, 1);
  78. }
  79. else if (j == 2) {
  80. dd = buf.substr(i + 1, 1);
  81. }
  82. }
  83. }
  84. int xxx = (int)(xx[0] - 48);
  85. int yyy = (int)(yy[0] - 48);
  86. int ddd = (int)(dd[0] - 48);
  87. ChessNode n(xxx, yyy, ddd);
  88. b->AddStep(n);
  89. }
  90. while (!b->route.empty()) {
  91. cout << b->route.top().location_x << " " << b->route.top().location_y << " " << b->route.top().player_id << endl;
  92. b->route.pop();
  93. }
  94. // 5、关闭文件
  95. ifs.close();
  96. return 0;
  97. }

三、简化下棋的过程

简化1:可以一人一手,每次读取栈顶元素对应的是黑棋或者白棋。如果是黑棋,下次就下白棋;如果是白棋,下次就下黑棋;如果没有棋,下次就下白棋

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/243712
推荐阅读
相关标签
  

闽ICP备14008679号