Công cụ bảo vệ mã nguồn .NET mạnh nhất, không thể unpack, miễn phí cho các khách hàng đầu tiên đăng ký.
Từ 1 tới 2 trên tổng số 2 kết quả

Đề tài: Lập trình cấu trúc cho Console, sử dụng thuật toán "dầu loang", mã nguồn Lines98

  1. #1
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    930

    Mặc định Lập trình cấu trúc cho Console, sử dụng thuật toán "dầu loang", mã nguồn Lines98

    C++ Code:
    1. #include <iostream>
    2. #include <vector>
    3. #include <stack>
    4. #include <windows.h>
    5. #include <time.h>
    6. using namespace std;
    7.  
    8. enum { TC_FREE = 0, TC_SELECTED, TC_LARGE, TC_SMALL, TC_ROAD };
    9. typedef struct
    10. {
    11.     short   Style;                  // Kiểu ô : TC_FREE = 0, TC_SELECTED, TC_LARGE, TC_SMALL, TC_ROAD
    12.     short   ColorIndex;             // Chỉ mục màu hệ thống - có 16 màu : 0 là nền, 9-15 là các chỉ mục màu sáng hơn màu nền
    13.     short   Index;                  // Chỉ mục
    14. } CELL;
    15. typedef struct
    16. {
    17.     short   Style;                  // Kiểu ép từ CELL qua chỉ có 2 giá trị : TC_LARGE, TC_FREE
    18.     short   PrevIndex;              // Chỉ mục nốt trước
    19. } TEMP;
    20. const   short   g_AttriIndex[] =    // Định nghĩa cho 7 chỉ mục kết hợp màu console
    21. {
    22.     FOREGROUND_RED | FOREGROUND_INTENSITY,
    23.     FOREGROUND_GREEN | FOREGROUND_INTENSITY,
    24.     FOREGROUND_BLUE | FOREGROUND_INTENSITY,
    25.     FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
    26.     FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
    27.     FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
    28.     FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
    29. };
    30.  
    31. // Cố định kích thước Console
    32. void ResizeConsole()
    33. {
    34.     HWND    hwnd = GetConsoleWindow();
    35.     RECT    r;
    36.     GetWindowRect(hwnd, &r);
    37.     MoveWindow(hwnd, r.left, r.top, 520, 460, TRUE);
    38.     long dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
    39.     dwStyle ^= WS_MAXIMIZEBOX;          // Làm mờ nút maximize
    40.     dwStyle ^= WS_THICKFRAME;           // Tạo border không thể kéo
    41.     SetWindowLongPtr(hwnd, GWL_STYLE, dwStyle);
    42. }
    43. // Đưa con nháy Caret tới vị trí giữa của 1 ô
    44. void GotoCell(short index)
    45. {
    46.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { 7 + index % 9 * 4, 5 + index / 9 * 2 });
    47. }
    48. // Ẩn hoặc hiện con nháy Caret
    49. void ShowConsoleCursor(bool show)
    50. {
    51.     HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    52.     CONSOLE_CURSOR_INFO     cci;
    53.     GetConsoleCursorInfo(console, &cci);
    54.     cci.bVisible = show;
    55.     SetConsoleCursorInfo(console, &cci);
    56. }
    57. // Chờ nhận 1 phím
    58. short GetKeyDown()
    59. {
    60.     short       key = 0;
    61.     while (!(key == VK_SPACE || key == VK_ESCAPE || key == VK_RETURN
    62.         || key == VK_LEFT || key == VK_UP || key == VK_RIGHT || key == VK_DOWN))
    63.     {
    64.         if (GetAsyncKeyState(VK_RETURN))    key = VK_RETURN;
    65.         if (GetAsyncKeyState(VK_SPACE))     key = VK_SPACE;
    66.         if (GetAsyncKeyState(VK_ESCAPE))    key = VK_ESCAPE;
    67.         if (GetAsyncKeyState(VK_LEFT))      key = VK_LEFT;
    68.         if (GetAsyncKeyState(VK_UP))        key = VK_UP;
    69.         if (GetAsyncKeyState(VK_RIGHT))     key = VK_RIGHT;
    70.         if (GetAsyncKeyState(VK_DOWN))      key = VK_DOWN;
    71.     }
    72.     return key;
    73. }
    74. // Vẽ tất cả các đối tượng cố định
    75. void DrawBoard()
    76. {
    77.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    78.     SetConsoleTextAttribute(console, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    79.     SetConsoleCursorPosition(console, { 28, 1 });
    80.     cout << "LINES98";
    81.     SetConsoleTextAttribute(console, 8);
    82.     SetConsoleCursorPosition(console, { 5, 2 });
    83.     cout << "==================================================";
    84.     for (short i = 4; i < 21; i += 2)
    85.     {
    86.         SetConsoleCursorPosition(console, { 5, i });
    87.         cout << "+---+---+---+---+---+---+---+---+---+";
    88.         SetConsoleCursorPosition(console, { 5, i + 1 });
    89.         cout << "|   |   |   |   |   |   |   |   |   |";
    90.     }
    91.     SetConsoleCursorPosition(console, { 5, 22 });
    92.     cout << "+---+---+---+---+---+---+---+---+---+";
    93.     SetConsoleCursorPosition(console, { 46, 7 });   cout << "<Left>";
    94.     SetConsoleCursorPosition(console, { 46, 9 });   cout << "<Up>";
    95.     SetConsoleCursorPosition(console, { 46, 11 });  cout << "<Right>";
    96.     SetConsoleCursorPosition(console, { 46, 13 });  cout << "<Down>";
    97.     SetConsoleCursorPosition(console, { 46, 15 });  cout << "<Spacebar>";
    98.     SetConsoleCursorPosition(console, { 46, 17 });  cout << "<Enter>";
    99.     SetConsoleCursorPosition(console, { 46, 19 });  cout << "<Esc>";
    100. }
    101. // Vẽ các viên bi chờ ở bên ngoài khung chơi
    102. void DrawFactory(short factory[3])
    103. {
    104.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    105.     for (short i = 0; i < 3; i++)
    106.     {
    107.         SetConsoleCursorPosition(console, { 46 + i * 4, 5 });
    108.         SetConsoleTextAttribute(console, factory[i]);
    109.         cout << 'O';
    110.     }
    111. }
    112. // Vẽ điểm số cộng dồn từ đầu khi chơi
    113. void DrawMark(short mark)
    114. {
    115.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    116.     SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    117.     SetConsoleCursorPosition(console, { 45, 21 });
    118.     cout << " Mark " << mark;
    119. }
    120. // Vẽ các ký hiệu đại diện cho ô : bi lớn, bi nhỏ, dấu chấm...
    121. void DrawCell(HANDLE console, CELL cell)
    122. {
    123.     short   x = 7 + cell.Index % 9 * 4;
    124.     short   y = 5 + cell.Index / 9 * 2;
    125.     SetConsoleCursorPosition(console, { x, y });
    126.     SetConsoleTextAttribute(console, cell.ColorIndex);
    127.     switch (cell.Style)
    128.     {
    129.     case TC_SELECTED:   cout << 'S'; break;     // Bi đang được chọn
    130.     case TC_LARGE:      cout << 'o'; break;     // Bi lớn
    131.     case TC_SMALL:      cout << '+'; break;     // Bi nhỏ đang chờ chuyển sang bi lớn
    132.     case TC_ROAD:       cout << '.'; break;     // Ký hiệu đánh dấu đường đi
    133.     case TC_FREE:       cout << ' '; break;     // Ô trống
    134.     }
    135.     SetConsoleCursorPosition(console, { x, y });
    136. }
    137. // Vẽ 1 ô
    138. void DrawCell(CELL cell)
    139. {
    140.     DrawCell(GetStdHandle(STD_OUTPUT_HANDLE), cell);
    141. }
    142. // Vẽ tất cả các ô
    143. void DrawCells(CELL cell[81])
    144. {
    145.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    146.     for (short i = 0; i < 81; i++)
    147.         DrawCell(console, cell[i]);
    148. }
    149. // Cho nhấp nháy tập hợp ô ăn được
    150. void DrawBonusCell(CELL cell[81], vector<short> & bonus)
    151. {
    152.     short   colorindex = cell[bonus[0]].ColorIndex;
    153.     short   count = (short)bonus.size();
    154.     for (short times = 0; times < 3; times++)
    155.     {
    156.         for (short i = 0; i < count; i++)       // Vẽ
    157.         {
    158.             cell[bonus[i]].Style = TC_LARGE;
    159.             cell[bonus[i]].ColorIndex = colorindex;
    160.             DrawCell(cell[bonus[i]]);
    161.         }
    162.         Sleep(200);
    163.         for (short i = 0; i < count; i++)       // Xóa
    164.         {
    165.             cell[bonus[i]].Style = TC_FREE;
    166.             cell[bonus[i]].ColorIndex = 0;
    167.             DrawCell(cell[bonus[i]]);
    168.         }
    169.         Sleep(200);
    170.     }
    171. }
    172. // Khởi tạo ngẫu nhiên cho tất cả ô
    173. void InitCells(CELL cell[81])
    174. {
    175.     for (short i = 0; i < 81; i++)              // Tất cả là ô trống
    176.     {
    177.         cell[i].Style = TC_FREE;
    178.         cell[i].ColorIndex = 0;
    179.         cell[i].Index = i;
    180.     }
    181.     for (short i = 0; i < 6; i++)               // Khởi tạo 3 bi lớn và nhỏ đầu tiên trên Board
    182.     {
    183.         short   index;
    184.         do
    185.         {
    186.             index = rand() % 81;
    187.         } while (cell[index].Style != TC_FREE);
    188.         cell[index].Style = (i < 3) ? TC_LARGE : TC_SMALL;
    189.         cell[index].ColorIndex = g_AttriIndex[rand() % 7];
    190.         cell[index].Index = index;
    191.     }
    192. }
    193. // Trả về số đếm của một kiểu ô nào đó cùng các phần tử chứa trong Vector
    194. short EnumStyleCell(CELL cell[81], short style, vector<short> & result)
    195. {
    196.     short count = 0;
    197.     result.resize(0);
    198.     for (short i = 0; i < 81; i++)
    199.         if (cell[i].Style == style)
    200.         {
    201.             result.push_back(i);
    202.             count++;
    203.         }
    204.     return count;
    205. }
    206. // Thuật toán chính : Vết dầu loang
    207. void LoopRoad(TEMP temp[81], vector<short> & prev, short end, stack<short> & road)
    208. {
    209.     vector<short>   next;                                   // Vector sẽ chứa các chỉ mục cho lần duyệt kế tiếp
    210.     for (short i = (short)prev.size() - 1; i >= 0; i--)     // Duyệt các chỉ mục được cho từ lần duyệt trước
    211.     {
    212.         short   preIndex;
    213.         short   index = prev[i];
    214.         short   row = index / 9;
    215.         short   col = index % 9;
    216.         if (index == end)                                   // Gặp đích - đẩy đường đi vào ngăn xếp
    217.         {
    218.             road.push(index);
    219.             while (temp[index].PrevIndex > -1)
    220.             {
    221.                 index = temp[index].PrevIndex;              // Lấy chỉ mục ô trước đó
    222.                 road.push(index);                           // Đẩy vào ngăn xếp
    223.             }
    224.             return;
    225.         }
    226.         preIndex = row * 9 + col - 1;                       // Xét ô bên trái
    227.         if (col > 0 && temp[preIndex].Style == TC_FREE)
    228.         {
    229.             temp[preIndex].Style = TC_ROAD;                 // Đánh dấu ô này là đường đi
    230.             temp[preIndex].PrevIndex = index;               // Thiết lập chỉ mục cha
    231.             next.push_back(preIndex);                       // Nối thêm vào mảng duyệt lần sau
    232.         }
    233.         preIndex = (row - 1) * 9 + col;                     // Xét ô phía trên
    234.         if (row > 0 && temp[preIndex].Style == TC_FREE)
    235.         {
    236.             temp[preIndex].Style = TC_ROAD;
    237.             temp[preIndex].PrevIndex = index;
    238.             next.push_back(preIndex);
    239.         }
    240.         preIndex = row * 9 + col + 1;                       // Xét ô bên phải
    241.         if (col < 8 && temp[preIndex].Style == TC_FREE)
    242.         {
    243.             temp[preIndex].Style = TC_ROAD;
    244.             temp[preIndex].PrevIndex = index;
    245.             next.push_back(preIndex);
    246.         }
    247.         preIndex = (row + 1) * 9 + col;                     // Xét ô phía dưới
    248.         if (row < 8 && temp[preIndex].Style == TC_FREE)
    249.         {
    250.             temp[preIndex].Style = TC_ROAD;
    251.             temp[preIndex].PrevIndex = index;
    252.             next.push_back(preIndex);
    253.         }
    254.     }
    255.     if (!next.empty())                                      // Nếu có một tập hợp ô mới cần xét...
    256.         LoopRoad(temp, next, end, road);                    // ... thì cho đệ quy tiếp tục
    257. }
    258. // Đường đi được trả về trong roadcell nếu có
    259. short FindRoad(CELL cell[81], short start, short end, vector<CELL> & roadcell)
    260. {
    261.     TEMP        temp[81];
    262.     for (short i = 0; i < 81; i++)              // Sao chép sang mảng tạm chỉ 2 giá trị : TC_LARGE, TC_FREE
    263.     {
    264.         if (cell[i].Style == TC_SELECTED || cell[i].Style == TC_LARGE)
    265.             temp[i].Style = TC_LARGE;
    266.         else
    267.             temp[i].Style = TC_FREE;
    268.         temp[i].PrevIndex = -1;
    269.     }
    270.     vector<short>   prev(1, start);
    271.     stack<short>    road;
    272.     LoopRoad(temp, prev, end, road);
    273.     short   count = (short)road.size();
    274.     roadcell.resize(count);                     // Khởi tạo vector lưu đường đi
    275.     for (short i = 0; i < count; i++)           // Đường đi được lưu trong roadcell
    276.     {
    277.         short   top = road.top();
    278.         roadcell[i].Index = top;                // ghi vào
    279.         roadcell[i].Style = cell[top].Style;
    280.         roadcell[i].ColorIndex = cell[top].ColorIndex;
    281.         road.pop();                             // Xóa trên stack cũ
    282.     }
    283.     return count;
    284. }
    285. // Vẽ đường đi
    286. void DrawRoad(CELL cell[81], vector<CELL> & roadcell)
    287. {
    288.     if (!roadcell.empty())
    289.     {
    290.         short   colorindex = cell[roadcell[0].Index].ColorIndex;
    291.         HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    292.         for (short i = (short)roadcell.size() - 1; i >= 0; i--)
    293.         {
    294.             cell[roadcell[i].Index].Style = TC_ROAD;
    295.             cell[roadcell[i].Index].ColorIndex = colorindex;
    296.             DrawCell(console, cell[roadcell[i].Index]);
    297.         }
    298.     }
    299. }
    300. // Cho viên bi đi từng bước
    301. void StepRoad(CELL cell[81], vector<CELL> & roadcell)
    302. {
    303.     short   colorindex = cell[roadcell[0].Index].ColorIndex;
    304.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    305.     short   count = (short)roadcell.size();
    306.     for (short i = 0; i < count - 1; i++)
    307.     {
    308.         // Bước tới
    309.         cell[roadcell[i + 1].Index].Style = TC_LARGE;
    310.         cell[roadcell[i + 1].Index].ColorIndex = colorindex;
    311.         DrawCell(console, cell[roadcell[i + 1].Index]);
    312.         // Xóa trước đó về ô trống hoặc bi nhỏ
    313.         if (roadcell[i].Style == TC_SMALL)
    314.         {
    315.             cell[roadcell[i].Index].Style = TC_SMALL;
    316.             cell[roadcell[i].Index].ColorIndex = roadcell[i].ColorIndex;
    317.         }
    318.         else
    319.         {
    320.             cell[roadcell[i].Index].Style = TC_FREE;
    321.             cell[roadcell[i].Index].ColorIndex = 0;
    322.         }
    323.         DrawCell(console, cell[roadcell[i].Index]);
    324.         Sleep(100);     // Tạo hiệu ứng chuyển động
    325.     }
    326. }
    327. // Từ 1 viên bi, tìm theo các hướng để nhận tập hợp thưởng vào nơi lưu bonus
    328. short BonusFromCell(CELL cell[81], short node, vector<short> & bonus)
    329. {
    330.     short   r, c, count;
    331.     short   colorindex = cell[node].ColorIndex;
    332.     // ngang
    333.     count = 1;
    334.     bonus.resize(1, node);
    335.     r = node / 9; c = node % 9;
    336.     while (--c >= 0 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // left
    337.     {
    338.         bonus.push_back(r * 9 + c); count++;
    339.     }
    340.     r = node / 9; c = node % 9;
    341.     while (++c <= 8 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // right
    342.     {
    343.         bonus.push_back(r * 9 + c); count++;
    344.     }
    345.     if (count >= 5)
    346.         return count;
    347.     // dọc
    348.     count = 1;
    349.     bonus.resize(1, node);
    350.     r = node / 9; c = node % 9;
    351.     while (--r >= 0 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // up
    352.     {
    353.         bonus.push_back(r * 9 + c); count++;
    354.     }
    355.     r = node / 9; c = node % 9;
    356.     while (++r <= 8 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // down
    357.     {
    358.         bonus.push_back(r * 9 + c); count++;
    359.     }
    360.     if (count >= 5)
    361.         return count;
    362.     // chéo thuận
    363.     count = 1;
    364.     bonus.resize(1, node);
    365.     r = node / 9; c = node % 9;
    366.     while (--r >= 0 && --c >= 0 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // tây bắc
    367.     {
    368.         bonus.push_back(r * 9 + c); count++;
    369.     }
    370.     r = node / 9; c = node % 9;
    371.     while (++r <= 8 && ++c <= 8 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // đông nam
    372.     {
    373.         bonus.push_back(r * 9 + c); count++;
    374.     }
    375.     if (count >= 5)
    376.         return count;
    377.     // chéo nghịch
    378.     count = 1;
    379.     bonus.resize(1, node);
    380.     r = node / 9; c = node % 9;
    381.     while (--r >= 0 && ++c <= 8 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // đông bắc
    382.     {
    383.         bonus.push_back(r * 9 + c); count++;
    384.     }
    385.     r = node / 9; c = node % 9;
    386.     while (++r <= 8 && --c >= 0 && cell[r * 9 + c].Style == TC_LARGE && cell[r * 9 + c].ColorIndex == colorindex)   // tây nam
    387.     {
    388.         bonus.push_back(r * 9 + c); count++;
    389.     }
    390.     if (count >= 5)
    391.         return count;
    392.     return 0;
    393. }
    394. // Tìm bonus từ nhiều viên bi ban đầu
    395. short BonusFromCells(CELL cell[81], vector<short> nodes, vector<short> & bonus)
    396. {
    397.     bonus.resize(0);
    398.     for (short i = (short)nodes.size() - 1; i >= 0; i--)
    399.     {
    400.         vector<short>   single(0);      // Tìm cho từng viên bi riêng lẻ
    401.         if (BonusFromCell(cell, nodes[i], single))
    402.         {
    403.             for (short j = (short)single.size() - 1; j >= 0; j--)
    404.                 bonus.push_back(single[j]);
    405.         }
    406.     }
    407.     return (short)bonus.size();
    408. }
    409. // Xuất thông báo số bi ăn được
    410. void MessageAddMark(short number)
    411. {
    412.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    413.     for (short i = 0; i < 4; i++)
    414.     {
    415.         SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    416.         SetConsoleCursorPosition(console, { 15, 24 });
    417.         cout << "Oh, + " << number << " marks !!!";
    418.         Sleep(400);         // Tạo hiệu ứng gây chú ý
    419.         SetConsoleTextAttribute(console, 0);
    420.         SetConsoleCursorPosition(console, { 15, 24 });
    421.         cout << "                                ";
    422.         Sleep(100);
    423.     }
    424. }
    425. // Các thông báo khác
    426. void MessageString(char string[])
    427. {
    428.     HANDLE  console = GetStdHandle(STD_OUTPUT_HANDLE);
    429.     for (short i = 0; i < 4; i++)
    430.     {
    431.         SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    432.         SetConsoleCursorPosition(console, { 15, 24 });
    433.         cout << string;
    434.         Sleep(400);     // Tạo hiệu ứng gây chú ý
    435.         SetConsoleTextAttribute(console, 0);
    436.         SetConsoleCursorPosition(console, { 15, 24 });
    437.         cout << "                      ";
    438.         Sleep(100);
    439.     }
    440. }
    441. // Xử lý khi nhấn các phím mũi tên
    442. void HandleArrowPress(short key, short & current)
    443. {
    444.     short   row = current / 9;
    445.     short   col = current % 9;
    446.     switch (key)
    447.     {
    448.     case VK_LEFT:   if (col > 0) col--; break;      // Left arrow
    449.     case VK_UP:     if (row > 0) row--; break;      // Up arrow
    450.     case VK_RIGHT:  if (col < 8) col++; break;      // Rifgr arrow
    451.     case VK_DOWN:   if (row < 8) row++; break;      // Down arrow
    452.     }
    453.     current = row * 9 + col;
    454.     GotoCell(current);                              // Đưa con nháy tới vị trí mới
    455. }
    456. // Xử lý khi nhấn Enter hoặc Spacebar
    457. void HandleEnterPress(CELL cell[81], short created[3], short & current, short & selected, short & mark)
    458. {
    459.     // 1: Enter một ô đã chọn trước đó - bỏ chọn
    460.     if (selected == current)
    461.     {
    462.         cell[current].Style = TC_LARGE;
    463.         DrawCell(cell[current]);
    464.         GotoCell(current);
    465.         selected = -1;
    466.     }
    467.     // 2: Enter một ô lớn khi chưa có chọn trước đó - chọn ô
    468.     else if (cell[current].Style == TC_LARGE && selected == -1)
    469.     {
    470.         cell[current].Style = TC_SELECTED;
    471.         DrawCell(cell[current]);
    472.         GotoCell(current);
    473.         selected = current;
    474.     }
    475.     // 3: Enter một ô lớn khi đã chọn một ô khác trước đó - bỏ chọn ô cũ chọn ô mới
    476.     else if (cell[current].Style == TC_LARGE && selected != -1)
    477.     {
    478.         cell[selected].Style = TC_LARGE;        // Bỏ chọn ô chọn trước đó
    479.         DrawCell(cell[selected]);
    480.         cell[current].Style = TC_SELECTED;      // Chọn ô mới
    481.         DrawCell(cell[current]);
    482.         GotoCell(current);
    483.         selected = current;
    484.     }
    485.     // 4: Enter lên ô trống hoặc ô chứa bi nhỏ khi đã chọn trước
    486.     else if (selected != -1)
    487.     {
    488.         vector<CELL>    roadcell;
    489.         if (FindRoad(cell, selected, current, roadcell))
    490.         {
    491.             ShowConsoleCursor(false);
    492.             DrawRoad(cell, roadcell);           // Vẽ đường đi bằng các dấu chấm cùng màu với màu bi
    493.             GotoCell(selected);
    494.             StepRoad(cell, roadcell);           // Cho bi chính đi dần qua từng vị trí
    495.             Sleep(200);
    496.             if (roadcell[roadcell.size() - 1].Style == TC_SMALL)    // Bi cuối đường là bi nhỏ bị đè
    497.             {
    498.                 vector<short>   freecell;
    499.                 short   count = EnumStyleCell(cell, TC_FREE, freecell);
    500.                 short   index = rand() % count;                     // Tìm 1 ô trống ngẫu nhiên
    501.                 cell[freecell[index]].Style = TC_SMALL;             // để chuyển ô bị đè tới đó
    502.                 cell[freecell[index]].ColorIndex = roadcell[roadcell.size() - 1].ColorIndex;
    503.                 DrawCell(cell[freecell[index]]);
    504.             }
    505.             vector<short>       bonus(0);
    506.             if (BonusFromCell(cell, current, bonus))            // Nếu có nhận những ô sẽ ăn
    507.             {
    508.                 DrawBonusCell(cell, bonus);                     // Vẽ nó ra
    509.                 short count = (short)bonus.size();
    510.                 mark += count;                                  // Cộng dồn điểm thưởng
    511.                 DrawMark(mark);                                 // Vẽ nó ra
    512.                 MessageAddMark(count);                          // Thông báo cho người chơi
    513.             }
    514.             vector<short>       smallcell;
    515.             if (EnumStyleCell(cell, TC_SMALL, smallcell))       // Từ nhỏ -> lớn
    516.             {
    517.                 short   count = (short)smallcell.size();
    518.                 for (short i = 0; i < count; i++)
    519.                 {
    520.                     cell[smallcell[i]].Style = TC_LARGE;        // Chuyển sang lớn
    521.                     DrawCell(cell[smallcell[i]]);               // Vẽ nó
    522.                 }
    523.                 Sleep(200);
    524.                 for (short i = 0; i < count; i++)               // Ăn bi thụ động
    525.                 {
    526.                     vector<short>       bonus(0);
    527.                     if (BonusFromCell(cell, smallcell[i], bonus))
    528.                     {
    529.                         DrawBonusCell(cell, bonus);
    530.                         MessageAddMark(count);
    531.                     }
    532.                 }
    533.             }
    534.             vector<short>       freecell;
    535.             if (EnumStyleCell(cell, TC_FREE, freecell))         // Chuẩn bị chuyển các ô bên ngoài vào board chính
    536.             {
    537.                 short   count = (short)freecell.size();
    538.                 for (short i = 0; i < min(count, 3); i++)       // Chuyển vào Board dưới dạng ô nhỏ
    539.                 {
    540.                     short   index;
    541.                     do
    542.                     {
    543.                         index = rand() % count;
    544.                     } while (cell[freecell[index]].Style != TC_FREE);
    545.                     cell[freecell[index]].Style = TC_SMALL;
    546.                     cell[freecell[index]].ColorIndex = created[i];
    547.                     DrawCell(cell[freecell[index]]);
    548.                 }
    549.                 for (short i = 0; i < 3; i++)                   // Phát sinh 3 bi mới
    550.                     created[i] = g_AttriIndex[rand() % 7];
    551.                 DrawFactory(created);                           // Vẽ nó
    552.             }
    553.             else
    554.                 MessageString("Game over !!!");
    555.             GotoCell(current);
    556.             ShowConsoleCursor(true);
    557.             selected = -1;
    558.         }
    559.         else
    560.         {
    561.             MessageString("Oh, no, no step !!!");
    562.             GotoCell(current);
    563.         }
    564.     }
    565. }
    566.  
    567. int main()
    568. {
    569.     ResizeConsole();
    570.     srand((unsigned int)time(0));
    571.     short   created[3] = { g_AttriIndex[rand() % 7], g_AttriIndex[rand() % 7], g_AttriIndex[rand() % 7] };
    572.     short   mark = 0;           // Số điểm
    573.     short   current = 40;       // Chỉ mục ô hiện hành
    574.     short   selected = -1;      // Chỉ mục ô được chọn
    575.     CELL    cell[81];           // Mảng ô
    576.     InitCells(cell);
    577.     DrawBoard();
    578.     DrawFactory(created);
    579.     DrawMark(mark);
    580.     DrawCells(cell);
    581.     GotoCell(current);
    582.  
    583.     // Bắt đầu cho người chơi chọn và đi bi
    584.     while (true)
    585.     {
    586.         short   key = GetKeyDown();
    587.         if (key == VK_ESCAPE)
    588.             return 0;
    589.         if (key == VK_RETURN || key == VK_SPACE)
    590.             HandleEnterPress(cell, created, current, selected, mark);
    591.         else if (key == VK_LEFT || key == VK_UP || key == VK_RIGHT || key == VK_DOWN)
    592.             HandleArrowPress(key, current);
    593.         Sleep(100);
    594.     }
    595.     return 0;
    596. }
    Attached Thumbnails Attached Thumbnails Lines98.jpg  
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.

  2. #2
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    930

    Nếu muốn thực hiện trên Windows thì như sau ( trên VS2015) nhé :
    Visual C++ Code:
    1. #include <windows.h>
    2. #include <time.h>
    3. #include <vector>
    4. using namespace std;
    5.  
    6. #define     STATIC_OUTSIDE      0       // 0 - 2
    7. #define     STATIC_MESSAGE      3       // Định danh cửa sổ thông báo điểm
    8.  
    9. enum { TC_FREE = 0, TC_LARGE, TC_SMALL, TC_ROAD };
    10. typedef struct
    11. {
    12.     short   Style;          // Kiểu ép từ CCell qua chỉ có 2 giá trị : TC_LARGE, TC_FREE
    13.     short   PrevIndex;      // Chỉ mục nốt trước
    14. } TEMP;
    15. class CWindow;
    16.  
    17. class CMess
    18. {
    19. private:
    20.     HWND        m_hWnd;                         // Thẻ cửa sổ Cell
    21.     int         m_nMark = 0;                    // Điểm số cộng dồn
    22.     COLORREF    m_crFore = RGB(255, 255, 0);    // Màu chữ
    23.     COLORREF    m_crBack = RGB(0, 0, 255);      // Màu nền
    24. public:
    25.     // Các thuộc tính
    26.     __declspec(property(get = getHwnd)) HWND Hwnd;
    27.     __declspec(property(get = getForeColor, put = setForeColor)) COLORREF ForeColor;
    28.     __declspec(property(get = getBackColor, put = setBackColor)) COLORREF BackColor;
    29.     __declspec(property(get = getMark, put = setMark)) int Mark;
    30.     __declspec(property(get = getParent, put = setParent)) CWindow * Parent;
    31.     // Các cài đặt thuộc tính
    32.     HWND getHwnd() { return m_hWnd; }
    33.     COLORREF getForeColor() { return m_crFore; }
    34.     void setForeColor(COLORREF crFore) { m_crFore = crFore; }
    35.     COLORREF getBackColor() { return m_crBack; }
    36.     void setBackColor(COLORREF crBack) { m_crBack = crBack; }
    37.     int getMark() { return m_nMark; }
    38.     void setMark(int nMark) { m_nMark = nMark; }
    39.     // Các hàm công cộng
    40.     HWND Create(HINSTANCE hInst, HWND hParent, UINT id);
    41.     void Move();
    42.     void Draw();
    43. };
    44. class CDrop
    45. {
    46. private:
    47.     HWND        m_hWnd;         // Thẻ cửa sổ Cell
    48.     UINT        m_uIndex;       // Chỉ mục Cell này
    49.     COLORREF    m_crFore;       // Màu bi
    50.     COLORREF    m_crBack;       // Màu nền
    51.     CWindow *   m_pWindow;      // Cửa sổ cha
    52. public:
    53.     // Các thuộc tính
    54.     __declspec(property(get = getHwnd)) HWND Hwnd;
    55.     __declspec(property(get = getIndex, put = setIndex)) UINT Index;
    56.     __declspec(property(get = getForeColor, put = setForeColor)) COLORREF ForeColor;
    57.     __declspec(property(get = getBackColor, put = setBackColor)) COLORREF BackColor;
    58.     __declspec(property(get = getParent, put = setParent)) CWindow * Parent;
    59.     // Các cài đặt thuộc tính
    60.     HWND getHwnd() { return m_hWnd; }
    61.     UINT getIndex() { return m_uIndex; }
    62.     void setIndex(UINT uIndex) { m_uIndex = uIndex; }
    63.     COLORREF getForeColor() { return m_crFore; }
    64.     void setForeColor(COLORREF crFore) { m_crFore = crFore; }
    65.     COLORREF getBackColor() { return m_crBack; }
    66.     void setBackColor(COLORREF crBack) { m_crBack = crBack; }
    67.     CWindow * getParent() { return m_pWindow; }
    68.     void setParent(CWindow * pWindow) { m_pWindow = pWindow; }
    69.     // Các hàm công cộng
    70.     HWND Create(HINSTANCE hInst, HWND hParent, UINT id);
    71.     void Move();
    72.     void Draw();
    73. };
    74. class CCell
    75. {
    76. private:
    77.     HWND        m_hWnd;         // Thẻ cửa sổ Cell
    78.     UINT        m_uIndex;       // Chỉ mục Cell này
    79.     UINT        m_uStyle;       // Kiểu Cell
    80.     BOOL        m_bSelected;    // Cell này đang chọn ?
    81.     COLORREF    m_crBack;       // Màu nền
    82.     COLORREF    m_crFore;       // Màu bi
    83.     CWindow *   m_pWindow;      // Cửa sổ cha
    84.    
    85.     // Thủ tục window
    86.     static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam);
    87.     // Các bộ xử lý thông điệp
    88.     LRESULT OnCreate(HINSTANCE hInst, HWND hWnd);
    89.     LRESULT OnPaint();
    90.     LRESULT OnLButtonDown(LPARAM lparam);
    91.  
    92. public:
    93.     // Các thuộc tính
    94.     __declspec(property(get = getHwnd)) HWND Hwnd;
    95.     __declspec(property(get = getIndex, put = setIndex)) UINT Index;
    96.     __declspec(property(get = getStyle, put = setStyle)) UINT Style;
    97.     __declspec(property(get = getSelected, put = setSelected)) BOOL Selected;
    98.     __declspec(property(get = getBackColor, put = setBackColor)) COLORREF BackColor;
    99.     __declspec(property(get = getForeColor, put = setForeColor)) COLORREF ForeColor;
    100.     __declspec(property(get = getParent, put = setParent)) CWindow * Parent;
    101.     // Các cài đặt thuộc tính
    102.     HWND getHwnd() { return m_hWnd; }
    103.     UINT getIndex() { return m_uIndex; }
    104.     void setIndex(UINT uIndex) { m_uIndex = uIndex; }
    105.     UINT getStyle() { return m_uStyle; }
    106.     void setStyle(UINT uStyle) { m_uStyle = uStyle; }
    107.     BOOL getSelected() { return m_bSelected; }
    108.     void setSelected(BOOL bSelected) { m_bSelected = bSelected; }
    109.     COLORREF getBackColor() { return m_crBack; }
    110.     void setBackColor(COLORREF crBack) { m_crBack = crBack; }
    111.     COLORREF getForeColor() { return m_crFore; }
    112.     void setForeColor(COLORREF crFore) { m_crFore = crFore; }
    113.     CWindow * getParent() { return m_pWindow; }
    114.     void setParent(CWindow * pWindow) { m_pWindow = pWindow; }
    115.     // Các hàm công cộng
    116.     HWND Create(HINSTANCE hInst, HWND hParent);
    117.     void Move();
    118.     void Draw();
    119. };
    120. class CWindow
    121. {
    122. private:
    123.     HINSTANCE   m_hInst;        // Thể hiện chương trình
    124.     HWND        m_hWnd;         // Thẻ cửa sổ chính
    125.     CCell       m_Cell[81];     // Các đối tượng Cell
    126.     CDrop       m_Drop[3];
    127.     CMess       m_Mess;
    128.     COLORREF    m_crTable[7] =
    129.     { RGB(255,255,0), RGB(255,0,255), RGB(0,255,255), RGB(255,0,0), RGB(0,255,0), RGB(0,0,255), RGB(128,128,128) };
    130.  
    131.     // Thủ tục window
    132.     static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam);
    133.     // Các bộ xử lý thông điệp
    134.     LRESULT OnCreate(HINSTANCE hInst, HWND hWnd);
    135.     LRESULT OnSize(LPARAM lparam);
    136.     LRESULT OnDrawItem(LPDRAWITEMSTRUCT pd);
    137.     LRESULT OnClose();
    138.     LRESULT OnDestroy();
    139.  
    140.     void LoopRoad(TEMP temp[81], vector<short> & prev, short end, vector<short> & road);
    141.     void DrawRoad(vector<short> & road);
    142.     void StepRoad(vector<short> & road);
    143.     short EnumStyleCell(short style, vector<short> & result);
    144.     short BonusFromCell(short node, vector<short> & bonus);
    145.    
    146. public:
    147.     // Các thuộc tính
    148.     __declspec(property(get = getSelectedCell)) CCell * SelectedCell;
    149.     __declspec(property(get = getCell)) CCell * Cell[];
    150.     // Các cài đặt thuộc tính
    151.     CCell * getSelectedCell();
    152.     CCell * getCell(int index) { return &m_Cell[index]; }
    153.     // Các phương thức
    154.     BOOL Create(HINSTANCE hInst);
    155.     int LoopMessage();
    156.     void HandleAll(short start, short end);
    157. };
    158.  
    159. HWND CMess::Create(HINSTANCE hInst, HWND hParent, UINT id)
    160. {
    161.     m_hWnd = CreateWindowEx(WS_EX_DLGMODALFRAME, TEXT("static"), NULL, WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 0, 0, 0, 0, hParent, (HMENU)id, hInst, NULL);
    162.     return m_hWnd;
    163. }
    164. void CMess::Move()
    165. {
    166.     MoveWindow(m_hWnd, 130, 545, 395, 30, TRUE);
    167. }
    168. void CMess::Draw()
    169. {
    170.     RECT    r;
    171.     HDC     hdc = GetDC(m_hWnd);
    172.     HBRUSH  hbrBack = CreateSolidBrush(m_crBack);
    173.     GetClientRect(m_hWnd, &r);
    174.     FillRect(hdc, &r, hbrBack);
    175.     DeleteObject(hbrBack);
    176.  
    177.     SetTextColor(hdc, m_crFore);
    178.     SetBkMode(hdc, TRANSPARENT);
    179.     TCHAR   szText[MAX_PATH];
    180.     wsprintf(szText, TEXT("Marks : %u"), m_nMark);
    181.     DrawText(hdc, szText, -1, &r, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    182.     ReleaseDC(m_hWnd, hdc);
    183. }
    184.  
    185. HWND CDrop::Create(HINSTANCE hInst, HWND hParent, UINT id)
    186. {
    187.     m_uIndex = id;
    188.     m_hWnd = CreateWindowEx(WS_EX_DLGMODALFRAME, TEXT("static"), NULL, WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 0, 0, 0, 0, hParent, (HMENU)id, hInst, NULL);
    189.     return m_hWnd;
    190. }
    191. void CDrop::Move()
    192. {
    193.     MoveWindow(m_hWnd, m_uIndex * 30 + 30, 545, 30, 30, TRUE);
    194. }
    195. void CDrop::Draw()
    196. {
    197.     RECT    r;
    198.     HDC     hdc = GetDC(m_hWnd);
    199.     HBRUSH  hbrBack = CreateSolidBrush(m_crBack);
    200.     GetClientRect(m_hWnd, &r);
    201.     FillRect(hdc, &r, hbrBack);
    202.     DeleteObject(hbrBack);
    203.     HBRUSH  hbrFore = CreateSolidBrush(m_crFore);
    204.     SelectObject(hdc, hbrFore);
    205.     Ellipse(hdc, 2, 2, r.right - 2, r.bottom - 2);
    206.     DeleteObject(hbrFore);
    207.     ReleaseDC(m_hWnd, hdc);
    208. }
    209.  
    210. LRESULT CCell::WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
    211. {
    212.     if (msg == WM_CREATE)
    213.     {
    214.         LPCREATESTRUCT  pcs = reinterpret_cast<LPCREATESTRUCT>(lparam);
    215.         CCell * pCell = reinterpret_cast<CCell*>(pcs->lpCreateParams);
    216.         SetWindowLongPtr(hWnd, GWLP_USERDATA, PtrToUlong(pCell));
    217.         return pCell->OnCreate(pcs->hInstance, hWnd);
    218.     }
    219.     CCell * pCell = reinterpret_cast<CCell*>(static_cast<LONG_PTR>(GetWindowLongPtr(hWnd, GWLP_USERDATA)));
    220.     switch (msg)
    221.     {
    222.     case WM_PAINT:          return pCell->OnPaint();
    223.     case WM_LBUTTONDOWN:    return pCell->OnLButtonDown(lparam);
    224.     }
    225.     return DefWindowProc(hWnd, msg, wparam, lparam);
    226. }
    227. LRESULT CCell::OnCreate(HINSTANCE hInst, HWND hWnd)
    228. {
    229.     m_hWnd = hWnd;
    230.     return 0;
    231. }
    232. LRESULT CCell::OnPaint()
    233. {
    234.     PAINTSTRUCT     ps;
    235.     BeginPaint(m_hWnd, &ps);
    236.     EndPaint(m_hWnd, &ps);
    237.     Draw();
    238.     return 0;
    239. }
    240. LRESULT CCell::OnLButtonDown(LPARAM lparam)
    241. {
    242.     if (m_uStyle == TC_LARGE)
    243.     {
    244.         if (this->Selected)                             // Click ngay cell đã chọn trước đó
    245.         {
    246.             this->Selected ^= 1;                        // Bỏ chọn
    247.             this->Draw();
    248.         }
    249.         else                                            // Cell này chưa được chọn
    250.         {
    251.             CCell * pCell = m_pWindow->SelectedCell;
    252.             if (pCell)                                  // Nếu có chọn trước một cell
    253.             {
    254.                 pCell->Selected ^= 1;                   // Bỏ chọn cell trước
    255.                 pCell->Draw();
    256.             }
    257.             this->Selected ^= 1;                        // Chọn cell này
    258.             this->Draw();
    259.         }
    260.     }
    261.     else
    262.     {
    263.         CCell * pCell;
    264.         if (pCell = m_pWindow->SelectedCell)
    265.             m_pWindow->HandleAll(pCell->Index, this->Index);
    266.     }
    267.     return 0;
    268. }
    269. HWND    CCell::Create(HINSTANCE hInst, HWND hParent)
    270. {
    271.     static  BOOL    bRegistered = 0;    // Sử dụng biến tĩnh để tránh đăng ký nhiều lần
    272.     WNDCLASS    w;
    273.     w.lpszClassName = TEXT("Cell");
    274.     if (!bRegistered)
    275.     {
    276.         w.cbClsExtra = 0;
    277.         w.cbWndExtra = 0;
    278.         w.hbrBackground = NULL;
    279.         w.hCursor = LoadCursor(NULL, IDC_ARROW);
    280.         w.hIcon = NULL;
    281.         w.hInstance = hInst;
    282.         w.lpfnWndProc = WndProc;
    283.         w.lpszMenuName = NULL;
    284.         w.style = CS_HREDRAW | CS_VREDRAW;
    285.         if (!RegisterClass(&w))
    286.             return FALSE;
    287.         bRegistered = true;
    288.     }
    289.     return CreateWindowEx(WS_EX_DLGMODALFRAME, w.lpszClassName, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hParent, NULL, hInst, this);
    290. }
    291. void    CCell::Move()
    292. {
    293.     UINT    row = m_uIndex / 9;
    294.     UINT    col = m_uIndex % 9;
    295.     MoveWindow(m_hWnd, 30 + col * 55, 30 + row * 55, 55, 55, TRUE);
    296. }
    297. void    CCell::Draw()
    298. {
    299.     RECT    r;
    300.     HDC     hdc = GetDC(m_hWnd);
    301.     HBRUSH  hbrBack = (m_bSelected) ? CreateSolidBrush(RGB(0, 128, 255)) : CreateSolidBrush(m_crBack);
    302.     GetClientRect(m_hWnd, &r);
    303.     FillRect(hdc, &r, hbrBack);
    304.     DeleteObject(hbrBack);
    305.     if (m_uStyle != TC_FREE)
    306.     {
    307.         HBRUSH  hbrFore = CreateSolidBrush(m_crFore);
    308.         SelectObject(hdc, hbrFore);
    309.         switch (m_uStyle)
    310.         {
    311.         case TC_LARGE:  Ellipse(hdc, 3, 3, r.right - 3, r.bottom - 3); break;
    312.         case TC_SMALL:  Ellipse(hdc, 13, 13, r.right - 13, r.bottom - 13); break;
    313.         }
    314.         DeleteObject(hbrFore);
    315.     }
    316.     ReleaseDC(m_hWnd, hdc);
    317. }
    318.  
    319. LRESULT CWindow::WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
    320. {
    321.     if (msg == WM_CREATE)
    322.     {
    323.         LPCREATESTRUCT  pcs = reinterpret_cast<LPCREATESTRUCT>(lparam);
    324.         CWindow * pWindow = reinterpret_cast<CWindow*>(pcs->lpCreateParams);
    325.         SetWindowLongPtr(hWnd, GWLP_USERDATA, PtrToUlong(pWindow));
    326.         return pWindow->OnCreate(pcs->hInstance, hWnd);
    327.     }
    328.     CWindow * pWindow = reinterpret_cast<CWindow*>(static_cast<LONG_PTR>(GetWindowLongPtr(hWnd, GWLP_USERDATA)));
    329.     switch (msg)
    330.     {
    331.     case WM_SIZE:           return pWindow->OnSize(lparam);
    332.     case WM_DRAWITEM:       return pWindow->OnDrawItem((LPDRAWITEMSTRUCT)lparam);
    333.     case WM_CLOSE:          return pWindow->OnClose();
    334.     case WM_DESTROY:        return pWindow->OnDestroy();
    335.     }
    336.     return DefWindowProc(hWnd, msg, wparam, lparam);
    337. }
    338. LRESULT CWindow::OnCreate(HINSTANCE hInst, HWND hWnd)
    339. {
    340.     m_hInst = hInst;
    341.     m_hWnd = hWnd;
    342.     // Tính toán kích thước cho cửa sổ chính
    343.     RECT    r = { 0, 0, 555 , 595 };
    344.     AdjustWindowRect(&r, WS_CAPTION, FALSE);
    345.     int     cxWindow = r.right - r.left;
    346.     int     cyWindow = r.bottom - r.top;
    347.     GetWindowRect(hWnd, &r);
    348.     r.right = r.left + cxWindow;
    349.     r.bottom = r.top + cyWindow;
    350.     MoveWindow(hWnd, r.left, r.top, cxWindow, cyWindow, TRUE);
    351.     // Khởi tạo
    352.     srand((UINT)time(NULL));
    353.     for (int i = 0; i < 81; i++)
    354.     {
    355.         m_Cell[i].Index = i;
    356.         m_Cell[i].Style = TC_FREE;
    357.         m_Cell[i].Selected = FALSE;
    358.         m_Cell[i].BackColor = RGB(255, 128, 0);
    359.         m_Cell[i].ForeColor = 0;
    360.         m_Cell[i].Parent = this;
    361.         if (!m_Cell[i].Create(hInst, hWnd))
    362.             return -1;
    363.     }
    364.     for (int i = 0; i < 6; i++)             // Khởi tạo 3 bi lớn và nhỏ đầu tiên trên Board
    365.     {
    366.         int index;
    367.         do
    368.         {
    369.             index = rand() % 81;
    370.         } while (m_Cell[index].Style != TC_FREE);
    371.         m_Cell[index].Style = (i < 3) ? TC_LARGE : TC_SMALL;
    372.         m_Cell[index].ForeColor = m_crTable[rand() % 7];
    373.     }
    374.     for (int i = 0; i < 3; i++)
    375.     {
    376.         m_Drop[i].Create(hInst, hWnd, STATIC_OUTSIDE + i);
    377.         m_Drop[i].ForeColor = m_crTable[rand() % 7];
    378.         m_Drop[i].BackColor = RGB(255, 128, 0);
    379.         m_Drop[i].Parent = this;
    380.     }
    381.     m_Mess.Create(hInst, hWnd, STATIC_MESSAGE);
    382.     return 0;
    383. }
    384. LRESULT CWindow::OnSize(LPARAM lparam)
    385. {
    386.     // Di chuyển các điều khiển tới vị trí mới
    387.     for (int i = 0; i < 81; i++)
    388.         m_Cell[i].Move();
    389.     for (int i = 0; i < 9; i++)
    390.         m_Drop[i].Move();
    391.     m_Mess.Move();
    392.     return 0;
    393. }
    394. LRESULT CWindow::OnDrawItem(LPDRAWITEMSTRUCT pd)
    395. {
    396.     if (pd->CtlID == STATIC_MESSAGE)
    397.         m_Mess.Draw();
    398.     if (pd->CtlID < STATIC_MESSAGE)
    399.         m_Drop[pd->CtlID].Draw();
    400.     return 0;
    401. }
    402. LRESULT CWindow::OnClose()
    403. {
    404.     DestroyWindow(m_hWnd);
    405.     return 0;
    406. }
    407. LRESULT CWindow::OnDestroy()
    408. {
    409.     PostQuitMessage(0);
    410.     return 0;
    411. }
    412. CCell * CWindow::getSelectedCell()
    413. {
    414.     for (int i = 0; i < 81; i++)
    415.         if (m_Cell[i].Selected)
    416.             return &m_Cell[i];
    417.     return NULL;
    418. }
    419. BOOL    CWindow::Create(HINSTANCE hInst)
    420. {
    421.     WNDCLASS    w;
    422.     w.cbClsExtra = 0;
    423.     w.cbWndExtra = 0;
    424.     w.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
    425.     w.hCursor = LoadCursor(NULL, IDC_ARROW);
    426.     w.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    427.     w.hInstance = hInst;
    428.     w.lpfnWndProc = WndProc;
    429.     w.lpszClassName = TEXT("Lines98");
    430.     w.lpszMenuName = NULL;
    431.     w.style = CS_HREDRAW | CS_VREDRAW;
    432.     if (!RegisterClass(&w))
    433.         return FALSE;
    434.     HWND    hwnd = CreateWindow(w.lpszClassName, w.lpszClassName, WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, this);
    435.     if (!hwnd)
    436.         return FALSE;
    437.     ShowWindow(hwnd, SW_SHOW);
    438.     UpdateWindow(hwnd);
    439.     return TRUE;
    440. }
    441. int     CWindow::LoopMessage()
    442. {
    443.     MSG     msg;
    444.     while (GetMessage(&msg, NULL, 0, 0))
    445.     {
    446.         TranslateMessage(&msg);
    447.         DispatchMessage(&msg);
    448.     }
    449.     return msg.wParam;
    450. }
    451. void    CWindow::HandleAll(short start, short end)
    452. {
    453.     TEMP        temp[81];
    454.     for (short i = 0; i < 81; i++)              // Sao chép sang mảng tạm chỉ 2 giá trị : TC_LARGE, TC_FREE
    455.     {
    456.         temp[i].Style = (m_Cell[i].Style == TC_LARGE) ? TC_LARGE : TC_FREE;
    457.         temp[i].PrevIndex = -1;
    458.     }
    459.     temp[start].Style = TC_FREE;
    460.     temp[end].Style = TC_LARGE;
    461.     vector<short>   prev(1, end);
    462.     vector<short>   road;
    463.     LoopRoad(temp, prev, start, road);
    464.     if (road.empty())
    465.     {
    466.         MessageBox(m_hWnd, TEXT("No Roads !!!"), TEXT("Lines98"), MB_OK | MB_ICONINFORMATION);
    467.         return;
    468.     }
    469.     DrawRoad(road);
    470.     StepRoad(road);
    471.     vector<short>       bonus(0);
    472.     if (BonusFromCell(end, bonus))                      // Nếu có nhận những ô sẽ ăn
    473.     {
    474.         m_Mess.Mark += bonus.size();
    475.         m_Mess.Draw();
    476.         for (short j = 0; j < 3; j++)
    477.         {
    478.             for (short i = (short)bonus.size() - 1; i >= 0; i--)
    479.             {
    480.                 m_Cell[bonus[i]].Style = TC_LARGE;
    481.                 m_Cell[bonus[i]].Draw();
    482.             }
    483.             Sleep(200);
    484.             for (short i = (short)bonus.size() - 1; i >= 0; i--)
    485.             {
    486.                 m_Cell[bonus[i]].Style = TC_FREE;
    487.                 m_Cell[bonus[i]].Draw();
    488.             }
    489.             Sleep(200);
    490.         }
    491.         return;
    492.     }
    493.     vector<short>       smallcell;
    494.     if (EnumStyleCell(TC_SMALL, smallcell))             // Từ nhỏ -> lớn
    495.     {
    496.         short   count = (short)smallcell.size();
    497.         for (short i = 0; i < count; i++)
    498.         {
    499.             m_Cell[smallcell[i]].Style = TC_LARGE;      // Chuyển sang lớn
    500.             m_Cell[smallcell[i]].Draw();
    501.         }
    502.         for (short i = 0; i < count; i++)               // Ăn bi thụ động
    503.         {
    504.             vector<short>       bonus(0);
    505.             if (BonusFromCell(smallcell[i], bonus))
    506.             {
    507.                 m_Mess.Mark += bonus.size();
    508.                 m_Mess.Draw();
    509.                 for (short j = 0; j < 3; j++)
    510.                 {
    511.                     for (short i = (short)bonus.size() - 1; i >= 0; i--)
    512.                     {
    513.                         m_Cell[bonus[i]].Style = TC_LARGE;
    514.                         m_Cell[bonus[i]].Draw();
    515.                     }
    516.                     Sleep(200);
    517.                     for (short i = (short)bonus.size() - 1; i >= 0; i--)
    518.                     {
    519.                         m_Cell[bonus[i]].Style = TC_FREE;
    520.                         m_Cell[bonus[i]].Draw();
    521.                     }
    522.                     Sleep(200);
    523.                 }
    524.             }
    525.         }
    526.     }
    527.     vector<short>       freecell;
    528.     if (EnumStyleCell(TC_FREE, freecell))           // Chuẩn bị chuyển các ô bên ngoài vào board chính
    529.     {
    530.         short   count = (short)freecell.size();
    531.         for (int i = 0; i < min(count, 3); i++)         // Chuyển vào Board dưới dạng ô nhỏ
    532.         {
    533.             short   index;
    534.             do
    535.             {
    536.                 index = rand() % count;
    537.             } while (m_Cell[freecell[index]].Style != TC_FREE);
    538.             m_Cell[freecell[index]].Style = TC_SMALL;
    539.             m_Cell[freecell[index]].ForeColor = m_Drop[i].ForeColor;
    540.             m_Cell[freecell[index]].Draw();
    541.         }
    542.         for (int i = 0; i < 3; i++)
    543.         {
    544.             m_Drop[i].ForeColor = m_crTable[rand() % 7];
    545.             m_Drop[i].Draw();
    546.         }
    547.     }
    548.     else
    549.     {
    550.         if (IDNO == MessageBox(m_hWnd, TEXT("YOU LOST !!!\n<Yes> : Replay\n<No> : Exit"), TEXT("Lines98"), MB_YESNO | MB_ICONQUESTION))
    551.             SendMessage(m_hWnd, WM_CLOSE, 0, 0);
    552.         else
    553.         {
    554.             for (int i = 0; i < 81; i++)
    555.             {
    556.                 m_Cell[i].Style = TC_FREE;
    557.                 m_Cell[i].Selected = FALSE;
    558.                 m_Cell[i].ForeColor = 0;
    559.                 m_Cell[i].Draw();
    560.             }
    561.             for (int i = 0; i < 6; i++)             // Khởi tạo 3 bi lớn và nhỏ đầu tiên trên Board
    562.             {
    563.                 int index;
    564.                 do
    565.                 {
    566.                     index = rand() % 81;
    567.                 } while (m_Cell[index].Style != TC_FREE);
    568.                 m_Cell[index].Style = (i < 3) ? TC_LARGE : TC_SMALL;
    569.                 m_Cell[index].ForeColor = m_crTable[rand() % 7];
    570.                 m_Cell[index].Draw();
    571.             }
    572.             for (int i = 0; i < 3; i++)
    573.             {
    574.                 m_Drop[i].ForeColor = m_crTable[rand() % 7];
    575.                 m_Drop[i].Draw();
    576.             }
    577.             m_Mess.Mark = 0;
    578.             m_Mess.Draw();
    579.         }
    580.     }
    581. }
    582. void    CWindow::LoopRoad(TEMP temp[81], vector<short> & prev, short end, vector<short> & road)
    583. {
    584.     vector<short>   next;                                   // Vector sẽ chứa các chỉ mục cho lần duyệt kế tiếp
    585.     for (short i = (short)prev.size() - 1; i >= 0; i--)     // Duyệt các chỉ mục được cho từ lần duyệt trước
    586.     {
    587.         short   preIndex;
    588.         short   index = prev[i];
    589.         short   row = index / 9;
    590.         short   col = index % 9;
    591.         if (index == end)                                   // Gặp đích - đẩy đường đi vào ngăn xếp
    592.         {
    593.             road.push_back(index);
    594.             while (temp[index].PrevIndex != -1)
    595.             {
    596.                 index = temp[index].PrevIndex;              // Lấy chỉ mục ô trước đó
    597.                 road.push_back(index);                          // Đẩy vào ngăn xếp
    598.             }
    599.             return;
    600.         }
    601.         preIndex = row * 9 + col - 1;                       // Xét ô bên trái
    602.         if (col > 0 && temp[preIndex].Style == TC_FREE)
    603.         {
    604.             temp[preIndex].Style = TC_ROAD;                 // Đánh dấu ô này là đường đi
    605.             temp[preIndex].PrevIndex = index;               // Thiết lập chỉ mục cha
    606.             next.push_back(preIndex);                       // Nối thêm vào mảng duyệt lần sau
    607.         }
    608.         preIndex = (row - 1) * 9 + col;                     // Xét ô phía trên
    609.         if (row > 0 && temp[preIndex].Style == TC_FREE)
    610.         {
    611.             temp[preIndex].Style = TC_ROAD;
    612.             temp[preIndex].PrevIndex = index;
    613.             next.push_back(preIndex);
    614.         }
    615.         preIndex = row * 9 + col + 1;                       // Xét ô bên phải
    616.         if (col < 8 && temp[preIndex].Style == TC_FREE)
    617.         {
    618.             temp[preIndex].Style = TC_ROAD;
    619.             temp[preIndex].PrevIndex = index;
    620.             next.push_back(preIndex);
    621.         }
    622.         preIndex = (row + 1) * 9 + col;                     // Xét ô phía dưới
    623.         if (row < 8 && temp[preIndex].Style == TC_FREE)
    624.         {
    625.             temp[preIndex].Style = TC_ROAD;
    626.             temp[preIndex].PrevIndex = index;
    627.             next.push_back(preIndex);
    628.         }
    629.     }
    630.     if (!next.empty())                                      // Nếu có một tập hợp ô mới cần xét...
    631.         LoopRoad(temp, next, end, road);                    // ... thì cho đệ quy tiếp tục
    632. }
    633. void    CWindow::DrawRoad(vector<short> & road)
    634. {
    635.     HBRUSH  hbrFore = CreateSolidBrush(m_Cell[road[0]].ForeColor);
    636.     HBRUSH  hbrBack = CreateSolidBrush(m_Cell[road[1]].BackColor);
    637.     for (short i = (short)road.size() - 1; i > 0; i--)
    638.     {
    639.         HWND    hWnd = m_Cell[road[i]].Hwnd;
    640.         HDC     hdc = GetDC(hWnd);
    641.         RECT    r;
    642.         GetClientRect(hWnd, &r);
    643.         FillRect(hdc, &r, hbrBack);
    644.         SelectObject(hdc, hbrFore);
    645.         if (m_Cell[road[i]].Style == TC_SMALL)
    646.         {
    647.             HBRUSH      hbr = CreateSolidBrush(m_Cell[road[i]].ForeColor);
    648.             SelectObject(hdc, hbr);
    649.             Ellipse(hdc, 13, 13, r.right - 13, r.bottom - 13);
    650.             DeleteObject(hbr);
    651.         }
    652.         else
    653.             Ellipse(hdc, 18, 18, r.right - 18, r.bottom - 18);
    654.         ReleaseDC(hWnd, hdc);
    655.     }
    656.     DeleteObject(hbrFore);
    657.     DeleteObject(hbrBack);
    658. }
    659. void    CWindow::StepRoad(vector<short> & road)
    660. {
    661.     m_Cell[road[0]].Selected ^= 1;
    662.     m_Cell[road[0]].Draw();
    663.     m_Cell[road[0]].Style = TC_FREE;
    664.     HBRUSH  hbrFore = CreateSolidBrush(m_Cell[road[0]].ForeColor);
    665.     HBRUSH  hbrBack = CreateSolidBrush(m_Cell[road[0]].BackColor);
    666.  
    667.     short   count = (short)road.size();
    668.     for (short i = 0; i < count - 1; i++)
    669.     {
    670.         HWND    hWnd = m_Cell[road[i + 1]].Hwnd;
    671.         HDC     hdc = GetDC(hWnd);
    672.         RECT    r;
    673.         GetClientRect(hWnd, &r);
    674.         FillRect(hdc, &r, hbrBack);
    675.         SelectObject(hdc, hbrFore);
    676.         Ellipse(hdc, 3, 3, r.right - 3, r.bottom - 3);
    677.         ReleaseDC(hWnd, hdc);
    678.  
    679.         hWnd = m_Cell[road[i]].Hwnd;
    680.         hdc = GetDC(hWnd);
    681.         GetClientRect(hWnd, &r);
    682.         FillRect(hdc, &r, hbrBack);
    683.         if (m_Cell[road[i]].Style == TC_SMALL)
    684.         {
    685.             HBRUSH      hbr = CreateSolidBrush(m_Cell[road[i]].ForeColor);
    686.             SelectObject(hdc, hbr);
    687.             Ellipse(hdc, 13, 13, r.right - 13, r.bottom - 13);
    688.             DeleteObject(hbr);
    689.         }
    690.         ReleaseDC(hWnd, hdc);
    691.         Sleep(50);
    692.     }
    693.     DeleteObject(hbrFore);
    694.     DeleteObject(hbrBack);
    695.  
    696.     BOOL        bOver = FALSE;
    697.     COLORREF    crOver = 0;
    698.     if (m_Cell[road[count - 1]].Style == TC_SMALL)
    699.     {
    700.         bOver = TRUE;
    701.         crOver = m_Cell[road[count - 1]].ForeColor;
    702.     }
    703.  
    704.     m_Cell[road[count - 1]].Style = TC_LARGE;
    705.     m_Cell[road[count - 1]].ForeColor = m_Cell[road[0]].ForeColor;
    706.  
    707.     if (bOver)
    708.     {
    709.         vector<short>   freecell;
    710.         short   count = EnumStyleCell(TC_FREE, freecell);
    711.         short   index = rand() % count;                     // Tìm 1 ô trống ngẫu nhiên
    712.         m_Cell[freecell[index]].Style = TC_SMALL;               // để chuyển ô bị đè tới đó
    713.         m_Cell[freecell[index]].ForeColor = crOver;
    714.         m_Cell[freecell[index]].Draw();
    715.     }
    716. }
    717. short   CWindow::EnumStyleCell(short style, vector<short> & result)
    718. {
    719.     short count = 0;
    720.     result.resize(0);
    721.     for (short i = 0; i < 81; i++)
    722.         if (m_Cell[i].Style == style)
    723.         {
    724.             result.push_back(i);
    725.             count++;
    726.         }
    727.     return count;
    728. }
    729. short   CWindow::BonusFromCell(short node, vector<short> & bonus)
    730. {
    731.     short       r, c, count;
    732.     COLORREF    color = m_Cell[node].ForeColor;
    733.     // ngang
    734.     count = 1;
    735.     bonus.resize(1, node);
    736.     r = node / 9; c = node % 9;
    737.     while (--c >= 0 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // left
    738.     {
    739.         bonus.push_back(r * 9 + c); count++;
    740.     }
    741.     r = node / 9; c = node % 9;
    742.     while (++c <= 8 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // right
    743.     {
    744.         bonus.push_back(r * 9 + c); count++;
    745.     }
    746.     if (count >= 5)
    747.         return count;
    748.     // dọc
    749.     count = 1;
    750.     bonus.resize(1, node);
    751.     r = node / 9; c = node % 9;
    752.     while (--r >= 0 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // up
    753.     {
    754.         bonus.push_back(r * 9 + c); count++;
    755.     }
    756.     r = node / 9; c = node % 9;
    757.     while (++r <= 8 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // down
    758.     {
    759.         bonus.push_back(r * 9 + c); count++;
    760.     }
    761.     if (count >= 5)
    762.         return count;
    763.     // chéo thuận
    764.     count = 1;
    765.     bonus.resize(1, node);
    766.     r = node / 9; c = node % 9;
    767.     while (--r >= 0 && --c >= 0 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // tây bắc
    768.     {
    769.         bonus.push_back(r * 9 + c); count++;
    770.     }
    771.     r = node / 9; c = node % 9;
    772.     while (++r <= 8 && ++c <= 8 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // đông nam
    773.     {
    774.         bonus.push_back(r * 9 + c); count++;
    775.     }
    776.     if (count >= 5)
    777.         return count;
    778.     // chéo nghịch
    779.     count = 1;
    780.     bonus.resize(1, node);
    781.     r = node / 9; c = node % 9;
    782.     while (--r >= 0 && ++c <= 8 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // đông bắc
    783.     {
    784.         bonus.push_back(r * 9 + c); count++;
    785.     }
    786.     r = node / 9; c = node % 9;
    787.     while (++r <= 8 && --c >= 0 && m_Cell[r * 9 + c].Style == TC_LARGE && m_Cell[r * 9 + c].ForeColor == color) // tây nam
    788.     {
    789.         bonus.push_back(r * 9 + c); count++;
    790.     }
    791.     if (count >= 5)
    792.         return count;
    793.     return 0;
    794. }
    795.  
    796. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR pCmd, int nShow)
    797. {
    798.     CWindow MainWnd;
    799.     if (!MainWnd.Create(hInstance))
    800.         return 0;
    801.     return MainWnd.LoopMessage();
    802. }
    Attached Thumbnails Attached Thumbnails Lines98.jpg  
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn