先上一張alpha beta原理圖,一看就懂ios
代碼有點長,主要是由於算評估值得時候用的是窮舉。 玩家是1,電腦是2,能夠選擇難度以及先手app
1 // 2 // main.cpp 3 // NEWTICTACTOE 4 // 5 // Created by mac on 2017/5/1. 6 // Copyright © 2017年 mac. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <vector> 11 #include <math.h> 12 #include <cctype> 13 #include <map> 14 15 using namespace::std; 16 vector<vector <int> > board(4 ,vector<int>(4,0)); 17 vector<vector <int> > boardvalues(4 ,vector<int>(4,99)); 18 int ALPHA =-1000; 19 int BETA = 1000; 20 int winner = -1; 21 int searchDepth; 22 bool isCutoffOccured = false; 23 int maxDepthReached = 0; 24 int totalNodesGenerated = 0; 25 int pruningMax = 0; 26 int pruningMin = 0; 27 bool drawGame = false; 28 29 int MaxValue(vector<vector <int> > board,int alpha,int beta,int depth); 30 int MinValue(vector<vector <int> > board,int alpha,int beta,int depth); 31 32 int get3PieceEval(vector<vector <int> > board){ 33 int PlayerScore = 0; 34 int AIScore = 0; 35 //row score 36 for(int i=0; i<4; i++){ 37 if ((board[i][0]==board[i][1])&&(board[i][0]==board[i][2])&&(board[i][3] == 0))// 38 { 39 if(board[i][0]==2) 40 AIScore += 6; 41 if((board[i][0]==1)&&(board[i][3] == 0)) 42 PlayerScore += 6; 43 } 44 if((board[i][0]==board[i][2])&&(board[i][0]==board[i][3])&&(board[i][1] == 0)) 45 { 46 if(board[i][0]==2) 47 AIScore += 6; 48 if(board[i][0]==1) 49 PlayerScore += 6; 50 } 51 if((board[i][0]==board[i][1])&&(board[i][0]==board[i][3])&&(board[i][2] ==0)) 52 { 53 if(board[i][0]==2) 54 AIScore += 6; 55 if(board[i][0]==1) 56 PlayerScore += 6; 57 } 58 if((board[i][1]==board[i][2])&&(board[i][1]==board[i][3])&&(board[i][0] ==0)) 59 { 60 if(board[i][1]==2) 61 AIScore += 6; 62 if(board[i][1]==1) 63 PlayerScore += 6; 64 } 65 66 } 67 //col score 68 for(int i=0; i<4; i++){ 69 if ((board[0][i]==board[1][i])&&(board[0][i]==board[2][i])&&(board[3][i] ==0))// 70 { 71 if(board[0][i]==2) 72 AIScore += 6; 73 if(board[0][i]==1) 74 PlayerScore += 6; 75 } 76 if((board[0][i]==board[2][i])&&(board[0][i]==board[3][i])&&(board[1][i] ==0)) 77 { 78 if(board[0][i]==2) 79 AIScore += 6; 80 if(board[0][i]==1) 81 PlayerScore += 6; 82 } 83 if((board[0][i]==board[1][i])&&(board[0][i]==board[3][i])&&(board[2][i] ==0)) 84 { 85 if(board[0][i]==2) 86 AIScore += 6; 87 if(board[0][i]==1) 88 PlayerScore += 6; 89 } 90 if((board[1][i]==board[2][i])&&(board[1][i]==board[3][i])&&(board[0][i] ==0)) 91 { 92 if(board[1][i]==2) 93 AIScore += 6; 94 if(board[1][i]==1) 95 PlayerScore += 6; 96 } 97 98 } 99 //45 Diagnal score 100 { 101 if((board[0][0]==board[1][1])&&(board[1][1]==board[2][2])&&(board[3][3] ==0))// 102 { 103 if(board[0][0]==2) 104 AIScore += 6; 105 if(board[0][0]==1) 106 PlayerScore += 6; 107 } 108 if((board[0][0]==board[2][2])&&(board[2][2]==board[3][3])&&(board[1][1] ==0))// 109 { 110 if(board[0][0]==2) 111 AIScore += 6; 112 if(board[0][0]==1) 113 PlayerScore += 6; 114 } 115 if((board[0][0]==board[1][1])&&(board[1][1]==board[3][3])&&(board[2][2] ==0))// 116 { 117 if(board[0][0]==2) 118 AIScore += 6; 119 if(board[0][0]==1) 120 PlayerScore += 6; 121 } 122 if((board[1][1]==board[2][2])&&(board[2][2]==board[3][3])&&(board[0][0] ==0))// 123 { 124 if(board[1][1]==2) 125 AIScore += 6; 126 if(board[1][1]==1) 127 PlayerScore += 6; 128 } 129 130 } 131 //135 Diagnal score 132 { 133 if((board[0][3]==board[1][2])&&(board[1][2]==board[2][1])&&(board[3][0] ==0))// 134 { 135 if(board[0][3]==2) 136 AIScore += 6; 137 if(board[0][3]==1) 138 PlayerScore += 6; 139 } 140 if((board[0][3]==board[1][2])&&(board[1][2]==board[3][0])&&(board[2][1] ==0))// 141 { 142 if(board[0][3]==2) 143 AIScore += 6; 144 if(board[0][3]==1) 145 PlayerScore += 6; 146 } 147 if((board[0][3]==board[2][1])&&(board[2][1]==board[3][0])&&(board[1][2] ==0))// 148 { 149 if(board[0][3]==2) 150 AIScore += 6; 151 if(board[0][3]==1) 152 PlayerScore += 6; 153 } 154 if((board[1][2]==board[2][1])&&(board[2][1]==board[3][0])&&(board[0][3] ==0))// 155 { 156 if(board[1][2]==2) 157 AIScore += 6; 158 if(board[1][2]==1) 159 PlayerScore += 6; 160 } 161 162 } 163 //cout<<"get1PieceEval"<<AIScore-PlayerScore<<endl; 164 return AIScore-PlayerScore; 165 166 } 167 //calculaye 2 pieces in a line 168 int get2PieceEval(vector<vector <int> > board){ 169 int PlayerScore = 0; 170 int AIScore = 0; 171 //row score 172 for(int i=0; i<4; i++){ 173 if((board[i][0]==board[i][1])&&(board[i][3]==0)&&(board[i][2]==0))// 174 { 175 if(board[i][0]==2) 176 AIScore += 3; 177 if(board[i][0]==1) 178 PlayerScore += 3; 179 } 180 if((board[i][0]==board[i][2])&&(board[i][1]==0)&&(board[i][3]==0)) 181 { 182 if(board[i][0]==2) 183 AIScore += 3; 184 if(board[i][0]==1) 185 PlayerScore += 3; 186 } 187 if((board[i][0]==board[i][3])&&(board[i][1]==0)&&(board[i][2]==0)) 188 { 189 if(board[i][0]==2) 190 AIScore += 3; 191 if(board[i][0]==1) 192 PlayerScore += 3; 193 } 194 if((board[i][1]==board[i][2])&&(board[i][0]==0)&&(board[i][3]==0)) 195 { 196 if(board[i][1]==2) 197 AIScore += 3; 198 if(board[i][1]==1) 199 PlayerScore += 3; 200 } 201 if((board[i][1]==board[i][3])&&(board[i][0]==0)&&(board[i][2]==0)) 202 { 203 if(board[i][1]==2) 204 AIScore += 3; 205 if(board[i][1]==1) 206 PlayerScore += 3; 207 } 208 if((board[i][2]==board[i][3])&&(board[i][0]==0)&&(board[i][1]==0)) 209 { 210 if(board[i][2]==2) 211 AIScore += 3; 212 if(board[i][2]==1) 213 PlayerScore += 3; 214 } 215 216 217 } 218 //col score 219 for(int i=0; i<4; i++){ 220 if((board[0][i]==board[1][i])&&(board[2][i]==0)&&(board[3][i]==0))// 221 { 222 if(board[0][i]==2) 223 AIScore += 3; 224 if(board[0][i]==1) 225 PlayerScore += 3; 226 } 227 if((board[0][i]==board[2][i])&&(board[1][i]==0)&&(board[3][i]==0)) 228 { 229 if(board[0][i]==2) 230 AIScore += 3; 231 if(board[0][i]==1) 232 PlayerScore += 3; 233 } 234 if((board[0][i]==board[3][i])&&(board[1][i]==0)&&(board[2][i]==0)) 235 { 236 if(board[0][i]==2) 237 AIScore += 3; 238 if(board[0][i]==1) 239 PlayerScore += 3; 240 } 241 if((board[1][i]==board[2][i])&&(board[0][i]==0)&&(board[3][i]==0)) 242 { 243 if(board[1][i]==2) 244 AIScore += 3; 245 if(board[1][i]==1) 246 PlayerScore += 3; 247 } 248 if((board[1][i]==board[3][i])&&(board[0][i]==0)&&(board[2][i]==0)) 249 { 250 if(board[1][i]==2) 251 AIScore += 3; 252 if(board[1][i]==1) 253 PlayerScore += 3; 254 } 255 if((board[2][i]==board[3][i])&&(board[0][i]==0)&&(board[1][i]==0)) 256 { 257 if(board[2][i]==2) 258 AIScore += 3; 259 if(board[2][i]==1) 260 PlayerScore += 3; 261 } 262 263 264 } 265 //45 Diagnal score 266 { 267 if((board[0][0]==board[1][1])&&(board[2][2]==0)&&(board[3][3]==0))// 268 { 269 if(board[0][0]==2) 270 AIScore += 3; 271 if(board[0][0]==1) 272 PlayerScore += 3; 273 } 274 if((board[0][0]==board[2][2])&&(board[1][1]==0)&&(board[3][3]==0))// 275 { 276 if(board[0][0]==2) 277 AIScore += 3; 278 if(board[0][0]==1) 279 PlayerScore += 3; 280 } 281 if((board[0][0]==board[3][3])&&(board[1][1]==0)&&(board[2][2]==0))// 282 { 283 if(board[0][0]==2) 284 AIScore += 3; 285 if(board[0][0]==1) 286 PlayerScore += 3; 287 } 288 if((board[1][1]==board[2][2])&&(board[0][0]==0)&&(board[3][3]==0))// 289 { 290 if(board[1][1]==2) 291 AIScore += 3; 292 if(board[1][1]==1) 293 PlayerScore += 3; 294 } 295 if((board[1][1]==board[3][3])&&(board[0][0]==0)&&(board[2][2]==0))// 296 { 297 if(board[1][1]==2) 298 AIScore += 3; 299 if(board[1][1]==1) 300 PlayerScore += 3; 301 } 302 if((board[2][2]==board[3][3])&&(board[0][0]==0)&&(board[1][1]==0))// 303 { 304 if(board[2][2]==2) 305 AIScore += 3; 306 if(board[2][2]==1) 307 PlayerScore += 3; 308 } 309 310 } 311 //135 Diagnal score 312 { 313 if((board[0][3]==board[1][2])&&(board[2][1]==0)&&(board[3][0]==0))// 314 { 315 if(board[0][3]==2) 316 AIScore += 3; 317 if(board[0][3]==1) 318 PlayerScore += 3; 319 } 320 if((board[0][3]==board[2][1])&&(board[1][2]==0)&&(board[3][0]==0))// 321 { 322 if(board[0][3]==2) 323 AIScore += 3; 324 if(board[0][3]==1) 325 PlayerScore += 3; 326 } 327 if((board[0][3]==board[3][0])&&(board[1][2]==0)&&(board[2][1]==0))// 328 { 329 if(board[0][3]==2) 330 AIScore += 3; 331 if(board[0][3]==1) 332 PlayerScore += 3; 333 } 334 if((board[1][2]==board[2][1])&&(board[0][3]==0)&&(board[3][0]==0))// 335 { 336 if(board[1][2]==2) 337 AIScore += 3; 338 if(board[1][2]==1) 339 PlayerScore += 3; 340 } 341 if((board[1][2]==board[3][0])&&(board[0][3]==0)&&(board[2][1]==0))// 342 { 343 if(board[1][2]==2) 344 AIScore += 3; 345 if(board[1][2]==1) 346 PlayerScore += 3; 347 } 348 if((board[2][1]==board[3][0])&&(board[0][3]==0)&&(board[1][2]==0))// 349 { 350 if(board[1][2]==2) 351 AIScore += 3; 352 if(board[1][2]==1) 353 PlayerScore += 3; 354 } 355 356 } 357 //cout<<"get1PieceEval"<<AIScore-PlayerScore<<endl; 358 return AIScore-PlayerScore; 359 } 360 //calculaye 1 piece score in a line 361 int get1PieceEval(vector<vector <int> > board){ 362 int PlayerScore = 0; 363 int AIScore = 0; 364 for(int i=0; i<4; i++){ 365 if (board[i][1]==0 && board[i][2]==0 && board[i][3]==0 )// 366 { 367 if(board[i][0]==1){ 368 PlayerScore++; 369 //cout<<"player add score row at"<<i<<" 0"<<endl; 370 } 371 if(board[i][0]==2){ 372 AIScore++; 373 //cout<<"AI add score row at"<<i<<" 0"<<endl; 374 } 375 } 376 if (board[i][0]==0 && board[i][2]==0 && board[i][3]==0 )// 377 { 378 if(board[i][1]==1){ 379 PlayerScore++; 380 //cout<<"player add score at"<<i<<" 1"<<endl; 381 } 382 if(board[i][1]==2){ 383 AIScore++; 384 //cout<<"AI add score row at"<<i<<" 1"<<endl; 385 } 386 } 387 if (board[i][0]==0 && board[i][1]==0 && board[i][2]==0 )// 388 { 389 if(board[i][3]==1){ 390 PlayerScore++; 391 //cout<<"player add score at"<<i<<" 2"<<endl; 392 } 393 if(board[i][3]==2){ 394 AIScore++; 395 //cout<<"AI add score row at"<<i<<" 2"<<endl; 396 } 397 } 398 if (board[i][0]==0 && board[i][1]==0 && board[i][3]==0 )// 399 { 400 if(board[i][2]==1){ 401 PlayerScore++; 402 //cout<<"player add score at"<<i<<" 3"<<endl; 403 } 404 if(board[i][2]==2){ 405 AIScore++; 406 //cout<<"AI add score row at"<<i<<" 3"<<endl; 407 } 408 } 409 } 410 411 for(int i=0; i<4; i++){ 412 if (board[1][i]==0 && board[2][i]==0 && board[3][i]==0 )// 413 { 414 if(board[0][i]==1){ 415 PlayerScore++; 416 //cout<<"player add score col at"<<"0 "<<i<<endl; 417 } 418 if(board[0][i]==2){ 419 AIScore++; 420 //cout<<"AI add score col at"<<"0 "<<i<<endl; 421 } 422 } 423 if (board[0][i]==0 && board[2][i]==0 && board[3][i]==0 )// 424 { 425 if(board[1][i]==1){ 426 PlayerScore++; 427 //cout<<"player add score at"<<"1 "<<i<<endl; 428 } 429 if(board[1][i]==2){ 430 AIScore++; 431 //cout<<"AI add score col at"<<"1 "<<i<<endl; 432 } 433 } 434 if (board[0][i]==0 && board[1][i]==0 && board[2][i]==0 )// 435 { 436 if(board[3][i]==1){ 437 PlayerScore++; 438 //cout<<"player add score at"<<"3 "<<i<<endl; 439 } 440 if(board[3][i]==2){ 441 AIScore++; 442 //cout<<"AI add score col at"<<"3 "<<i<<endl; 443 } 444 } 445 if (board[0][i]==0 && board[1][i]==0 && board[3][i]==0 )// 446 { 447 if(board[2][i]==1){ 448 PlayerScore++; 449 //cout<<"player add score at"<<"2 "<<i<<endl; 450 } 451 if(board[2][i]==2){ 452 AIScore++; 453 //cout<<"AI add score col at"<<"2 "<<i<<endl; 454 } 455 } 456 } 457 //diagnal 45 458 { 459 if (board[0][0]==0 && board[1][1]==0 && board[2][2]==0 )// 460 { 461 if(board[3][3]==1){ 462 PlayerScore++; 463 //cout<<"player add score at"<<"3 "<<"3"<<endl; 464 } 465 if(board[3][3]==2){ 466 AIScore++; 467 //cout<<"AI add score 45 at"<<"3 "<<"3"<<endl; 468 } 469 } 470 if (board[0][0]==0 && board[2][2]==0 && board[3][3]==0 )// 471 { 472 if(board[1][1]==1){ 473 PlayerScore++; 474 //cout<<"player add score at"<<"1 "<<"1"<<endl; 475 476 } 477 if(board[1][1]==2){ 478 AIScore++; 479 //cout<<"AI add score 45 at"<<"1 "<<"1"<<endl; 480 } 481 } 482 if (board[0][0]==0 && board[1][1]==0 && board[3][3]==0 )// 483 { 484 if(board[2][2]==1){ 485 PlayerScore++; 486 //cout<<"player add score at"<<"2 "<<"2"<<endl; 487 488 } 489 if(board[2][2]==2){ 490 AIScore++; 491 //cout<<"AI add score 45 at"<<"2 "<<"2"<<endl; 492 } 493 } 494 if (board[1][1]==0 && board[2][2]==0 && board[3][3]==0 )// 495 { 496 if(board[0][0]==1){ 497 PlayerScore++; 498 //cout<<"player add score at"<<"0 "<<"0"<<endl; 499 500 } 501 if(board[0][0]==2){ 502 AIScore++; 503 //cout<<"AI add score 45 at"<<"0 "<<"0"<<endl; 504 } 505 } 506 507 } 508 509 { 510 if (board[0][3]==0 && board[1][2]==0 && board[2][1]==0 )// 511 { 512 if(board[3][0]==1){ 513 PlayerScore++; 514 //cout<<"player add score at"<<"3 "<<"0"<<endl; 515 516 } 517 if(board[3][0]==2){ 518 AIScore++; 519 //cout<<"AI add score 135 at"<<"3 "<<"0"<<endl; 520 } 521 } 522 if (board[0][3]==0 && board[1][2]==0 && board[3][0]==0 )// 523 { 524 if(board[2][1]==1){ 525 PlayerScore++; 526 //cout<<"player add score at"<<"2 "<<"1"<<endl; 527 528 } 529 if(board[2][1]==2){ 530 AIScore++; 531 //cout<<"AI add score 135 at"<<"2 "<<"1"<<endl; 532 } 533 } 534 if (board[0][3]==0 && board[2][1]==0 && board[3][0]==0 )// 535 { 536 if(board[1][2]==1){ 537 PlayerScore++; 538 //cout<<"player add score at"<<"1 "<<"2"<<endl; 539 540 } 541 if(board[1][2]==2){ 542 AIScore++; 543 //cout<<"AI add score 135 at"<<"1 "<<"2"<<endl; 544 } 545 } 546 if (board[1][2]==0 && board[2][1]==0 && board[3][0]==0 )// 547 { 548 if(board[0][3]==1){ 549 PlayerScore++; 550 //cout<<"player add score at"<<"0 "<<"3"<<endl; 551 552 } 553 if(board[0][3]==2){ 554 AIScore++; 555 //cout<<"AI add score 135 at"<<"0 "<<"3"<<endl; 556 } 557 } 558 559 } 560 //cout<<"get1PieceEval"<<AIScore-PlayerScore<<endl; 561 return AIScore-PlayerScore; 562 } 563 //get evaluate score 564 int GetEvals(vector<vector <int> > board){ 565 int result = 0; 566 result = get3PieceEval(board) + get2PieceEval(board) + get1PieceEval(board); 567 return result; 568 } 569 //print current board 570 void print_board(vector<vector <int> > board){ 571 cout<<"-----------------"<<endl; 572 for(int i = 0; i<4 ;i++){ 573 cout<<"|"; 574 for(int j = 0; j<4 ;j++){ 575 cout<<" "<<board[i][j]<<" "; 576 cout<<"|"; 577 } 578 cout<<endl; 579 cout<<"-----------------"<<endl; 580 } 581 } 582 //check if game end 583 bool Terminal_Test(vector<vector <int> > board){ 584 //row check 585 for(int i=0; i<4; i++){ 586 if ((board[i][0]!=0)&&(board[i][0]==board[i][1])&&(board[i][1]==board[i][2])&&(board[i][2]==board[i][3]))// 587 { 588 winner = board[i][0]; 589 //cout<<"row winnner:"<<winner<<endl; 590 return true; 591 } 592 } 593 //col check 594 for(int j=0; j<4; j++){ 595 if ((board[0][j]!=0)&&(board[0][j]==board[1][j])&&(board[1][j]==board[2][j])&&(board[2][j]==board[3][j]))// 596 { 597 winner = board[0][j]; 598 //cout<<"col winnner:"<<winner<<endl; 599 return true; 600 } 601 } 602 //diagnal check 603 if((board[0][0]!=0)&&(board[0][0]==board[1][1])&&(board[1][1]==board[2][2])&&(board[2][2]==board[3][3]))// 604 { 605 winner = board[0][0]; 606 //cout<<"diagnal winnner:"<<winner<<endl; 607 return true; 608 } 609 if((board[0][3]!=0)&&(board[0][3]==board[1][2])&&(board[1][2]==board[2][1])&&(board[2][1]==board[3][0]))// 610 { 611 winner = board[0][3]; 612 //cout<<"diagnal winnner:"<<winner<<endl; 613 return true; 614 } 615 for(int m = 0 ;m< 4 ;m++){ 616 for(int n =0; n< 4; n++){ 617 if(board[m][n]==0){ //is there an empty position? 618 winner = -1; 619 return false; 620 } 621 } 622 } 623 winner = 0; 624 //cout<<"full board no winner"<<endl; 625 return true;; 626 } 627 628 vector<int> findPlaceable(vector<vector <int> > board){ 629 vector<int> position; 630 for(int i=0; i< 4;i++){ 631 for(int j=0; j<4;j++){ 632 if(board[i][j]==0){ 633 position.push_back(i*4+j); 634 } 635 } 636 } 637 return position; 638 } 639 640 int MaxValue(vector<vector <int> > board,int alpha,int beta,int depth){ 641 //cout<<"depth"<<depth<<endl; 642 //print_board(board); 643 if(Terminal_Test(board)) 644 { 645 if (winner == 0){ 646 drawGame = true; 647 maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth); 648 //cout<<"game end draw game"<<endl; 649 return 0; 650 } 651 else if (winner == 1){ 652 drawGame = false; 653 maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth); 654 //cout<<"game end player win"<<endl; 655 return -1000; 656 } 657 else{ 658 drawGame = false; 659 maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth); 660 //cout<<"game end AI win"<<endl; 661 return 1000; 662 } 663 } 664 //game not end 665 if(depth==0) 666 { 667 //cout<<"cutoff happened"<<endl; 668 maxDepthReached = searchDepth; 669 isCutoffOccured = true; 670 return GetEvals(board); 671 } 672 else{ 673 drawGame = false; 674 int v = INT_MIN; 675 map<int,int> posScoreMap; 676 vector<int> avaliablePos = findPlaceable(board); 677 678 for(int i = 0; i<avaliablePos.size(); i++){ 679 int row,col; 680 row = avaliablePos[i]/4; 681 col = avaliablePos[i]%4; 682 board[row][col] = 2; 683 //cout<<"enter minvalue func"<<endl; 684 totalNodesGenerated++; 685 posScoreMap[avaliablePos[i]] = MinValue(board, alpha, beta, depth-1); 686 //cout<<"back to maxvalue func,"<<"returned value is:"<<posScoreMap[avaliablePos[i]]<<endl; 687 //cout<<"alpha is:"<<alpha<<" beta is:"<<beta<<" v is:"<<v<<endl; 688 board[row][col] = 0; 689 v =max(posScoreMap[avaliablePos[i]],v); 690 if (v>=beta){ 691 //cout<<"new v>=beta pruning happen"<<endl; 692 pruningMax++; 693 return v; 694 } 695 alpha = max(alpha, v); 696 //cout<<"new v is:"<<v<<" new alpha is:"<<alpha<<endl; 697 } 698 return v; 699 } 700 } 701 702 int MinValue(vector<vector <int> > board,int alpha,int beta,int depth){ 703 //cout<<"depth"<<depth<<endl; 704 //print_board(board); 705 if(Terminal_Test(board)) 706 { 707 if (winner == 0){ 708 drawGame = true; 709 maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth); 710 //cout<<"game end draw game"<<endl; 711 return 0; 712 } 713 else if (winner == 1){ 714 drawGame = false; 715 maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth); 716 //cout<<"game end player win"<<endl; 717 return -1000; 718 } 719 else{ 720 drawGame = false; 721 maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth); 722 //cout<<"game end AI win"<<endl; 723 return 1000; 724 } 725 } 726 //game not end 727 if(depth==0) 728 { 729 maxDepthReached = searchDepth; 730 isCutoffOccured = true; 731 //cout<<"cutoff happened"<<endl; 732 return GetEvals(board); 733 } 734 else{ 735 drawGame = false; 736 int v = INT_MAX; 737 map<int,int> posScoreMap; 738 vector<int> avaliablePos = findPlaceable(board); 739 740 for(int i = 0; i<avaliablePos.size(); i++){ 741 int row,col; 742 row = avaliablePos[i]/4; 743 col = avaliablePos[i]%4; 744 board[row][col] = 1; 745 //cout<<"enter maxvalue func"<<endl; 746 totalNodesGenerated++; 747 posScoreMap[avaliablePos[i]] = MaxValue(board, alpha, beta, depth-1); 748 //cout<<"back to minvalue func,"<<"returned value is:"<<posScoreMap[avaliablePos[i]]<<endl; 749 //cout<<"alpha is:"<<alpha<<" beta is:"<<beta<<" v is:"<<v<<endl; 750 board[row][col] = 0; 751 v =min(posScoreMap[avaliablePos[i]],v); 752 if (v<=alpha){ 753 //cout<<"new v<=alpha pruning happen"<<endl; 754 pruningMin++; 755 return v; 756 } 757 beta = min(beta, v); 758 //cout<<"new v is:"<<v<<" new beta is:"<<beta<<endl; 759 } 760 return v; 761 } 762 } 763 764 int Alpha_Beta_Search(){ 765 cout<<"enter alphabeta search"<<endl; 766 int move,alpha,beta,bestScore; 767 vector<int> avaliablePos; 768 map<int,int> posScoreMap; //move, score 769 int v = INT_MIN; 770 771 alpha = ALPHA; 772 beta = BETA; 773 avaliablePos = findPlaceable(board); 774 for(int i = 0; i<avaliablePos.size(); i++){ 775 int row,col; 776 row = avaliablePos[i]/4; 777 col = avaliablePos[i]%4; 778 board[row][col] = 2; 779 totalNodesGenerated++; 780 posScoreMap[avaliablePos[i]] = MinValue(board, alpha, beta, searchDepth-1); 781 board[row][col] = 0; 782 boardvalues[row][col] = posScoreMap[avaliablePos[i]]; 783 //cout<<"get score on position:"<<avaliablePos[i]<<"is:"<<posScoreMap[avaliablePos[i]]<<endl; 784 //cout<<"alpha is:"<<alpha<<" beta is:"<<beta<<" v is:"<<v<<endl; 785 v =max(posScoreMap[avaliablePos[i]],v); 786 if (v>=beta){ 787 //cout<<"new v>=beta pruning happen"<<endl; 788 pruningMax++; 789 return avaliablePos[i]; 790 } 791 alpha = max(alpha, v); 792 //cout<<"new v is:"<<v<<" new alpha is:"<<alpha<<endl; 793 } 794 795 move = avaliablePos[0]; 796 bestScore = posScoreMap[move]; 797 for (map<int,int>::iterator it=posScoreMap.begin(); it!=posScoreMap.end(); ++it){ 798 if(it->second > bestScore){ 799 bestScore = it->second; 800 move = it->first; 801 } 802 } 803 804 if(isCutoffOccured) 805 cout<<"Cutoff Occured: "<< "true"<<endl; 806 else 807 cout<<"Cutoff Occured: "<< "false"<<endl; 808 cout<<"max Depth Reached: "<< maxDepthReached<<endl; 809 cout<<"------------------------------------------------------------"<<endl; 810 cout<<"total Nodes Generated: "<< totalNodesGenerated<<endl; 811 cout<<"------------------------------------------------------------"<<endl; 812 cout<<"pruning in Max func: "<< pruningMax<<endl; 813 cout<<"------------------------------------------------------------"<<endl; 814 cout<<"pruning in Min func: "<< pruningMin<<endl; 815 cout<<"------------------------------------------------------------"<<endl; 816 cout<<"Max Search Depth: "<< searchDepth<<endl; 817 cout<<"------------------------------------------------------------"<<endl; 818 isCutoffOccured = false; 819 maxDepthReached = 0; 820 totalNodesGenerated = 0; 821 pruningMax = 0; 822 pruningMin = 0; 823 824 825 cout<<"score board:"<<endl; 826 print_board(boardvalues); 827 for(int i =0;i<4;i++){ 828 for(int j=0;j<4;j++){ 829 boardvalues[i][j]=99; 830 } 831 } 832 return move; 833 } 834 835 836 int main(int argc, const char * argv[]) { 837 //board[0][0] = 1; 838 //board[1][0] = 1; 839 //board[2][0] = 1; 840 //board[3][0] = 2; 841 //board[0][3] = 2; 842 //print_board(board); 843 cout<<"**************************************"<<endl; 844 cout<<" Welcome To Tic-Tac-Toe "<<endl; 845 cout<<"**************************************"<<endl; 846 cout<<endl; 847 cout<<endl; 848 cout<<endl; 849 int difficulty; 850 bool firstMove=true; 851 852 cout<<"Please select difficulty:(1.easy 2.intermediate 3.difficult)"<<endl; 853 cout<<"------------------------------------------------------------"<<endl; 854 cin >> difficulty; 855 856 int firstmove=0; 857 cout<<"Do you want to move first:(1.yes 2.no)"<<endl; 858 cout<<"------------------------------------------------------------"<<endl; 859 cin >> firstmove; 860 //3 levels difficulty matches 3 search depth; 861 switch (difficulty){ 862 case 1: 863 searchDepth = 3; 864 break; 865 case 2: 866 searchDepth = 5; 867 break; 868 case 3: 869 searchDepth = 7; 870 break; 871 } 872 //determine if player want to move first 873 switch (firstmove){ 874 case 1: 875 firstMove = true; 876 break; 877 case 2: 878 firstMove = false; 879 break; 880 } 881 882 if(firstMove){ 883 while(1){ 884 int row,col; 885 cout<<"Enter your Move:(format: a b, a is row b is col)"<<endl; 886 cout<<"------------------------------------------------------------"<<endl; 887 cin>>row>>col; 888 cout<<"your move is row: "<<row<<" and col: "<<col<<endl; 889 cout<<"------------------------------------------------------------"<<endl; 890 board[row][col] = 1; 891 print_board(board); 892 if(Terminal_Test(board)) 893 { 894 if(winner == 1){ 895 cout<< "You Win!"<<endl; 896 break; 897 } 898 else{ 899 cout<< "Draw Game!"<<endl; 900 break; 901 } 902 } 903 int AIMove = Alpha_Beta_Search(); 904 cout<<"AI move is row: "<<AIMove/4<<" and col: "<<AIMove%4<<endl; 905 cout<<"------------------------------------------------------------"<<endl; 906 board[AIMove/4][AIMove%4] = 2; 907 print_board(board); 908 if(Terminal_Test(board)) 909 { 910 if(!drawGame){ 911 cout<< "Computer Win!"<<endl; 912 break; 913 } 914 else{ 915 cout<< "Draw Game!"<<endl; 916 break; 917 } 918 } 919 } 920 } 921 else{ 922 while(1) 923 { 924 int row,col; 925 int AIMove = Alpha_Beta_Search(); 926 cout<<"AI move is row: "<<AIMove/4<<" and col: "<<AIMove%4<<endl; 927 cout<<"------------------------------------------------------------"<<endl; 928 board[AIMove/4][AIMove%4] = 2; 929 print_board(board); 930 if(Terminal_Test(board)) 931 { 932 if(!drawGame){ 933 cout<< "Computer Win!"<<endl; 934 break; 935 } 936 else{ 937 cout<< "Draw Game!"<<endl; 938 break; 939 } 940 } 941 cout<<"Enter your Move:(format: a b, a is row b is col)"<<endl; 942 cout<<"------------------------------------------------------------"<<endl; 943 cin>>row>>col; 944 cout<<"your move is row: "<<row<<" and col: "<<col<<endl; 945 cout<<"------------------------------------------------------------"<<endl; 946 board[row][col] = 1; 947 print_board(board); 948 if(Terminal_Test(board)) 949 { 950 if(winner == 1){ 951 cout<< "You Win!"<<endl; 952 break; 953 } 954 else{ 955 cout<< "Draw Game!"<<endl; 956 break; 957 } 958 } 959 } 960 } 961 962 return 0; 963 }
運行截圖:lua