基于 EasyX 的五子棋軟件。
算法部分想了很久,也參考了網(wǎng)上的其他游戲的。原理主要就是:遍歷每個空閑的點,根據(jù)下在那個點后連成的棋形來判斷其分值,再選出分值最高的位置并返回給游戲函數(shù)。
還在上小學,更深層次的判定算法還沒學,就先將就一下吧。
運行效果如下:
完整的游戲源代碼如下:
#include#include #include #include #include // 類定義 // 保存位置的類 class seat { public: int i = 0; // y 坐標 int j = 0; // x 坐標 int number = 0; // 分數(shù) }; // 保存棋盤的類 class box { public: void draw(); // 繪制 public: int x = 0; // x 坐標 int y = 0; // y 坐標 int value = -1; // 值(黑棋:1,白棋:0,空位:-1) int modle; // 模式 bool isnew = false; // 是否有選擇框 int number = 0; // 分數(shù) COLORREF color = WHITE; // 棋盤背景色 }; // 函數(shù)聲明 void draw(); // 繪制 void init(); // 初始化 seat findbestseat(int color); // 尋找最佳位置 void isWIN(); // 判斷輸贏 void game(); // 游戲主函數(shù) // main函數(shù) int main() { initgraph(700, 700, NOMINIMIZE); // 初始化繪圖環(huán)境 setbkcolor(WHITE); cleardevice(); setbkmode(TRANSPARENT); // 設置透明文字輸出背景 while (1) { init(); // 初始化 game(); // 游戲開始 cleardevice(); } } // 全局變量 box BOX[19][19]; // 棋盤 int win = -1; // 誰贏了(0:白棋,1:黑棋,2:平局) int whoplay = 0; // 輪到誰下棋了 int playercolor = 0; // 玩家顏色 int dx[4]{ 1,0,1,1 }; // - | / 四個方向 int dy[4]{ 0,1,1,-1 }; // 類函數(shù)定義 // 繪制函數(shù) void box::draw() { COLORREF thefillcolor = getfillcolor(); // 備份填充顏色 setlinestyle(PS_SOLID, 2); // 線樣式設置 setfillcolor(color); // 填充顏色設置 solidrectangle(x, y, x + 30, y + 30); // 繪制無邊框的正方形 if (isnew) { // 如果是新下的 // 繪制邊框線 setlinecolor(LIGHTGRAY); line(x + 1, y + 2, x + 8, y + 2); line(x + 2, y + 1, x + 2, y + 8); line(x + 29, y + 2, x + 22, y + 2); line(x + 29, y + 1, x + 29, y + 8); line(x + 2, y + 29, x + 8, y + 29); line(x + 2, y + 22, x + 2, y + 29); line(x + 29, y + 29, x + 22, y + 29); line(x + 29, y + 22, x + 29, y + 29); } setlinecolor(BLACK); switch (modle) { // 以下是不同位置棋盤的樣式 case 0: line(x + 15, y, x + 15, y + 30); line(x - 1, y + 15, x + 30, y + 15); break; // * // *** // * case 1: line(x + 14, y + 15, x + 30, y + 15); setlinestyle(PS_SOLID, 3); line(x + 15, y, x + 15, y + 30); setlinestyle(PS_SOLID, 2); break; // * // *** // * case 2: line(x - 1, y + 15, x + 15, y + 15); setlinestyle(PS_SOLID, 3); line(x + 15, y, x + 15, y + 30); setlinestyle(PS_SOLID, 2); break; // * // *** // * case 3: line(x + 15, y + 15, x + 15, y + 30); setlinestyle(PS_SOLID, 3); line(x - 1, y + 15, x + 30, y + 15); setlinestyle(PS_SOLID, 2); break; // *** // * // * case 4: line(x + 15, y, x + 15, y + 15); setlinestyle(PS_SOLID, 3); line(x - 1, y + 15, x + 30, y + 15); setlinestyle(PS_SOLID, 2); break; // * // * // *** case 5: setlinestyle(PS_SOLID, 3); line(x + 15, y, x + 15, y + 15); line(x + 15, y + 15, x + 30, y + 15); setlinestyle(PS_SOLID, 2); break; // * // * // *** case 6: setlinestyle(PS_SOLID, 3); line(x + 15, y, x + 15, y + 15); line(x - 1, y + 15, x + 15, y + 15); setlinestyle(PS_SOLID, 2); break; // * // * // *** case 7: setlinestyle(PS_SOLID, 3); line(x - 1, y + 15, x + 15, y + 15); line(x + 15, y + 15, x + 15, y + 30); setlinestyle(PS_SOLID, 2); break; // *** // * // * case 8: setlinestyle(PS_SOLID, 3); line(x + 15, y + 15, x + 30, y + 15); line(x + 15, y + 15, x + 15, y + 30); setlinestyle(PS_SOLID, 2); break; // *** // * // * case 9: line(x + 15, y, x + 15, y + 30); line(x - 1, y + 15, x + 30, y + 15); setfillcolor(BLACK); setlinestyle(PS_SOLID, 1); fillcircle(x + 15, y + 15, 4); break; // * // *O* // * } switch (value) { case 0: // 白棋 setfillcolor(WHITE); setlinestyle(PS_SOLID, 1); fillcircle(x + 15, y + 15, 13); break; case 1: // 黑棋 setfillcolor(BLACK); setlinestyle(PS_SOLID, 1); fillcircle(x + 15, y + 15, 13); break; } setfillcolor(thefillcolor); // 還原填充色 } // 其他函數(shù)定義 // 繪制棋盤 void draw() { int modle = 0; // 棋盤樣式 int number = 0; // 坐標輸出的位置 // 坐標(數(shù)值) TCHAR strnum[19][3] = { _T("1"),_T("2") ,_T("3") ,_T("4"),_T("5") ,_T("6") ,_T("7"),_T("8"),_T("9"),_T("10"), _T("11"),_T("12") ,_T("13") ,_T("14"),_T("15") ,_T("16") ,_T("17"),_T("18"),_T("19") }; // 坐標(字母) TCHAR strabc[19][3] = { _T("A"),_T("B") ,_T("C") ,_T("D"),_T("E") ,_T("F") ,_T("G"),_T("H"),_T("I"),_T("J"), _T("K"),_T("L") ,_T("M") ,_T("N"),_T("O") ,_T("P") ,_T("Q"),_T("R"),_T("S") }; for (int i = 0, k = 0; i < 570; i += 30) { for (int j = 0, g = 0; j < 570; j += 30) { BOX[k][g].color = RGB(255, 205, 150);// 棋盤底色 // x、y 坐標 BOX[k][g].x = 65 + j; BOX[k][g].y = 50 + i; BOX[k][g].number = 0;// 初始化分數(shù) // 棋盤樣式的判斷 if (k == 0 && g == 0) { modle = 8; } else if (k == 0 && g == 18) { modle = 7; } else if (k == 18 && g == 18) { modle = 6; } else if (k == 18 && g == 0) { modle = 5; } else if (k == 0) { modle = 3; } else if (k == 18) { modle = 4; } else if (g == 0) { modle = 1; } else if (g == 18) { modle = 2; } else if ((k == 3 && g == 3) || (k == 3 && g == 15) || (k == 15 && g == 3) || (k == 15 && g == 15) || (k == 3 && g == 9) || (k == 9 && g == 3) || (k == 15 && g == 9) || (k == 9 && g == 15) || (k == 9 && g == 9)) { modle = 9; } else { modle = 0; } BOX[k][g].modle = modle; BOX[k][g].draw(); // 繪制 if (BOX[k][g].isnew == true) { BOX[k][g].isnew = false; // 把上一個下棋位置的黑框清除 } g++; } k++; } // 畫坐標 LOGFONT nowstyle; gettextstyle(&nowstyle); settextstyle(0, 0, NULL); for (int i = 0; i < 19; i++) { outtextxy(75 + number, 35, strnum[i]); outtextxy(53, 55 + number, strabc[i]); number += 30; } settextstyle(&nowstyle); } // 對局初始化 void init() { win = -1;// 誰贏了 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { BOX[i][j].number = 0;// 分數(shù) BOX[i][j].value = -1;// 值 } } } // 核心函數(shù) // 尋找最佳位置 seat findbestseat(int color) { // 評分表 int Score[3][5] = { { 0, 20, 360, 5800, 92840 }, // 防守0子 { 0, 0, 20, 360, 92840 }, // 防守1子 { 0, 0, 0, 0, 92840 } // 防守2子 }; seat bestseat; // 最佳位置 int MAXnumber[361] = { 0 }; // 最佳分數(shù)(可能有多個) int MAXx[361] = { 0 }; // 最佳 x 坐標(可能有多個) int MAXy[361] = { 0 }; // 最佳 y 坐標(可能有多個) int number = 0; // 下一個最佳分數(shù)儲存位置 int truenumber; // 輸出的最佳分數(shù)位置 int nowi = 0; // 現(xiàn)在遍歷到的y坐標 int nowj = 0; // 現(xiàn)在遍歷到的x坐標 int length[4]; // 四個方向的長度 int emeny[4]; // 四個方向的敵子 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { if (BOX[i][j].value == -1) { // 遍歷每一個可能的位置 // 自己 BOX[i][j].value = color; // 嘗試下在這里 for (int k = 0; k < 4; k++) { length[k] = 0; emeny[k] = 0; nowi = i; nowj = j; while (nowi <= 18 && nowj <= 18 && nowi >= 0 && nowj >= 0 && BOX[nowi][nowj].value == color) { length[k]++; nowj += dx[k]; nowi += dy[k]; } if (BOX[nowi][nowj].value == 1 - color || nowi < 0 || nowj < 0 || nowi > 18 || nowj > 18) { emeny[k]++; } nowi = i; nowj = j; while (nowi <= 18 && nowj <= 18 && nowi >= 0 && nowj >= 0 && BOX[nowi][nowj].value == color) { length[k]++; nowj -= dx[k]; nowi -= dy[k]; } if (BOX[nowi][nowj].value == 1 - color || nowi < 0 || nowj < 0 || nowi > 18 || nowj > 18) { emeny[k]++; } length[k] -= 2; // 判斷長度 if (length[k] > 4) { length[k] = 4; } BOX[i][j].number += Score[emeny[k]][length[k]] * 4 + !(!length[k]) * 20;//加分系統(tǒng) length[k] = 0; emeny[k] = 0; } // 敵人(原理同上) BOX[i][j].value = 1 - color; for (int k = 0; k < 4; k++) { length[k] = 0; emeny[k] = 0; nowi = i; nowj = j; while (nowi <= 18 && nowj <= 18 && nowi >= 0 && nowj >= 0 && BOX[nowi][nowj].value == 1 - color) { length[k]++; nowj += dx[k]; nowi += dy[k]; } if (BOX[nowi][nowj].value == color || nowi < 0 || nowj < 0 || nowi > 18 || nowj > 18) { emeny[k]++; } nowi = i; nowj = j; while (nowi <= 18 && nowj <= 18 && nowi >= 0 && nowj >= 0 && BOX[nowi][nowj].value == 1 - color) { length[k]++; nowj -= dx[k]; nowi -= dy[k]; } if (BOX[nowi][nowj].value == color || nowi < 0 || nowj < 0 || nowi > 18 || nowj > 18) { emeny[k]++; } length[k] -= 2; if (length[k] > 4) { length[k] = 4; } BOX[i][j].number += Score[emeny[k]][length[k]]; length[k] = 0; emeny[k] = 0; } BOX[i][j].value = -1; } if (BOX[i][j].number == MAXnumber[0]) { // 如果和最高分數(shù)相同 MAXnumber[number] = BOX[i][j].number; MAXy[number] = i; MAXx[number] = j; number++; // 新增一個分數(shù)及坐標 } if (BOX[i][j].number > MAXnumber[0]) { // 如果比最高分數(shù)高 for (int k = 0; k < number; k++) { MAXnumber[k] = 0; MAXy[k] = 0; MAXx[k] = 0; } number = 0; MAXnumber[number] = BOX[i][j].number; MAXy[number] = i; MAXx[number] = j; number++; // 清空數(shù)組再加入 } } } // 生成隨機位置 srand(time(NULL)); truenumber = rand() % number; bestseat.i = MAXy[truenumber]; bestseat.j = MAXx[truenumber]; bestseat.number = MAXnumber[truenumber]; // 返回位置 return bestseat; } // 判斷輸贏 void isWIN() { bool isinit = true; // 是否剛剛開局 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { if (BOX[i][j].value != -1) { // 遍歷每個可能的位置 isinit = false; // 如果有,那么就不是剛剛開局 int nowcolor = BOX[i][j].value; // 現(xiàn)在遍歷到的顏色 int length[4] = { 0,0,0,0 }; // 四個方向的長度 for (int k = 0; k < 4; k++) { // 原理同尋找最佳位置 int nowi = i; int nowj = j; while (nowi <= 18 && nowj <= 18 && nowi >= 0 && nowj >= 0 && BOX[nowi][nowj].value == nowcolor) { length[k]++; nowj += dx[k]; nowi += dy[k]; } nowi = i; nowj = j; while (nowi <= 18 && nowj <= 18 && nowi >= 0 && nowj >= 0 && BOX[nowi][nowj].value == 1 - nowcolor) { length[k]++; nowj -= dx[k]; nowi -= dy[k]; } } for (int k = 0; k < 4; k++) { if (length[k] >= 5) { // 如果滿五子 if (nowcolor == playercolor) { win = playercolor; // 玩家勝 } if (nowcolor == 1 - playercolor) { win = 1 - playercolor; // 電腦勝 } } } if ((!isinit) && findbestseat(playercolor).number == 0 && findbestseat(1 - playercolor).number == 0) { // 如果不是開局且雙方無最佳位置 win = 2; // 平局 } } } } } // 游戲主函數(shù) void game() { // 上一個鼠標停的坐標 int oldi = 0; int oldj = 0; // 隨機化玩家顏色 srand(time(NULL)); playercolor = rand() % 2; // 繪制背景 setfillcolor(RGB(255, 205, 150)); solidrectangle(40, 25, 645, 630); // 設置字體樣式 settextstyle(30, 15, 0, 0, 0, 1000, false, false, false); settextcolor(BLACK); // 輸出標示語 if (playercolor == 0) { outtextxy(150, 650, _T("玩家執(zhí)白后行,電腦執(zhí)黑先行")); whoplay = 1; } else { outtextxy(150, 650, _T("玩家執(zhí)黑先行,電腦執(zhí)白后行")); whoplay = 0; } draw(); // 繪制 while (1) { NEXTPLAYER: if (whoplay == 0) { // 玩家下棋 MOUSEMSG mouse = GetMouseMsg(); // 獲取鼠標信息 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { if (mouse.x > BOX[i][j].x && mouse.x BOX[i][j].y && mouse.y < BOX[i][j].y + 30//判斷y坐標 && BOX[i][j].value == -1)//判斷是否是空位置 { // 如果停在某一個空位置上面 if (mouse.mkLButton) { // 如果按下了 BOX[i][j].value = playercolor; // 下棋 BOX[i][j].isnew = true; // 新位置更新 oldi = -1; oldj = -1; // 下一個玩家 whoplay = 1; goto DRAW; } // 更新選擇框 BOX[oldi][oldj].isnew = false; BOX[oldi][oldj].draw(); BOX[i][j].isnew = true; BOX[i][j].draw(); oldi = i; oldj = j; } } } } else { // 電腦下棋 seat best; best = findbestseat(1 - playercolor); // 尋找最佳位置 if (best.number == 0) { // 開局情況 int drawi = 9; int drawj = 9; while (BOX[drawi][drawj].value != -1) { drawi--; drawj++; } BOX[drawi][drawj].value = 1 - playercolor; BOX[drawi][drawj].isnew = true; } else { BOX[best.i][best.j].value = 1 - playercolor;//下在最佳位置 BOX[best.i][best.j].isnew = true; } whoplay = 0; goto DRAW; // 輪到下一個 } } DRAW: // 繪制 isWIN(); // 檢測輸贏 draw(); if (win == -1) { // 如果沒有人勝利 Sleep(500); goto NEXTPLAYER; // 前往下一個玩家 } // 勝利處理 settextcolor(RGB(0, 255, 0)); Sleep(1000); if (win == 0) { outtextxy(320, 320, _T("白勝")); } if (win == 1) { outtextxy(320, 320, _T("黑勝")); } if (win == 2) { outtextxy(320, 320, _T("平局")); } // 給反應時間 Sleep(5000); return; }
大家趕緊去動手試試吧!
審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
游戲
+關注
關注
2文章
744瀏覽量
26326 -
C語言
+關注
關注
180文章
7605瀏覽量
137000 -
編程
+關注
關注
88文章
3619瀏覽量
93781 -
源碼
+關注
關注
8文章
643瀏覽量
29251 -
C++
+關注
關注
22文章
2110瀏覽量
73688
原文標題:【項目實戰(zhàn)】輕松實現(xiàn)C/C++大作業(yè):五子棋游戲!附帶源碼
文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
labview五子棋程序
本帖最后由 桂花酒 于 2012-6-10 13:43 編輯
labview五子棋程序,想用的可以看看!本來是發(fā)的求助帖,找五子棋程序,不過剛才下了一個,鑒于論壇上現(xiàn)在已經(jīng)搜不著了(我原來下過,不過刪了)一起學習!
發(fā)表于 06-10 13:16
C語言實現(xiàn)雙人對戰(zhàn)五子棋游戲
在編寫五子棋游戲前首先對整個項目進行分析:1、五子棋的界面繪制及顯示2、對輸入的數(shù)據(jù)進行寫入3、判斷輸入的數(shù)據(jù)多對應的位置上是否可以下棋其中包括檢測此位置是否為空及是否超出下棋的有效位
發(fā)表于 08-17 09:18
C語言五子棋程序分享!
先輸入棋盤規(guī)模,然后輸棋子的坐標,先輸入縱軸的,再輸入橫軸,悔棋算法用的是堆棧,記得當時剛開始學數(shù)據(jù)結構~很簡單的一個程序~五子棋.c (4.13 KB )
發(fā)表于 09-30 01:35
LabVIEW五子棋小游戲
使用LabVIEW2016版本實現(xiàn)的五子棋小游戲程序,游戲分為左右手互搏模式和隨機人機對戰(zhàn)模式,人機對戰(zhàn)只是實現(xiàn)了在玩家落子后電腦隨機落子的
發(fā)表于 10-13 13:30
基于LabVIEW的五子棋博弈算法
對棋局的局勢進行分析;同時為了提高下棋的效率,對棋型進行了分類,并對原有的博弈算法進行改進,采用進攻和防守兩個權值簡化決策過程。通過真實的對弈測試表明,基于LabVIEW的五予棋博弈算法能快速、準確地
發(fā)表于 12-17 11:32
?29次下載
評論