控制台上的黑白棋
来源:互联网 发布:网络获客 编辑:程序博客网 时间:2024/04/20 01:44
关于黑白棋,点击打开链接
这篇博客,我介绍一下用c++写一个黑白棋游戏的时候,需要注意的几个难点。
我的这个代码只支持单机双人对战,所以双方必须在一起运行这个程序,交替利用键盘输入下棋的位置。
支持人机对战的代码,在我的另外一篇博客中:点击打开链接
在那篇博客中还加入了一点新功能,而且指出了本文中代码的bug并且改正过来了。
游戏开始界面:
功能:提示双方棋子数,提示该睡下棋,提示并在棋盘中显示哪些位置可以下棋
容错性:输入的列不区分大小写,如果输入错误则重新输入
缺陷:不支持悔棋
开发黑白棋游戏要注意三种情况:
(1)如果甲方下棋之后乙方无法下棋,则甲方可以继续下棋。
也就是说,有的时候一方可以连续下很多步。
我的测试:
白方下完4A之后,还是该白方下:
测试通过
(2)如果棋盘还没下满,但是双方都无法下子,那么游戏结束
我的测试:
白方下8E之后游戏结束:
测试通过
(3)如果一方的棋子全部被吃掉,则游戏结束
我的测试:
黑方下1G之后:
测试通过
所有的代码都在一个cpp文件中,只有120行
完整代码:
#include<iostream>#include <stdlib.h> using namespace std;int list[8][8] = { 0 }; //棋盘状态,1是黑子,2是白子,0是空的int p=1;//现在该谁下,1是黑方,2是白方const int dr[8] = { 0, 0, 1, 1, 1, -1, -1, -1 },dc[8] = { 1, -1, 0, 1, -1, 0, 1, -1 };//8个方向向量bool playOK(int r, int c, int dr, int dc)//判断某个格子的某个方向能否下子{if (list[r][c] != 0)return false;int tr = r, tc = c; //tr和tc分别表示该点通过行和列往特定方向移动后的坐标while (tr + dr >= 0 && tr + dr < 8 && tc + dc >= 0 && tc + dc < 8 && list[tr + dr][tc + dc] == 3 - p){//循环遍历,未到达边界或者右边的棋子是对方的则循环继续,否则循环退出tr += dr, tc += dc; //移动坐标}//若使循环退出的那一格里,是对方的棋子,则(r,c)可落子,否则不可落子if (tr == r && tc == c)return false;//难点,这一句不可少if (tr + dr >= 0 && tr + dr < 8 && tc + dc >= 0 && tc + dc < 8 && list[tr + dr][tc + dc] == p)return true;return false;}bool OK(int r, int c)//判断某个格子能否下子{if (list[r][c])return false;for (int i = 0; i < 8; i++) //只要一个方向满足可以下的条件,就可以下if (playOK(r, c, dr[i], dc[i]))return true; //调用return false;}int num(int k) //统计棋子数目,1是黑子,2是白子{int s = 0;for (int i = 0; i < 8; i++)for (int j = 0; j < 8; j++)if (list[i][j] == k)s++;return s;}void display() //显示棋盘和棋子{system("cls");for (int i = 0; i < 8; i++){if (!i){cout << " ";for (int j = 0; j < 8; j++)cout << char('A' + j) << " ";cout << endl;}cout << i + 1 << " ";for (int j = 0; j < 8; j++){if (list[i][j] == 2)cout << "○";else if (list[i][j] == 1)cout << "●";else if (OK(i, j))cout <<"?";elsecout << " ."; //调用cout << " ";}cout << endl<<endl;}cout << "黑方:" << num(1) << " 白方:" << num(2)<<" 轮到"; //调用if (p == 1)cout << "黑方下\n"; else cout << "白方下\n";cout << "候选项:";for (int i = 0; i < 8; i++)for (int j = 0; j < 8; j++)if (OK(i, j)) //调用cout << " " << char('1' + i) << char('A' + j);}void init() //初始化{list[3][3] = list[4][4] = 2;list[3][4] = list[4][3] = 1;display(); //调用}bool end_() //判断游戏是否结束{for (int i = 0; i < 8; i++)for (int j = 0; j < 8; j++)if (OK(i, j))return false; //调用p = 3 - p;//改变p的2个地方之一display(); //难点,这一句不可少 //调用for (int i = 0; i < 8; i++)for (int j = 0; j < 8; j++)if (OK(i, j))return false; //调用cout << "\n游戏结束\n";if (num(1) < num(2))cout << "白方胜利";else if (num(1)>num(2))cout << "黑方胜利";else cout << "平局";return true;}void turn(int tr, int tc, int dr, int dc) //吃子函数play()的一个方向{if (!playOK(tr, tc, dr, dc))return; //难点,这一句不可少 //调用while (tr + dr >= 0 && tr + dr < 8 && tc + dc >= 0 && tc + dc < 8 && list[tr + dr][tc + dc] == 3 - p){list[tr + dr][tc + dc] = p; //在该处换掉棋子的颜色tr += dr, tc += dc;}}void play()//落下一个子{cout << "\n输入行(1-8)和列(A-H)" << endl;char x, y;cin >> x >> y;int r = x - '1', c = y - 'a';if (y>'A' && y < 'Z')c = y - 'A';if (!OK(r, c)) //调用{cout << "ERROR!";return;}for (int i = 0; i < 8; i++)turn(r, c, dr[i], dc[i]);list[r][c] = p;p = 3 - p;//改变p的2个地方之一display();//调用}int main(){system("color f0");//白底黑字init();while (!end_())play();system("pause>nul");return 0;}
0 0
- 控制台上的黑白棋
- 我的黑白棋
- 黑白棋的问题
- 黑白棋的落子
- 基于VC++的黑白棋
- 【9702】黑白棋的移动
- 黑白棋的基础程序
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 全排列方法二(康托展开)
- php内存管理之内存分配
- Layer弹出层
- js监测关闭当前页面、关闭浏览器和取消监测
- 分层开发
- 控制台上的黑白棋
- mt4 部分内置函数
- 玲珑杯round11-C:Niro has a bicycle
- 团体程序设计天梯赛-练习集 L2-003. 月饼 贪心 解题报告
- 2017_NJCTF_reverse_echo_server
- 对于thinkphp唯一索引重复时出错的解决办法
- 切换标签离开当前页面时改变title提示
- 1207: [HNOI2004]打鼹鼠
- HDOJ 5675-ztr loves math【数学】