A collection of games (written or co-written by me)
1 #include <algorithm> // min & max 2 #include <cmath> 3 #include <conio.h> 4 #include <ctime> 5 #include <fstream> 6 #include <iostream> 7 #include <map> 8 #include <windows.h> 9 #define hConsole (GetStdHandle(STD_OUTPUT_HANDLE)) 10 using namespace std; 11 12 // Helper function of clear(). 13 inline void resetCursor() 14 { 15 SetConsoleCursorPosition(hConsole, {0, 0}); 16 } 17 //Math.random=function(){return 0.9;} 18 // Clear the screen. 19 inline void clear() 20 { 21 resetCursor(); 22 for (int i = 0; i < 17; i++, cout << endl) 23 for (int j = 0; j < 50; j++) 24 cout << ' '; 25 resetCursor(); 26 } 27 28 // Set the output color to [color]. 29 inline void setConsoleColor(WORD color) 30 { 31 cout.flush(); 32 SetConsoleTextAttribute(hConsole, color); 33 } 34 35 // Sleep [secs] seconds. 36 inline void sleepSecs(int secs) 37 { 38 Sleep(secs * 1000); 39 } 40 41 inline void gaga() 42 { 43 clear(); 44 cout << "CE = Compiler Excellent" << endl 45 << "RE = Runs Excellent" << endl 46 << "TLE = Time Limit Enough" << endl 47 << "MLE = Memory Limit Enough" << endl 48 << "ILE = Idleness Limit Enough" << endl 49 << "OLE = Output Limit Enough" << endl 50 << "UKE = Understand Knowledge Easily" << endl 51 << "WA = Wonderful Answer" << endl 52 << "PC = Partially CE" << endl 53 << "AC = Awful Compiler" << endl 54 << "PE = Physical Exercise" << endl 55 << "DOJ = Duck Or Jump" << endl 56 << "SJE = Simple Judge Exit" << endl 57 << "AU = All Understood" << endl 58 << "AK = All Killed" << endl; 59 system("color 01"); 60 sleepSecs(1); 61 system("color 02"); 62 sleepSecs(1); 63 system("color 03"); 64 sleepSecs(1); 65 system("color 04"); 66 sleepSecs(1); 67 system("color 05"); 68 sleepSecs(1); 69 system("color 06"); 70 sleepSecs(1); 71 system("color f"); 72 sleepSecs(1); 73 system("color 08"); 74 sleepSecs(1); 75 system("color 09"); 76 sleepSecs(1); 77 system("color a"); 78 sleepSecs(1); 79 system("color b"); 80 sleepSecs(1); 81 system("color c"); 82 sleepSecs(1); 83 system("color d"); 84 sleepSecs(1); 85 system("color e"); 86 sleepSecs(1); 87 system("color 7"); 88 sleepSecs(1); 89 system("pause"); 90 clear(); 91 } 92 93 // 2048 Board. 94 class Board 95 { 96 private: 97 struct trans_table_entry_t 98 { 99 uint8_t depth; 100 float heuristic; 101 }; 102 int penaltyScore; 103 104 typedef unsigned long long bitBoard; 105 typedef map<bitBoard, trans_table_entry_t> trans_table_t; 106 typedef unsigned short row_t; 107 typedef int (*get_move_func_t)(bitBoard); 108 109 struct eval_state 110 { 111 trans_table_t trans_table; 112 int maxdepth, curdepth, cachehits, depth_limit; 113 114 inline eval_state() : maxdepth(0), curdepth(0), cachehits(0), depth_limit(0) {} 115 }; 116 117 static constexpr bitBoard ROW_MASK = 0xFFFFULL, COL_MASK = 0x000F000F000F000FULL; 118 static constexpr const char *CELL_STRING[] = {" ", " CE ", " JG ", " RE ", " TLE ", " MLE ", " ILE ", " OLE ", " UKE ", " WA ", " PC ", " AC ", " PE ", " DOJ ", " SJE ", " AK "}; 119 static constexpr WORD COLORS[] = {7, 6, 3, 13, 9, 9, 9, 9, 8, 12, 14, 10, 5, 14, 8, 11}; 120 static constexpr int SAVE_KEY = 10382; 121 122 static inline bitBoard unpackCol(row_t row) 123 { 124 bitBoard tmp = row; 125 return (tmp | (tmp << 12ULL) | (tmp << 24ULL) | (tmp << 36ULL)) & COL_MASK; 126 } 127 128 static inline row_t reverseRow(row_t row) 129 { 130 return (row >> 12) | ((row >> 4) & 0x00F0) | ((row << 4) & 0x0F00) | (row << 12); 131 } 132 133 static inline bitBoard transpose(bitBoard x) 134 { 135 bitBoard a1 = x & 0xF0F00F0FF0F00F0FULL; 136 bitBoard a2 = x & 0x0000F0F00000F0F0ULL; 137 bitBoard a3 = x & 0x0F0F00000F0F0000ULL; 138 bitBoard a = a1 | (a2 << 12) | (a3 >> 12); 139 bitBoard b1 = a & 0xFF00FF0000FF00FFULL; 140 bitBoard b2 = a & 0x00FF00FF00000000ULL; 141 bitBoard b3 = a & 0x00000000FF00FF00ULL; 142 return b1 | (b2 >> 24) | (b3 << 24); 143 } 144 145 static inline int countEmpty(bitBoard x) 146 { 147 x |= (x >> 2) & 0x3333333333333333ULL; 148 x |= (x >> 1); 149 x = ~x & 0x1111111111111111ULL; 150 x += x >> 32; 151 x += x >> 16; 152 x += x >> 8; 153 x += x >> 4; 154 return x & 0xf; 155 } 156 157 static inline bitBoard execMoveUp(bitBoard board) 158 { 159 bitBoard t = transpose(board); 160 board ^= col_up_table[(t >> 0) & ROW_MASK] << 0; 161 board ^= col_up_table[(t >> 16) & ROW_MASK] << 4; 162 board ^= col_up_table[(t >> 32) & ROW_MASK] << 8; 163 board ^= col_up_table[(t >> 48) & ROW_MASK] << 12; 164 return board; 165 } 166 167 static inline bitBoard execMoveDown(bitBoard board) 168 { 169 bitBoard t = transpose(board); 170 board ^= col_down_table[(t >> 0) & ROW_MASK] << 0; 171 board ^= col_down_table[(t >> 16) & ROW_MASK] << 4; 172 board ^= col_down_table[(t >> 32) & ROW_MASK] << 8; 173 board ^= col_down_table[(t >> 48) & ROW_MASK] << 12; 174 return board; 175 } 176 177 static inline bitBoard execMoveLeft(bitBoard board) 178 { 179 bitBoard ret = board; 180 ret ^= bitBoard(row_left_table[(board >> 0) & ROW_MASK]) << 0; 181 ret ^= bitBoard(row_left_table[(board >> 16) & ROW_MASK]) << 16; 182 ret ^= bitBoard(row_left_table[(board >> 32) & ROW_MASK]) << 32; 183 ret ^= bitBoard(row_left_table[(board >> 48) & ROW_MASK]) << 48; 184 return ret; 185 } 186 187 static inline bitBoard execMoveRight(bitBoard board) 188 { 189 bitBoard ret = board; 190 ret ^= bitBoard(row_right_table[(board >> 0) & ROW_MASK]) << 0; 191 ret ^= bitBoard(row_right_table[(board >> 16) & ROW_MASK]) << 16; 192 ret ^= bitBoard(row_right_table[(board >> 32) & ROW_MASK]) << 32; 193 ret ^= bitBoard(row_right_table[(board >> 48) & ROW_MASK]) << 48; 194 return ret; 195 } 196 197 static inline bitBoard execMove(int move, bitBoard board) 198 { 199 switch (move) 200 { 201 case 0: 202 return execMoveUp(board); 203 case 1: 204 return execMoveDown(board); 205 case 2: 206 return execMoveLeft(board); 207 case 3: 208 return execMoveRight(board); 209 default: 210 return ~0ULL; 211 } 212 } 213 214 static row_t row_left_table[65536], row_right_table[65536]; 215 static bitBoard col_up_table[65536], col_down_table[65536]; 216 static float heur_score_table[65536], score_table[65536]; 217 218 static constexpr float SCORE_LOST_PENALTY = 200000.0f, 219 SCORE_MONOTONICITY_POWER = 4.0f, 220 SCORE_MONOTONICITY_WEIGHT = 47.0f, 221 SCORE_SUM_POWER = 3.5f, 222 SCORE_SUM_WEIGHT = 11.0f, 223 SCORE_MERGES_WEIGHT = 700.0f, 224 SCORE_EMPTY_WEIGHT = 270.0f; 225 226 static inline unsigned unifRandom(unsigned n) 227 { 228 static bool seeded = false; 229 if (!seeded) 230 srand(time(NULL)), seeded = true; 231 return rand() % n; 232 } 233 234 static inline bitBoard drawTile() 235 { 236 return unifRandom(10) == 0 ? 2 : 1; 237 } 238 239 static inline float calcScore(bitBoard board, const float *table) 240 { 241 return table[(board >> 0) & ROW_MASK] + 242 table[(board >> 16) & ROW_MASK] + 243 table[(board >> 32) & ROW_MASK] + 244 table[(board >> 48) & ROW_MASK]; 245 } 246 247 static constexpr float CPROB_THRESH_BASE = 0.0001f; 248 static constexpr int CACHE_DEPTH_LIMIT = 15; 249 250 static inline float scoreHeurBoard(bitBoard board) 251 { 252 return calcScore(board, heur_score_table) + 253 calcScore(transpose(board), heur_score_table); 254 } 255 256 static float score_move_node(eval_state &state, bitBoard board, float cprob) 257 { 258 float best = 0.0f; 259 state.curdepth++; 260 for (int move = 0; move < 4; ++move) 261 { 262 bitBoard newboard = execMove(move, board); 263 if (board != newboard) 264 best = max(best, scoreTilechooseNode(state, newboard, cprob)); 265 } 266 state.curdepth--; 267 return best; 268 } 269 270 static float scoreTilechooseNode(eval_state &state, bitBoard board, float cprob) 271 { 272 if (cprob < CPROB_THRESH_BASE || state.curdepth >= state.depth_limit) 273 { 274 state.maxdepth = max(state.curdepth, state.maxdepth); 275 return scoreHeurBoard(board); 276 } 277 if (state.curdepth < CACHE_DEPTH_LIMIT) 278 { 279 const trans_table_t::iterator &i = state.trans_table.find(board); 280 if (i != state.trans_table.end()) 281 { 282 trans_table_entry_t entry = i->second; 283 if (entry.depth <= state.curdepth) 284 { 285 state.cachehits++; 286 return entry.heuristic; 287 } 288 } 289 } 290 int num_open = countEmpty(board); 291 cprob /= num_open; 292 float res = 0.0f; 293 bitBoard tmp = board; 294 bitBoard tile_2 = 1; 295 while (tile_2) 296 { 297 if ((tmp & 0xf) == 0) 298 { 299 res += score_move_node(state, board | tile_2, cprob * 0.9f) * 0.9f; 300 res += score_move_node(state, board | (tile_2 << 1), cprob * 0.1f) * 0.1f; 301 } 302 tmp >>= 4; 303 tile_2 <<= 4; 304 } 305 res /= num_open; // bug might be here 306 if (state.curdepth < CACHE_DEPTH_LIMIT) 307 { 308 trans_table_entry_t entry = {static_cast<uint8_t>(state.curdepth), res}; 309 state.trans_table[board] = entry; 310 } 311 return res; 312 } 313 314 static inline float _scoreToplevelMove(eval_state &state, bitBoard board, int move) 315 { 316 bitBoard newboard = execMove(move, board); 317 if (board == newboard) 318 return 0; 319 return scoreTilechooseNode(state, newboard, 1.0f) + 1e-6; 320 } 321 322 static inline int count_distinct_tiles(bitBoard board) 323 { 324 uint16_t bitset = 0; 325 while (board) 326 { 327 bitset |= 1 << (board & 0xf); 328 board >>= 4; 329 } 330 bitset >>= 1; 331 int count = 0; 332 while (bitset) 333 { 334 bitset &= bitset - 1; 335 count++; 336 } 337 return count; 338 } 339 340 static inline float scoreToplevelMove(bitBoard board, int move) 341 { 342 float res; 343 double elapsed; 344 eval_state state; 345 state.depth_limit = max(3, count_distinct_tiles(board) - 2); 346 return _scoreToplevelMove(state, board, move); 347 } 348 349 bitBoard bb; 350 351 public: 352 inline Board() : penaltyScore(0) {} 353 static inline void initTables() 354 { 355 for (unsigned row = 0; row < 65536; row++) 356 { 357 unsigned line[4] = { 358 (row >> 0) & 0xf, 359 (row >> 4) & 0xf, 360 (row >> 8) & 0xf, 361 (row >> 12) & 0xf}; 362 363 // Score 364 float score = 0.0f; 365 for (int i = 0; i < 4; ++i) 366 { 367 int rank = line[i]; 368 if (rank >= 2) 369 score += (rank - 1) * (1 << rank); 370 } 371 score_table[row] = score; 372 373 float sum = 0; 374 int empty = 0, merges = 0, prev = 0, counter = 0; 375 for (int i = 0; i < 4; ++i) 376 { 377 int rank = line[i]; 378 sum += pow(rank, SCORE_SUM_POWER); 379 if (rank == 0) 380 empty++; 381 else 382 { 383 if (prev == rank) 384 counter++; 385 else if (counter > 0) 386 { 387 merges += 1 + counter; 388 counter = 0; 389 } 390 prev = rank; 391 } 392 } 393 if (counter > 0) 394 merges += 1 + counter; 395 float monotonicity_left = 0; 396 float monotonicity_right = 0; 397 for (int i = 1; i < 4; ++i) 398 if (line[i - 1] > line[i]) 399 monotonicity_left += pow(line[i - 1], SCORE_MONOTONICITY_POWER) - pow(line[i], SCORE_MONOTONICITY_POWER); 400 else 401 monotonicity_right += pow(line[i], SCORE_MONOTONICITY_POWER) - pow(line[i - 1], SCORE_MONOTONICITY_POWER); 402 heur_score_table[row] = SCORE_LOST_PENALTY + 403 SCORE_EMPTY_WEIGHT * empty + 404 SCORE_MERGES_WEIGHT * merges - 405 SCORE_MONOTONICITY_WEIGHT * min(monotonicity_left, monotonicity_right) - 406 SCORE_SUM_WEIGHT * sum; 407 408 for (int i = 0; i < 3; i++) 409 { 410 int j; 411 for (j = i + 1; j < 4; j++) 412 { 413 if (line[j] != 0) 414 break; 415 } 416 if (j == 4) 417 break; 418 419 if (line[i] == 0) 420 { 421 line[i] = line[j]; 422 line[j] = 0; 423 i--; 424 } 425 else if (line[i] == line[j]) 426 { 427 if (line[i] != 0xf) 428 line[i]++; 429 line[j] = 0; 430 } 431 } 432 433 row_t result = (line[0] << 0) | (line[1] << 4) | (line[2] << 8) | (line[3] << 12); 434 row_t rev_result = reverseRow(result); 435 unsigned rev_row = reverseRow(row); 436 437 row_left_table[row] = row ^ result; 438 row_right_table[rev_row] = rev_row ^ rev_result; 439 col_up_table[row] = unpackCol(row) ^ unpackCol(result); 440 col_down_table[rev_row] = unpackCol(rev_row) ^ unpackCol(rev_result); 441 } 442 } 443 444 // Return the game's current score. 445 inline int getScore() const 446 { 447 return calcScore(bb, score_table) + 0.5f - penaltyScore; 448 } 449 450 // Return the cell at (i, j). Empty cells are represented as 0. 451 inline int getCell(int i, int j) const 452 { 453 int bit = (i << 2) + j << 2; 454 int pow = bb >> bit & 0xf; 455 return pow == 0 ? 0 : 1 << pow; 456 } 457 458 // I/O operators 459 460 // I/O operator: istream >> 461 friend inline istream &operator>>(istream &in, Board &board) 462 { 463 board.bb = 0; 464 for (int i = 0; i < 4; i++) 465 for (int j = 0; j < 4; j++) 466 { 467 int cell; 468 in >> cell; 469 if (cell < 0) 470 cell = 0; 471 int pow = 0; 472 while (cell > 1) 473 cell >>= 1, pow++; 474 if (pow > 14) 475 pow = 13; 476 board.bb ^= bitBoard(pow) << bitBoard((i << 2) + j << 2); 477 } 478 return in; 479 } 480 481 // I/O operator: ostream << 482 friend inline ostream &operator<<(ostream &out, const Board &board) 483 { 484 setConsoleColor(7); 485 out << "*****************************" << endl; 486 const int sc = board.getScore(); 487 out << '*'; 488 int lim = 20, tmp = sc; 489 do 490 lim--; 491 while (tmp /= 10); 492 int len = lim >> 1; 493 lim -= len; 494 while (len--) 495 out << ' '; 496 out << "Score: " << sc; 497 while (lim--) 498 out << ' '; 499 out << '*' << endl 500 << "*****************************" << endl; 501 bitBoard tmpb = board.bb; 502 for (int i = 0; i < 4; i++) 503 { 504 for (int j = 0; j < 4; j++) 505 { 506 int cell = tmpb & 0xf; 507 setConsoleColor(15); 508 out << '|'; 509 if (cell > 15) 510 { 511 setConsoleColor(7); 512 out << " INF "; 513 } 514 else 515 { 516 setConsoleColor(COLORS[cell]); 517 out << CELL_STRING[cell]; 518 } 519 tmpb >>= 4; 520 } 521 setConsoleColor(7); 522 out << '|' << endl 523 << "_____________________________" << endl; 524 } 525 out << "*****************************" << endl; 526 return out; 527 } 528 529 // Randomly add cells 2 or 4. 530 inline void update() 531 { 532 int index = unifRandom(countEmpty(bb)); 533 bitBoard tmp = bb, tile = drawTile(); 534 if (tile == 2) 535 penaltyScore += 4; 536 while (true) 537 { 538 while ((tmp & 0xf) != 0) 539 { 540 tmp >>= 4; 541 tile <<= 4; 542 } 543 if (index == 0) 544 break; 545 --index; 546 tmp >>= 4; 547 tile <<= 4; 548 } 549 bb |= tile; 550 } 551 552 // Initialize cells. 553 inline void initialize() 554 { 555 bb = drawTile() << (4 * unifRandom(16)); 556 update(); 557 } 558 559 // Controls 560 561 inline void moveLeft() { bb = execMoveLeft(bb); } 562 inline void moveRight() { bb = execMoveRight(bb); } 563 inline void moveUp() { bb = execMoveUp(bb); } 564 inline void moveDown() { bb = execMoveDown(bb); } 565 566 // Board save & load 567 568 enum GameLoadState 569 { 570 OK, 571 FILE_FORMAT_WRONG, 572 FILE_DOES_NOT_EXIST 573 }; 574 575 // Load the game with saved file [filename]. 576 inline GameLoadState loadGame(const char *filename = "2048.dat") 577 { 578 ifstream fin(filename); 579 if (fin.fail()) 580 return fin.eof() ? FILE_FORMAT_WRONG : FILE_DOES_NOT_EXIST; 581 int ps; 582 fin >> ps; 583 ps ^= SAVE_KEY; 584 if (ps & 1) 585 return FILE_FORMAT_WRONG; 586 penaltyScore = ps >> 1; 587 if (!(fin >> bb)) 588 return FILE_FORMAT_WRONG; 589 bb ^= SAVE_KEY; 590 return OK; 591 } 592 593 // Save the game into [filename]. 594 inline void saveGame(const char *filename = "2048.dat") const 595 { 596 ofstream fout(filename); 597 fout << (penaltyScore << 1 ^ SAVE_KEY) << ' ' << (bb ^ SAVE_KEY) << endl; 598 } 599 600 // Game result checks 601 602 // Alive check 603 inline bool isAlive() const 604 { 605 for (int move = 0; move < 4; move++) 606 if (execMove(move, bb) != bb) 607 return true; 608 return false; 609 } 610 611 // Won check 612 inline bool isWon() const 613 { 614 bitBoard tmp = bb; 615 for (int i = 0; i < 4; i++) 616 for (int j = 0; j < 4; j++) 617 { 618 int cell = tmp & 0xf; 619 if (cell >= 15) 620 return true; 621 tmp >>= 4; 622 } 623 return false; 624 } 625 626 // Games 627 628 // Player interactive controls. 629 inline void playerControls() 630 { 631 penaltyScore = 0; 632 system("color 7"); 633 clear(); 634 cout << *this; 635 while (isAlive()) 636 { 637 bool upArrow = GetAsyncKeyState(VK_UP), downArrow = GetAsyncKeyState(VK_DOWN), 638 leftArrow = GetAsyncKeyState(VK_LEFT), rightArrow = GetAsyncKeyState(VK_RIGHT); 639 if (upArrow) 640 if (execMoveUp(bb) != bb) 641 moveUp(); 642 else 643 continue; 644 else if (downArrow) 645 if (execMoveDown(bb) != bb) 646 moveDown(); 647 else 648 continue; 649 else if (leftArrow) 650 if (execMoveLeft(bb) != bb) 651 moveLeft(); 652 else 653 continue; 654 else if (rightArrow) 655 if (execMoveRight(bb) != bb) 656 moveRight(); 657 else 658 continue; 659 else 660 continue; 661 update(), clear(); 662 cout << *this; 663 if (isWon()) 664 { 665 sleepSecs(1); 666 cout << "You AK IOI!" << endl; 667 sleepSecs(3); 668 system("pause"); 669 return; 670 } 671 saveGame(); 672 if (upArrow) 673 while (GetAsyncKeyState(VK_UP)) 674 ; 675 else if (downArrow) 676 while (GetAsyncKeyState(VK_DOWN)) 677 ; 678 else if (leftArrow) 679 while (GetAsyncKeyState(VK_LEFT)) 680 ; 681 else 682 while (GetAsyncKeyState(VK_RIGHT)) 683 ; 684 } 685 sleepSecs(1); 686 cout << "Game Over" << endl; 687 sleepSecs(3); 688 system("pause"); 689 } 690 691 // Let the AI move a step. 692 inline void AIMove() 693 { 694 float best = scoreToplevelMove(bb, 0); 695 int bestmove = 0; 696 for (int move = 1; move < 4; move++) 697 { 698 float res = scoreToplevelMove(bb, move); 699 if (res > best) 700 { 701 best = res; 702 bestmove = move; 703 } 704 } 705 bb = execMove(bestmove, bb); 706 } 707 708 // AI automatic controls. 709 inline void AIControls() 710 { 711 penaltyScore = 0; 712 system("color 7"); 713 clear(); 714 cout << *this; 715 while (isAlive()) 716 { 717 clock_t start = clock(); 718 AIMove(); 719 update(), clear(); 720 cout << *this; 721 if (isWon()) 722 { 723 sleepSecs(1); 724 cout << "You AK IOI!" << endl; 725 sleepSecs(3); 726 system("pause"); 727 return; 728 } 729 clock_t best_end = start + CLOCKS_PER_SEC / 10; // 100ms 730 while (clock() < best_end) 731 ; 732 } 733 sleepSecs(1); 734 cout << "Game Over" << endl; 735 sleepSecs(3); 736 system("pause"); 737 } 738 }; 739 740 // Static members of Board 741 Board::row_t Board::row_left_table[65536], Board::row_right_table[65536]; 742 Board::bitBoard Board::col_up_table[65536], Board::col_down_table[65536]; 743 float Board::heur_score_table[65536], Board::score_table[65536]; 744 constexpr const char *Board::CELL_STRING[]; 745 constexpr WORD Board::COLORS[]; 746 747 int main() 748 { 749 ios::sync_with_stdio(false); 750 cin.tie(nullptr); 751 srand(time(NULL)); 752 system("title 2048"); 753 Board::initTables(); 754 Board board; 755 while (true) 756 { 757 clear(); 758 cout << " 欢迎来到2048游戏!" << endl 759 << "********************************" << endl 760 << "* 1. 手动模式 *" << endl 761 << "* 2. 作弊模式 *" << endl 762 << "* 3. 简单说明 *" << endl 763 << "* 4. 搞笑的AKIOI *" << endl 764 << "* 5. 退出程序 *" << endl 765 << "********************************" << endl; 766 again:; 767 char ch = getch(); 768 if (ch == '5') 769 return 0; 770 if (ch == '1') 771 { 772 loadFailed:; 773 clear(); 774 cout << " 开始游戏" << endl 775 << "********************************" << endl 776 << "* 1. 新游戏 *" << endl 777 << "* 2. 继续游戏 *" << endl 778 << "* 3. 自定义游戏 *" << endl 779 << "********************************" << endl; 780 while (true) 781 { 782 ch = getch(); 783 if (ch == '1') 784 board.initialize(); 785 else if (ch == '2') 786 { 787 Board::GameLoadState state = board.loadGame(); 788 if (state == Board::OK) 789 break; 790 cout << (state == Board::FILE_DOES_NOT_EXIST ? "无游戏存档" : "游戏存档格式错误") << endl; 791 sleepSecs(2); 792 goto loadFailed; 793 } 794 else if (ch == '3') 795 { 796 cout << "请输入4行4列 (2^n):" << endl; 797 cin >> board; 798 } 799 else 800 continue; 801 break; 802 } 803 board.playerControls(); 804 continue; 805 } 806 if (ch == '2') 807 { 808 board.initialize(); 809 board.AIControls(); 810 continue; 811 } 812 if (ch == '3') 813 { 814 clear(); 815 cout << "上下左右 控制方向,尽可能得到块数大的方块!" << endl; 816 system("pause"); 817 clear(); 818 continue; 819 } 820 if (ch == '4') 821 gaga(); 822 else 823 goto again; 824 } 825 return 0; 826 }2048
1 #include <bits/stdc++.h> 2 #include <cstring> 3 #include <time.h> 4 #include <cstdlib> 5 #include <windows.h> 6 #include <algorithm> // min & max 7 #include <cmath> 8 #include <conio.h> 9 #include <ctime> 10 #include <fstream> 11 #include <iostream> 12 #include <map> 13 #include <windows.h> 14 using namespace std; 15 16 #define int long long 17 #define forn(i,a,n) for (int i=a; i<n; i++) 18 19 // ____ _ _ ____ _ _ __ __ _ _ _ __ 20 /// ___)/ )( \( __)( \/ )( )( ( \( \/ )( ) 21 //\___ \) __ ( ) _) ) ( )( / / ) / )( 22 //(____/\_)(_/(____)(_/\_)(__)\_)__)(__/ (__) 23 24 int x,y; 25 string b[20][20]; 26 int a[20][20]; 27 28 void SetColor(unsigned short ForeColor=7,unsigned short BackGroundColor=0){ 29 HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); 30 SetConsoleTextAttribute(hCon,ForeColor|BackGroundColor); 31 } 32 33 void gotoxy(int x,int y) { 34 COORD pos = {x,y}; 35 HANDLE hOut =GetStdHandle(STD_OUTPUT_HANDLE); 36 SetConsoleCursorPosition(hOut,pos); 37 } 38 39 int print(){ 40 gotoxy(2,1); 41 42 cout<<"┌"; 43 44 for(int i=2; i<=14; i++) { 45 46 gotoxy(2,i); 47 48 cout<<"├"; 49 50 } 51 52 gotoxy(2,15); 53 54 cout<<"└";//输出棋盘左侧 55 56 for(int i=4; i<=28; i+=2) { 57 58 print(); 59 60 }//用一个循环来输出棋盘中间部分 61 62 gotoxy(30,1); 63 64 cout<<"┐"; 65 66 for(int i=2; i<=14; i++) { 67 68 gotoxy(30,i); 69 70 cout<<"┤"; 71 72 } 73 74 gotoxy(30,15); 75 76 cout<<"┘";//输出棋盘右侧 77 } 78 79 int print_y(){ 80 printf("╔━━━┳━━━┳━━━┳━━━┳━━━"); 81 printf("┳"); 82 printf("━━━┳━━━┳━━━┳━━━┳━━━"); 83 printf("┳"); 84 printf("━━━┳━━━┳━━━┳━━━┳━━━┓\n"); 85 for(int i=1;i<=15;i++) 86 { 87 for(int j=1;j<=15;j++) 88 { 89 if (x==i-1&&y==j-1){ 90 cout<<"┃ "; 91 SetColor(9); 92 cout<<"▋▋"<<""; 93 SetColor(15); 94 if (j==15) cout<<"┃"; 95 } 96 cout<<"┃ "; 97 if (j==15) cout<<"┃"; 98 } 99 cout<<endl; 100 if(i!=15) 101 { 102 cout<<"┣━━━╋━━━╋━━━╋━━━╋━━━"; 103 cout<<"╋"; 104 cout<<"━━━╋━━━╋━━━╋━━━╋━━━"; 105 cout<<"╋" ; 106 cout<<"━━━╋━━━╋━━━╋━━━╋━━━┫"; 107 cout<<endl; 108 } 109 else 110 { 111 printf("┗━━━┻━━━┻━━━┻━━━┻━━━"); 112 printf("┻"); 113 printf("━━━┻━━━┻━━━┻━━━┻━━━"); 114 printf("┻"); 115 printf("━━━┻━━━┻━━━┻━━━┻━━━┛\n"); 116 } 117 } 118 forn(i,1,16){ 119 forn(j,1,16){ 120 if (a[i-1][j-1]!=0){ 121 gotoxy(j*2+(j!=1)*2*(j-1),i*2-1); 122 cout<<b[i][j]; 123 } 124 } 125 } 126 } 127 128 int cur; 129 130 void move(int i,int j){ 131 if (b[i+1][j+1]!="e"){ 132 gotoxy(20,15); 133 SetColor(2); 134 cout<<"You cannot move here!"; 135 Sleep(2000); 136 SetColor(15); 137 return; 138 } 139 if (cur%2!=0) b[i+1][j+1]="●"; 140 else b[i+1][j+1]="○"; 141 a[i][j]=(cur%2)+1; 142 cur++; 143 } 144 145 int w1,w2; 146 147 bool l(int c,int i,int j){ 148 if (j<4) return 0; 149 if (a[i][j-4]==c&&a[i][j-3]==c&&a[i][j-2]==c&&a[i][j-1]==c&&a[i][j]==c) return 1; 150 return 0; 151 } 152 153 bool r(int c,int i,int j){ 154 if (j>10) return 0; 155 if (a[i][j+4]==c&&a[i][j+3]==c&&a[i][j+2]==c&&a[i][j+1]==c&&a[i][j]==c) return 1; 156 return 0; 157 } 158 159 bool u(int c,int i,int j){ 160 if (i<4) return 0; 161 if (a[i-4][j]==c&&a[i-3][j]==c&&a[i-2][j]==c&&a[i-1][j]==c&&a[i][j]==c) return 1; 162 return 0; 163 } 164 165 bool d(int c,int i,int j){ 166 if (i>10) return 0; 167 if (a[i+4][j]==c&&a[i+3][j]==c&&a[i+2][j]==c&&a[i+1][j]==c&&a[i][j]==c) return 1; 168 return 0; 169 } 170 171 bool d1(int c,int i,int j){ 172 if (j<4||i<4) return 0; 173 if (a[i-4][j-4]==c&&a[i-3][j-3]==c&&a[i-2][j-2]==c&&a[i-1][j-1]==c&&a[i][j]==c) return 1; 174 return 0; 175 } 176 177 bool d2(int c,int i,int j){ 178 if (j>10||i>10) return 0; 179 if (a[i+4][j+4]==c&&a[i+3][j+3]==c&&a[i+2][j+2]==c&&a[i+1][j+1]==c&&a[i][j]==c) return 1; 180 return 0; 181 } 182 183 bool d3(int c,int i,int j){ 184 if (j>10||i<4) return 0; 185 if (a[i-4][j+4]==c&&a[i-3][j+3]==c&&a[i-2][j+2]==c&&a[i-1][j+1]==c&&a[i][j]==c) return 1; 186 return 0; 187 } 188 189 bool d4(int c,int i,int j){ 190 if (j<4||i>10) return 0; 191 if (a[i+4][j-4]==c&&a[i+3][j-3]==c&&a[i+2][j-2]==c&&a[i+1][j-1]==c&&a[i][j]==c) return 1; 192 return 0; 193 } 194 195 bool win1(){ 196 forn(i,0,15){ 197 forn(j,0,15){ 198 if (l(1,i,j)||r(1,i,j)||u(1,i,j)||d(1,i,j)) return 1; 199 if (d1(1,i,j)||d2(1,i,j)||d3(1,i,j)||d4(1,i,j)) return 1; 200 } 201 } 202 } 203 204 bool win2(){ 205 forn(i,0,15){ 206 forn(j,0,15){ 207 if (l(2,i,j)||r(2,i,j)||u(2,i,j)||d(2,i,j)) return 1; 208 if (d1(2,i,j)||d2(2,i,j)||d3(2,i,j)||d4(2,i,j)) return 1; 209 } 210 } 211 } 212 213 void enter(){ 214 forn(i,0,20) forn(j,0,20) a[i][j]=0; 215 cur=0; 216 forn(i,0,20) forn(j,0,20) b[i][j]="e"; 217 x=0,y=0; 218 system("cls"); 219 cout<<endl<<endl<<endl; 220 cout<<" chessboard loading..."<<endl; 221 cout<<endl<<endl<<endl<<""; 222 forn(i,0,50){ 223 cout<<"■"; 224 Sleep(10); 225 } 226 system("cls"); 227 system("mode con cols=70 lines=35"); 228 forn(i,0,35){ 229 forn(j,0,70){ 230 cout<<"■"; 231 } 232 if (i%5==0) Sleep(2); 233 } 234 system("cls"); 235 int up=0,down=0,left=0,right=0; 236 while (true){ 237 system("cls"); 238 print_y(); 239 cout<<endl; 240 if (win1()){ 241 Sleep(2000); 242 system("cls"); 243 cout<<endl<<endl<<endl; 244 SetColor(5); 245 cout<<" Player 1 wins !"<<endl<<endl; 246 w1++; 247 cout<<" Loading Results ......"<<endl; 248 cout<<endl<<endl<<endl; 249 cout<<" "; 250 forn(i,0,30){ 251 cout<<"■"; 252 Sleep(15); 253 } 254 system("cls"); 255 cout<<endl<<endl<<endl; 256 cout<<" Player 1 wins !"<<endl; 257 cout<<endl; 258 cout<<" Player 1 wins "<<w1<<" games in total."<<endl; 259 cout<<" Player 2 wins "<<w2<<" games in total."<<endl; 260 Sleep(5000); 261 SetColor(15); 262 return; 263 } 264 if (win2()){ 265 Sleep(2000); 266 system("cls"); 267 cout<<endl<<endl<<endl; 268 SetColor(5); 269 cout<<" Player 2 wins !"<<endl<<endl; 270 w2++; 271 cout<<" Loading Results ......"<<endl; 272 cout<<endl<<endl<<endl; 273 cout<<" "; 274 forn(i,0,30){ 275 cout<<"■"; 276 Sleep(15); 277 } 278 system("cls"); 279 cout<<endl<<endl<<endl; 280 cout<<" Player 2 wins !"<<endl; 281 cout<<endl; 282 cout<<" Player 1 wins "<<w1<<" games in total."<<endl; 283 cout<<" Player 2 wins "<<w2<<" games in total."<<endl; 284 Sleep(5000); 285 SetColor(15); 286 return; 287 } 288 again:; 289 int t=GetAsyncKeyState(' '); 290 up = GetAsyncKeyState(VK_UP); 291 down = GetAsyncKeyState(VK_DOWN); 292 left = GetAsyncKeyState(VK_LEFT); 293 right = GetAsyncKeyState(VK_RIGHT); 294 Sleep(200); 295 if (up){ 296 if (x!=0) x--; 297 } 298 else if (down){ 299 if (x!=14) x++; 300 } 301 else if (left){ 302 if (y!=0) y--; 303 } 304 else if (right){ 305 if (y!=14) y++; 306 } 307 else if (t){ 308 move(x,y); 309 } 310 else goto again; 311 } 312 } 313 314 signed main(){ 315 316 //freopen("input.txt","r",stdin); 317 //freopen("output.txt","w",stdout); 318 319 // SetColor(9); blue 320 // SetColor(15); black 321 again:; 322 system("mode con cols=100 lines=20"); 323 SetColor(15); 324 cout<<" Welcome-to-this-game"<<endl; 325 cout<<" ---This-is-a-gobang-game----"<<endl; 326 cout<<" | 1. enter |"<<endl; 327 cout<<" | 2. exit |"<<endl; 328 cout<<" ----------------------------"<<endl; 329 char c=getch(); 330 if (c=='1'){ 331 enter(); 332 goto again; 333 } 334 if (c=='2'){ 335 system("CLS"); 336 exit(0); 337 } 338 else goto again; 339 return 0; 340 }五子棋(双人)
标签:return,int,MASK,state,Games,board,include From: https://www.cnblogs.com/SFlyer/p/games_by_me.html