井字棋人机对弈的实现
以3*3的二维数组存放棋盘,输入两个数字表示要下的位置,然后人机对弈;
1.划分模块
(1). 输出模块
输出棋盘:不断的清屏、打印、清屏、打印以实现动画式的效果( 一般都会把清除光标带上的 )。
输出结果:谁输谁赢。
(2).判断模块
此处分为两个模块
其一用来判断所选位置是否可以下(即是否已经存在棋子),
其二是判断当前棋面是否有输赢,或平局。
(3).电脑下棋模块
此模块最为重要,要考虑到各种情况的应对措施,思路下面具体说;
(4).主函数
把问题分小了,划分为各个模块,用子函数实现,主函数相对来说就简单了。
2.简单思路介绍
输出棋盘的操作都带着清屏 打印 (cls、print);
判断就返回两个值表示是否即可,这些都不是重点;
重点是这里,人机博弈:首先有个优先度,
第一: 要赢;
第二:在实在不能赢的情况下,不能输,最多为平局;
第三:如果以上都没有,就随机下;
3.代码实现及详细思路
就按源代码中的顺序写了,思路自己对应一下吧。
1.去光标
1 // 去光标 2 void qgb ( ) 3 { 4 HANDLE handle = GetStdHandle ( STD_OUTPUT_HANDLE ); 5 CONSOLE_CURSOR_INFO CursorInfo; 6 GetConsoleCursorInfo ( handle, &CursorInfo ); 7 CursorInfo.bVisible = false; 8 SetConsoleCursorInfo ( handle, &CursorInfo ); 9 }
2.判断所选位置是否可以下子
1 // 判断所选位置是否可下 不可下返回-1 可以下返回0 2 int IsNULL ( int array[3][3], int x, int y ) 3 { 4 if ( array[x][y] == 0 ) return 0; 5 return -1; 6 }
3.打印棋盘
不断的清屏 打印 清屏 打印;
1 // 打印棋盘 2 void Print ( int array[3][3] ) 3 { 4 system( "cls" ); 5 int i, j; 6 printf ( " 井 字 棋 " ); 7 for ( i = 0; i < 3; i ++ ) 8 { 9 printf ( " +-+-+-+ |" ); 10 for ( j = 0; j < 3; j ++ ) 11 { 12 if ( array[i][j] == 0 ) printf( " " ); 13 if ( array[i][j] == 1 ) printf( "X" ); 14 if ( array[i][j] == -1 ) printf( "O" ); 15 printf( "|" ); 16 } 17 } 18 printf ( " +-+-+-+ " ); 19 }
4.电脑下棋部分
其一考虑赢,即有一线有两个自己的棋子,则优先放在第三个的位置。
其二考虑不输,即不然对方赢,一条线上有两个对方棋子,则下在第三个位置堵住。
其三随机下。
重点:一定要按该思路的顺序 先考虑赢,再考虑不输,最后考虑随机,即使你分 横竖撇捺的位置来实现的,最后也得等赢的情况全部考虑完在考虑其他情况,我刚开始就傻逼了。
代码:
1 // 电脑下子 2 int GO ( int array[3][3] ) 3 { 4 int i, t; 5 int k; 6 for ( i = 0; i < 3; i ++ ) 7 { 8 t = array[i][0] + array[i][1] + array[i][2]; 9 if ( t == -2 ) 10 { 11 for ( k = 0; k < 3; k ++ ) 12 { 13 if ( array[i][k] == 0 ) 14 { 15 array[i][k] = -1; 16 return 0; 17 } 18 19 } 20 } 21 } 22 for ( i = 0; i < 3; i ++ ) 23 { 24 t = array[0][i] + array[1][i] + array[2][i]; 25 if ( t == -2 ) 26 { 27 for ( k = 0; k < 3; k ++ ) 28 { 29 if ( array[k][i] == 0 ) 30 { 31 array[k][i] = -1; 32 return 0; 33 } 34 } 35 } 36 } 37 int j = 0; t = 0; 38 for ( i = 0; i < 3; i ++ ) 39 { 40 j += array[i][i]; 41 t += array[i][2-i]; 42 } 43 if ( t == -2 ) 44 { 45 for ( k = 0; k < 3; k ++ ) 46 { 47 if ( array[k][2-k] == 0 ) 48 { 49 array[k][2-k] = -1; 50 return 0; 51 } 52 } 53 } 54 if ( j == -2 ) 55 { 56 for ( k = 0; k < 3; k ++ ) 57 { 58 if ( array[k][k] == 0 ) 59 { 60 array[k][k] = -1; 61 return 0; 62 } 63 } 64 } 65 66 67 68 for ( i = 0; i < 3; i ++ ) 69 { 70 t = array[i][0] + array[i][1] + array[i][2]; 71 if ( t == 2 ) 72 { 73 for ( k = 0; k < 3; k ++ ) 74 { 75 if ( array[i][k] == 0 ) 76 { 77 array[i][k] = -1; 78 return 0; 79 } 80 81 } 82 } 83 } 84 for ( i = 0; i < 3; i ++ ) 85 { 86 t = array[0][i] + array[1][i] + array[2][i]; 87 if ( t == 2 ) 88 { 89 for ( k = 0; k < 3; k ++ ) 90 { 91 if ( array[k][i] == 0 ) 92 { 93 array[k][i] = -1; 94 return 0; 95 } 96 } 97 } 98 } 99 j = 0; t = 0; 100 for ( i = 0; i < 3; i ++ ) 101 { 102 j += array[i][i]; 103 t += array[i][2-i]; 104 } 105 if ( t == 2 ) 106 { 107 for ( k = 0; k < 3; k ++ ) 108 { 109 if ( array[k][2-k] == 0 ) 110 { 111 array[k][2-k] = -1; 112 return 0; 113 } 114 } 115 } 116 if ( j == 2 ) 117 { 118 for ( k = 0; k < 3; k ++ ) 119 { 120 if ( array[k][k] == 0 ) 121 { 122 array[k][k] = -1; 123 return 0; 124 } 125 } 126 } 127 128 129 while ( 1 ) 130 { 131 srand ( time ( 0 ) ); 132 i = rand ( ) % 3; 133 j = rand ( ) % 3; 134 if ( IsNULL ( array, i, j ) == 0 ) 135 { 136 array[i][j] = -1; 137 break; 138 } 139 } 140 return 0; 141 }
5.检查胜负情况
代码:
1 // 平局返回0;正方胜返回1;负反胜利返回-1;否则返回6; 2 int Check ( int array[3][3] ) 3 { 4 int i, t; 5 for ( i = 0; i < 3; i ++ ) 6 { 7 t = array[i][0] + array[i][1] + array[i][2]; 8 if ( t == -3 ) return -1; 9 if ( t == 3 ) return 1; 10 } 11 for ( i = 0; i < 3; i ++ ) 12 { 13 t = array[0][i] + array[1][i] + array[2][i]; 14 if ( t == -3 ) return -1; 15 if ( t == 3 ) return 1; 16 } 17 int j = 0; t = 0; 18 for ( i = 0; i < 3; i ++ ) 19 { 20 j += array[i][i]; 21 t += array[i][2-i]; 22 } 23 if ( t == -3 || j == -3 ) return -1; 24 if ( t == 3 || j == 3 ) return 1; 25 for ( i = 0; i < 3; i ++ ) 26 { 27 for ( j = 0; j < 3; j ++ ) 28 { 29 if ( array[i][j] == 0 ) return 6; 30 } 31 } 32 return 0; 33 }
6.我另外加的一个 集Check 和Print 一起的函数,用来输出结果;
代码:
1 int CP ( int array[3][3] ) 2 { 3 int t = Check ( array ); 4 Print ( array ); 5 if ( t == 0 ) 6 { 7 printf ( " 平局!"); 8 system ( "pause" ); 9 return 0; 10 } 11 if ( t == 1 ) 12 { 13 printf ( " 恭喜你 赢了! "); 14 system ( "pause" ); 15 return 0; 16 } 17 if ( t == -1 ) 18 { 19 printf ( " 很抱歉 输了! "); 20 system ( "pause" ); 21 return 0; 22 } 23 return -1; 24 }
7.主函数
代码:
1 int main ( ) 2 { 3 system ( "title 井字棋小游戏--BY:nanshao_zz" ); 4 qgb ( ); 5 int array[3][3]; 6 memset ( array, 0, sizeof ( array ) ); 7 Print ( array ); 8 int x, y, t; 9 while ( 1 ) 10 { 11 scanf ( "%d %d", &x, &y ); 12 x --; 13 y --; 14 if ( x > 2 || y > 2 || x < 0 || y < 0 ) 15 { 16 printf( " 输入范围: 1-3! " ); 17 continue; 18 } 19 if ( IsNULL ( array, x, y ) == -1 ) 20 { 21 printf ( "所选位置已存在! " ); 22 continue; 23 } 24 array[x][y] = 1; 25 t = CP ( array ); 26 if ( t == 0 ) return 0; 27 GO ( array ); 28 t = CP ( array ); 29 if ( t == 0 ) return 0; 30 } 31 return 0; 32 }
全部代码:
1 #include "algorithm" 2 #include "windows.h" 3 #include "iostream" 4 #include "stdlib.h" 5 #include "string.h" 6 #include "stdio.h" 7 #include "vector" 8 #include "math.h" 9 #include "time.h" 10 #include "string" 11 #include "map" 12 13 using namespace std; 14 15 // 去光标 16 void qgb ( ) 17 { 18 HANDLE handle = GetStdHandle ( STD_OUTPUT_HANDLE ); 19 CONSOLE_CURSOR_INFO CursorInfo; 20 GetConsoleCursorInfo ( handle, &CursorInfo ); 21 CursorInfo.bVisible = false; 22 SetConsoleCursorInfo ( handle, &CursorInfo ); 23 } 24 25 // 判断所选位置是否可下 不可下返回-1 可以下返回0 26 int IsNULL ( int array[3][3], int x, int y ) 27 { 28 if ( array[x][y] == 0 ) return 0; 29 return -1; 30 } 31 32 // 打印棋盘 33 void Print ( int array[3][3] ) 34 { 35 system( "cls" ); 36 int i, j; 37 printf ( " 井 字 棋 " ); 38 for ( i = 0; i < 3; i ++ ) 39 { 40 printf ( " +-+-+-+ |" ); 41 for ( j = 0; j < 3; j ++ ) 42 { 43 if ( array[i][j] == 0 ) printf( " " ); 44 if ( array[i][j] == 1 ) printf( "X" ); 45 if ( array[i][j] == -1 ) printf( "O" ); 46 printf( "|" ); 47 } 48 } 49 printf ( " +-+-+-+ " ); 50 } 51 52 // 电脑下子 53 int GO ( int array[3][3] ) 54 { 55 int i, t; 56 int k; 57 for ( i = 0; i < 3; i ++ ) 58 { 59 t = array[i][0] + array[i][1] + array[i][2]; 60 if ( t == -2 ) 61 { 62 for ( k = 0; k < 3; k ++ ) 63 { 64 if ( array[i][k] == 0 ) 65 { 66 array[i][k] = -1; 67 return 0; 68 } 69 70 } 71 } 72 } 73 for ( i = 0; i < 3; i ++ ) 74 { 75 t = array[0][i] + array[1][i] + array[2][i]; 76 if ( t == -2 ) 77 { 78 for ( k = 0; k < 3; k ++ ) 79 { 80 if ( array[k][i] == 0 ) 81 { 82 array[k][i] = -1; 83 return 0; 84 } 85 } 86 } 87 } 88 int j = 0; t = 0; 89 for ( i = 0; i < 3; i ++ ) 90 { 91 j += array[i][i]; 92 t += array[i][2-i]; 93 } 94 if ( t == -2 ) 95 { 96 for ( k = 0; k < 3; k ++ ) 97 { 98 if ( array[k][2-k] == 0 ) 99 { 100 array[k][2-k] = -1; 101 return 0; 102 } 103 } 104 } 105 if ( j == -2 ) 106 { 107 for ( k = 0; k < 3; k ++ ) 108 { 109 if ( array[k][k] == 0 ) 110 { 111 array[k][k] = -1; 112 return 0; 113 } 114 } 115 } 116 117 118 119 for ( i = 0; i < 3; i ++ ) 120 { 121 t = array[i][0] + array[i][1] + array[i][2]; 122 if ( t == 2 ) 123 { 124 for ( k = 0; k < 3; k ++ ) 125 { 126 if ( array[i][k] == 0 ) 127 { 128 array[i][k] = -1; 129 return 0; 130 } 131 132 } 133 } 134 } 135 for ( i = 0; i < 3; i ++ ) 136 { 137 t = array[0][i] + array[1][i] + array[2][i]; 138 if ( t == 2 ) 139 { 140 for ( k = 0; k < 3; k ++ ) 141 { 142 if ( array[k][i] == 0 ) 143 { 144 array[k][i] = -1; 145 return 0; 146 } 147 } 148 } 149 } 150 j = 0; t = 0; 151 for ( i = 0; i < 3; i ++ ) 152 { 153 j += array[i][i]; 154 t += array[i][2-i]; 155 } 156 if ( t == 2 ) 157 { 158 for ( k = 0; k < 3; k ++ ) 159 { 160 if ( array[k][2-k] == 0 ) 161 { 162 array[k][2-k] = -1; 163 return 0; 164 } 165 } 166 } 167 if ( j == 2 ) 168 { 169 for ( k = 0; k < 3; k ++ ) 170 { 171 if ( array[k][k] == 0 ) 172 { 173 array[k][k] = -1; 174 return 0; 175 } 176 } 177 } 178 179 180 while ( 1 ) 181 { 182 srand ( time ( 0 ) ); 183 i = rand ( ) % 3; 184 j = rand ( ) % 3; 185 if ( IsNULL ( array, i, j ) == 0 ) 186 { 187 array[i][j] = -1; 188 break; 189 } 190 } 191 return 0; 192 } 193 194 // 平局返回0;正方胜返回1;负反胜利返回-1;否则返回6; 195 int Check ( int array[3][3] ) 196 { 197 int i, t; 198 for ( i = 0; i < 3; i ++ ) 199 { 200 t = array[i][0] + array[i][1] + array[i][2]; 201 if ( t == -3 ) return -1; 202 if ( t == 3 ) return 1; 203 } 204 for ( i = 0; i < 3; i ++ ) 205 { 206 t = array[0][i] + array[1][i] + array[2][i]; 207 if ( t == -3 ) return -1; 208 if ( t == 3 ) return 1; 209 } 210 int j = 0; t = 0; 211 for ( i = 0; i < 3; i ++ ) 212 { 213 j += array[i][i]; 214 t += array[i][2-i]; 215 } 216 if ( t == -3 || j == -3 ) return -1; 217 if ( t == 3 || j == 3 ) return 1; 218 for ( i = 0; i < 3; i ++ ) 219 { 220 for ( j = 0; j < 3; j ++ ) 221 { 222 if ( array[i][j] == 0 ) return 6; 223 } 224 } 225 return 0; 226 } 227 228 229 int CP ( int array[3][3] ) 230 { 231 int t = Check ( array ); 232 Print ( array ); 233 if ( t == 0 ) 234 { 235 printf ( " 平局!"); 236 system ( "pause" ); 237 return 0; 238 } 239 if ( t == 1 ) 240 { 241 printf ( " 恭喜你 赢了! "); 242 system ( "pause" ); 243 return 0; 244 } 245 if ( t == -1 ) 246 { 247 printf ( " 很抱歉 输了! "); 248 system ( "pause" ); 249 return 0; 250 } 251 return -1; 252 } 253 254 int main ( ) 255 { 256 system ( "title 井字棋小游戏--BY:nanshao_zz" ); 257 qgb ( ); 258 int array[3][3]; 259 memset ( array, 0, sizeof ( array ) ); 260 Print ( array ); 261 int x, y, t; 262 while ( 1 ) 263 { 264 scanf ( "%d %d", &x, &y ); 265 x --; 266 y --; 267 if ( x > 2 || y > 2 || x < 0 || y < 0 ) 268 { 269 printf( " 输入范围: 1-3! " ); 270 continue; 271 } 272 if ( IsNULL ( array, x, y ) == -1 ) 273 { 274 printf ( "所选位置已存在! " ); 275 continue; 276 } 277 array[x][y] = 1; 278 t = CP ( array ); 279 if ( t == 0 ) return 0; 280 GO ( array ); 281 t = CP ( array ); 282 if ( t == 0 ) return 0; 283 } 284 return 0; 285 }
希望可以帮到正在学这个的你,欢迎批评指正!