/*--------
--------
--------
---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.
");
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("
");
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
", 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("
");
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.简单
"
161 << " B.困难"<< "
";
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:显示所有合法位置.
--指令M(x,y)放置棋子的坐标.
--指令Q: 打印棋盘.
"
179 << "--指令E: 退出.
";
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:显示所有合法位置.
--指令M(x,y)放置棋子的坐标(如:M23).
--指令Q: 打印棋盘.
"
201 << "--指令E: 退出.
";
202 }
203 else if (cmd == "E") { //输入E退出
204 break;
205 }
206 }
207 if (T > 0)
208 printf("
");
209 }
210 return 0;
211 }