Minesweeper-Spiel in C-Sprache

Der Code wird in einem Projekt fertiggestellt und in drei .c.h-Dateien (game.c, game.h, main.c) aufgeteilt
und durch Ausführen in der Clion-Software debuggt.

/Allgemeine Idee/
Die Hauptfunktion main.c ist ein großer Rahmen (Menü, Minensuchboot). Board-Initialisierung, Zufallsfunktion generiert Minen, Spieler räumen Minen)
game.h-Funktionsdeklaration (einige Funktionsdeklarationen außer Hauptfunktion und Spielfunktion)
game.c-Funktion Implementierung (Implementierung einiger Funktionen außer Hauptfunktion und Spielfunktion)

/game.c实现/

① Initialisieren Sie zuerst das Minensuchbrett (verwenden Sie zwei Zeichenfelder mit der gleichen Größe wie das Minensuchbrett
1. Lagern Sie Minen 2. Zeigen Sie dem Spieler das Minensuchbrett an. Um Vermeiden Sie das Durchqueren. Es gibt einen Zugang außerhalb der Grenzen, die Brettgröße ist auf 11 eingestellt*11, Minen sind in der Größe 9 angeordnet*9, und der Spieler wird auch in der Größe 9< a i=4>9 angezeigt. Entspricht dem Ausblenden der ersten und letzten Zeile, der ersten und letzten Spalte.) 1 Das Schachbrett wird initialisiert auf 0 2 Das Schachbrett wird auf initialisiert*
*

②Zeigen Sie nach der Initialisierung des Schachbretts das Schachbrett an.
③Zufallsfunktion generiert Minen und speichert sie im ersten Zeichenarray
④Die Implementierung des Player-Minensuchboots umfasst: Player Enter ob die Koordinatenposition meine ist. Wenn die Koordinaten keine Minen sind, gibt es dann Minen im umgebenden Kreis? Wenn es sich bei den Koordinaten nicht um Minen handelt und keine Minen in der Nähe sind, wird eine Rekursion verwendet, um diese Koordinaten als leer anzuzeigen.

Im Folgenden sind einige Funktionsimplementierungen aufgeführt:

//Bestimmen Sie, wie viele Minen sich in der Nähe befinden (erhalten Sie die Informationen zur Minennummer an acht Positionen in einem Kreis mit Ausnahme der Eingabekoordinaten).
Für Zeichen ist ein bestimmtes Zeichen –' 0‘ ist eine Ganzzahl. Acht Koordinaten minus acht ‚0‘ sind die Anzahl der Minen in den acht Koordinaten)

//判断周围多少雷,返回雷数
int BombNumber(char mine[ROWS][COLS],int row,int col){
    
    

    return mine[row -1][col-1] + mine[row - 1][col] + mine[row - 1][col+1] + \
            mine[row][col-1] + mine[row][col+1] + \
            mine[row+1][col - 1] + mine[row+1][col] + mine[row+1][col+1] -8*'0';
}

Als die vom Spieler eingegebenen Koordinaten ursprünglich keine Minen waren und die acht umgebenden Koordinaten keine Minen waren, wollte ich ursprünglich die neun Koordinaten in der Funktion auflisten und sie vor der Anzeige leer speichern. Aber im Lernvideo wird erwähnt, dass Rekursion verwendet werden kann, um ein leeres Schachbrett darzustellen. Ich habe online nach dem Code anderer Leute gesucht und gelernt, wie man mithilfe der Rekursion ein Schachbrett rendert.

//假设是3*3的棋盘
	        show[row - 1][col - 1] = ' ';//第一行
            show[row - 1][col] = ' ';
            show[row - 1][col + 1] = ' ';
            show[row][col - 1] = ' ';//第二行
            show[row][col] = ' ';
            show[row][col + 1] = ' ';
            show[row + 1][col - 1] = ' ';//第三行
            show[row + 1][col] = ' ';
            show[row + 1][col + 1] = ' ';

Ein Schachbrett rekursiv präsentieren
//Die rekursive Idee in diesem Code ist 1. Die Koordinate ist keine Mine 2. Die acht umgebenden Koordinaten sind auch keine Mine
Durchlaufen Sie die vom Spieler eingegebenen Koordinaten neun Mal, um festzustellen, ob jede Koordinate legal ist, keine Minen enthält und dem Spieler nicht angezeigt wird.
Nachdem die Koordinaten die Bedingungen erfüllt haben, wird die Rufen Sie die Funktion auf, um festzustellen, ob sich in einem Kreis Minen befinden. Wenn in der Schleife kein Donner in einem Kreis mit einer bestimmten Koordinate vorhanden ist, wird die rekursive Funktion erneut eingegeben und dann die Koordinaten der Koordinate durchlaufen, um mit dem oben Gesagten fortzufahren Prozess. Wenn die Koordinaten die Bedingungen nicht erfüllen, wird die Rekursion beendet und die else-Anweisung wird eingegeben, bis die neun Schleifen abgeschlossen sind.

void BlankBoard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){
    
    
    int i=0,j=0,flag=0;
    show[row][col] = ' ';
    for(i=row-1;i<=row+1;i++) {
    
    
        for (j = col-1; j <=col+1; j++) {
    
    
            if((i>0&&i<=ROW)&&(j>0&&j<=COL)&&(mine[i][j]!='1')&&(show[i][j]=='*')) {
    
    
                flag = BombNumber(mine, i, j);//判断一圈是否是雷,返回的是雷的数量
                if(!flag)
                    BlankBoard(mine,show,i,j);//递归
                else
                    show[i][j]=flag+'0';//将得到的非0的雷数放到展示给玩家的棋盘里
            }
        }
    }
}

//Spieler führen Kernoperationen des Spiels aus

void StartBomb(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
    
    
    char array[5]="\0";//使用字符串接收玩家输入的信息
    int x,y,flag=0,win=0;

    while(win<(row*col-Bomb))
    //展示给玩家的坐标数量<整个棋盘的非雷坐标数就进入循环
    //直到玩家看到的非*坐标数量已经是所有非雷坐标
    {
    
    
        printf("玩家输入坐标,坐标形式为:x,y\n");
        gets(array);
        x=array[0]-'0';//字符-'0'为整数
        y=array[2]-'0';
        if((x>=1&&x<=ROW)&&(y>=1&&y<=COL)&&(show[x][y])=='*')//坐标合法且没有显示给玩家
        {
    
    
            if(mine[x][y]=='1')//在存储雷的棋盘中'1'代表是雷
            {
    
    
                printf("很遗憾,该坐标中放了雷,玩家被炸死");
                printf("雷分布如下:\n");
                Display(mine,ROW,COL);//显示存储雷的棋盘
                break;}
            else{
    
    
                flag=BombNumber(mine, x, y);//判断该坐标周围一圈是否是雷
                if(flag>0){
    
    //周围一圈有雷
                show[x][y]=flag+'0';
                Display(show,ROW,COL);}
                else{
    
    
                    BlankBoard(mine,show,x,y);
                    Display(show,ROW,COL);}
               winwin=Showboard(show,ROW,COL);}//判断展示给玩家的坐标数
        }
        else
            printf("坐标无效,请重新输入\n");
    }
    if(win==(row*col-Bomb)){
    
    
        printf("恭喜玩家排雷成功!\n");
        Display(mine,ROW,COL);
    }
}

//Das Folgende ist der vollständige Code (Ich habe noch nie ein normales Minesweeper-Spiel gespielt, daher ist mein Verständnis von Gewinnen und Verlieren in Minesweeper-Spielen möglicherweise nicht korrekt, aber die allgemeine Idee ist in Ordnung)

//Haupt c


#include"game.h"

//初版扫雷

// 显示菜单
void menu(){
    
    
    printf("*********1.game***0.退出*********\n");
    printf("*********输入数字进行选择***********\n");
}
//游戏核心
//使用两个字符数组1->存放雷信息 2->用于输出到屏幕
//使用随机函数放置雷
//玩家排雷

void game() {
    
    
    char Mine [ROWS][COLS]={
    
    0};
    char Show [ROWS][COLS]={
    
    0};;
    //数组初始化
    Init(Mine,ROWS,COLS,'0');
    Init(Show,ROWS,COLS,'*');
    //显示
    //Display(Mine,ROWS,COLS);//显示初始化的雷棋盘
    Display(Show,ROWS,COLS);//显示玩家棋盘
    SetBomb(Mine,ROW,COL);//随机生成雷
    //Display(Mine,ROW,COL);//显示雷棋盘
    StartBomb(Mine,Show,ROW,COL);//玩家进行扫雷
}

int main()
{
    
    
    setbuf(stdout,NULL);//及时输出缓冲区内容
    int number=0;
    srand((unsigned int )time(NULL));//时间戳帮助生成棋盘上的随机坐标

    do{
    
    
        menu();
        scanf("%d",&number);
        getchar();//玩家输入的坐标使用字符串输入的,所以此时需要用getchar取走\n
        switch(number)
        {
    
    
            case 1:
                game();
                break;
            case 0:
                printf("正在退出\n");
                break;
            default:
                printf("选择错误,重新输入\n");
                break;
        }
    }while(number);

}


//game.h

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

#define ROW 9
#define COL 9

#define ROWS (ROW+2)
#define COLS (COL+2)

#define Bomb 10

#ifndef TEXT1_GAME_H
#define TEXT1_GAME_H

void Init(char board[ROWS][COLS],int rows,int cols,char set);
void Display(char board[ROWS][COLS],int row,int col);
void SetBomb(char board[ROWS][COLS],int row,int col);
void StartBomb(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
int  BombNumber(char mine[ROWS][COLS],int row,int col);
void BlankBoard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
int Showboard(char board[ROWS][COLS],int row,int col);
#endif

//game.c

#include"game.h"

//初始化
void Init(char board[ROWS][COLS],int rows,int cols,char set){
    
    
    int i=0,j=0;
    for(i=0;i<ROWS;i++){
    
    
        for(j=0;j<COLS;j++)
            board[i][j]=set;
    }
}

//显示函数
void Display(char board[ROWS][COLS],int row,int col)
{
    
    
    int i=0,j=0;
    //打印列数
    for(i=0;i<=COL;i++)
        printf("%d|",i);
    printf("\n");
    for(i=1;i<=ROW;i++){
    
    
        printf("%d|",i);//打印行数
        for(j=1;j<=COL;j++)
            printf("%c ",board[i][j]);
        printf("\n");
    }
}

//放置炸弹
void SetBomb(char board[ROWS][COLS],int row,int col)
{
    
    

  int numberBomb=1;
  while(numberBomb<=Bomb)
  {
    
    
      int x=(rand()%ROW)+1;
      int y=(rand()%COL)+1;
          if(board[x][y]=='0') {
    
    
              board[x][y] = '1';
              numberBomb++;}
  }
}

void StartBomb(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
    
    
    char array[5]="\0";
    int x,y,flag=0,win=0;

    while(win<(row*col-Bomb))
    {
    
    
        printf("玩家输入坐标,坐标形式为:x,y\n");
        gets(array);
        x=array[0]-'0';
        y=array[2]-'0';
        if((x>=1&&x<=ROW)&&(y>=1&&y<=COL)&&(show[x][y])=='*')
        {
    
    
            if(mine[x][y]=='1')
            {
    
    
                printf("很遗憾,该坐标中放了雷,玩家被炸死");
                printf("雷分布如下:\n");
                Display(mine,ROW,COL);
                break;}
            else{
    
    
                flag=BombNumber(mine, x, y);
                if(flag>0){
    
    
                show[x][y]=flag+'0';
                Display(show,ROW,COL);
                }
                else{
    
    
                    BlankBoard(mine,show,x,y);
                    Display(show,ROW,COL);}
               }
            win=Showboard(show,ROW,COL);
        }
        else
            printf("坐标无效,请重新输入\n");
    }
    if(win==(row*col-Bomb)){
    
    
        printf("恭喜玩家排雷成功!\n");
        Display(mine,ROW,COL);
    }
}

//判断周围多少雷
int BombNumber(char mine[ROWS][COLS],int row,int col){
    
    

    return mine[row -1][col-1] + mine[row - 1][col] + mine[row - 1][col+1] + \
            mine[row][col-1] + mine[row][col+1] + \
            mine[row+1][col - 1] + mine[row+1][col] + mine[row+1][col+1] -8*'0';
}

//1.该坐标不是雷 2.周围的八个坐标也不是雷
void BlankBoard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){
    
    
    int i=0,j=0,flag=0;
    show[row][col] = ' ';
    for(i=row-1;i<=row+1;i++) {
    
    
        for (j = col-1; j <=col+1; j++) {
    
    
            if((i>0&&i<=ROW)&&(j>0&&j<=COL)&&(mine[i][j]!='1')&&(show[i][j]=='*')) {
    
    
                flag = BombNumber(mine, i, j);
                if(!flag)
                    BlankBoard(mine,show,i,j);
                else
                    show[i][j]=flag+'0';
/*          show[row - 1][col - 1] = ' ';
            show[row - 1][col] = ' ';
            show[row - 1][col + 1] = ' ';
            show[row][col - 1] = ' ';
            show[row][col] = ' ';
            show[row][col + 1] = ' ';
            show[row + 1][col - 1] = ' ';
            show[row + 1][col] = ' ';
            show[row + 1][col + 1] = ' ';*/

            }
        }
    }
}


int Showboard(char board[ROWS][COLS],int row,int col){
    
    
    int i=0,j=0,number=0;
    for(i=1;i<=row;i++){
    
    
        for(j=1;j<=col;j++){
    
    
            if(board[i][j]!='*')
                number++;
        }
    }
    return number;
}

Fügen Sie hier eine Bildbeschreibung ein

Supongo que te gusta

Origin blog.csdn.net/ainuliba/article/details/134866385
Recomendado
Clasificación