每天一個(gè)編程小項(xiàng)目,提升你的編程能力!
程序簡(jiǎn)介
掃雷游戲升級(jí)版!六邊形掃雷(尋寶模式)稍稍介紹一下哈~
他也是要把所有安全的地方點(diǎn)出來。
他沒有掃雷模式的消零算法。每一個(gè)安全的點(diǎn)都需要單獨(dú)挖出來,一次顯示一個(gè)格子。
添加了生命值的概念,也就是說存在一定的容錯(cuò)。
顯示的數(shù)字有別于掃雷模式。點(diǎn)擊寶藏點(diǎn),會(huì)顯示周圍寶藏點(diǎn)數(shù)量,綠色;點(diǎn)擊地雷,會(huì)顯示周圍地雷數(shù)量,黑色。注意,這個(gè)數(shù)字不包括自己,顯示的范圍自然就是 0~6 了。點(diǎn)擊地雷會(huì)減生命值,生命值歸零則結(jié)束。
所以雷和寶藏都是有價(jià)值的,都是能給準(zhǔn)確信息的。
我能給一個(gè)參考難度:占總格子數(shù) 40%的地雷,占總地雷數(shù) 50 %的生命值。
【注:需要編譯器+圖形庫插件可以在文末領(lǐng)取】
程序運(yùn)行展示
簡(jiǎn)單了解游戲后我們就來試試吧?。ㄖ苯由显创a,大家可以看注釋)
//////////////////////////////////////// // 程序:六邊形掃雷:尋寶模式 # include# include # include # include static double pi = acos (-1.0); // 圓周率 π static HWND hOut; // 畫布 // 定義一個(gè)結(jié)構(gòu)體,按鈕 struct Node1 { int posx1, posy1, posx2, posy2; // 坐標(biāo) LPTSTR text; // 文字 int mod; // 狀態(tài) }; // 定義一個(gè)結(jié)構(gòu)體,六邊形格子 struct Node2 { int i, j, k; // 特征值 int mod_life; // 翻開 int mod_mine; // 雷 int mod_flag; // 標(biāo)記 int posx, posy; // 坐標(biāo) int num_mine; // 周圍雷數(shù) int num_peace; // 周圍空地塊 }; // 定義一個(gè)類 class Gary { public: void carry (); // 主進(jìn)程 void initialization (); // 初始化 void draw_scene (); // 繪制界面函數(shù) void draw_box (int num_box); // 繪制格子 void draw_flag (int num_box); // 繪制標(biāo)記 void draw_num (int num_box, int num); // 繪制數(shù)字 void move (); // 窗口主視角 void create (); // 地雷生成 void check_over (); // 結(jié)束判定 int num_button; // 按鈕數(shù)量參數(shù) int exit_carry; // 主循函數(shù)控制參數(shù) int exit_move; // 開始界面控制參數(shù) int exit_game; // 游戲進(jìn)行控制參數(shù) int num_life; // 生命值 int num_size; // 邊長 int num_mine; // 總雷數(shù) int num_box; // 總地塊數(shù) int num_flag; // 標(biāo)記數(shù) COLORREF color_text[2]; // 按鈕繪制填充 Node1 boxm[30]; // 按鈕,預(yù)制 30 個(gè) Node2 box[1000]; // 地塊 }; // 標(biāo)記繪制函數(shù) void Gary::draw_flag (int num_box) { setlinestyle (PS_SOLID, 1); setlinecolor (BLACK); line (box[num_box].posx + 2, box[num_box].posy + 7, box[num_box].posx + 2, box[num_box].posy - 7); setfillcolor (LIGHTRED); setlinecolor (LIGHTRED); fillrectangle (box[num_box].posx - 7 + 2, box[num_box].posy - 7, box[num_box].posx + 2, box[num_box].posy - 1); } // 數(shù)字繪制函數(shù) void Gary::draw_num (int num_box, int num) { int i; // 畫六邊形,格子處于點(diǎn)擊后狀態(tài) setfillcolor (RGB (170, 170, 170)); setlinecolor (RGB (85, 85, 85)); POINT pts[6]; setlinestyle (PS_SOLID, 1); for (i = 0; i < 6; i++) { pts[i].x = long(box[num_box].posx + 14.0 * cos (60.0 * double (i) * pi / 180.0)); pts[i].y = long(box[num_box].posy + 14.0 * sin (60.0 * double (i) * pi / 180.0)); } fillpolygon (pts, 6); // 數(shù)字繪制 TCHAR s[15]; settextstyle (20, 0, _T ("Consolas")); _stprintf_s (s, _T ("%0.1d"), num); outtextxy (box[num_box].posx - 5, box[num_box].posy - 10, s); } // 場(chǎng)景繪制函數(shù) void Gary::draw_scene () { TCHAR s[15]; int i, j; setlinecolor (BLACK); setfillcolor (WHITE); setlinestyle (PS_SOLID, 1); // 主界面 fillrectangle (401, 0, 650, 400); // 根據(jù)按鈕數(shù)量繪制 settextcolor (BLACK); for (i = 0; i < num_button; i++) { setfillcolor (color_text[boxm[i].mod]); setbkcolor (color_text[boxm[i].mod]); // 邊框 fillrectangle (boxm[i].posx1, boxm[i].posy1, boxm[i].posx2, boxm[i].posy2); // 文字 outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + 4, boxm[i].text); } // 設(shè)置參數(shù) setbkcolor (WHITE); settextcolor (BLACK); setlinecolor (BLACK); // 變量繪制 j = 25; // 生命值 i = 1; setbkcolor (color_text[boxm[i].mod]); _stprintf_s (s, _T ("%0.1d"), num_life); outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + j, s); // 邊長 i = 2; setbkcolor (color_text[boxm[i].mod]); _stprintf_s (s, _T ("%0.1d"), num_size); outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + j, s); // 總地雷數(shù) i = 3; setbkcolor (color_text[boxm[i].mod]); _stprintf_s (s, _T ("%0.1d"), num_mine); outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + j, s); // 格子 i = 4; setbkcolor (color_text[boxm[i].mod]); _stprintf_s (s, _T ("%0.1d"), num_box); outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + j, s); // 標(biāo)記數(shù) i = 5; setbkcolor (color_text[boxm[i].mod]); _stprintf_s (s, _T ("%0.1d"), num_flag); outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + j, s); FlushBatchDraw (); } // 地雷生成函數(shù) void Gary::create () { int i, j; // 設(shè)置雷 for (i = 0; i < num_mine; i++) { // 隨機(jī) j = rand () % 1000; while (box[j].mod_mine == 1 || box[j].mod_life == 1) { // 隨機(jī) j = rand () % 1000; } // 是雷 box[j].mod_mine = 1; } // 周邊雷數(shù)統(tǒng)計(jì) // 遍歷 for (i = 0; i <= 888; i++) { if (box[i].mod_life == 0) { // 遍歷 for (j = 0; j <= 999; j++) { // 排除自己 if (j != i && box[j].mod_life == 0) { // 周圍六個(gè) if ((box[j].posx - box[i].posx) * (box[j].posx - box[i].posx) + (box[j].posy - box[i].posy) * (box[j].posy - box[i].posy) <= 900) { // 是雷 if (box[j].mod_mine == 1) { // 周邊雷數(shù)參數(shù)加一 box[i].num_mine++; } // 不是雷 else if (box[j].mod_mine == 0) { // 周邊安全數(shù)參數(shù)加一 box[i].num_peace++; } } } } } } } // 結(jié)束判斷函數(shù) void Gary::check_over () { int i, k; k = 0; for (i = 0; i <= 888; i++) { // 每有一個(gè)翻開且不是雷的點(diǎn),則加一 if (box[i].mod_mine == 0 && box[i].mod_life == 1) { k++; } } // 全翻開則結(jié)束 if (k == num_box - num_mine) { // 將所有未翻開雷做上標(biāo)記 for (i = 0; i <= 888; i++) { if (box[i].mod_mine == 1 && box[i].mod_life == 0) { draw_flag (i); } } // 勝利標(biāo)志:笑臉 setfillcolor (WHITE); setlinecolor (WHITE); fillrectangle (50, 20, 75, 45); settextstyle (30, 0, _T ("Wingdings")); setbkmode (TRANSPARENT); settextcolor (BLACK); outtextxy (50, 20, 0x4A); setbkmode (OPAQUE); settextstyle (20, 0, _T ("Consolas")); // 結(jié)束變化 exit_game = 1; boxm[1].mod = 0; boxm[2].mod = 0; boxm[3].mod = 0; boxm[6].mod = 0; boxm[7].mod = 1; num_flag = 0; // 繪制 draw_scene (); } } // 格子繪制函數(shù) void Gary::draw_box (int num_box) { int i; int posx, posy; // 六邊形繪制 posx = box[num_box].posx; posy = box[num_box].posy; POINT pts[6]; setlinestyle (PS_SOLID, 2); // 背景色 setfillcolor (RGB (255, 255, 255)); for (i = 0; i < 6; i++) { pts[i].x = long(posx + 14.0 * cos (60.0 * double (i) * pi / 180.0)); pts[i].y = long(posy + 14.0 * sin (60.0 * double (i) * pi / 180.0)); } solidpolygon (pts, 6); // 灰邊 setlinecolor (RGB (85, 85, 85)); line (pts[0].x, pts[0].y, pts[1].x, pts[1].y); line (pts[5].x, pts[5].y, pts[0].x, pts[0].y); line (pts[1].x, pts[1].y, pts[2].x, pts[2].y); // 前景色 setfillcolor (RGB (170, 170, 170)); for (i = 0; i < 6; i++) { pts[i].x = long(posx + 12.0 * cos (60.0 * double (i) * pi / 180.0)); pts[i].y = long(posy + 12.0 * sin (60.0 * double (i) * pi / 180.0)); } solidpolygon (pts, 6); FlushBatchDraw (); } // 初始化函數(shù) void Gary::initialization () { int i, j, k, t; // 隨機(jī)初始化 srand ((unsigned)time (NULL)); // 顏色初始化 color_text[0] = WHITE; color_text[1] = RGB (170, 170, 170); // 按鈕的初始化 num_button = 10; // 坐標(biāo) for (i = 0; i < 10; i++) { boxm[i].posx1 = 410 + 120 * (i % 2); boxm[i].posy1 = 25 + 75 * (i / 2); boxm[i].posx2 = 520 + 120 * (i % 2); boxm[i].posy2 = 75 + 75 * (i / 2); } // 內(nèi)容 boxm[0].text = _T ("尋寶模式"); boxm[1].text = _T ("生命值"); boxm[2].text = _T ("地圖邊長"); boxm[3].text = _T ("總地雷數(shù)"); boxm[4].text = _T ("總地塊數(shù)"); boxm[5].text = _T ("已標(biāo)記數(shù)"); boxm[6].text = _T ("開始"); boxm[7].text = _T ("重置"); boxm[8].text = _T ("截圖"); boxm[9].text = _T ("退出"); // 狀態(tài) boxm[0].mod = 1; boxm[1].mod = 1; boxm[2].mod = 1; boxm[3].mod = 1; boxm[4].mod = 1; boxm[5].mod = 1; boxm[6].mod = 1; boxm[7].mod = 0; boxm[8].mod = 0; boxm[9].mod = 0; num_box = 3 * num_size * (num_size - 1) + 1; num_flag = 0; // 繪制參數(shù)初始化 setlinecolor (BLACK); setlinestyle (PS_SOLID, 1); settextstyle (20, 0, _T ("Consolas")); // 第一次繪制 draw_scene (); // 重置 setfillcolor (WHITE); fillrectangle (0, 0, 400, 400); // 平靜臉 setfillcolor (WHITE); setlinecolor (WHITE); fillrectangle (50, 20, 75, 45); settextstyle (30, 0, _T ("Wingdings")); setbkmode (TRANSPARENT); settextcolor (BLACK); outtextxy (50, 20, 0x4B); setbkmode (OPAQUE); settextstyle (20, 0, _T ("Consolas")); // 格子初始化 for (t = 0; t <= 999; t++) { // 已翻開 box[t].mod_life = 1; // 城墻 box[t].mod_mine = 2; // 坐標(biāo),點(diǎn)不到 box[t].posx = -200; box[t].posy = -200; } // 初始化 for (i = 0; i < num_size; i++) { for (j = 0; j < num_size; j++) { for (k = 0; k < num_size; k++) { // 特征值至少一個(gè)為零 if (i == 0 || j == 0 || k == 0) { // 編號(hào) t = i * 100 + j * 10 + k; // 特征值 box[t].i = i; box[t].j = j; box[t].k = k; // 未翻開 box[t].mod_life = 0; // 不是雷 box[t].mod_mine = 0; // 未標(biāo)記 box[t].mod_flag = 0; // 坐標(biāo) box[t].posx = 200 + 22 * (j - k); box[t].posy = 200 - 25 * i + 13 * (j + k); // 周圍雷數(shù)初始化 box[t].num_mine = 0; box[t].num_peace = 0; // 繪制地塊 draw_box (t); } } } } // 地雷生成函數(shù) create (); } // 窗口主視角函數(shù),獲取用戶操作 void Gary::move () { // 鼠標(biāo)定義 ExMessage m; TCHAR ss[15]; int i, t; exit_move = 0; exit_game = 0; while (exit_move == 0) { // 鼠標(biāo)信息 if (peekmessage (&m, EM_MOUSE | EM_KEY)) { // 左鍵單擊判斷 if (m.message == WM_LBUTTONDOWN) { // 判斷是否點(diǎn)擊了格子 if (m.x > 0 && m.y > 0 && m.x < 400 && m.y < 400 && exit_game == 0) { for (t = 0; t <= 888; t++) { // 成功點(diǎn)擊未標(biāo)記的空格子 if ((m.x - box[t].posx) * (m.x - box[t].posx) + (m.y - box[t].posy) * (m.y - box[t].posy) <= 144 && box[t].mod_life == 0 && box[t].mod_flag == 0) { // 點(diǎn)擊的格子不是雷 if (box[t].mod_mine == 0) { // 綠色,安全,繪制 settextcolor (LIGHTGREEN); draw_num (t, box[t].num_peace); // 改為翻開 box[t].mod_life = 1; } // 點(diǎn)擊的格子雷 else if (box[t].mod_mine == 1) { // 扣除生命值 num_life--; // 黑色,危險(xiǎn),繪制 settextcolor (BLACK); draw_num (t, box[t].num_mine); // 改為翻開 box[t].mod_life = 1; // 生命值減為零 if (num_life <= 0) { // 失敗標(biāo)志:哭臉 setfillcolor (WHITE); setlinecolor (WHITE); fillrectangle (50, 20, 75, 45); settextstyle (30, 0, _T ("Wingdings")); setbkmode (TRANSPARENT); settextcolor (BLACK); outtextxy (50, 20, 0x4C); setbkmode (OPAQUE); settextstyle (20, 0, _T ("Consolas")); // 失敗 exit_game = 1; boxm[1].mod = 0; boxm[2].mod = 0; boxm[3].mod = 0; boxm[6].mod = 0; boxm[7].mod = 1; num_flag = 0; } // 繪制 draw_scene (); } // 成功結(jié)束判斷 check_over (); break; } } } // 判斷是否點(diǎn)擊了可點(diǎn)擊按鈕 for (i = 0; i < num_button; i++) { if (m.x > boxm[i].posx1 && m.y > boxm[i].posy1 && m.x < boxm[i].posx2 && m.y < boxm[i].posy2 && boxm[i].mod == 0) { break; } } // 點(diǎn)擊矩形按鈕 switch (i) { // 生命值:num_life case 1: { // 輸入 InputBox (ss, 10, _T ("輸入生命值(1 ~ 999)")); _stscanf_s (ss, _T ("%d"), &i); if (i > 0 && i <= 999) { num_life = i; } else { MessageBox (hOut, _T ("輸入錯(cuò)誤,不在范圍內(nèi)"), _T ("來自小豆子的提醒"), MB_OK); } // 繪制 draw_scene (); break; } // 地圖邊長:num_size case 2: { // 輸入 InputBox (ss, 10, _T ("輸入邊長(2 ~ 8)")); _stscanf_s (ss, _T ("%d"), &i); if (i > 1 && i <= 8) { num_size = i; num_box = 3 * num_size * (num_size - 1) + 1; } else { MessageBox (hOut, _T ("輸入錯(cuò)誤,不在范圍內(nèi)"), _T ("來自小豆子的提醒"), MB_OK); } // 繪制 draw_scene (); break; } // 總地雷數(shù):num_mine case 3: { InputBox (ss, 10, _T ("輸入地雷數(shù)(1 ~ 總格子數(shù))")); _stscanf_s (ss, _T ("%d"), &i); if (i > 0 && i < num_box) { num_mine = i; } else { MessageBox (hOut, _T ("輸入錯(cuò)誤,不在范圍內(nèi)"), _T ("來自小豆子的提醒"), MB_OK); } // 繪制 draw_scene (); break; } // 開始 case 6: { num_box = 3 * num_size * (num_size - 1) + 1; if (num_mine < num_box && num_life > 0) { exit_game = 0; // 初始化 initialization (); } else { MessageBox (hOut, _T ("請(qǐng)將雷數(shù)修改為小于格子數(shù)或?qū)⑸敌薷臑榇笥诹?), _T ("來自小豆子的提醒"), MB_OK); } break; } // 重置 case 7: { // 結(jié)束游戲進(jìn)程,進(jìn)入準(zhǔn)備階段 if (exit_game == 0) { exit_game = 1; boxm[1].mod = 0; boxm[2].mod = 0; boxm[3].mod = 0; boxm[6].mod = 0; boxm[7].mod = 1; num_flag = 0; // 繪制 draw_scene (); } break; } // 截圖 case 8: { saveimage (_T ("image.png")); break; } // 退出 case 9: { exit_game = 1; exit_move = 1; exit_carry = 1; break; } default:break; } } // 右鍵,且處于游戲進(jìn)行狀態(tài) else if (m.message == WM_RBUTTONDOWN && exit_game == 0) { for (t = 0; t <= 888; t++) { // 成功點(diǎn)擊空格子 if ((m.x - box[t].posx) * (m.x - box[t].posx) + (m.y - box[t].posy) * (m.y - box[t].posy) <= 144 && box[t].mod_life == 0) { // 標(biāo)記狀態(tài)轉(zhuǎn)換 box[t].mod_flag = (box[t].mod_flag == 0 ? 1 : 0); // 繪制 draw_box (t); // 畫小旗子 if (box[t].mod_flag == 1) { draw_flag (t); num_flag++; } else { num_flag--; } // 繪制 draw_scene (); } } } } } } // 主進(jìn)程 void Gary::carry () { // 窗口定義 hOut = initgraph (651, 401); SetWindowText (hOut, _T ("六邊形掃雷:掃雷模式")); // 參數(shù)初始化 num_size = 5; num_mine = 10; num_life = 3; // 背景繪制 setbkcolor (WHITE); cleardevice (); // 進(jìn)程控制 exit_carry = 0; while (exit_carry == 0) { initialization (); move (); } closegraph (); } // 主函數(shù) int main (void) { Gary G; G.carry (); return 0; }
大家趕緊去動(dòng)手試試吧!
審核編輯:湯梓紅
-
游戲
+關(guān)注
關(guān)注
2文章
723瀏覽量
26212 -
編程
+關(guān)注
關(guān)注
88文章
3521瀏覽量
93263 -
程序
+關(guān)注
關(guān)注
115文章
3719瀏覽量
80355 -
編譯器
+關(guān)注
關(guān)注
1文章
1602瀏覽量
48894
原文標(biāo)題:【項(xiàng)目實(shí)戰(zhàn)】C語言+easyX帶你實(shí)現(xiàn):掃雷游戲(六邊形升級(jí)版)!
文章出處:【微信號(hào):cyuyanxuexi,微信公眾號(hào):C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論