├── README.md └── game_theo ├── README.md └── five_in_a_line ├── README.md ├── fiveinaline.c └── reference.c /README.md: -------------------------------------------------------------------------------- 1 | # UCAS-assignments-20 2 | 硕士课程作业(2020) 3 | -------------------------------------------------------------------------------- /game_theo/README.md: -------------------------------------------------------------------------------- 1 | # 博弈论 2 | ## 介绍 3 | 本文件夹下为课程“博弈论”的作业。 4 | -------------------------------------------------------------------------------- /game_theo/five_in_a_line/README.md: -------------------------------------------------------------------------------- 1 | # 基于极大极小搜索的五子棋程序 2 | ## 介绍 3 | 本程序实现了一个基于极大极小定理(1928,John von Neumann)的五子棋程序,可以实现先手对弈与后手对弈。 4 | ## 说明与致谢 5 | 本程序的图形界面部分来自中国科学院大学2016年秋季学期本科必修课《C语言程序设计基础》,感谢计算所武成岗老师的指导。\ 6 | 本程序的经验得分函数部分是本人于2016.12的作品,并使用在上述课程的大作业上。 7 | ## 运行环境 8 | 本程序用C(C99)编写,只需用gcc编译时加上-std=c99即可。 9 | ## 方法 10 | 本程序包含两个主要部分:\ 11 | 第一部分是一个基于经验的得分判断函数(autoscore(int x, int y, int PLAYER)),该函数返回玩家PLAYER在坐标点(x, y)的经验分数。\ 12 | 第二部分是极大极小搜索算法(struct point autoret()),该函数进行一次深度为3的极大极小搜索并返回搜索结果。 13 | ## 实现细节 14 | ### 基于经验的得分函数 15 | 该函数考虑各种棋型并分别对其评价分数,最后得到一个得分。\ 16 | 棋型分为活一、活二、冲三、活三、冲四、活四、成五等。这些棋型又分为四个等级,包括直接胜利的棋型、可以决胜的棋型、可以逼迫对手应对的棋型和其它有利于己方的棋型,这四类的得分按数量级递减。 17 | ### 极大极小搜索目标函数 18 | 极大极小搜索的深度为3,但是由于三级剪枝只留下一枝,因此实际应用极大极小搜索的层数只有2。第一层为我方决策,第二层为对方决策。\ 19 | 极大极小搜索由一个总体的极大极小目标函数,一个剪枝过程以及极大极小搜索本身构成。\ 20 | 在极大极小目标函数中,本程序设定了两组参数:\ 21 | 第一组是对抗系数(ADVERSCONS),指的是对方对目标函数的贡献与己方对目标函数的贡献之比。对抗系数大则偏向防守,反之偏向进攻。\ 22 | 第二组是贪心率,分为我方贪心率(GREEDYRATE)与对方贪心率(ADVGREEDYRATE),前者指第三层我方对目标函数的贡献与第一层我方对目标函数贡献之比,后者指第三层对方对目标函数的贡献与第二层对方对目标函数贡献之比。贪心率越小越贪心。 23 | ### 剪枝策略 24 | 在剪枝函数中,本程序用搜索束宽度(SEARCHBEAM1、SEARCHBEAM2)这组参数来设定第一层搜索与第二层搜索剪枝剩余的数目。这两个值设定为5即可。\ 25 | 剪枝的策略如下:对于棋盘上某一点,该点不被剪枝的充分条件是我方能在该点取得较大的得分,或对方能在该点取得较大的得分。为解释这一点,我们考虑如下的情况:假设该点是对方的一招必杀技,如果此步我方不在该点落子,则下一步对方必在该点落子并对极大极小目标函数造成最大的惩罚。这样,我方落子在其它任何位置都要遭受这一惩罚,只有落子在该点不需要承担这一惩罚。所以在不能事先向下一层搜索的情况下,最简单的策略是将该点对方的得分加到剪枝目标函数上。\ 26 | 基于这一思想,剪枝目标函数被设定为我方在该点的得分加上剪枝系数(PRUNEADV)乘以修改过的对方得分函数。剪枝系数必须是一个小于等于1的数。\ 27 | 一级剪枝与二级剪枝的宽度由搜索束宽度指定。在三级剪枝的过程中,算法遍历棋盘上所有节点并只选择一个剪枝目标函数最大的点。在一级与二级剪枝的过程中,算法遍历棋盘上所有节点并用一个最小堆辅助选出其中最大的几个点。 28 | ## 使用说明 29 | 用gcc编译然后运行即可,具体操作在图形界面中有说明。 30 | ## 实验 31 | 本程序的实验基准为本人在2016.12编写的五子棋程序,该程序和本程序使用同样的经验得分函数与图形界面,但没有极大极小搜索。尽管该程序没有任何一层以上的搜索策略与算法,本人曾经在2017年用该程序在当时课程上的淘汰赛中打败数名对手进入全班前8名的行列,也打败了4399小游戏网站上本人测试过的所有五子棋。\ 32 | 用基准程序与本程序对弈,在计算机上以不同的参数运行了数次,结果如下:\ 33 | 对抗系数0.5- 先手败、后手败;\ 34 | 对抗系数0.8- 先手胜、后手败;\ 35 | 对抗系数1.0- 先手败、后手败;\ 36 | 对抗系数1.5- 先手胜、后手胜;\ 37 | 对抗系数2.0- 先手胜、后手死局。\ 38 | 实验结果显示对抗系数取1.5左右较为合适。 39 | -------------------------------------------------------------------------------- /game_theo/five_in_a_line/fiveinaline.c: -------------------------------------------------------------------------------- 1 | //Copyright 2020 Lab Mikazu. All Rights Reserved. 2 | //Project "Mayim Mayim" 1st. work 3 | 4 | #include 5 | #include 6 | #include 7 | #define SIZE 15 8 | #define PLAYER1 1 9 | #define PLAYER2 2 10 | #define SEARCHBEAM1 5 11 | #define SEARCHBEAM2 5 12 | #define ADVERSCONS 0.8 13 | #define PRUNEADV 0.9 14 | #define GREEDYRATE 0.5 15 | #define ADVGREEDYRATE 0.5 16 | 17 | //棋盘使用Unicode画的,一个符号占两个char,所以要*3,+1是为了末尾的'\0' 18 | char aInitDisplayBoardArray[SIZE+1][SIZE*3+1] = 19 | { 20 | "┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓", 21 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 22 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 23 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 24 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 25 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 26 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 27 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 28 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 29 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 30 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 31 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 32 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 33 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 34 | "┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛", 35 | "A B C D E F G H I J K L M N O" 36 | }; 37 | //此数组用于显示 38 | char aDisplayBoardArray[SIZE+1][SIZE*3+1]; 39 | //此数组用于算法计算使用 40 | int aRecordBoard[SIZE][SIZE];// 41 | char play1Pic[]="●"; 42 | char play2Pic[]="◎"; 43 | char _play1Pic[]="▲"; 44 | char _play2Pic[]="△"; 45 | //棋手最近一次落子时的坐标 46 | int current_x;//行号 47 | int current_y;//列号 48 | int current_player; 49 | 50 | struct point{ 51 | int x; 52 | int y; 53 | int value; 54 | }; 55 | 56 | void initRecordBorard(void); 57 | void recordtoDisplayArray(void); 58 | void displayBoard(void); 59 | void set_piece(int x,int y, int player); 60 | int narugo(int x, int y, int PLAYER); 61 | int judge(int x, int y, int PLAYER); 62 | int muda(int x, int y); 63 | int kinte(int x, int y, int PLAYER); 64 | int bekaru(int x, int y, int PLAYER); 65 | int ikiyo(int x, int y, int PLAYER); 66 | int okiyo(int x, int y, int PLAYER); 67 | int real_ikimi(int x, int y, int PLAYER); 68 | int nagatsure(int x, int y, int PLAYER); 69 | int autoscore(int x, int y, int PLAYER); 70 | struct point autoret(); 71 | struct point ret(); 72 | int score[SIZE][SIZE]; 73 | struct point mystart[6]={{7,7,0}, {8,7,0}, {9,7,0}, {8,8,0}, {9,8,0}, {9,9,0}}; 74 | int myrandomizer=-1, myrandoms; 75 | 76 | //程序交互界面部分 77 | 78 | 79 | void main(){ 80 | void ningendoushi(); 81 | void wagakokoro(); 82 | char C1, C2, C3; 83 | for(;;){ 84 | system("clear"); 85 | printf(" 五 子 棋\nFive in a Row\n 五目並べ\n\nPRESS ENTER\n\nMikazu S. Takahashi (Ziyue Ji)\n\n"); 86 | for(;getchar()!='\n';); 87 | system("clear"); 88 | printf("SELECT YOUR MODE\n1=对战程序\n2=双人游戏\n\n"); 89 | for(;(C1=getchar())!='1'&&C1!='2';); 90 | if(C1=='1'){ 91 | system("clear"); 92 | printf("Versus The Computer - プログラムに挑戦する\n 继续?Y/N\n"); 93 | for(;(C2=getchar())!='Y'&&C2!='y'&&C2!='N'&&C2!='n';); 94 | if(C2=='Y'||C2=='y'){ 95 | wagakokoro(); 96 | printf("继续?Y/N\n"); 97 | for(;(C3=getchar())!='Y'&&C3!='y'&&C3!='N'&&C3!='n';); 98 | if(C3=='N'||C3=='n'){ 99 | break; 100 | }else{ 101 | getchar(); 102 | } 103 | } 104 | }else{ 105 | system("clear"); 106 | printf("Person versus person - 二人で遊ぶ\n 继续?Y/N\n"); 107 | for(;(C2=getchar())!='Y'&&C2!='y'&&C2!='N'&&C2!='n';); 108 | if(C2=='Y'||C2=='y'){ 109 | ningendoushi(); 110 | printf("继续?Y/N\n"); 111 | for(;(C3=getchar())!='Y'&&C3!='y'&&C3!='N'&&C3!='n';); 112 | if(C3=='N'||C3=='n'){ 113 | break; 114 | }else{ 115 | getchar(); 116 | } 117 | } 118 | } 119 | } 120 | } 121 | 122 | void wagakokoro(){ 123 | 124 | int a1, b1, i, kachi1, kachi2, CHAL, MYAI; 125 | char C4; 126 | struct point RET; 127 | 128 | system("clear"); 129 | printf("挑战者,请您选择自己喜欢的颜色。\nY=Black N=White\n"); 130 | for(;(C4=getchar())!='Y'&&C4!='y'&&C4!='N'&&C4!='n';); 131 | if(C4=='Y'||C4=='y'){ 132 | CHAL=PLAYER1; 133 | MYAI=PLAYER2; 134 | }else if(C4=='N'||C4=='n'){ 135 | CHAL=PLAYER2; 136 | MYAI=PLAYER1; 137 | } 138 | 139 | initRecordBorard(); 140 | recordtoDisplayArray(); 141 | displayBoard(); 142 | current_player=PLAYER1; 143 | 144 | 145 | for(i=0;i<225;i++){ 146 | if(current_player==CHAL){ 147 | for(;;){ 148 | printf("请输入您的落子位置。示例:8,8\n"); 149 | scanf("%d, %d", &a1, &b1); 150 | if(muda(a1-1, b1-1)==1){ 151 | displayBoard(); 152 | printf("无法在此处落子。\n"); 153 | }else{ 154 | break; 155 | } 156 | }if(kinte(a1-1, b1-1, CHAL)==1){ 157 | displayBoard(); 158 | printf("很遗憾您下出了禁手(详见wikipedia五子棋规则),\n因此我获胜了。\n"); 159 | break; 160 | }else{ 161 | kachi1=judge(a1-1, b1-1, CHAL); 162 | set_piece(a1-1,b1-1,CHAL); 163 | }recordtoDisplayArray(); 164 | displayBoard(); 165 | if(kachi1==1){ 166 | printf("您获胜了。 恭喜!\n"); 167 | break; 168 | } 169 | }else if(current_player==MYAI){ 170 | 171 | 172 | 173 | 174 | 175 | RET=autoret(); 176 | if(i==0){ 177 | for(;(myrandoms=(rand()%6))==myrandomizer;); 178 | myrandomizer=myrandoms; 179 | RET=mystart[myrandomizer]; 180 | }kachi2=judge(RET.x, RET.y, MYAI); 181 | set_piece(RET.x, RET.y, MYAI); 182 | recordtoDisplayArray(); 183 | displayBoard(); 184 | if(kachi2==1){ 185 | printf("我获胜了, 您还需精进技艺。\n"); 186 | break; 187 | }printf("我的出招是(%d,%d),您的对策如何?\n", RET.x+1, RET.y+1); 188 | } 189 | 190 | 191 | if(current_player==CHAL){ 192 | current_player=MYAI; 193 | }else if(current_player==MYAI){ 194 | current_player=CHAL; 195 | } 196 | 197 | 198 | 199 | 200 | 201 | }if(i>=225){ 202 | printf("你真牛逼。\n"); 203 | }printf("PRESS ENTER\n"); 204 | getchar(); 205 | for(;getchar()!='\n';); 206 | system("clear"); 207 | 208 | } 209 | 210 | void ningendoushi() 211 | { 212 | initRecordBorard(); 213 | recordtoDisplayArray(); 214 | displayBoard(); 215 | int a1, b1, a2, b2, i, kachi1, kachi2; 216 | for(i=0;i<113;i++){ 217 | 218 | 219 | 220 | for(;;){ 221 | printf("玩家1请输入落子位置:\n"); 222 | current_player=PLAYER1; 223 | scanf("%d, %d", &a1, &b1); 224 | if(muda(a1-1, b1-1)==1){ 225 | displayBoard(); 226 | printf("此处无法落子。\n"); 227 | }else{ 228 | break; 229 | } 230 | }if(kinte(a1-1, b1-1, PLAYER1)==1){ 231 | displayBoard(); 232 | printf("您下出了禁手(详见wikipedia五子棋规则),\n玩家2获胜了! 恭喜!\n"); 233 | break; 234 | }else{ 235 | kachi1=judge(a1-1, b1-1, PLAYER1); 236 | set_piece(a1-1,b1-1,PLAYER1); 237 | }recordtoDisplayArray(); 238 | displayBoard(); 239 | if(kachi1==1){ 240 | printf("玩家1获胜了! 恭喜!\n"); 241 | break; 242 | }printf("对方出招为(%d,%d),您的对策如何?\n", a1, b1); 243 | 244 | 245 | 246 | 247 | 248 | 249 | for(;;){ 250 | printf("玩家2请输入落子位置:\n"); 251 | current_player=PLAYER2; 252 | scanf("%d, %d", &a2, &b2); 253 | if(muda(a2-1, b2-1)==1){ 254 | displayBoard(); 255 | printf("此处无法落子。\n"); 256 | }else{ 257 | break; 258 | } 259 | }if(kinte(a2-1, b2-1, PLAYER2)==1){ 260 | displayBoard(); 261 | printf("您下出了禁手(详见wikipedia五子棋规则),\n玩家1获胜了! 恭喜!\n"); 262 | break; 263 | }else{ 264 | kachi2=judge(a2-1, b2-1, PLAYER2); 265 | set_piece(a2-1,b2-1,PLAYER2); 266 | }recordtoDisplayArray(); 267 | displayBoard(); 268 | if(kachi2==1){ 269 | printf("玩家2获胜了! 恭喜!\n"); 270 | break; 271 | }printf("对方出招为(%d,%d),您的对策如何?\n", a2, b2); 272 | 273 | 274 | 275 | 276 | 277 | }if(i>=113){ 278 | printf("你们都真牛逼。\n"); 279 | }printf("PRESS ENTER\n"); 280 | getchar(); 281 | for(;getchar()!='\n';); 282 | system("clear"); 283 | 284 | } 285 | 286 | ///////////////////////////////////////////////////////////// 287 | // 函数名称: set_piece 288 | // 作用:将棋手player的棋子落在x行y列 289 | 290 | // 参数:无 291 | // 返回值:无 292 | ///////////////////////////////////////////////////////////// 293 | void set_piece(int x,int y, int player){ 294 | aRecordBoard[x][y]=player; 295 | current_x=x; 296 | current_y=y; 297 | } 298 | 299 | ///////////////////////////////////////////////////////////// 300 | // 函数名称: kinte 301 | // 作用:禁じ手を判断する 302 | 303 | // 参数:x, y, PLAYER 304 | // 返回值:0/1 305 | ///////////////////////////////////////////////////////////// 306 | int muda(int x, int y){ 307 | if(x<0||x>=SIZE||y<0||y>=SIZE||(aRecordBoard[x][y]!=0)){ 308 | return 1; 309 | }return 0; 310 | } 311 | int kinte(int x, int y, int PLAYER){ 312 | if(muda(x, y)==1){ 313 | return 1; 314 | }if(judge(x, y, PLAYER)){ 315 | return 0; 316 | }if(ikiyo(x, y, PLAYER)+okiyo(x, y, PLAYER)>1){ 317 | return 1; 318 | }if(real_ikimi(x, y, PLAYER)>1){ 319 | return 1; 320 | }if(nagatsure(x, y, PLAYER)){ 321 | return 1; 322 | }return 0; 323 | } 324 | 325 | ///////////////////////////////////////////////////////////// 326 | // 函数名称: judge 327 | // 作用:「そこ」では勝つのか否のかを判断する 328 | 329 | // 参数:x, y, player 330 | // 返回值:0/1 331 | ///////////////////////////////////////////////////////////// 332 | int bekaru(int x, int y, int PLAYER){ 333 | if(x<0||x>=SIZE||y<0||y>=SIZE||aRecordBoard[x][y]!=PLAYER){ 334 | return 0; 335 | }else{ 336 | return 1; 337 | } 338 | } 339 | 340 | int narugo(int x, int y, int PLAYER){ 341 | int r=0; 342 | if(muda(x, y)==1){ 343 | return 0; 344 | }aRecordBoard[x][y]=PLAYER; 345 | int i=x, j=y; 346 | for(i=x-4;i<=x;i++){ 347 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j, PLAYER)&&bekaru(i+2, j, PLAYER)&&bekaru(i+3, j, PLAYER)&&bekaru(i+4, j, PLAYER)){ 348 | if(PLAYER==PLAYER1){ 349 | if(!bekaru(i-1, j, PLAYER)&&!bekaru(i+5, j, PLAYER)){ 350 | r++; 351 | break; 352 | }else{ 353 | break; 354 | } 355 | }else{ 356 | r++; 357 | break; 358 | } 359 | } 360 | }i=x; 361 | j=y; 362 | for(j=y-4;j<=y;j++){ 363 | if(bekaru(i, j, PLAYER)&&bekaru(i, j+1, PLAYER)&&bekaru(i, j+2, PLAYER)&&bekaru(i, j+3, PLAYER)&&bekaru(i, j+4, PLAYER)){ 364 | if(PLAYER==PLAYER1){ 365 | if(!bekaru(i, j-1, PLAYER)&&!bekaru(i, j+5, PLAYER)){ 366 | r++; 367 | break; 368 | }else{ 369 | break; 370 | } 371 | }else{ 372 | r++; 373 | break; 374 | } 375 | } 376 | }i=x; 377 | j=y; 378 | for(i=x-4,j=y-4;i<=x;i++,j++){ 379 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j+1, PLAYER)&&bekaru(i+2, j+2, PLAYER)&&bekaru(i+3, j+3, PLAYER)&&bekaru(i+4, j+4, PLAYER)){ 380 | if(PLAYER==PLAYER1){ 381 | if(!bekaru(i-1, j-1, PLAYER)&&!bekaru(i+5, j+5, PLAYER)){ 382 | r++; 383 | break; 384 | }else{ 385 | break; 386 | } 387 | }else{ 388 | r++; 389 | break; 390 | } 391 | } 392 | }i=x; 393 | j=y; 394 | for(i=x-4,j=y+4;i<=x;i++,j--){ 395 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j-1, PLAYER)&&bekaru(i+2, j-2, PLAYER)&&bekaru(i+3, j-3, PLAYER)&&bekaru(i+4, j-4, PLAYER)){ 396 | if(PLAYER==PLAYER1){ 397 | if(!bekaru(i-1, j+1, PLAYER)&&!bekaru(i+5, j-5, PLAYER)){ 398 | r++; 399 | break; 400 | }else{ 401 | break; 402 | } 403 | }else{ 404 | r++; 405 | break; 406 | } 407 | } 408 | }aRecordBoard[x][y]=0; 409 | return r; 410 | } 411 | 412 | int judge(int x, int y, int PLAYER){ 413 | if(muda(x, y)){ 414 | return 0; 415 | }if(narugo(x, y, PLAYER)){ 416 | return 1; 417 | }else{ 418 | return 0; 419 | } 420 | } 421 | 422 | ///////////////////////////////////////////////////////////// 423 | // 函数名称:initRecordBorard 424 | // 作用:初始化二维数组aRecordBoard 425 | // 参数:无 426 | // 返回值:无 427 | ///////////////////////////////////////////////////////////// 428 | void initRecordBorard(void){ 429 | 430 | //通过双重循环,将aRecordBoard清0 431 | int i, j; 432 | for(i=0;ia[2*i+1].value){ 518 | temp = a[2*i+1]; 519 | a[2*i+1] = a[i]; 520 | a[i] = temp; 521 | i = 2*i+1; 522 | }else if(2*i+2a[2*i+2].value){ 523 | temp = a[2*i+2]; 524 | a[2*i+2] = a[i]; 525 | a[i] = temp; 526 | i = 2*i+2; 527 | }else{ 528 | break; 529 | } 530 | } 531 | } 532 | 533 | struct point autoret(){ 534 | struct point r, temp; 535 | struct point ord1[SEARCHBEAM1], ord2[SEARCHBEAM1][SEARCHBEAM2]; 536 | int max1[SEARCHBEAM1], min2[SEARCHBEAM2]; 537 | int adversarial_player = !(current_player-1)+1; 538 | int i=0, j=0, m=0, n=0; 539 | int i0=0, j0=0; 540 | int max, min; 541 | int tmpscr; 542 | 543 | //开始初始化一级与二级最小堆; 544 | for(i=0; iord1[0].value&&!muda(i, j)){ 562 | myminiheap(ord1, SEARCHBEAM1, temp); 563 | } 564 | } 565 | }for(m=0; mord2[m][0].value&&!muda(i, j)){ 579 | myminiheap(ord2[m], SEARCHBEAM2, temp); 580 | } 581 | } 582 | }for(n=0; nmax){ 607 | max=tmpscr; 608 | i0=i; 609 | j0=j; 610 | } 611 | } 612 | } 613 | 614 | //三级剪枝完毕,填充第二层搜索框一位并去掉伪子 615 | min2[n] = 1/(1+GREEDYRATE)*ord1[m].value - 1/(1+ADVGREEDYRATE)*ADVERSCONS*ord2[m][n].value + GREEDYRATE/(1+GREEDYRATE)*autoscore(i0, j0, current_player) - ADVGREEDYRATE/(1+ADVGREEDYRATE)*PRUNEADV*autoscore2(i0, j0, adversarial_player); 616 | aRecordBoard[ord2[m][n].x][ord2[m][n].y]=0; 617 | } 618 | 619 | //第二层搜索框返回所有结果,取极小值填充第一层搜索框的第m位内容、取掉伪子 620 | min=2147483647; 621 | for(i=0; imax){ 639 | max = max1[i]; 640 | r.x = ord1[i].x; 641 | r.y = ord1[i].y; 642 | r.value = max1[i]; 643 | }score[ord1[i].x][ord1[i].y]=max1[i]; 644 | } 645 | return r; 646 | } 647 | 648 | ///////////////////////////////////////////////////////////// 649 | // 函数名称:autoscore 650 | // 作用:empirical energy function 651 | // 参数:x, y, PLAYER 652 | // 返回值:int 653 | ///////////////////////////////////////////////////////////// 654 | int autoscore(int x, int y, int PLAYER){ 655 | if(kinte(x, y, PLAYER)){ 656 | return 0; 657 | }else{ 658 | int hi=tanehi(x, y, PLAYER), hu=ikihu(x, y, PLAYER), omi=okimi(x, y, PLAYER), mi=ikimi(x, y, PLAYER), oyo=okiyo(x, y, PLAYER), his1=hissatsu1(x, y, PLAYER), his2=hissatsu2(x, y, PLAYER), yo=ikiyo(x, y, PLAYER), itsu=narugo(x, y, PLAYER); 659 | return (hi+120*hu+130*omi+12000*mi+105000*oyo+90000*his2+95000*his1+300000*yo+3000000*itsu); 660 | } 661 | } 662 | 663 | int autoscore2(int x, int y, int PLAYER){ 664 | if(kinte(x, y, PLAYER)){ 665 | return 0; 666 | }else{ 667 | int hi=tanehi(x, y, PLAYER), hu=ikihu(x, y, PLAYER), omi=okimi(x, y, PLAYER), mi=ikimi(x, y, PLAYER), oyo=okiyo(x, y, PLAYER), his1=hissatsu1(x, y, PLAYER), his2=hissatsu2(x, y, PLAYER), yo=ikiyo(x, y, PLAYER), itsu=narugo(x, y, PLAYER); 668 | return (hi+100*hu+120*omi+10000*mi+12000*oyo+90000*his2+95000*his1+300000*yo+1000000*itsu); 669 | } 670 | } 671 | 672 | ///////////////////////////////////////////////////////////// 673 | // 函数名称: 674 | // 作用:形を基準に得点を判断する 675 | // 参数: 676 | // 返回值: 677 | ///////////////////////////////////////////////////////////// 678 | int ikiyo(int x, int y, int PLAYER){ 679 | int r=0; 680 | if(muda(x, y)==1){ 681 | return 0; 682 | }aRecordBoard[x][y]=PLAYER; 683 | int i=x, j=y; 684 | for(i=x-3;i<=x;i++){ 685 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j, PLAYER)&&bekaru(i+2, j, PLAYER)&&bekaru(i+3, j, PLAYER)){ 686 | if(judge(i-1, j, PLAYER)&&judge(i+4, j, PLAYER)){ 687 | r++; 688 | break; 689 | } 690 | } 691 | }i=x; 692 | j=y; 693 | for(j=y-3;j<=y;j++){ 694 | if(bekaru(i, j, PLAYER)&&bekaru(i, j+1, PLAYER)&&bekaru(i, j+2, PLAYER)&&bekaru(i, j+3, PLAYER)){ 695 | if(judge(i, j-1, PLAYER)&&judge(i, j+4, PLAYER)){ 696 | r++; 697 | break; 698 | } 699 | } 700 | }i=x; 701 | j=y; 702 | for(i=x-3,j=y-3;i<=x;i++,j++){ 703 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j+1, PLAYER)&&bekaru(i+2, j+2, PLAYER)&&bekaru(i+3, j+3, PLAYER)){ 704 | if(judge(i-1, j-1, PLAYER)&&judge(i+4, j+4, PLAYER)){ 705 | r++; 706 | break; 707 | } 708 | } 709 | }i=x; 710 | j=y; 711 | for(i=x-3,j=y+3;i<=x;i++,j--){ 712 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j-1, PLAYER)&&bekaru(i+2, j-2, PLAYER)&&bekaru(i+3, j-3, PLAYER)){ 713 | if(judge(i-1, j+1, PLAYER)&&judge(i+4, j-4, PLAYER)){ 714 | r++; 715 | break; 716 | } 717 | } 718 | }aRecordBoard[x][y]=0; 719 | return r; 720 | } 721 | 722 | int okiyo(int x, int y, int PLAYER){ 723 | int r=0; 724 | if(muda(x, y)==1){ 725 | return 0; 726 | }aRecordBoard[x][y]=PLAYER; 727 | int i=x, j=y, k=0; 728 | for(i=x-4;i<=x;i++){ 729 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)+bekaru(i+4, j, PLAYER)==4){ 730 | for(k=0;k<=4&&bekaru(i+k, j, PLAYER);k++); 731 | if(judge(i+k, j, PLAYER)){ 732 | if(k==0||k==4){ 733 | if((k==0&&!judge(i+5, j, PLAYER))||(k==4&&!judge(i-1, j, PLAYER))){ 734 | r++; 735 | } 736 | }else{ 737 | r++; 738 | } 739 | } 740 | } 741 | }i=x; 742 | j=y; 743 | for(j=y-4;j<=y;j++){ 744 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)+bekaru(i, j+4, PLAYER)==4){ 745 | for(k=0;k<=4&&bekaru(i, j+k, PLAYER);k++); 746 | if(judge(i, j+k, PLAYER)){ 747 | if(k==0||k==4){ 748 | if((k==0&&!judge(i, j+5, PLAYER))||(k==4&&!judge(i, j-1, PLAYER))){ 749 | r++; 750 | } 751 | }else{ 752 | r++; 753 | } 754 | } 755 | } 756 | }i=x; 757 | j=y; 758 | for(i=x-4,j=y-4;i<=x;i++,j++){ 759 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)+bekaru(i+4, j+4, PLAYER)==4){ 760 | for(k=0;k<=4&&bekaru(i+k, j+k, PLAYER);k++); 761 | if(judge(i+k, j+k, PLAYER)){ 762 | if(k==0||k==4){ 763 | if((k==0&&!judge(i+5, j+5, PLAYER))||(k==4&&!judge(i-1, j-1, PLAYER))){ 764 | r++; 765 | } 766 | }else{ 767 | r++; 768 | } 769 | } 770 | } 771 | }i=x; 772 | j=y; 773 | for(i=x-4,j=y+4;i<=x;i++,j--){ 774 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)+bekaru(i+4, j-4, PLAYER)==4){ 775 | for(k=0;k<=4&&bekaru(i+k, j-k, PLAYER);k++); 776 | if(judge(i+k, j-k, PLAYER)){ 777 | if(k==0||k==4){ 778 | if((k==0&&!judge(i+5, j-5, PLAYER))||(k==4&&!judge(i-1, j+1, PLAYER))){ 779 | r++; 780 | } 781 | }else{ 782 | r++; 783 | } 784 | } 785 | } 786 | }aRecordBoard[x][y]=0; 787 | return r; 788 | } 789 | 790 | int real_ikimi(int x, int y, int PLAYER){ 791 | int r=0; 792 | if(muda(x, y)==1){ 793 | return 0; 794 | }aRecordBoard[x][y]=PLAYER; 795 | int i=x, j=y, k=0; 796 | for(i=x-3;i<=x;i++){ 797 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)==3){ 798 | for(k=0;k<=3&&bekaru(i+k, j, PLAYER);k++); 799 | if(ikiyo(i+k, j, PLAYER)){ 800 | if(!kinte(i+k, j, PLAYER)){ 801 | r++; 802 | break; 803 | } 804 | } 805 | } 806 | }i=x; 807 | j=y; 808 | for(j=y-3;j<=y;j++){ 809 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)==3){ 810 | for(k=0;k<=3&&bekaru(i, j+k, PLAYER);k++); 811 | if(ikiyo(i, j+k, PLAYER)){ 812 | if(!kinte(i, j+k, PLAYER)){ 813 | r++; 814 | break; 815 | } 816 | } 817 | } 818 | }i=x; 819 | j=y; 820 | for(i=x-3,j=y-3;i<=x;i++,j++){ 821 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)==3){ 822 | for(k=0;k<=3&&bekaru(i+k, j+k, PLAYER);k++); 823 | if(ikiyo(i+k, j+k, PLAYER)){ 824 | if(!kinte(i+k, j+k, PLAYER)){ 825 | r++; 826 | break; 827 | } 828 | } 829 | } 830 | }i=x; 831 | j=y; 832 | for(i=x-3,j=y+3;i<=x;i++,j--){ 833 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)==3){ 834 | for(k=0;k<=3&&bekaru(i+k, j-k, PLAYER);k++); 835 | if(ikiyo(i+k, j-k, PLAYER)){ 836 | if(!kinte(i+k, j-k, PLAYER)){ 837 | r++; 838 | break; 839 | } 840 | } 841 | } 842 | }aRecordBoard[x][y]=0; 843 | return r; 844 | } 845 | 846 | int nagatsure(int x, int y, int PLAYER){ 847 | int r=0; 848 | if(muda(x, y)==1){ 849 | return 0; 850 | }aRecordBoard[x][y]=PLAYER; 851 | int i=x, j=y; 852 | for(i=x-5;i<=x;i++){ 853 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j, PLAYER)&&bekaru(i+2, j, PLAYER)&&bekaru(i+3, j, PLAYER)&&bekaru(i+4, j, PLAYER)&&bekaru(i+5, j, PLAYER)){ 854 | r++; 855 | break; 856 | } 857 | }i=x; 858 | j=y; 859 | for(j=y-5;j<=y;j++){ 860 | if(bekaru(i, j, PLAYER)&&bekaru(i, j+1, PLAYER)&&bekaru(i, j+2, PLAYER)&&bekaru(i, j+3, PLAYER)&&bekaru(i, j+4, PLAYER)&&bekaru(i, j+5, PLAYER)){ 861 | r++; 862 | break; 863 | } 864 | }i=x; 865 | j=y; 866 | for(i=x-5,j=y-5;i<=x;i++,j++){ 867 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j+1, PLAYER)&&bekaru(i+2, j+2, PLAYER)&&bekaru(i+3, j+3, PLAYER)&&bekaru(i+4, j+4, PLAYER)&&bekaru(i+5, j+5, PLAYER)){ 868 | r++; 869 | break; 870 | } 871 | }i=x; 872 | j=y; 873 | for(i=x-5,j=y+5;i<=x;i++,j--){ 874 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j-1, PLAYER)&&bekaru(i+2, j-2, PLAYER)&&bekaru(i+3, j-3, PLAYER)&&bekaru(i+4, j-4, PLAYER)&&bekaru(i+5, j-5, PLAYER)){ 875 | r++; 876 | break; 877 | } 878 | }aRecordBoard[x][y]=0; 879 | return r; 880 | } 881 | 882 | int ikihu(int x, int y, int PLAYER){ 883 | int r=0, i=0; 884 | if(muda(x, y)==1){ 885 | return 0; 886 | }aRecordBoard[x][y]=PLAYER; 887 | for(i=-1;i<=1;i+=2){ 888 | if(bekaru(x+i, y, PLAYER)&&ikimi(x-i, y, PLAYER)){ 889 | r++; 890 | }if(bekaru(x, y+i, PLAYER)&&ikimi(x, y-i, PLAYER)){ 891 | r++; 892 | }if(bekaru(x+i, y+i, PLAYER)&&ikimi(x-i, y-i, PLAYER)){ 893 | r++; 894 | }if(bekaru(x+i, y-i, PLAYER)&&ikimi(x-i, y+i, PLAYER)){ 895 | r++; 896 | }if(bekaru(x+2*i, y, PLAYER)&&ikimi(x+i, y, PLAYER)){ 897 | r++; 898 | }if(bekaru(x, y+2*i, PLAYER)&&ikimi(x, y+i, PLAYER)){ 899 | r++; 900 | }if(bekaru(x+2*i, y+2*i, PLAYER)&&ikimi(x+i, y+i, PLAYER)){ 901 | r++; 902 | }if(bekaru(x+2*i, y-2*i, PLAYER)&&ikimi(x+i, y-i, PLAYER)){ 903 | r++; 904 | } 905 | }aRecordBoard[x][y]=0; 906 | return r; 907 | } 908 | 909 | int tanehi(int x, int y, int PLAYER){ 910 | int r=0, i=0; 911 | if(muda(x, y)==1){ 912 | return 0; 913 | }for(i=-1;i<=1;i+=2){ 914 | r+=(bekaru(x+i, y, PLAYER)+bekaru(x, y+i, PLAYER)+bekaru(x+i, y+i, PLAYER)+bekaru(x+i, y-i, PLAYER)); 915 | }return r; 916 | } 917 | 918 | int real_okimi(int x, int y, int PLAYER){ 919 | int r=0; 920 | if(muda(x, y)==1){ 921 | return 0; 922 | }aRecordBoard[x][y]=PLAYER; 923 | int i=x, j=y, k=0; 924 | for(i=x-4;i<=x;i++){ 925 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)+bekaru(i+4, j, PLAYER)==3){ 926 | if(!bekaru(i, j, PLAYER)&&!bekaru(i+4, j, PLAYER)){ 927 | for(k=-1;k<=5;k++){ 928 | if(!bekaru(i+k, j, PLAYER)&&okiyo(i+k, j, PLAYER)&&!kinte(i+k, j, PLAYER)){ 929 | r++; 930 | break; 931 | } 932 | } 933 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+3, j, PLAYER)&&!bekaru(i+4, j, PLAYER)){ 934 | for(k=-1;k<=4;k++){ 935 | if(!bekaru(i+k, j, PLAYER)&&okiyo(i+k, j, PLAYER)&&!kinte(i+k, j, PLAYER)){ 936 | r++; 937 | break; 938 | } 939 | } 940 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+4, j, PLAYER)){ 941 | for(k=0;k<=4;k++){ 942 | if(!bekaru(i+k, j, PLAYER)&&okiyo(i+k, j, PLAYER)&&!kinte(i+k, j, PLAYER)){ 943 | r++; 944 | break; 945 | } 946 | } 947 | } 948 | } 949 | }i=x; 950 | j=y; 951 | for(j=y-4;j<=y;j++){ 952 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)+bekaru(i, j+4, PLAYER)==3){ 953 | if(!bekaru(i, j, PLAYER)&&!bekaru(i, j+4, PLAYER)){ 954 | for(k=-1;k<=5;k++){ 955 | if(!bekaru(i, j+k, PLAYER)&&okiyo(i, j+k, PLAYER)&&!kinte(i, j+k, PLAYER)){ 956 | r++; 957 | break; 958 | } 959 | } 960 | }else if(bekaru(i, j, PLAYER)&&bekaru(i, j+3, PLAYER)&&!bekaru(i, j+4, PLAYER)){ 961 | for(k=-1;k<=4;k++){ 962 | if(!bekaru(i, j+k, PLAYER)&&okiyo(i, j+k, PLAYER)&&!kinte(i, j+k, PLAYER)){ 963 | r++; 964 | break; 965 | } 966 | } 967 | }else if(bekaru(i, j, PLAYER)&&bekaru(i, j+4, PLAYER)){ 968 | for(k=0;k<=4;k++){ 969 | if(!bekaru(i, j+k, PLAYER)&&okiyo(i, j+k, PLAYER)&&!kinte(i, j+k, PLAYER)){ 970 | r++; 971 | break; 972 | } 973 | } 974 | } 975 | } 976 | }i=x; 977 | j=y; 978 | for(i=x-4,j=y-4;i<=x;i++,j++){ 979 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)+bekaru(i+4, j+4, PLAYER)==3){ 980 | if(!bekaru(i, j, PLAYER)&&!bekaru(i+4, j+4, PLAYER)){ 981 | for(k=-1;k<=5;k++){ 982 | if(!bekaru(i+k, j+k, PLAYER)&&okiyo(i+k, j+k, PLAYER)&&!kinte(i+k, j+k, PLAYER)){ 983 | r++; 984 | break; 985 | } 986 | } 987 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+3, j+3, PLAYER)&&!bekaru(i+4, j+4, PLAYER)){ 988 | for(k=-1;k<=4;k++){ 989 | if(!bekaru(i+k, j+k, PLAYER)&&okiyo(i+k, j+k, PLAYER)&&!kinte(i+k, j+k, PLAYER)){ 990 | r++; 991 | break; 992 | } 993 | } 994 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+4, j+4, PLAYER)){ 995 | for(k=0;k<=4;k++){ 996 | if(!bekaru(i+k, j+k, PLAYER)&&okiyo(i+k, j+k, PLAYER)&&!kinte(i+k, j+k, PLAYER)){ 997 | r++; 998 | break; 999 | } 1000 | } 1001 | } 1002 | } 1003 | }i=x; 1004 | j=y; 1005 | for(i=x-4,j=y+4;i<=x;i++,j--){ 1006 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)+bekaru(i+4, j-4, PLAYER)==3){ 1007 | if(!bekaru(i, j, PLAYER)&&!bekaru(i+4, j-4, PLAYER)){ 1008 | for(k=-1;k<=5;k++){ 1009 | if(!bekaru(i+k, j-k, PLAYER)&&okiyo(i+k, j-k, PLAYER)&&!kinte(i+k, j-k, PLAYER)){ 1010 | r++; 1011 | break; 1012 | } 1013 | } 1014 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+3, j-3, PLAYER)&&!bekaru(i+4, j-4, PLAYER)){ 1015 | for(k=-1;k<=4;k++){ 1016 | if(!bekaru(i+k, j-k, PLAYER)&&okiyo(i+k, j-k, PLAYER)&&!kinte(i+k, j-k, PLAYER)){ 1017 | r++; 1018 | break; 1019 | } 1020 | } 1021 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+4, j-4, PLAYER)){ 1022 | for(k=0;k<=4;k++){ 1023 | if(!bekaru(i+k, j-k, PLAYER)&&okiyo(i+k, j-k, PLAYER)&&!kinte(i+k, j-k, PLAYER)){ 1024 | r++; 1025 | break; 1026 | } 1027 | } 1028 | } 1029 | } 1030 | }aRecordBoard[x][y]=0; 1031 | return r; 1032 | } 1033 | 1034 | int hissatsu1(int x, int y, int PLAYER){ 1035 | if(kinte(x, y, PLAYER)){ 1036 | return 0; 1037 | }if(okiyo(x, y, PLAYER)+ikimi(x, y, PLAYER)>1){ 1038 | return 1; 1039 | }return 0; 1040 | } 1041 | 1042 | int hisnum1(int x, int y, int PLAYER){ 1043 | if(kinte(x, y, PLAYER)){ 1044 | return 0; 1045 | }aRecordBoard[x][y]=PLAYER; 1046 | int r=0, i; 1047 | for(i=-4;i<=4;i++){ 1048 | if(hissatsu1(x+i, y, PLAYER)){ 1049 | r++; 1050 | }if(hissatsu1(x, y+i, PLAYER)){ 1051 | r++; 1052 | }if(hissatsu1(x+i, y+i, PLAYER)){ 1053 | r++; 1054 | }if(hissatsu1(x+i, y-i, PLAYER)){ 1055 | r++; 1056 | } 1057 | }aRecordBoard[x][y]=0; 1058 | return r; 1059 | } 1060 | 1061 | int hissatsu2(int x, int y, int PLAYER){ 1062 | if(kinte(x, y, PLAYER)){ 1063 | return 0; 1064 | }if(hissatsu1(x, y, PLAYER)){ 1065 | return 0; 1066 | }if(okiyo(x, y, PLAYER)+ikimi(x, y, PLAYER)+hisnum1(x, y, PLAYER)>1){ 1067 | return 1; 1068 | }return 0; 1069 | } 1070 | 1071 | ///////////////////////////////////////////////////////////// 1072 | // 函数名称: 1073 | // 作用:誰も見ることのない新世界。 1074 | // 参数: 1075 | // 返回值: 1076 | ///////////////////////////////////////////////////////////// 1077 | int hameyo(int x, int y, int PLAYER){ 1078 | int r=0; 1079 | if(muda(x, y)==1){ 1080 | return 0; 1081 | }aRecordBoard[x][y]=PLAYER; 1082 | int i=x, j=y, k=0; 1083 | for(i=x-4;i<=x;i++){ 1084 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)+bekaru(i+4, j, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i+4, j, PLAYER)){ 1085 | if((judge(i+1, j, PLAYER)&&x!=i)||(judge(i+3, j, PLAYER)&&x!=i+4)){ 1086 | r++; 1087 | } 1088 | } 1089 | }i=x; 1090 | j=y; 1091 | for(j=y-4;j<=y;j++){ 1092 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)+bekaru(i, j+4, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i, j+4, PLAYER)){ 1093 | if((judge(i, j+1, PLAYER)&&y!=j)||(judge(i, j+3, PLAYER)&&y!=j+4)){ 1094 | r++; 1095 | } 1096 | } 1097 | }i=x; 1098 | j=y; 1099 | for(i=x-4,j=y-4;i<=x;i++,j++){ 1100 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)+bekaru(i+4, j+4, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i+4, j+4, PLAYER)){ 1101 | if((judge(i+1, j+1, PLAYER)&&x!=i)||(judge(i+3, j+3, PLAYER)&&x!=i+4)){ 1102 | r++; 1103 | } 1104 | } 1105 | }i=x; 1106 | j=y; 1107 | for(i=x-4,j=y+4;i<=x;i++,j--){ 1108 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)+bekaru(i+4, j-4, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i+4, j-4, PLAYER)){ 1109 | if((judge(i+1, j-1, PLAYER)&&x!=i)||(judge(i+3, j-3, PLAYER)&&x!=i+4)){ 1110 | r++; 1111 | } 1112 | } 1113 | }aRecordBoard[x][y]=0; 1114 | return r; 1115 | } 1116 | 1117 | int ikimi(int x, int y, int PLAYER){ 1118 | return real_ikimi(x, y, PLAYER)-hameyo(x, y, PLAYER); 1119 | } 1120 | 1121 | int okimi(int x, int y, int PLAYER){ 1122 | return real_okimi(x, y, PLAYER)+hameyo(x, y, PLAYER); 1123 | } 1124 | -------------------------------------------------------------------------------- /game_theo/five_in_a_line/reference.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define SIZE 15 5 | #define PLAYER1 1 6 | #define PLAYER2 2 7 | 8 | //棋盘使用Unicode画的,一个符号占两个char,所以要*3,+1是为了末尾的'\0' 9 | char aInitDisplayBoardArray[SIZE+1][SIZE*3+1] = 10 | { 11 | "┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓", 12 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 13 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 14 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 15 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 16 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 17 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 18 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 19 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 20 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 21 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 22 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 23 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 24 | "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨", 25 | "┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛", 26 | "A B C D E F G H I J K L M N O" 27 | }; 28 | //此数组用于显示 29 | char aDisplayBoardArray[SIZE+1][SIZE*3+1]; 30 | //此数组用于算法计算使用 31 | int aRecordBoard[SIZE][SIZE];// 32 | char play1Pic[]="●"; 33 | char play2Pic[]="◎"; 34 | char _play1Pic[]="▲"; 35 | char _play2Pic[]="△"; 36 | //棋手最近一次落子时的坐标 37 | int current_x;//行号 38 | int current_y;//列号 39 | int current_player; 40 | 41 | struct point{ 42 | int x; 43 | int y; 44 | int value; 45 | }; 46 | 47 | 48 | void initRecordBorard(void); 49 | void recordtoDisplayArray(void); 50 | void displayBoard(void); 51 | void set_piece(int x,int y, int player); 52 | int narugo(int x, int y, int PLAYER); 53 | int judge(int x, int y, int PLAYER); 54 | int muda(int x, int y); 55 | int kinte(int x, int y, int PLAYER); 56 | int bekaru(int x, int y, int PLAYER); 57 | int ikiyo(int x, int y, int PLAYER); 58 | int okiyo(int x, int y, int PLAYER); 59 | int real_ikimi(int x, int y, int PLAYER); 60 | int nagatsure(int x, int y, int PLAYER); 61 | int autoscore(int x, int y, int PLAYER); 62 | struct point autoret(); 63 | struct point ret(); 64 | int score[15][15]; 65 | struct point mystart[6]={{7,7,0}, {8,7,0}, {9,7,0}, {8,8,0}, {9,8,0}, {9,9,0}}; 66 | int myrandomizer=-1, myrandoms; 67 | 68 | 69 | void main(){ 70 | void ningendoushi(); 71 | void wagakokoro(); 72 | char C1, C2, C3; 73 | for(;;){ 74 | system("clear"); 75 | printf(" 五 子 棋\nFive in a Row\n 五目並べ\n\nPRESS ENTER\n\nMikazu S. Takahashi (Ziyue Ji)\n\n"); 76 | for(;getchar()!='\n';); 77 | system("clear"); 78 | printf("SELECT YOUR MODE\n1=对战程序\n2=双人游戏\n\n"); 79 | for(;(C1=getchar())!='1'&&C1!='2';); 80 | if(C1=='1'){ 81 | system("clear"); 82 | printf("Versus The Computer - プログラムに挑戦する\n 继续?Y/N\n"); 83 | for(;(C2=getchar())!='Y'&&C2!='y'&&C2!='N'&&C2!='n';); 84 | if(C2=='Y'||C2=='y'){ 85 | wagakokoro(); 86 | printf("继续?Y/N\n"); 87 | for(;(C3=getchar())!='Y'&&C3!='y'&&C3!='N'&&C3!='n';); 88 | if(C3=='N'||C3=='n'){ 89 | break; 90 | }else{ 91 | getchar(); 92 | } 93 | } 94 | }else{ 95 | system("clear"); 96 | printf("Person versus person - 二人で遊ぶ\n 继续?Y/N\n"); 97 | for(;(C2=getchar())!='Y'&&C2!='y'&&C2!='N'&&C2!='n';); 98 | if(C2=='Y'||C2=='y'){ 99 | ningendoushi(); 100 | printf("继续?Y/N\n"); 101 | for(;(C3=getchar())!='Y'&&C3!='y'&&C3!='N'&&C3!='n';); 102 | if(C3=='N'||C3=='n'){ 103 | break; 104 | }else{ 105 | getchar(); 106 | } 107 | } 108 | } 109 | } 110 | } 111 | 112 | void wagakokoro(){ 113 | 114 | int a1, b1, i, kachi1, kachi2, CHAL, MYAI; 115 | char C4; 116 | struct point RET; 117 | 118 | system("clear"); 119 | printf("挑战者,请您选择自己喜欢的颜色。\nY=Black N=White\n"); 120 | for(;(C4=getchar())!='Y'&&C4!='y'&&C4!='N'&&C4!='n';); 121 | if(C4=='Y'||C4=='y'){ 122 | CHAL=PLAYER1; 123 | MYAI=PLAYER2; 124 | }else if(C4=='N'||C4=='n'){ 125 | CHAL=PLAYER2; 126 | MYAI=PLAYER1; 127 | } 128 | 129 | initRecordBorard(); 130 | recordtoDisplayArray(); 131 | displayBoard(); 132 | current_player=PLAYER1; 133 | 134 | 135 | for(i=0;i<225;i++){ 136 | if(current_player==CHAL){ 137 | for(;;){ 138 | printf("请输入您的落子位置:\n"); 139 | scanf("%d, %d", &a1, &b1); 140 | if(muda(a1-1, b1-1)==1){ 141 | displayBoard(); 142 | printf("无法在此处落子。\n"); 143 | }else{ 144 | break; 145 | } 146 | }if(kinte(a1-1, b1-1, CHAL)==1){ 147 | displayBoard(); 148 | printf("很遗憾您下出了禁手(详见wikipedia五子棋规则),\n因此我获胜了。\n"); 149 | break; 150 | }else{ 151 | kachi1=judge(a1-1, b1-1, CHAL); 152 | set_piece(a1-1,b1-1,CHAL); 153 | }recordtoDisplayArray(); 154 | displayBoard(); 155 | if(kachi1==1){ 156 | printf("您获胜了。 恭喜!\n"); 157 | break; 158 | } 159 | }else if(current_player==MYAI){ 160 | 161 | 162 | 163 | 164 | 165 | RET=autoret(); 166 | if(i==0){ 167 | for(;(myrandoms=(rand()%6))==myrandomizer;); 168 | myrandomizer=myrandoms; 169 | RET=mystart[myrandomizer]; 170 | }kachi2=judge(RET.x, RET.y, MYAI); 171 | set_piece(RET.x, RET.y, MYAI); 172 | recordtoDisplayArray(); 173 | displayBoard(); 174 | if(kachi2==1){ 175 | printf("我获胜了, 您还需精进技艺。\n"); 176 | break; 177 | }printf("我的出招是(%d,%d),您的对策如何?\n", RET.x+1, RET.y+1); 178 | } 179 | 180 | 181 | if(current_player==CHAL){ 182 | current_player=MYAI; 183 | }else if(current_player==MYAI){ 184 | current_player=CHAL; 185 | } 186 | 187 | 188 | 189 | 190 | 191 | }if(i>=225){ 192 | printf("你真牛逼。\n"); 193 | }printf("PRESS ENTER\n"); 194 | getchar(); 195 | for(;getchar()!='\n';); 196 | system("clear"); 197 | 198 | } 199 | 200 | void ningendoushi() 201 | { 202 | initRecordBorard(); 203 | recordtoDisplayArray(); 204 | displayBoard(); 205 | int a1, b1, a2, b2, i, kachi1, kachi2; 206 | for(i=0;i<113;i++){ 207 | 208 | 209 | 210 | for(;;){ 211 | printf("玩家1请输入落子位置:\n"); 212 | current_player=PLAYER1; 213 | scanf("%d, %d", &a1, &b1); 214 | if(muda(a1-1, b1-1)==1){ 215 | displayBoard(); 216 | printf("此处无法落子。\n"); 217 | }else{ 218 | break; 219 | } 220 | }if(kinte(a1-1, b1-1, PLAYER1)==1){ 221 | displayBoard(); 222 | printf("您下出了禁手(详见wikipedia五子棋规则),\n玩家2获胜了! 恭喜!\n"); 223 | break; 224 | }else{ 225 | kachi1=judge(a1-1, b1-1, PLAYER1); 226 | set_piece(a1-1,b1-1,PLAYER1); 227 | }recordtoDisplayArray(); 228 | displayBoard(); 229 | if(kachi1==1){ 230 | printf("玩家1获胜了! 恭喜!\n"); 231 | break; 232 | }printf("对方出招为(%d,%d),您的对策如何?\n", a1, b1); 233 | 234 | 235 | 236 | 237 | 238 | 239 | for(;;){ 240 | printf("玩家2请输入落子位置:\n"); 241 | current_player=PLAYER2; 242 | scanf("%d, %d", &a2, &b2); 243 | if(muda(a2-1, b2-1)==1){ 244 | displayBoard(); 245 | printf("此处无法落子。\n"); 246 | }else{ 247 | break; 248 | } 249 | }if(kinte(a2-1, b2-1, PLAYER2)==1){ 250 | displayBoard(); 251 | printf("您下出了禁手(详见wikipedia五子棋规则),\n玩家1获胜了! 恭喜!\n"); 252 | break; 253 | }else{ 254 | kachi2=judge(a2-1, b2-1, PLAYER2); 255 | set_piece(a2-1,b2-1,PLAYER2); 256 | }recordtoDisplayArray(); 257 | displayBoard(); 258 | if(kachi2==1){ 259 | printf("玩家2获胜了! 恭喜!\n"); 260 | break; 261 | }printf("对方出招为(%d,%d),您的对策如何?\n", a2, b2); 262 | 263 | 264 | 265 | 266 | 267 | }if(i>=113){ 268 | printf("你们都真牛逼。\n"); 269 | }printf("PRESS ENTER\n"); 270 | getchar(); 271 | for(;getchar()!='\n';); 272 | system("clear"); 273 | 274 | } 275 | ///////////////////////////////////////////////////////////// 276 | // 函数名称: set_piece 277 | // 作用:将棋手player的棋子落在x行y列 278 | 279 | // 参数:无 280 | // 返回值:无 281 | ///////////////////////////////////////////////////////////// 282 | 283 | void set_piece(int x,int y, int player){ 284 | aRecordBoard[x][y]=player; 285 | current_x=x; 286 | current_y=y; 287 | } 288 | 289 | ///////////////////////////////////////////////////////////// 290 | // 函数名称: kinte 291 | // 作用:禁じ手を判断する 292 | 293 | // 参数:x, y, PLAYER 294 | // 返回值:0/1 295 | ///////////////////////////////////////////////////////////// 296 | int muda(int x, int y){ 297 | if(x<0||x>14||y<0||y>14||(aRecordBoard[x][y]!=0)){ 298 | return 1; 299 | }return 0; 300 | } 301 | int kinte(int x, int y, int PLAYER){ 302 | if(muda(x, y)==1){ 303 | return 1; 304 | }if(judge(x, y, PLAYER)){ 305 | return 0; 306 | }if(ikiyo(x, y, PLAYER)+okiyo(x, y, PLAYER)>1){ 307 | return 1; 308 | }if(real_ikimi(x, y, PLAYER)>1){ 309 | return 1; 310 | }if(nagatsure(x, y, PLAYER)){ 311 | return 1; 312 | }return 0; 313 | } 314 | 315 | 316 | 317 | 318 | 319 | 320 | int ikiyo(int x, int y, int PLAYER){ 321 | int r=0; 322 | if(muda(x, y)==1){ 323 | return 0; 324 | }aRecordBoard[x][y]=PLAYER; 325 | int i=x, j=y; 326 | for(i=x-3;i<=x;i++){ 327 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j, PLAYER)&&bekaru(i+2, j, PLAYER)&&bekaru(i+3, j, PLAYER)){ 328 | if(judge(i-1, j, PLAYER)&&judge(i+4, j, PLAYER)){ 329 | r++; 330 | break; 331 | } 332 | } 333 | }i=x; 334 | j=y; 335 | for(j=y-3;j<=y;j++){ 336 | if(bekaru(i, j, PLAYER)&&bekaru(i, j+1, PLAYER)&&bekaru(i, j+2, PLAYER)&&bekaru(i, j+3, PLAYER)){ 337 | if(judge(i, j-1, PLAYER)&&judge(i, j+4, PLAYER)){ 338 | r++; 339 | break; 340 | } 341 | } 342 | }i=x; 343 | j=y; 344 | for(i=x-3,j=y-3;i<=x;i++,j++){ 345 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j+1, PLAYER)&&bekaru(i+2, j+2, PLAYER)&&bekaru(i+3, j+3, PLAYER)){ 346 | if(judge(i-1, j-1, PLAYER)&&judge(i+4, j+4, PLAYER)){ 347 | r++; 348 | break; 349 | } 350 | } 351 | }i=x; 352 | j=y; 353 | for(i=x-3,j=y+3;i<=x;i++,j--){ 354 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j-1, PLAYER)&&bekaru(i+2, j-2, PLAYER)&&bekaru(i+3, j-3, PLAYER)){ 355 | if(judge(i-1, j+1, PLAYER)&&judge(i+4, j-4, PLAYER)){ 356 | r++; 357 | break; 358 | } 359 | } 360 | }aRecordBoard[x][y]=0; 361 | return r; 362 | } 363 | 364 | 365 | 366 | 367 | 368 | 369 | int okiyo(int x, int y, int PLAYER){ 370 | int r=0; 371 | if(muda(x, y)==1){ 372 | return 0; 373 | }aRecordBoard[x][y]=PLAYER; 374 | int i=x, j=y, k=0; 375 | for(i=x-4;i<=x;i++){ 376 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)+bekaru(i+4, j, PLAYER)==4){ 377 | for(k=0;k<=4&&bekaru(i+k, j, PLAYER);k++); 378 | if(judge(i+k, j, PLAYER)){ 379 | if(k==0||k==4){ 380 | if((k==0&&!judge(i+5, j, PLAYER))||(k==4&&!judge(i-1, j, PLAYER))){ 381 | r++; 382 | } 383 | }else{ 384 | r++; 385 | } 386 | } 387 | } 388 | }i=x; 389 | j=y; 390 | for(j=y-4;j<=y;j++){ 391 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)+bekaru(i, j+4, PLAYER)==4){ 392 | for(k=0;k<=4&&bekaru(i, j+k, PLAYER);k++); 393 | if(judge(i, j+k, PLAYER)){ 394 | if(k==0||k==4){ 395 | if((k==0&&!judge(i, j+5, PLAYER))||(k==4&&!judge(i, j-1, PLAYER))){ 396 | r++; 397 | } 398 | }else{ 399 | r++; 400 | } 401 | } 402 | } 403 | }i=x; 404 | j=y; 405 | for(i=x-4,j=y-4;i<=x;i++,j++){ 406 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)+bekaru(i+4, j+4, PLAYER)==4){ 407 | for(k=0;k<=4&&bekaru(i+k, j+k, PLAYER);k++); 408 | if(judge(i+k, j+k, PLAYER)){ 409 | if(k==0||k==4){ 410 | if((k==0&&!judge(i+5, j+5, PLAYER))||(k==4&&!judge(i-1, j-1, PLAYER))){ 411 | r++; 412 | } 413 | }else{ 414 | r++; 415 | } 416 | } 417 | } 418 | }i=x; 419 | j=y; 420 | for(i=x-4,j=y+4;i<=x;i++,j--){ 421 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)+bekaru(i+4, j-4, PLAYER)==4){ 422 | for(k=0;k<=4&&bekaru(i+k, j-k, PLAYER);k++); 423 | if(judge(i+k, j-k, PLAYER)){ 424 | if(k==0||k==4){ 425 | if((k==0&&!judge(i+5, j-5, PLAYER))||(k==4&&!judge(i-1, j+1, PLAYER))){ 426 | r++; 427 | } 428 | }else{ 429 | r++; 430 | } 431 | } 432 | } 433 | }aRecordBoard[x][y]=0; 434 | return r; 435 | } 436 | 437 | 438 | 439 | 440 | 441 | int real_ikimi(int x, int y, int PLAYER){ 442 | int r=0; 443 | if(muda(x, y)==1){ 444 | return 0; 445 | }aRecordBoard[x][y]=PLAYER; 446 | int i=x, j=y, k=0; 447 | for(i=x-3;i<=x;i++){ 448 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)==3){ 449 | for(k=0;k<=3&&bekaru(i+k, j, PLAYER);k++); 450 | if(ikiyo(i+k, j, PLAYER)){ 451 | if(!kinte(i+k, j, PLAYER)){ 452 | r++; 453 | break; 454 | } 455 | } 456 | } 457 | }i=x; 458 | j=y; 459 | for(j=y-3;j<=y;j++){ 460 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)==3){ 461 | for(k=0;k<=3&&bekaru(i, j+k, PLAYER);k++); 462 | if(ikiyo(i, j+k, PLAYER)){ 463 | if(!kinte(i, j+k, PLAYER)){ 464 | r++; 465 | break; 466 | } 467 | } 468 | } 469 | }i=x; 470 | j=y; 471 | for(i=x-3,j=y-3;i<=x;i++,j++){ 472 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)==3){ 473 | for(k=0;k<=3&&bekaru(i+k, j+k, PLAYER);k++); 474 | if(ikiyo(i+k, j+k, PLAYER)){ 475 | if(!kinte(i+k, j+k, PLAYER)){ 476 | r++; 477 | break; 478 | } 479 | } 480 | } 481 | }i=x; 482 | j=y; 483 | for(i=x-3,j=y+3;i<=x;i++,j--){ 484 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)==3){ 485 | for(k=0;k<=3&&bekaru(i+k, j-k, PLAYER);k++); 486 | if(ikiyo(i+k, j-k, PLAYER)){ 487 | if(!kinte(i+k, j-k, PLAYER)){ 488 | r++; 489 | break; 490 | } 491 | } 492 | } 493 | }aRecordBoard[x][y]=0; 494 | return r; 495 | } 496 | 497 | 498 | 499 | 500 | int nagatsure(int x, int y, int PLAYER){ 501 | int r=0; 502 | if(muda(x, y)==1){ 503 | return 0; 504 | }aRecordBoard[x][y]=PLAYER; 505 | int i=x, j=y; 506 | for(i=x-5;i<=x;i++){ 507 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j, PLAYER)&&bekaru(i+2, j, PLAYER)&&bekaru(i+3, j, PLAYER)&&bekaru(i+4, j, PLAYER)&&bekaru(i+5, j, PLAYER)){ 508 | r++; 509 | break; 510 | } 511 | }i=x; 512 | j=y; 513 | for(j=y-5;j<=y;j++){ 514 | if(bekaru(i, j, PLAYER)&&bekaru(i, j+1, PLAYER)&&bekaru(i, j+2, PLAYER)&&bekaru(i, j+3, PLAYER)&&bekaru(i, j+4, PLAYER)&&bekaru(i, j+5, PLAYER)){ 515 | r++; 516 | break; 517 | } 518 | }i=x; 519 | j=y; 520 | for(i=x-5,j=y-5;i<=x;i++,j++){ 521 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j+1, PLAYER)&&bekaru(i+2, j+2, PLAYER)&&bekaru(i+3, j+3, PLAYER)&&bekaru(i+4, j+4, PLAYER)&&bekaru(i+5, j+5, PLAYER)){ 522 | r++; 523 | break; 524 | } 525 | }i=x; 526 | j=y; 527 | for(i=x-5,j=y+5;i<=x;i++,j--){ 528 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j-1, PLAYER)&&bekaru(i+2, j-2, PLAYER)&&bekaru(i+3, j-3, PLAYER)&&bekaru(i+4, j-4, PLAYER)&&bekaru(i+5, j-5, PLAYER)){ 529 | r++; 530 | break; 531 | } 532 | }aRecordBoard[x][y]=0; 533 | return r; 534 | } 535 | 536 | 537 | 538 | ///////////////////////////////////////////////////////////// 539 | // 函数名称: judge 540 | // 作用:「そこ」では勝つのか否のかを判断する 541 | 542 | // 参数:x, y, player 543 | // 返回值:0/1 544 | ///////////////////////////////////////////////////////////// 545 | 546 | int bekaru(int x, int y, int PLAYER){ 547 | if(x<0||x>14||y<0||y>14||aRecordBoard[x][y]!=PLAYER){ 548 | return 0; 549 | }else{ 550 | return 1; 551 | } 552 | } 553 | 554 | 555 | 556 | 557 | 558 | int narugo(int x, int y, int PLAYER){ 559 | int r=0; 560 | if(muda(x, y)==1){ 561 | return 0; 562 | }aRecordBoard[x][y]=PLAYER; 563 | int i=x, j=y; 564 | for(i=x-4;i<=x;i++){ 565 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j, PLAYER)&&bekaru(i+2, j, PLAYER)&&bekaru(i+3, j, PLAYER)&&bekaru(i+4, j, PLAYER)){ 566 | if(PLAYER==PLAYER1){ 567 | if(!bekaru(i-1, j, PLAYER)&&!bekaru(i+5, j, PLAYER)){ 568 | r++; 569 | break; 570 | }else{ 571 | break; 572 | } 573 | }else{ 574 | r++; 575 | break; 576 | } 577 | } 578 | }i=x; 579 | j=y; 580 | for(j=y-4;j<=y;j++){ 581 | if(bekaru(i, j, PLAYER)&&bekaru(i, j+1, PLAYER)&&bekaru(i, j+2, PLAYER)&&bekaru(i, j+3, PLAYER)&&bekaru(i, j+4, PLAYER)){ 582 | if(PLAYER==PLAYER1){ 583 | if(!bekaru(i, j-1, PLAYER)&&!bekaru(i, j+5, PLAYER)){ 584 | r++; 585 | break; 586 | }else{ 587 | break; 588 | } 589 | }else{ 590 | r++; 591 | break; 592 | } 593 | } 594 | }i=x; 595 | j=y; 596 | for(i=x-4,j=y-4;i<=x;i++,j++){ 597 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j+1, PLAYER)&&bekaru(i+2, j+2, PLAYER)&&bekaru(i+3, j+3, PLAYER)&&bekaru(i+4, j+4, PLAYER)){ 598 | if(PLAYER==PLAYER1){ 599 | if(!bekaru(i-1, j-1, PLAYER)&&!bekaru(i+5, j+5, PLAYER)){ 600 | r++; 601 | break; 602 | }else{ 603 | break; 604 | } 605 | }else{ 606 | r++; 607 | break; 608 | } 609 | } 610 | }i=x; 611 | j=y; 612 | for(i=x-4,j=y+4;i<=x;i++,j--){ 613 | if(bekaru(i, j, PLAYER)&&bekaru(i+1, j-1, PLAYER)&&bekaru(i+2, j-2, PLAYER)&&bekaru(i+3, j-3, PLAYER)&&bekaru(i+4, j-4, PLAYER)){ 614 | if(PLAYER==PLAYER1){ 615 | if(!bekaru(i-1, j+1, PLAYER)&&!bekaru(i+5, j-5, PLAYER)){ 616 | r++; 617 | break; 618 | }else{ 619 | break; 620 | } 621 | }else{ 622 | r++; 623 | break; 624 | } 625 | } 626 | }aRecordBoard[x][y]=0; 627 | return r; 628 | } 629 | 630 | 631 | 632 | 633 | int judge(int x, int y, int PLAYER){ 634 | if(muda(x, y)){ 635 | return 0; 636 | }if(narugo(x, y, PLAYER)){ 637 | return 1; 638 | }else{ 639 | return 0; 640 | } 641 | } 642 | 643 | ///////////////////////////////////////////////////////////// 644 | // 函数名称:initRecordBorard 645 | // 作用:初始化二维数组aRecordBoard 646 | // 参数:无 647 | // 返回值:无 648 | ///////////////////////////////////////////////////////////// 649 | void initRecordBorard(void){ 650 | //通过双重循环,将aRecordBoard清0 651 | int i, j; 652 | for(i=0;imax){ 744 | max=score[i][j]; 745 | r.x=i; 746 | r.y=j; 747 | r.value=score[i][j]; 748 | } 749 | } 750 | } 751 | return r; 752 | } 753 | 754 | 755 | 756 | 757 | 758 | 759 | struct point autoret(){ 760 | struct point r; 761 | r=ret(); 762 | return r; 763 | } 764 | 765 | 766 | 767 | 768 | int autoscore(int x, int y, int PLAYER){ 769 | if(kinte(x, y, PLAYER)){ 770 | return 0; 771 | }else{ 772 | int hi=tanehi(x, y, PLAYER), hu=ikihu(x, y, PLAYER), omi=okimi(x, y, PLAYER), mi=ikimi(x, y, PLAYER), oyo=okiyo(x, y, PLAYER), his1=hissatsu1(x, y, PLAYER), his2=hissatsu2(x, y, PLAYER), yo=ikiyo(x, y, PLAYER), itsu=narugo(x, y, PLAYER); 773 | if(PLAYER!=current_player){ 774 | return (hi+100*hu+120*omi+10000*mi+12000*oyo+90000*his2+95000*his1+300000*yo+1000000*itsu); 775 | }else{ 776 | return (hi+120*hu+130*omi+12000*mi+105000*oyo+90000*his2+95000*his1+300000*yo+1000000*itsu); 777 | } 778 | } 779 | } 780 | 781 | 782 | 783 | 784 | 785 | int ikihu(int x, int y, int PLAYER){ 786 | int r=0, i=0; 787 | if(muda(x, y)==1){ 788 | return 0; 789 | }aRecordBoard[x][y]=PLAYER; 790 | for(i=-1;i<=1;i+=2){ 791 | if(bekaru(x+i, y, PLAYER)&&ikimi(x-i, y, PLAYER)){ 792 | r++; 793 | }if(bekaru(x, y+i, PLAYER)&&ikimi(x, y-i, PLAYER)){ 794 | r++; 795 | }if(bekaru(x+i, y+i, PLAYER)&&ikimi(x-i, y-i, PLAYER)){ 796 | r++; 797 | }if(bekaru(x+i, y-i, PLAYER)&&ikimi(x-i, y+i, PLAYER)){ 798 | r++; 799 | }if(bekaru(x+2*i, y, PLAYER)&&ikimi(x+i, y, PLAYER)){ 800 | r++; 801 | }if(bekaru(x, y+2*i, PLAYER)&&ikimi(x, y+i, PLAYER)){ 802 | r++; 803 | }if(bekaru(x+2*i, y+2*i, PLAYER)&&ikimi(x+i, y+i, PLAYER)){ 804 | r++; 805 | }if(bekaru(x+2*i, y-2*i, PLAYER)&&ikimi(x+i, y-i, PLAYER)){ 806 | r++; 807 | } 808 | }aRecordBoard[x][y]=0; 809 | return r; 810 | } 811 | 812 | 813 | 814 | int tanehi(int x, int y, int PLAYER){ 815 | int r=0, i=0; 816 | if(muda(x, y)==1){ 817 | return 0; 818 | }for(i=-1;i<=1;i+=2){ 819 | r+=(bekaru(x+i, y, PLAYER)+bekaru(x, y+i, PLAYER)+bekaru(x+i, y+i, PLAYER)+bekaru(x+i, y-i, PLAYER)); 820 | }return r; 821 | } 822 | 823 | 824 | int real_okimi(int x, int y, int PLAYER){ 825 | int r=0; 826 | if(muda(x, y)==1){ 827 | return 0; 828 | }aRecordBoard[x][y]=PLAYER; 829 | int i=x, j=y, k=0; 830 | for(i=x-4;i<=x;i++){ 831 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)+bekaru(i+4, j, PLAYER)==3){ 832 | if(!bekaru(i, j, PLAYER)&&!bekaru(i+4, j, PLAYER)){ 833 | for(k=-1;k<=5;k++){ 834 | if(!bekaru(i+k, j, PLAYER)&&okiyo(i+k, j, PLAYER)&&!kinte(i+k, j, PLAYER)){ 835 | r++; 836 | break; 837 | } 838 | } 839 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+3, j, PLAYER)&&!bekaru(i+4, j, PLAYER)){ 840 | for(k=-1;k<=4;k++){ 841 | if(!bekaru(i+k, j, PLAYER)&&okiyo(i+k, j, PLAYER)&&!kinte(i+k, j, PLAYER)){ 842 | r++; 843 | break; 844 | } 845 | } 846 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+4, j, PLAYER)){ 847 | for(k=0;k<=4;k++){ 848 | if(!bekaru(i+k, j, PLAYER)&&okiyo(i+k, j, PLAYER)&&!kinte(i+k, j, PLAYER)){ 849 | r++; 850 | break; 851 | } 852 | } 853 | } 854 | } 855 | }i=x; 856 | j=y; 857 | for(j=y-4;j<=y;j++){ 858 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)+bekaru(i, j+4, PLAYER)==3){ 859 | if(!bekaru(i, j, PLAYER)&&!bekaru(i, j+4, PLAYER)){ 860 | for(k=-1;k<=5;k++){ 861 | if(!bekaru(i, j+k, PLAYER)&&okiyo(i, j+k, PLAYER)&&!kinte(i, j+k, PLAYER)){ 862 | r++; 863 | break; 864 | } 865 | } 866 | }else if(bekaru(i, j, PLAYER)&&bekaru(i, j+3, PLAYER)&&!bekaru(i, j+4, PLAYER)){ 867 | for(k=-1;k<=4;k++){ 868 | if(!bekaru(i, j+k, PLAYER)&&okiyo(i, j+k, PLAYER)&&!kinte(i, j+k, PLAYER)){ 869 | r++; 870 | break; 871 | } 872 | } 873 | }else if(bekaru(i, j, PLAYER)&&bekaru(i, j+4, PLAYER)){ 874 | for(k=0;k<=4;k++){ 875 | if(!bekaru(i, j+k, PLAYER)&&okiyo(i, j+k, PLAYER)&&!kinte(i, j+k, PLAYER)){ 876 | r++; 877 | break; 878 | } 879 | } 880 | } 881 | } 882 | }i=x; 883 | j=y; 884 | for(i=x-4,j=y-4;i<=x;i++,j++){ 885 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)+bekaru(i+4, j+4, PLAYER)==3){ 886 | if(!bekaru(i, j, PLAYER)&&!bekaru(i+4, j+4, PLAYER)){ 887 | for(k=-1;k<=5;k++){ 888 | if(!bekaru(i+k, j+k, PLAYER)&&okiyo(i+k, j+k, PLAYER)&&!kinte(i+k, j+k, PLAYER)){ 889 | r++; 890 | break; 891 | } 892 | } 893 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+3, j+3, PLAYER)&&!bekaru(i+4, j+4, PLAYER)){ 894 | for(k=-1;k<=4;k++){ 895 | if(!bekaru(i+k, j+k, PLAYER)&&okiyo(i+k, j+k, PLAYER)&&!kinte(i+k, j+k, PLAYER)){ 896 | r++; 897 | break; 898 | } 899 | } 900 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+4, j+4, PLAYER)){ 901 | for(k=0;k<=4;k++){ 902 | if(!bekaru(i+k, j+k, PLAYER)&&okiyo(i+k, j+k, PLAYER)&&!kinte(i+k, j+k, PLAYER)){ 903 | r++; 904 | break; 905 | } 906 | } 907 | } 908 | } 909 | }i=x; 910 | j=y; 911 | for(i=x-4,j=y+4;i<=x;i++,j--){ 912 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)+bekaru(i+4, j-4, PLAYER)==3){ 913 | if(!bekaru(i, j, PLAYER)&&!bekaru(i+4, j-4, PLAYER)){ 914 | for(k=-1;k<=5;k++){ 915 | if(!bekaru(i+k, j-k, PLAYER)&&okiyo(i+k, j-k, PLAYER)&&!kinte(i+k, j-k, PLAYER)){ 916 | r++; 917 | break; 918 | } 919 | } 920 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+3, j-3, PLAYER)&&!bekaru(i+4, j-4, PLAYER)){ 921 | for(k=-1;k<=4;k++){ 922 | if(!bekaru(i+k, j-k, PLAYER)&&okiyo(i+k, j-k, PLAYER)&&!kinte(i+k, j-k, PLAYER)){ 923 | r++; 924 | break; 925 | } 926 | } 927 | }else if(bekaru(i, j, PLAYER)&&bekaru(i+4, j-4, PLAYER)){ 928 | for(k=0;k<=4;k++){ 929 | if(!bekaru(i+k, j-k, PLAYER)&&okiyo(i+k, j-k, PLAYER)&&!kinte(i+k, j-k, PLAYER)){ 930 | r++; 931 | break; 932 | } 933 | } 934 | } 935 | } 936 | }aRecordBoard[x][y]=0; 937 | return r; 938 | } 939 | 940 | 941 | 942 | 943 | int hissatsu1(int x, int y, int PLAYER){ 944 | if(kinte(x, y, PLAYER)){ 945 | return 0; 946 | }if(okiyo(x, y, PLAYER)+ikimi(x, y, PLAYER)>1){ 947 | return 1; 948 | }return 0; 949 | } 950 | int hisnum1(int x, int y, int PLAYER){ 951 | if(kinte(x, y, PLAYER)){ 952 | return 0; 953 | }aRecordBoard[x][y]=PLAYER; 954 | int r=0, i; 955 | for(i=-4;i<=4;i++){ 956 | if(hissatsu1(x+i, y, PLAYER)){ 957 | r++; 958 | }if(hissatsu1(x, y+i, PLAYER)){ 959 | r++; 960 | }if(hissatsu1(x+i, y+i, PLAYER)){ 961 | r++; 962 | }if(hissatsu1(x+i, y-i, PLAYER)){ 963 | r++; 964 | } 965 | }aRecordBoard[x][y]=0; 966 | return r; 967 | } 968 | int hissatsu2(int x, int y, int PLAYER){ 969 | if(kinte(x, y, PLAYER)){ 970 | return 0; 971 | }if(hissatsu1(x, y, PLAYER)){ 972 | return 0; 973 | }if(okiyo(x, y, PLAYER)+ikimi(x, y, PLAYER)+hisnum1(x, y, PLAYER)>1){ 974 | return 1; 975 | }return 0; 976 | } 977 | 978 | 979 | 980 | ///////////////////////////////////////////////////////////// 981 | // 函数名称: 982 | // 作用:誰も見ることのない新世界。 983 | // 参数: 984 | // 返回值: 985 | ///////////////////////////////////////////////////////////// 986 | 987 | int hameyo(int x, int y, int PLAYER){ 988 | int r=0; 989 | if(muda(x, y)==1){ 990 | return 0; 991 | }aRecordBoard[x][y]=PLAYER; 992 | int i=x, j=y, k=0; 993 | for(i=x-4;i<=x;i++){ 994 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j, PLAYER)+bekaru(i+2, j, PLAYER)+bekaru(i+3, j, PLAYER)+bekaru(i+4, j, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i+4, j, PLAYER)){ 995 | if((judge(i+1, j, PLAYER)&&x!=i)||(judge(i+3, j, PLAYER)&&x!=i+4)){ 996 | r++; 997 | } 998 | } 999 | }i=x; 1000 | j=y; 1001 | for(j=y-4;j<=y;j++){ 1002 | if(bekaru(i, j, PLAYER)+bekaru(i, j+1, PLAYER)+bekaru(i, j+2, PLAYER)+bekaru(i, j+3, PLAYER)+bekaru(i, j+4, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i, j+4, PLAYER)){ 1003 | if((judge(i, j+1, PLAYER)&&y!=j)||(judge(i, j+3, PLAYER)&&y!=j+4)){ 1004 | r++; 1005 | } 1006 | } 1007 | }i=x; 1008 | j=y; 1009 | for(i=x-4,j=y-4;i<=x;i++,j++){ 1010 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j+1, PLAYER)+bekaru(i+2, j+2, PLAYER)+bekaru(i+3, j+3, PLAYER)+bekaru(i+4, j+4, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i+4, j+4, PLAYER)){ 1011 | if((judge(i+1, j+1, PLAYER)&&x!=i)||(judge(i+3, j+3, PLAYER)&&x!=i+4)){ 1012 | r++; 1013 | } 1014 | } 1015 | }i=x; 1016 | j=y; 1017 | for(i=x-4,j=y+4;i<=x;i++,j--){ 1018 | if(bekaru(i, j, PLAYER)+bekaru(i+1, j-1, PLAYER)+bekaru(i+2, j-2, PLAYER)+bekaru(i+3, j-3, PLAYER)+bekaru(i+4, j-4, PLAYER)==4&&bekaru(i, j, PLAYER)&&bekaru(i+4, j-4, PLAYER)){ 1019 | if((judge(i+1, j-1, PLAYER)&&x!=i)||(judge(i+3, j-3, PLAYER)&&x!=i+4)){ 1020 | r++; 1021 | } 1022 | } 1023 | }aRecordBoard[x][y]=0; 1024 | return r; 1025 | } 1026 | 1027 | int ikimi(int x, int y, int PLAYER){ 1028 | return real_ikimi(x, y, PLAYER)-hameyo(x, y, PLAYER); 1029 | } 1030 | 1031 | int okimi(int x, int y, int PLAYER){ 1032 | return real_okimi(x, y, PLAYER)+hameyo(x, y, PLAYER); 1033 | } 1034 | --------------------------------------------------------------------------------