简单的黑白棋游戏

简单的黑白棋游戏

/*--------
--------
--------
---WB---
---BW---
--------
--------
--------
*/ //tab1.txt
/--------
--------
--------
---WB---
---BW---
----W---
--------
--------

*/ //tab2.txt
1
#include<iostream> 2 #include<cstdio> 3 #include<fstream> 4 #include<string> 5 #include<cstring> 6 using namespace std; 7 8 const int maxn = 16; 9 char tab[maxn][maxn]; //棋盘的最大大小--可以重新设置 ↖ ↑↗ 10 const int dir[8][2] = {-1,0, 1,0, 0,-1, 0,1, -1,-1, -1,1, 1,-1, 1,1}; //代表八个方向←㊣ → 11 // ↙↓↘ 12 char now(const char beg, const bool flag); //将当前棋子转换成 应该 输入的棋子 13 bool legal(const int r, const int c, const char x); //检测当前要放置的棋子是否合法 14 void L(char x); //显示所有合法放置的位置 15 void out_cnt(); //输出放置棋子后,黑白棋子各自的数量 16 void Mrc(const int r, const int c, const char x); //指令棋子和位置-放置--并输出操作后黑白棋子各自数量 17 void print(); //打印当前棋盘 18 19 char now(const char beg, const bool flag) 20 { 21 if (beg == 'B') { 22 if (flag) return 'B'; //利用flag--为true,照常返回该字符 23 return 'W'; //为false, 转换成合法棋子返回 24 } 25 if (beg == 'W') { 26 if (flag) return 'W'; 27 return 'B'; 28 } 29 } 30 31 bool legal(const int r, const int c, const char x) //合法性检测 32 { 33 char y; 34 if (x == 'B') y = 'W'; 35 if (x == 'W') y = 'B'; 36 if (tab[r][c] != '-') return false; //放的位置已经被占 37 for (int i = 0; i < 8; i++) { //遍历一个位置的8个方向 38 int rr = r, cc = c, dr = dir[i][0], dc = dir[i][1]; //rr,cc为要放置的位置, dr,dc组成一个方向 39 if (tab[rr+dr][cc+dc] == y) { //保证至少相同颜色棋子之间夹着一个不同颜色的棋子 40 while (true) { 41 rr += dr; cc += dc; //在一个方向的一条直线上遍历搜索 42 if (tab[rr][cc] == x) //遇到一个和自己一样颜色的棋子, 43 return true; //说明r,c这个位置可以放置棋子 44 if (tab[rr][cc] == '-' || tab[rr][cc] == 0) //棋盘越界或遇到空位置 45 break; 46 } 47 } 48 } 49 return false; //都没有找到合法位置放置,显然一个false 50 } 51 52 void L(char x) //显示所有合法放置位置 53 { 54 int flag = 0; //算出合法位置数目,为零则另外输出 NO legal move. 55 for (int i = 1; i <= 8; i++) //遍历所有合法位置 56 { 57 for (int j = 1; j <= 8; j++) { 58 if (legal(i, j, x)) { 59 if (flag++) //第一个位置前面不要输出空格 60 printf(" (%d,%d)", i, j); 61 else 62 printf("(%d,%d)", i, j); 63 } 64 } 65 } 66 if (!flag) 67 { 68 printf("No legal move.\n"); 69 cout << "Game over." << endl; 70 int wcnt = 0, bcnt = 0; 71 for (int i = 1; i <= 8; i++) 72 { 73 for (int j = 1; j <= 8; j++) 74 { 75 if (tab[i][j] == 'W') wcnt++; 76 if (tab[i][j] == 'B') bcnt++; 77 } 78 } 79 if(wcnt > bcnt) 80 cout << "白子胜!" << endl; 81 else if (wcnt < bcnt) 82 cout << "黑子胜! " << endl; 83 else 84 cout << "平局 !" << endl; 85 } 86 else 87 printf("\n"); 88 } 89 90 void out_cnt() 91 { 92 int wcnt = 0, bcnt = 0; 93 for (int i = 1; i <= 8; i++) 94 { 95 for (int j = 1; j <= 8; j++) 96 { 97 if (tab[i][j] == 'W') wcnt++; 98 if (tab[i][j] == 'B') bcnt++; 99 } 100 } 101 printf("Black - %2d White - %2d\n", bcnt, wcnt); 102 } 103 104 void Mrc(const int r, const int c, const char x) 105 { 106 char y; 107 if (x == 'W') y = 'B'; 108 if (x == 'B') y = 'W'; 109 tab[r][c] = x; //已结检查过放置是否合法--接下来主要任务是完成两相同棋子之间的棋子变色任务 110 for (int i = 0; i < 8; i++)//遍历8个方向 111 { 112 bool ok = false; //遇到可翻转的方向,置为true,并退出 113 int rr = r, cc = c, dr = dir[i][0], dc = dir[i][1]; 114 if (tab[rr+dr][cc+dc] == y) { //查找中间有不同棋子的方向 115 while (true) { //该方向上寻找是否还有与自己一样颜色的棋子 116 rr += dr; cc += dc; 117 if (tab[rr][cc] == x) { 118 ok = true; //这个方向的棋子可以都翻转为x 119 break; 120 } 121 if (tab[rr][cc] == '-' || tab[rr][cc] == 0) 122 break; 123 } 124 } 125 if (ok) { //因为可以翻转的棋子不止一个方向--所以应该在方向循环的里面 126 rr = r, cc = c; //将两相同颜色之间的棋子变色 127 if (true) { 128 rr += dr; cc += dc; 129 if (tab[rr][cc] == x) break; //一直遇到与自己一样颜色的棋子,退出 130 else tab[rr][cc] = x; //将之间的棋子全部翻成和自己一样 131 } 132 } 133 } 134 out_cnt(); //输出操作后黑白子的数目 135 } 136 137 //打印棋盘 138 void print() 139 { 140 cout << " "; 141 for (int j = 1; j <= 8; j++) 142 cout << j ; 143 cout << endl; 144 for (int i = 1; i <= 8; i++) 145 { 146 cout << i << "." << tab[i]+1; 147 printf("\n"); 148 } 149 } 150 151 int main() 152 { 153 fstream in1("tab1.txt"); 154 fstream in2("tab2.txt"); 155 int T; //局数 156 cout << "输入游戏局数: "; 157 cin >> T; 158 while (T--) 159 { 160 cout << "选择游戏难度: A.简单\n" 161 << " B.困难"<< "\n"; 162 char level; cin >> level; 163 memset(tab, 0, sizeof(tab)); 164 if (level == 'A') { 165 for (int i = 1; i <= 8; i++) //输入棋盘 166 in1 >> (tab[i] + 1); //文件读入棋盘 167 } 168 if (level == 'B') { 169 for (int i = 1; i <= 8; i++) 170 in2 >> (tab[i] + 1); 171 } 172 print(); //打印棋盘 173 char beg; //开始棋子 174 cout << "输入先行棋子(白子-W 黑子-B): "; 175 cin >> beg; 176 bool flag = true; //标志_合法输入棋子 177 string cmd; 178 cout << "输入--指令L:显示所有合法位置.\n--指令M(x,y)放置棋子的坐标.\n--指令Q: 打印棋盘.\n" 179 << "--指令E: 退出.\n"; 180 while (cin >> cmd) { //输入命令 181 if (cmd == "L") { //显示所有合法输入位置 182 L(now(beg, flag)); //now()可以自动转换成 合法输入的棋子颜色 183 } 184 else if (cmd[0] == 'M') { //放置棋子 185 int r = cmd[1] - '0', c = cmd[2] - '0'; //位置 186 if (!legal(r, c, now(beg, flag))) { //如果输入不合法 187 flag = !flag; 188 Mrc(r, c, now(beg, flag)); //转换成合法游戏者 放置 189 print(); 190 } 191 else { 192 Mrc(r, c, now(beg, flag)); //合法就直接放置棋子 193 print(); 194 } 195 flag = !flag; //放置棋子后 切换游戏者 196 } 197 else if (cmd == "Q") { //打印棋盘 198 print(); 199 // break; 200 cout << "输入--指令L:显示所有合法位置.\n--指令M(x,y)放置棋子的坐标(如:M23).\n--指令Q: 打印棋盘.\n" 201 << "--指令E: 退出.\n"; 202 } 203 else if (cmd == "E") { //输入E退出 204 break; 205 } 206 } 207 if (T > 0) 208 printf("\n"); 209 } 210 return 0; 211 }

 

posted @ 2016-05-28 17:43 douzujun 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值