用c写了一个简单的两人对战命令行五子棋游戏。
1. 带界面,界面菜单有三个选项:a (棋盘尺寸 20x20), b (伪30x30尺寸,暂时留白),c(退出)。
2. 棋盘由 0-399 这400个整数构成,代表400个落棋点。
3. 棋手 A, B。落子方式为输入落棋点代号按 enter 即可。
4. 规则:先成 横、竖、正斜/、反斜五子一线即赢。
5. 判断过程优化,棋盘是int pos[20][20]数组,pos[i][j] = i * 20 +j。这个等式用来判定落棋点是否以有子,等式不成立即说明有子。
6. 包括越界判断:共可落棋400粒,超过400粒即棋盘满,为和棋。
7. 程序基本结构:
- main()
- welcome()
- init()
- draw()
- aorb()
- go()
- welcome()
对于加机器人(人机对战)的思考:
针对已有落棋点进行概率分析, 用树结构图向下表示双方可能的每一步,确定是按己方棋路走,还是狙击对手。向下扩展的步数越多,则机器人越智能。
Notice: linux 下 gcc 4.4 编译通过.
1 /* wuziqi.c -- a simple game (main routines)
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 Written by DCMorgan */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 void init (int pos[20][20]); // 初始化棋盘
22 void draw (int pos[20][20]); // 每次落子后都重绘棋盘
23 void aorb (int pos[20][20]); // 决定 A 还是 B走
24 void go (int pos[20][20], int ab); // 落子
25 int test (int pos[20][20], int ab); // 测试是否五子一线
26 void welcome(); // 界面
27
28 int
29 main (void)
30 {
31
32 welcome();
33
34 return 0;
35 }
36
37 void
38 init (int pos[20][20])
39 {
40 int i, j;
41 int n = 0;
42
43 for (i = 0; i < 20; i++)
44 {
45 for (j = 0; j < 20; j++)
46 {
47 pos[i][j] = n; // 棋盘位置初始化
48 n += 1;
49 }
50 }
51
52 return;
53 }
54
55 void
56 welcome ()
57 {
58 char opt; // 选项
59 int pos[20][20]; // 棋盘
60
61 init (pos);
62 fputs("\
63 ********************************\n\
64 * Welcome to this game. Enjoy! *\n\
65 * ******************************\n\
66 Please choose the size:\n\
67 a: 20x20\n\
68 b: 30x30\n\
69 q: quite \n", stdout);
70 printf("\nYour choice: ");
71 opt = getchar();
72 getchar();
73 switch (opt) {
74 case 'A':
75 case 'a':
76 draw (pos);
77 aorb (pos);
78 break;
79 case 'b':
80 case 'B':
81 printf("\n\nNow it's not vailable. Please update your program\n\n");
82 welcome();
83 break;
84 case 'q':
85 case 'Q':
86 printf("\n\nHow about this game. It's really interesting, uh?\n");
87 printf("Welcome to play again. Bye!\n");
88 break;
89 default:
90 welcome();
91 break;
92 }
93 return;
94 }
95
96 void
97 draw (int pos[20][20])
98 {
99 int i, j;
100
101 printf("\n");
102 for (i = 0; i < 20; i++)
103 {
104 for (j = 0; j < 20; j++)
105 {
106 if ( pos[i][j] == (i*20+j)) // 判断是否以落子
107 {
108 printf("%5d", pos[i][j]); // 若没有,输出位置
109 }
110 else
111 {
112 printf("%5c", pos[i][j]); // 若落子,输出棋子
113 }
114 }
115 printf("\n");
116 }
117 return;
118 }
119
120 void
121 aorb (int pos[20][20])
122 {
123 int n; // 循环控制变量,n 为0 时,一盘结束
124 int ab; // ab=1 时 , a 走, 否则 b走
125 char c; // y/n
126
127 n = 1;
128 ab = 1;
129 while (n)
130 {
131 if ((n%2) != 0) // a 走
132 {
133 ab = 1;
134 printf("A go: ");
135 go (pos, ab);
136 }
137 else
138 {
139 ab = 0;
140 printf("B go: "); // b 走
141 go (pos, ab);
142 }
143 n += 1;
144 draw(pos);
145 if (!test(pos, ab)) // 测试是否胜利
146 {
147 break;
148 }
149 if (n > 400) // 棋盘无处落子
150 {
151 printf("\nNo room. So peace\n");
152 break;
153 }
154 }
155 printf("Want to play again?y/n: "); // 一局结束
156 c = getchar();
157 if ( c == 'Y' || c == 'y')
158 {
159 welcome();
160 }
161 else
162 {
163 printf("Bye!");
164 }
165 return;
166 }
167
168 void
169 go (int pos[10][20], int ab)
170 {
171 char s[6];
172 int c, i, j;
173
174 printf(" ");
175 fgets(s, 5, stdin);
176 c = atoi(s);
177 if (c >= 0|| c <= 400) // 落子在棋盘范围内
178 {
179 for (i = 0; i < 21; i++)
180 {
181 if ((i*20) > c)
182 {
183 i -= 1;
184 j = c - i * 20;
185 break;
186 }
187 }
188 if (pos[i][j] == (i * 20 + j)) // 测试欲落子位置是否有子, 若无子
189 {
190 if (ab)
191 pos[i][j] = 'X'; // a 子
192 else
193 pos[i][j] = 'O'; // b 子
194 }
195 else // 若有子,
196 {
197 draw(pos);
198 printf("\nWrong step.\n");
199 ab == 1 ? printf("A go again: ") : printf("B go again: ");
200 go (pos, ab);
201 }
202 }
203 }
204
205 int
206 test (int pos[20][20], int ab)
207 {
208 int i, j, a, b;
209
210 for (i = 0; i < 20; i++)
211 {
212 for (j = 0; j < 20; j++)
213 {
214 a = pos[i][j];
215 if (((j < 16) && a==pos[i][j] && a==pos[i][j+1] && a==pos[i][j+2] && a==pos[i][j+3]
216 && a==pos[i][j+4]) ||
217 ((i < 16) && (j < 16) && a==pos[i][j] && a==pos[i+1][j+1] && a==pos[i+2][j+2]
218 && a==pos[i+3][j+3] && a==pos[i+4][j+4]) ||
219 ((i < 16) && (j > 3) && a==pos[i][j] && a==pos[i+1][j-1] && a==pos[i+2][j-2]
220 && a==pos[i+3][j-3] && a==pos[i+4][j-4]) ||
221 ((i < 16) && a==pos[i][j] && a==pos[i+1][j] && a==pos[i+2][j]
222 && a==pos[i+3][j] && a==pos[i+4][j]))
223 {
224 if (ab)
225 {
226 printf("\nCongratulations: A win\n");
227 b = 0;
228 return b;
229 }
230 else
231 {
232 printf("\nCongratulations: B win\n");
233 b = 0;
234 return b;
235 }
236 }
237 }
238 }
239 }
240
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 Written by DCMorgan */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 void init (int pos[20][20]); // 初始化棋盘
22 void draw (int pos[20][20]); // 每次落子后都重绘棋盘
23 void aorb (int pos[20][20]); // 决定 A 还是 B走
24 void go (int pos[20][20], int ab); // 落子
25 int test (int pos[20][20], int ab); // 测试是否五子一线
26 void welcome(); // 界面
27
28 int
29 main (void)
30 {
31
32 welcome();
33
34 return 0;
35 }
36
37 void
38 init (int pos[20][20])
39 {
40 int i, j;
41 int n = 0;
42
43 for (i = 0; i < 20; i++)
44 {
45 for (j = 0; j < 20; j++)
46 {
47 pos[i][j] = n; // 棋盘位置初始化
48 n += 1;
49 }
50 }
51
52 return;
53 }
54
55 void
56 welcome ()
57 {
58 char opt; // 选项
59 int pos[20][20]; // 棋盘
60
61 init (pos);
62 fputs("\
63 ********************************\n\
64 * Welcome to this game. Enjoy! *\n\
65 * ******************************\n\
66 Please choose the size:\n\
67 a: 20x20\n\
68 b: 30x30\n\
69 q: quite \n", stdout);
70 printf("\nYour choice: ");
71 opt = getchar();
72 getchar();
73 switch (opt) {
74 case 'A':
75 case 'a':
76 draw (pos);
77 aorb (pos);
78 break;
79 case 'b':
80 case 'B':
81 printf("\n\nNow it's not vailable. Please update your program\n\n");
82 welcome();
83 break;
84 case 'q':
85 case 'Q':
86 printf("\n\nHow about this game. It's really interesting, uh?\n");
87 printf("Welcome to play again. Bye!\n");
88 break;
89 default:
90 welcome();
91 break;
92 }
93 return;
94 }
95
96 void
97 draw (int pos[20][20])
98 {
99 int i, j;
100
101 printf("\n");
102 for (i = 0; i < 20; i++)
103 {
104 for (j = 0; j < 20; j++)
105 {
106 if ( pos[i][j] == (i*20+j)) // 判断是否以落子
107 {
108 printf("%5d", pos[i][j]); // 若没有,输出位置
109 }
110 else
111 {
112 printf("%5c", pos[i][j]); // 若落子,输出棋子
113 }
114 }
115 printf("\n");
116 }
117 return;
118 }
119
120 void
121 aorb (int pos[20][20])
122 {
123 int n; // 循环控制变量,n 为0 时,一盘结束
124 int ab; // ab=1 时 , a 走, 否则 b走
125 char c; // y/n
126
127 n = 1;
128 ab = 1;
129 while (n)
130 {
131 if ((n%2) != 0) // a 走
132 {
133 ab = 1;
134 printf("A go: ");
135 go (pos, ab);
136 }
137 else
138 {
139 ab = 0;
140 printf("B go: "); // b 走
141 go (pos, ab);
142 }
143 n += 1;
144 draw(pos);
145 if (!test(pos, ab)) // 测试是否胜利
146 {
147 break;
148 }
149 if (n > 400) // 棋盘无处落子
150 {
151 printf("\nNo room. So peace\n");
152 break;
153 }
154 }
155 printf("Want to play again?y/n: "); // 一局结束
156 c = getchar();
157 if ( c == 'Y' || c == 'y')
158 {
159 welcome();
160 }
161 else
162 {
163 printf("Bye!");
164 }
165 return;
166 }
167
168 void
169 go (int pos[10][20], int ab)
170 {
171 char s[6];
172 int c, i, j;
173
174 printf(" ");
175 fgets(s, 5, stdin);
176 c = atoi(s);
177 if (c >= 0|| c <= 400) // 落子在棋盘范围内
178 {
179 for (i = 0; i < 21; i++)
180 {
181 if ((i*20) > c)
182 {
183 i -= 1;
184 j = c - i * 20;
185 break;
186 }
187 }
188 if (pos[i][j] == (i * 20 + j)) // 测试欲落子位置是否有子, 若无子
189 {
190 if (ab)
191 pos[i][j] = 'X'; // a 子
192 else
193 pos[i][j] = 'O'; // b 子
194 }
195 else // 若有子,
196 {
197 draw(pos);
198 printf("\nWrong step.\n");
199 ab == 1 ? printf("A go again: ") : printf("B go again: ");
200 go (pos, ab);
201 }
202 }
203 }
204
205 int
206 test (int pos[20][20], int ab)
207 {
208 int i, j, a, b;
209
210 for (i = 0; i < 20; i++)
211 {
212 for (j = 0; j < 20; j++)
213 {
214 a = pos[i][j];
215 if (((j < 16) && a==pos[i][j] && a==pos[i][j+1] && a==pos[i][j+2] && a==pos[i][j+3]
216 && a==pos[i][j+4]) ||
217 ((i < 16) && (j < 16) && a==pos[i][j] && a==pos[i+1][j+1] && a==pos[i+2][j+2]
218 && a==pos[i+3][j+3] && a==pos[i+4][j+4]) ||
219 ((i < 16) && (j > 3) && a==pos[i][j] && a==pos[i+1][j-1] && a==pos[i+2][j-2]
220 && a==pos[i+3][j-3] && a==pos[i+4][j-4]) ||
221 ((i < 16) && a==pos[i][j] && a==pos[i+1][j] && a==pos[i+2][j]
222 && a==pos[i+3][j] && a==pos[i+4][j]))
223 {
224 if (ab)
225 {
226 printf("\nCongratulations: A win\n");
227 b = 0;
228 return b;
229 }
230 else
231 {
232 printf("\nCongratulations: B win\n");
233 b = 0;
234 return b;
235 }
236 }
237 }
238 }
239 }
240