您好,登錄后才能下訂單哦!
這篇文章主要介紹C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲的具體代碼,供大家參考,具體內(nèi)容如下
效果圖如下:
設(shè)計(jì)思路:
棋盤(pán)設(shè)計(jì)為15×15格,初始狀態(tài)光標(biāo)在棋盤(pán)的中央,白棋先走,輪流落子,當(dāng)一方連成五子或下滿棋盤(pán)時(shí),游戲結(jié)束(連成五子的一方獲勝,下滿棋盤(pán)為和棋)。當(dāng)游戲一方勝利后顯示勝利信息,提示信息利用漢字點(diǎn)陣輸出。
程序游戲是一個(gè)二維平面圖,可用二維數(shù)組來(lái)實(shí)現(xiàn),數(shù)組兩個(gè)下標(biāo)可以表示棋盤(pán)上的位置,數(shù)組元素的值代表棋格上的狀態(tài),共有三種情況,分別是0代表空格,1代表白棋,2代表黑棋。程序的主要工作是接收棋手按鍵操作,棋手1用設(shè)定四個(gè)鍵控制光標(biāo)移動(dòng),回車鍵表示落子。棋手2用另四個(gè)鍵控制光標(biāo)移動(dòng),空格鍵表示落子。接收到回車鍵或空格鍵,說(shuō)明棋手落子,先判斷是否是有效位置,即有棋子的位置不能重疊落子。落子成功后,馬上判斷以該位置為中心的八個(gè)方向:上、下、左、右、左上、左下、右上、右下是否有相同顏色的棋子連成五子,如果連成五子,則游戲結(jié)束。
#include<stdio.h> #include<stdlib.h> #include<windows.h> #pragma comment(lib, "WINMM.LIB") #include <mmsystem.h> #include<conio.h> #include<time.h> #define width 32 //棋盤(pán)總寬度 #define high 31 //棋盤(pán)總高度 #define MAX_X 15 //棋盤(pán)橫向格子數(shù) #define MAX_Y 15 //棋盤(pán)縱向格子數(shù) #define WIDTH (16+width) //游戲總高度 #define HIGH (high+4) //游戲總高度 #define player1 1 //白子玩家 #define player2 2 //黑子玩家 #define emptyPlayer 0//無(wú)子 #define Unplayer -2 //中途退出游戲,無(wú)玩家獲勝 typedef struct Stack{ //記錄下每次落子的坐標(biāo) int x[MAX_X*MAX_Y]; int y[MAX_X*MAX_Y]; //相當(dāng)于棧頂指針 int top; }Stack; int pos[MAX_X][MAX_Y];//存儲(chǔ)棋盤(pán)上各位置處的狀態(tài) 比如有白子為1, 有黑子為2,無(wú)子為0 int px,py; //光標(biāo)位置 int player = 1;//記錄當(dāng)前玩家 默認(rèn)玩家從白方開(kāi)始 int flag1 = 0;//標(biāo)志游戲開(kāi)始 int gameOver_player = -1;//判斷結(jié)束的標(biāo)志 int pre_px = -1, pre_py = -1;//記錄下上一次的坐標(biāo)位置 void gotoxy(int x,int y);//設(shè)置CMD窗口光標(biāo)位置 void hide_cursor(); //隱藏CMD窗口光標(biāo) void map();//打印地圖 void game_Description();//打印動(dòng)態(tài)游戲說(shuō)明 void initMapState();//初始化游戲位置數(shù)據(jù) void mapState(int qizi);//數(shù)組記錄下對(duì)應(yīng)位置的狀態(tài) int isGoPlay();//判斷是否可以落子 int hasGoPlay(int Player);//以落子處為中心,判斷已經(jīng)落子后的棋盤(pán)是否五子相連 void goPlay(int Player, Stack* p);//落子 Player 1 2 0 void yiDongKuang();//移動(dòng)框 void player1_move();//玩家1_移動(dòng) void player2_move();//玩家2_移動(dòng) int gameOver();//判斷游戲是否結(jié)束 Stack* createStack();//創(chuàng)建空棧 void push(Stack* p, int x, int y);//入棧 void color(const unsigned short textColor);//自定義函根據(jù)參數(shù)改變顏色 //void setColor(unsigned short backColor);//設(shè)置游戲背景顏色 void gotoxy(int x,int y)//設(shè)置CMD窗口光標(biāo)位置 { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void hide_cursor() //隱藏CMD窗口光標(biāo) { CONSOLE_CURSOR_INFO cci; cci.bVisible = FALSE; cci.dwSize = sizeof(cci); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorInfo(handle, &cci); } void color(const unsigned short textColor) //自定義函根據(jù)參數(shù)改變顏色 { if(textColor>0 && textColor<=15) //參數(shù)在0-15的范圍顏色 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), textColor); //用一個(gè)參數(shù),改變字體顏色 else //默認(rèn)的字體顏色是白色 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); } //打印地圖 void map() { int x, y; color(02); /*開(kāi)始打印棋盤(pán)格子*/ //打印橫向圖格 for(y = 2; y < high - 1; y+=2){ for(x = 1; x < width - 2; x+=2){ gotoxy(x , y); printf("-+"); } } //打印豎向圖格 for(y = 1; y < high; y += 2) { for(x = 2; x < width-2; x += 2){ gotoxy(x , y); printf("|"); } } /*打印棋盤(pán)格子結(jié)束*/ /*開(kāi)始打印圖框*/ //打印棋盤(pán)圖框 for (y = 0; y < high; y++) { for (x = 0; x < width; x+=2) { if (x == 0 || x == width - 2){ gotoxy(x, y); printf("|"); } if(y == 0 || y == high - 1 ){ gotoxy(x, y); printf("--"); } } } //打印右圖框 for(y = 0; y < high; y++){ for(x = width; x < WIDTH; x+=2){ if (x == WIDTH - 2){ gotoxy(x, y); printf("|"); } if(y == 0 || y == high - 1 ){ gotoxy(x, y); printf("--"); } } } //打印下圖框 y->high ~ HiGH-1 x->0 ~ WIDTH-2 for(y = high; y < HIGH; y++){ for(x = 0; x < WIDTH; x+=2){ if (x == 0 || x == WIDTH - 2){ gotoxy(x, y); printf("|"); } if(y == high || y == HIGH - 1 ){ gotoxy(x, y); printf("--"); } } } //打印下圖框內(nèi)容 gotoxy( 1, high+1); printf(" 歡迎來(lái)到五子棋游戲!"); //打印右圖框內(nèi)容 gotoxy( width-1, 1); printf("游戲說(shuō)明:"); gotoxy( width-1, 3); printf("1)X表示玩家一棋"); gotoxy( width-1, 4); printf("子,而O表示玩家"); gotoxy( width-1, 5); printf("二棋子"); gotoxy( width-1, 7); printf("2)X先、O后,交替"); gotoxy( width-1, 8); printf("下子,每次只能下"); gotoxy( width-1, 9); printf("一子"); gotoxy( width-1, 11); printf("3)棋子下在棋盤(pán)"); gotoxy( width-1, 12); printf("的格子內(nèi),棋子下"); gotoxy( width-1, 13); printf("定后,不得向其它"); gotoxy( width-1, 14); printf("點(diǎn)移動(dòng)"); gotoxy( width-1, 16); printf("4)最先連成五子"); gotoxy( width-1, 17); printf("的一方即為獲勝"); gotoxy( width-1, 19); printf("玩家一 移動(dòng)鍵:"); gotoxy( width-1, 20); printf("w上 s下 a左 d右"); gotoxy( width-1, 21); printf("下子: 空格鍵"); gotoxy( width-1, 23); printf("玩家二 移動(dòng)鍵:"); gotoxy( width-1, 24); printf("i上 k下 j左 l右"); gotoxy( width-1, 25); printf("下子:回車鍵"); gotoxy( width+1, 27); color(4); printf("退出鍵: Y"); gotoxy( width+1, 29); color(6); printf("悔棋鍵: G"); /*打印圖框結(jié)束*/ color(02); /*打印棋盤(pán)上的四個(gè)標(biāo)記點(diǎn)*/ gotoxy( 3*2+2 , 3*2+2); printf("*"); gotoxy( (MAX_X-4)*2 , 3*2+2); printf("*"); gotoxy( 3*2+2 , (MAX_Y-4)*2); printf("*"); gotoxy( (MAX_X-4)*2 , (MAX_Y-4)*2); printf("*"); /*打印結(jié)束*/ /*開(kāi)始修邊*/ /*gotoxy(width - 1, 0); printf(" "); gotoxy(width - 1, high - 1); printf(" ");*/ /*修邊結(jié)束*/ /*打印地圖完成*/ } //打印動(dòng)態(tài)游戲說(shuō)明 void game_Description() { //打印下圖框內(nèi)容 gotoxy( 1, high+1); printf(" "); if(player == player1){ gotoxy( 1, high+1); color(2); printf(" 玩家一下棋中..."); }else if(player == player2){ gotoxy( 1, high+1); color(2); printf(" 玩家二下棋中..."); } } //初始化游戲位置數(shù)據(jù) void initMapState() { for(int i = 0 ; i < MAX_Y; i++){ for(int j = 0; j < MAX_X; j++){ pos[i][j] = 0;//初始狀態(tài)全為空 } } //注意 光標(biāo)的位置和存儲(chǔ)在數(shù)組中的位置是不同的 px = 7; py = 7; gotoxy(py*2+1,px*2+1);//初始位置 } //數(shù)組記錄下對(duì)應(yīng)位置的狀態(tài) void mapState(int qizi) { //2*px+1 = x //2*py+1 = y //px->0~14 //py->0~14 if(px >= MAX_X || px < 0 || py >= MAX_Y || py < 0) return;//其他情況不可以記錄狀態(tài) pos[px][py] = qizi; } //判斷是否可以落子 int isGoPlay() { if(px >= MAX_X || px < 0 || py >= MAX_Y || py < 0) return 0;//其他情況不可以記錄狀態(tài) if(pos[px][py] == emptyPlayer){//說(shuō)明無(wú)子 return 1; }else{//說(shuō)明有子 return 0; } } //以落子處為中心,判斷已經(jīng)落子后的棋盤(pán)是否五子相連 int hasGoPlay(int Player) { //分為兩部分,先記錄一部分的相同Player的個(gè)數(shù) //再記錄下另余部分的個(gè)數(shù),相加為相連棋子總個(gè)數(shù) int port1 = 0, port2 = 0; int x, y, count; //上下查找 x = px, y = py-1; while(pos[x][y]==Player && y >= 0){ ++port1;//上部分個(gè)數(shù) --y;//上移 } y = py+1; while(pos[x][y]==Player && y < MAX_Y){ ++port2;//下部分個(gè)數(shù) ++y;//下移 } //計(jì)算總數(shù) count = port1 + port2 + 1; if(count >= 5) return 1; //左右查找 port1 = 0, port2 = 0; x = px-1, y = py; while(pos[x][y]==Player && x >= 0){ ++port1;//上部分個(gè)數(shù) --x;//左移 } x = px+1; while(pos[x][y]==Player && x < MAX_X){ ++port2;//下部分個(gè)數(shù) ++x;//右移 } //計(jì)算總數(shù) count = port1 + port2 + 1; if(count >= 5) return 1; //左上右下查找 port1 = 0, port2 = 0; x = px-1, y = py-1; while(pos[x][y]==Player && x >= 0 && y >= 0){ ++port1;//上部分個(gè)數(shù) --x;//左移 --y;//上移 } x = px+1, y = py+1; while(pos[x][y]==Player && x < MAX_X && y < MAX_Y){ ++port2;//下部分個(gè)數(shù) ++x;//右移 ++y;//下移 } //計(jì)算總數(shù) count = port1 + port2 + 1; if(count >= 5) return 1; //右上左下查找 port1 = 0, port2 = 0; x = px+1, y = py-1; while(pos[x][y]==Player && x < MAX_X && y >= 0){ ++port1;//上部分個(gè)數(shù) ++x;//左移 --y;//上移 } x = px-1, y = py+1; while(pos[x][y]==Player && x >= 0 && y < MAX_Y){ ++port2;//下部分個(gè)數(shù) --x;//右移 ++y;//下移 } //計(jì)算總數(shù) count = port1 + port2 + 1; if(count >= 5) return 1; return 0; } //落子 Player 1 2 0 void goPlay(int Player, Stack* p) { if(isGoPlay()){//說(shuō)明可以落子 mapState(Player);//將對(duì)應(yīng)位置的情況記錄在數(shù)組中 if(hasGoPlay(Player)){//如果五子相連,則 gameover gameOver_player = Player; //記錄此刻勝利玩家,結(jié)束游戲 } /*入棧*/ push(p, px, py); /*角色切換*/ if(Player == player1){ player = player2;//切換成玩家1 gotoxy(px*2+1, py*2+1 );//將光標(biāo)移動(dòng)到對(duì)應(yīng)位置 color(07); printf("X");//打印玩家1 game_Description();// 動(dòng)態(tài)說(shuō)明 }else if(Player == player2){ player = player1;//切換成另一個(gè)玩家2 gotoxy( px*2+1, py*2+1);//將光標(biāo)移動(dòng)到對(duì)應(yīng)位置 color(07); printf("O");//打印玩家2 game_Description();// 動(dòng)態(tài)說(shuō)明 } } } //入棧 void push(Stack* p, int x, int y) { //將此刻的坐標(biāo)入棧 int top = p->top; ++p->top;//移動(dòng)棧針 p->x[top] = x; p->y[top] = y; return; } //出棧 void pop(Stack* p) { int x, y; //出棧,移動(dòng)棧頂指針 //如果棧為空,則不彈出 if(p->top <= 0) return; --p->top; int top = p->top; //記錄下彈出的位置 x = p->x[top]; y = p->y[top]; //在彈出位置打印空格 gotoxy(x*2+1, y*2+1); printf(" "); //抹除記錄 pos[x][y] = 0; } //移動(dòng)框 void yiDongKuang() { //打印移動(dòng)框 gotoxy(px*2, py*2+1); color(11); printf("["); gotoxy(px*2+2, py*2+1); printf("]"); //打印移動(dòng)框結(jié)束 if(pre_px != -1 && pre_py != -1){ if(pre_px > px && pre_py == py){//當(dāng)向左移動(dòng)時(shí) //將上一個(gè)位置的右邊保持原樣 gotoxy(pre_px*2+2, pre_py*2+1); color(2); printf("|"); }else if(pre_px < px && pre_py == py){//當(dāng)向右移動(dòng)時(shí) //將上一個(gè)位置的左邊保持原樣 gotoxy(pre_px*2, pre_py*2+1); color(2); printf("|"); }else{//當(dāng)向上下移動(dòng)時(shí) //將上一個(gè)位置的左右邊保持原樣 gotoxy(pre_px*2+2, pre_py*2+1); color(2); printf("|"); gotoxy(pre_px*2, pre_py*2+1); color(2); printf("|"); } } pre_px = px; pre_py = py; } //玩家1 移動(dòng) void player1_move(Stack* p) { char key; if (_kbhit())//檢測(cè)是否按鍵 { fflush(stdin); key = _getch();//保存按鍵 game_Description();//動(dòng)態(tài)說(shuō)明 } switch(key) { case 'w': py--;yiDongKuang();break;//上 case 'a': px--;yiDongKuang();break;//左 case 'd': px++;yiDongKuang();break;//右 case 's': py++;yiDongKuang();break;//下 case ' ': goPlay(player1, p);break;//落子 case 'y': gameOver_player = -2; gameOver();//退出游戲 case 'Y': gameOver_player = -2; gameOver();//退出游戲 case 'g': pop(p); pop(p); break;//悔棋 case 'G': pop(p); pop(p); break;//悔棋 default: break; } //限制光標(biāo)范圍 if(py < 0) py = MAX_Y-1; else if(py >= MAX_Y) py = 0; else if(px < 0) px = MAX_X-1; else if(px >= MAX_X) px = 0; gotoxy(2*py+1, 2*px+1); } //玩家2 移動(dòng) void player2_move(Stack* p) { char key; if (_kbhit())//檢測(cè)是否按鍵 { fflush(stdin); key = _getch();//保存按鍵 game_Description();//動(dòng)態(tài)說(shuō)明 } switch(key) { case 'i': py--;yiDongKuang();break;//上 case 'j': px--;yiDongKuang();break;//左 case 'l': px++;yiDongKuang();break;//右 case 'k': py++;yiDongKuang();break;//下 case '\r': goPlay(player2, p);break;//落子 case 'y': gameOver_player = -2; gameOver();//退出游戲 case 'Y': gameOver_player = -2; gameOver();//退出游戲 case 'g': pop(p); pop(p); break;//悔棋 case 'G': pop(p); pop(p); break;//悔棋 default: break; } //限制光標(biāo)范圍 if(py < 0) py = MAX_Y-1; else if(py >= MAX_Y) py = 0; else if(px < 0) px = MAX_X-1; else if(px >= MAX_X) px = 0; gotoxy(2*px+1, 2*py+1); } //創(chuàng)建空棧 Stack* createStack(){ //申請(qǐng)空間 Stack* p = (Stack* )malloc(sizeof(Stack)); //如果未申請(qǐng)到空間 if(p==NULL) return NULL; p->top = 0;//初始化棧頂 return p; } //判斷游戲是否結(jié)束 int gameOver() { //gamerOver_player -1 表示繼續(xù)游戲 1 表示白方勝利 2 表示黑方勝利 0 表示平局 //五子相連 一方取勝 y->high ~ HiGH-1 x->0 ~ WIDTH-2 if(gameOver_player == -1){ return 1; }else if(gameOver_player == player1){//白方勝利 gotoxy( 1, high+1); printf("玩家1勝利?。?!"); return 0; }else if(gameOver_player == player2){//黑方勝利 gotoxy( 1, high+1); printf("玩家2勝利!??!"); return 0; }else if(gameOver_player == emptyPlayer){//棋盤(pán)滿棋 平局 gotoxy( 1, high+1); printf("平局!!!"); return 0; }else if(gameOver_player == Unplayer){//中途退出 gotoxy( 1, high+1); printf("正在退出游戲中..."); exit(1); } return 1; } int main(){ //調(diào)整游戲框 system("mode con cols=48 lines=35"); //打印地圖 map(); //初始化游戲位置數(shù)據(jù) initMapState(); //創(chuàng)建空棧 Stack* p = createStack(); //隱藏光標(biāo) hide_cursor(); //游戲循環(huán) 控制移動(dòng) while(gameOver()){ //不斷調(diào)換人物 if(player == player1) player1_move(p);// 切換玩家1 else if(player == player2) player2_move(p);// 切換玩家2 } free(p); }
以上是“C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。