今天分享一篇使用vs2010,配合easy-X圖形庫編寫的五子棋控制檯遊戲。
自帶遊戲資源。 且免費下載
下面是百度網盤下載連接:
鏈接:https://pan.baidu.com/s/1MMJKNDvNJy5UvT9mtM30xw
提取碼:4rvv
遊戲棋盤是15 * 15 的,應該符合很多大專院校的期末大作業!!!
具體過程就不詳細解釋了,等哪天心情好就把他完善一下,使用C++的面向對象在搞一遍。
代碼中關鍵地方也有註釋,自己去看!!!
代碼一共650行,其中很多地方都還可以去優化的,寫了很多重複的代碼,也寫了很多垃圾代碼。
不過遊戲界面基本完善,遊戲功能該有還是會有,比如 音樂, 悔棋等。
遊戲還有一個BUG,當棋盤下滿棋子也還沒有分出勝負,程序是不會做任何操作的,唯有點擊重新開始遊戲或者退出遊戲或者悔棋。我就懶得再加代碼了,其實很簡單的,有興趣的小夥也可以自行完善一下!
思路:再寫一個函數用於判斷數組是否存滿了(數組中已經沒有0值了),如果滿了,就顯示“棋盤已滿”的字體,然後等待用戶點擊開始遊戲或者退出遊戲即可。重新開始遊戲後記得回覆白棋先出,將悔棋記錄刪除掉,將數組全部值都賦值0.
或許還有其他的BUG是我沒有發現的,有興趣的也可以找一下!!!
另外代碼運行需要的文件可以點擊我的頭像去下載,免費的!
或者點這裏!
對了,代碼中有使用到vector容器作爲悔棋記錄,不懂的點這裏!
不說了,上代碼:
#include <iostream>
#include <Windows.h>
#include <graphics.h> // 圖形庫
#include <vector> // 動態數組,該地方用於悔棋
#include <mmsystem.h> // 背景音樂
// 加載 winmm.lid庫文件
#pragma comment(lib,"winmm.lib")
using namespace std;
#define GRAPHICS_X 880
#define GRAPHICS_Y 780
// 遊戲棋盤
#define PLATE_X 30 //////
#define PLATE_Y 50 ///// 棋盤的矩形的座標值
#define PLATE_XX 50*14+PLATE_X ////
#define PLATE_YY 50*15 ///
// 偏移量
#define OFFSET 50 // 每個棋盤空格相隔50像素
// 記錄悔棋的容器
typedef struct VECTOR {
vector<int> x;
vector<int> y;
};
// 悔棋標誌
VECTOR pullBack; // 記錄棋盤上一下好的棋子的座標,好用於悔棋
// 遊戲初始化界面
void initgraphGame(void) {
// 初始化圖像界面
initgraph(1080, 720);
// 將圖片應用於界面中
loadimage(0, _T("begin-1.jpg"));
// 設置字體顏色
settextcolor(RGB(255, 255, 255));
// 設置字體
settextstyle(35, 0, _T("微軟雅黑"));
// 設置字體的背景顏色爲透明
setbkmode(TRANSPARENT);
// 寫字
outtextxy(415, 60, _T("正在加載遊戲..."));
// 設置畫筆粗細
setlinestyle(PS_SOLID, 5);
// 畫一個空心矩形
rectangle(220, 195, 820, 305);
// 設置字體顏色
settextcolor(RGB(0, 0, 0));
// 設置字體
settextstyle(120, 0, _T("微軟雅黑"));
// 寫字
outtextxy(244, 190, _T("編程使我快樂"));
// 設置字體顏色
settextcolor(RGB(255, 200, 88));
// 寫字
outtextxy(110, 410, _T("歡迎進入五子棋遊戲"));
Sleep(3000);
closegraph();
}
// 遊戲背景音樂
void music(void) {
mciSendString("play Sunburst.mp3 repeat", 0, 0, 0);
}
// 背景音樂標識
bool gameMusicFlag = true;
// 遊戲背景音樂開關
void musicFlag(void) {
if (gameMusicFlag) {
gameMusicFlag = false;
mciSendString("pause Sunburst.mp3",NULL,0,NULL); // 暫停
//mciSendString("close Sunburst.mp3",NULL,0,NULL); // 停止
} else {
gameMusicFlag = true;
music();
}
}
// 棋盤繪製
void plate(void) {
// 設置畫筆粗細
setlinestyle(PS_SOLID, 2);
for (int i=0; i<13; i++) {
// 固定值加上一個偏移量
line(PLATE_X, PLATE_Y+(OFFSET*(i+1)), PLATE_XX, PLATE_Y+(OFFSET*(i+1))); // 行
line(PLATE_X+(OFFSET*(i+1)), PLATE_Y, PLATE_X+(OFFSET*(i+1)), PLATE_YY); // 縱
}
}
// 遊戲 開始 和 結束 和 悔棋 和 音樂開關 和 五子棋 繪製
void gameButton(void) {
// 設置畫筆粗細
setlinestyle(PS_SOLID, 2);
// 設置字體顏色
settextcolor(RGB(0, 0, 0));
// 設置字體
settextstyle(25, 0, _T("微軟雅黑"));
// 字體外的方框
rectangle(760, 175, 850, 225);
// 寫字
outtextxy(767, 185, _T("音樂開關"));
// 字體外的方框
rectangle(760, 250, 850, 300);
// 寫字
outtextxy(767, PLATE_Y*5+10, _T("開始遊戲"));
// 字體外的方框
rectangle(760, 450, 850, 500);
// 寫字
outtextxy(767, 460, _T("結束遊戲"));
// 字體外的方框
rectangle(760, 650, 850, 700);
// 寫字
outtextxy(785, 662, _T("悔棋"));
// 設置字體
settextstyle(30, 0, _T("微軟雅黑"));
// 五子棋
outtextxy(700/2, 10, _T("五子棋"));
}
// 開始遊戲提示
void gameHints(void) {
// 設置畫筆粗細
setlinestyle(PS_SOLID, 2);
// 設置字體顏色
settextcolor(RGB(0, 0, 0));
// 設置字體
settextstyle(28, 0, _T("微軟雅黑"));
// 字體外的方框
rectangle(760, 50, 850, 150);
// 寫字
outtextxy(775, 65, _T("請點擊"));
outtextxy(763, 100, _T("開始遊戲"));
}
// 清楚提示
void deleteHints(void) {
IMAGE image;
loadimage(&image, _T("cheng.jpg"));
putimage(758, 48, &image);
}
// 遊戲界面
void gameInterface(void) {
// 初始化圖像界面
initgraph(GRAPHICS_X, GRAPHICS_Y);
// 設置圖像的背景顏色
setbkcolor(RGB(255,200,88));
// 應用到圖像中
cleardevice();
// 設置畫筆顏色
setlinecolor(RGB(0,0,0));
// 設置畫筆粗細
setlinestyle(PS_SOLID, 3);
// 畫一個空心矩形
rectangle(PLATE_X, PLATE_Y, PLATE_XX, PLATE_YY);
// 畫棋板
plate();
// 遊戲按鈕
gameButton();
// 開始遊戲提示
gameHints();
}
// 遊戲選手
typedef struct PLAYER {
int white;
int black;
};
PLAYER player; // 用於左上角提示選手下棋
// frame of reference 座標
typedef struct FOR {
int x;
int y;
};
FOR fofr; // 用於更新數組
// 鼠標座標
typedef struct MOUSES {
int x;
int y;
};
MOUSES mouses; // 用於下棋
int Map[15][15] = { // int Map[15][15] = {0}; <== 可以寫成這樣
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
IMAGE imageBlack; // 黑棋圖片存儲變量
IMAGE imageWhite; // 白棋圖片存儲變量
// 遊戲選手顯示
void gamePlayerShow(void) {
// 設置畫筆粗細
setlinestyle(PS_SOLID, 2);
// 設置字體
settextstyle(30, 0, _T("微軟雅黑"));
// 字體外的方框
rectangle(750, 40, 860, 160);
// 清除提示
deleteHints();
if (player.white) {
// 設置字體顏色
settextcolor(RGB(255, 255, 255));
// 寫字
outtextxy(780, 52, _T("白方"));
outtextxy(780, 80, _T("下棋"));
// 預先加載圖片
loadimage(&imageWhite, _T("white.jpg"), 30, 30);
// 顯示棋子
putimage(790, 110, &imageWhite);
} else if (player.black) {
// 設置字體顏色
settextcolor(RGB(0, 0, 0));
// 寫字
outtextxy(780, 52, _T("黑方"));
outtextxy(780, 80, _T("下棋"));
// 預先加載圖片
loadimage(&imageBlack, _T("black.jpg"), 30, 30);
// 顯示棋子
putimage(790, 110, &imageBlack);
} else {
outtextxy(780, 52, _T("第三方"));
outtextxy(780, 80, _T("下棋"));
}
}
// 鼠標事件:點擊開始遊戲與退出遊戲
bool beginGame(void) {
MOUSEMSG mouse; // 鼠標變量
while (1) {
mouse = GetMouseMsg(); // 調用系統的函數
// 如果有鼠標左鍵點擊操作
if (mouse.uMsg == WM_LBUTTONDOWN) {
if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 250 && mouse.y < 300)) {
return true;
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 450 && mouse.y < 500)) {
return false;
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 175 && mouse.y < 225)) {
musicFlag(); // 音樂控制
continue;
}
}
Sleep(10); // 讓CPU休息一下下
}
}
// 重新開始遊戲
void newGame(void) {
// 重新開始遊戲
gameInterface(); // 初始化地圖
for (int i=0; i<15; i++) { // 地圖全部置爲零
for (int j=0; j<15; j++) {
Map[i][j] = 0;
}
}
// 重新開始遊戲,將悔棋標誌清空
pullBack.x.clear();
pullBack.y.capacity();
// 重新開始遊戲之後,恢復白棋先出
player.black = 0;
player.white = 1;
}
// 鼠標點擊操作
int ifbool(void) {
MOUSEMSG mouse; // 鼠標變量
while (1) {
mouse = GetMouseMsg(); // 調用系統的函數
// 如果有鼠標左鍵點擊操作
if (mouse.uMsg == WM_LBUTTONDOWN) { // 下棋操作
for (int i=0; i<15; i++) {
for (int j=0; j<15; j++) { // 判斷鼠標的座標是否在該區域
if ((mouse.x >= i*50+PLATE_X-15 && mouse.x <= i*50+PLATE_X+15) &&
(mouse.y >= j*50+PLATE_Y-15 && mouse.y <= j*50+PLATE_Y+15)) {
// 等於零,該區域沒有棋子
if (Map[i][j] == 0) {
fofr.x = i; // 用於更新數組
fofr.y = j;
mouses.x = i*50+PLATE_X; // 用於下棋
mouses.y = j*50+PLATE_Y;
pullBack.x.push_back(i); // 用於悔棋
pullBack.y.push_back(j);
return 1;
} else {
return 2;
}
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 250 && mouse.y < 300)) { // 重新開始遊戲
newGame(); // 重新開始遊戲函數
return 3;
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 650 && mouse.y < 700)) { // 悔棋操作
if (pullBack.x.size() > 0 && pullBack.y.size() > 0) { // 大於零,說明有棋子記錄,可以悔棋
int x = pullBack.x[pullBack.x.size()-1];
int y = pullBack.y[pullBack.y.size()-1];
// 刪除容器上的一個悔棋記錄
pullBack.x.pop_back();
pullBack.y.pop_back();
Map[x][y] = 0;
// 重新加載遊戲
gameInterface(); // 初始化地圖
for (int i=0; i<15; i++) { // 將地圖上的棋子擺回來
for (int j=0; j<15; j++) {
if (Map[i][j] == 1) {
loadimage(&imageWhite, _T("white.jpg"), 30, 30);
putimage(i*50+PLATE_X-15, j*50+PLATE_Y-15, &imageWhite);
} else if (Map[i][j] == 2) {
loadimage(&imageBlack, _T("black.jpg"), 30, 30);
putimage(i*50+PLATE_X-15, j*50+PLATE_Y-15, &imageBlack);
}
}
}
if (player.black == 1) {
player.black = 0;
player.white = 1;
} else {
player.black = 1;
player.white = 0;
}
return 4;
}
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 450 && mouse.y < 500)) { // 推出遊戲操作
// 結束程序
closegraph();
exit(1);
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 175 && mouse.y < 225)) {
musicFlag(); // 音樂控制
continue;
}
}
}
}
Sleep(10);
}
}
// 下棋
void playChess(void) {
if (player.black) { // 如果爲真
// 預先加載圖片
loadimage(&imageBlack, _T("black.jpg"), 30, 30);
// 將棋子下到棋板上面
putimage(mouses.x-15, mouses.y-15, &imageBlack);
player.black = 0; // 下棋順序標誌
player.white = 1; // 下棋順序標誌
Map[fofr.x][fofr.y] = 2; // 更新數組
} else {
// 預先加載圖片
loadimage(&imageWhite, _T("white.jpg"), 30, 30);
// 將棋子下到棋板上面
putimage(mouses.x-15, mouses.y-15, &imageWhite);
player.black = 1;
player.white = 0;
Map[fofr.x][fofr.y] = 1;
}
}
// 提示該處已有棋子
void hint(void) {
// 清除提示
deleteHints();
// 設置畫筆粗細
setlinestyle(PS_SOLID, 2);
// 設置字體顏色
settextcolor(RGB(0, 0, 0));
// 設置字體
settextstyle(25, 0, _T("微軟雅黑"));
// 字體外的方框
rectangle(760, 50, 850, 150);
// 寫字
outtextxy(788, 52, _T("此處"));
outtextxy(768, 80, _T("已有棋子"));
// 確認 字體外的方框
rectangle(765, 110, 845, 145);
// 設置字體
settextstyle(25, 0, _T("微軟雅黑"));
// 寫字
outtextxy(790, 115, _T("確認"));
MOUSEMSG mouse; // 鼠標變量
while (1) {
mouse = GetMouseMsg(); // 調用系統的函數
// 如果有鼠標左鍵點擊操作
if (mouse.uMsg == WM_LBUTTONDOWN) {
if ((mouse.x > 765 && mouse.x < 845) && (mouse.y > 90 && mouse.y < 145)) {
// 清除提示
deleteHints();
break;
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 250 && mouse.y < 300)) {
newGame(); // 重新開始遊戲函數
break;
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 450 && mouse.y < 500)) {
// 結束程序
closegraph();
exit(1);
} else if ((mouse.x > 760 && mouse.x < 850) && (mouse.y > 175 && mouse.y < 225)) {
musicFlag(); // 音樂控制
continue;
}
}
Sleep(10);
}
}
void playGames(void);
// 執行勝利界面
void Victory(int victory) {
Sleep(300);
//closegraph();
//initgraph(680, 417);
//IMAGE image;
//// 加載圖片
//loadimage(&image, _T("timg.jpg"));
//putimage(0, 0, &image);
settextstyle(77, 0, _T("微軟雅黑"));
// 設置字體的背景顏色爲透明
setbkmode(TRANSPARENT);
if (victory == 1) {
settextcolor(RGB(255, 255, 255));
outtextxy(180, 150, _T("恭喜白棋獲勝"));
} else if (victory == 2) {
settextcolor(RGB(0, 0, 0));
outtextxy(180, 150, _T("恭喜黑棋獲勝"));
} else {
outtextxy(200, 150, _T("參數有問題!"));
}
// 點擊開始遊戲
if (beginGame()) {
newGame(); // 重新加載遊戲
// 玩遊戲
playGames();
} else {
closegraph();
exit(1);
}
/*system("pause");
closegraph();
exit(1);*/
}
// 判斷是否下完了五個一樣的棋子
void ifVictory(void) {
for (int i=0; i<15; i++) {
for (int j=0; j<15; j++) {
// 核心算法,遊戲棋子判斷
if ((Map[i][j]==1 && Map[i-1][j-1]==1 && Map[i-2][j-2]==1 && Map[i-3][j-3]==1 && Map[i-4][j-4]==1) || // 左上角
(Map[i][j]==1 && Map[i+1][j-1]==1 && Map[i+2][j-2]==1 && Map[i+3][j-3]==1 && Map[i+4][j-4]==1) || // 右上角
(Map[i][j]==1 && Map[i-1][j+1]==1 && Map[i-2][j+2]==1 && Map[i-3][j+3]==1 && Map[i-4][j+4]==1) || // 左下角
(Map[i][j]==1 && Map[i+1][j+1]==1 && Map[i+2][j+2]==1 && Map[i+3][j+3]==1 && Map[i+4][j+4]==1) || // 右下角
(Map[i][j]==1 && Map[i][j-1]==1 && Map[i][j-2]==1 && Map[i][j-3]==1 && Map[i][j-4]==1) || // 上
(Map[i][j]==1 && Map[i][j+1]==1 && Map[i][j+2]==1 && Map[i][j+3]==1 && Map[i][j+4]==1) || // 下
(Map[i][j]==1 && Map[i-1][j]==1 && Map[i-2][j]==1 && Map[i-3][j]==1 && Map[i-4][j]==1) || // 左
(Map[i][j]==1 && Map[i+1][j]==1 && Map[i+2][j]==1 && Map[i+3][j]==1 && Map[i+4][j]==1)) { // 右
Victory(1); // 執行勝利代碼
} else if ((Map[i][j]==2 && Map[i-1][j-1]==2 && Map[i-2][j-2]==2 && Map[i-3][j-3]==2 && Map[i-4][j-4]==2) || // 左上角
(Map[i][j]==2 && Map[i+1][j-1]==2 && Map[i+2][j-2]==2 && Map[i+3][j-3]==2 && Map[i+4][j-4]==2) || // 右上角
(Map[i][j]==2 && Map[i-1][j+1]==2 && Map[i-2][j+2]==2 && Map[i-3][j+3]==2 && Map[i-4][j+4]==2) || // 左下角
(Map[i][j]==2 && Map[i+1][j+1]==2 && Map[i+2][j+2]==2 && Map[i+3][j+3]==2 && Map[i+4][j+4]==2) || // 右下角
(Map[i][j]==2 && Map[i][j-1]==2 && Map[i][j-2]==2 && Map[i][j-3]==2 && Map[i][j-4]==2) || // 上
(Map[i][j]==2 && Map[i][j+1]==2 && Map[i][j+2]==2 && Map[i][j+3]==2 && Map[i][j+4]==2) || // 下
(Map[i][j]==2 && Map[i-1][j]==2 && Map[i-2][j]==2 && Map[i-3][j]==2 && Map[i-4][j]==2) || // 左
(Map[i][j]==2 && Map[i+1][j]==2 && Map[i+2][j]==2 && Map[i+3][j]==2 && Map[i+4][j]==2)) { // 右
Victory(2); // 執行勝利代碼
}
}
}
}
// 玩遊戲
void playGames(void) {
while (1) {
gamePlayerShow(); // 選手下棋提示
int keyword = ifbool(); // 鼠標點擊棋盤
if (keyword == 1) {
playChess(); // 下棋
ifVictory(); // 判斷是否下完了五個一樣的棋子
} else if (keyword == 2) {
hint(); // 提示該處已有棋子
} else if (keyword == 3) {
// 已執行界面重新加載,清楚開始遊戲提示
deleteHints();
} else if (keyword == 4) {
// 已執行界面重新加載,清楚開始遊戲提示
deleteHints();
}
}
}
int main(void) {
// 白色爲1,白棋先出
player.black = 0;
player.white = 1;
// 加載遊戲
initgraphGame();
// 背景音樂
music();
// 遊戲界面
gameInterface();
// 開始遊戲
if (beginGame()) {
// 玩遊戲
playGames();
}
return 0;
}
最後附上游戲截圖: