溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲

發(fā)布時(shí)間:2021-05-27 10:27:19 來(lái)源:億速云 閱讀:173 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲的具體代碼,供大家參考,具體內(nèi)容如下

效果圖如下:

C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲

設(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è)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI