首先,写一个头文件,方便之后的代码编写。
在这次编写中,我们将以游戏的最简单难度为设计目标——9*9的棋盘,10个雷。
于是,需要初始化两个数组,一个用于埋雷,一个供玩家游玩。
我们在头文件开头定义棋盘的大小和一些游戏的基本操作。
然后,把游戏的开始界面写出来。
运行一下,没有什么问题,继续。
关于游戏底层机制,玩电脑比较久的或多或少都知道一点儿,这里就不再赘述了。
我们直接进入写代码的环节。
游戏引导:
游戏底层代码,为方便后续维护,这一部分代码将体现在另外一个文件上:
初始化棋盘:
打印棋盘:
随机埋雷:
获取周围雷的个数:
展开:
排雷,游戏主体,最复杂的一部分:
最后的文件列表:
game.h 头文件
game.c 游戏主程序
main.c 引导器
本程序在编写时参考了部分公开网络资料。
附代码:
main.c
#include "game.h"
void TITLE()
{
printf("==============\nC Minesweeper\n==============\nEnter 1 to play, Enter 2 to exit.\n\n");
}
void CP_GAME()
{
char bomb[ROW_alt][COL_alt];
char show[ROW_alt][COL_alt];
CP_INIT(bomb, ROW_alt, COL_alt, '0');
CP_INIT(show, ROW_alt, COL_alt, '*');
CP_PRINT(show, ROW, COL);
CP_SETMINE(bomb, ROW, COL);
CP_FIND(bomb, show, ROW, COL);
}
int main(void)
{
int USER_INPUT = 0;
srand((unsigned int)time(NULL));
do {
TITLE();
printf("Enter your selection: ");
scanf_s("%d", &USER_INPUT);
switch (USER_INPUT) {
case 1:
printf("Launch 'C Minesweeper'\n");
CP_GAME();
break;
case 2:
printf("Exit program\n");
break;
default:
printf("You made wrong selection, please try again.\n");
break;
}
} while (USER_INPUT!=2);
return 0;
}
game.c
#include "game.h"
void CP_INIT(char CP_BOARD[ROW_alt][COL_alt], int ROW_USR_alt, int COL_USR_alt, char CP_VAR)
{
int CP_I = 0;
for (CP_I = 0; CP_I < ROW_USR_alt; CP_I++)
{
for (int CP_J = 0; CP_J < COL_USR_alt; CP_J++) {
CP_BOARD[CP_I][CP_J] = CP_VAR;
}
}
}
void CP_PRINT(char CP_BOARD[ROW_alt][COL_alt], int ROW_USR, int COL_USR)
{
printf("WELCOME TO PLAY 'C Minesweeper'!\n");
for (int CP_I = 0; CP_I <= COL_USR; CP_I++)
{
printf("%d ", CP_I);
}
printf("\n");
for (int CP_I = 1; CP_I <= ROW_USR; CP_I++)
{
printf("%d ", CP_I);
for (int CP_J = 1; CP_J <= COL_USR; CP_J++)
{
printf("%c ", CP_BOARD[CP_I][CP_J]);
}
printf("\n");
}
}
void CP_SETMINE(char CP_BOARD[ROW_alt][COL_alt], int ROW_USR, int COL_USR)
{
int CP_COUNT = CP_IS_COUNT;
while (CP_COUNT)
{
int x = rand() % ROW_USR + 1;
int y = rand() % COL_USR + 1;
if (CP_BOARD[x][y] == '0')
{
CP_BOARD[x][y] = '1';
CP_COUNT--;
}
}
}
int CP_GETMINE(char bomb[ROW_alt][COL_alt], int x, int y)
{
return (bomb[x - 1][y] + bomb[x - 1][y - 1] + bomb[x][y - 1] + bomb[x + 1][y - 1] + bomb[x + 1][y] + bomb[x + 1][y + 1] + bomb[x][y + 1] + bomb[x - 1][y + 1] - 8 * '0');
}
void OpenUp(char bomb[ROW_alt][COL_alt], char show[ROW_alt][COL_alt], int ROW_USR, int COL_USR, int x, int y, int* pw)
{
if (x >= 1 && x <= ROW_USR && y >= 1 && y <= COL_USR)
{
int sum = CP_GETMINE(bomb, x, y);
if (sum == 0)
{
(*pw)++;
show[x][y] = ' ';
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (show[i][j] == '*')
OpenUp(bomb, show, ROW_USR, COL_USR, i, j, pw);
}
}
}
else
{
(*pw)++;
show[x][y] = sum + '0';
}
}
}
void CP_FIND(char bomb[ROW_alt][COL_alt], char show[ROW_alt][COL_alt], int ROW_USR, int COL_USR)
{
int x = 0;
int y = 0;
int win = 0;
int* pw = &win;
while (win < ROW_USR * COL_USR - CP_IS_COUNT)
{
printf("Enter position where you want to check:");
scanf_s("%d %d", &x, &y);
if (x >= 1 && x <= ROW_USR && y >= 1 && y <= COL_USR)
{
if (bomb[x][y] == '1')
{
printf("Sorry, you lose.\n");
CP_PRINT(bomb, ROW, COL);
break;
}
else
{
if (show[x][y] != '*')
{
printf("Repetitive! Please select again.\n");
continue;
}
else
{
OpenUp(bomb, show, ROW_USR, COL_USR, x, y, pw);
system("cls");
CP_PRINT(show, ROW, COL);
}
}
}
else
{
printf("Illegal! Please select again.\n");
}
}
if (win == ROW_USR * COL_USR - CP_IS_COUNT)
{
printf("Congrats\n");
CP_PRINT(bomb, ROW, COL);
}
}
game.h
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#define CP_IS_COUNT 10
#define ROW 9
#define COL 9
#define ROW_alt ROW+2
#define COL_alt COL+2
void CP_INIT(char CP_BOARD[ROW_alt][COL_alt], int ROW_USR_alt, int COL_USR_alt, char CP_VAR);
void CP_PRINT(char CP_BOARD[ROW_alt][COL_alt], int ROW_USR, int COL_USR);
void CP_SETMINE(char CP_BOARD[ROW_alt][COL_alt], int ROW_USR, int COL_USR);
void CP_FIND(char bomb[ROW_alt][COL_alt], char show[ROW_alt][COL_alt], int ROW_USR, int COL_USR);
注意:请以“.c”作为源代码文件扩展名,不要用“.cpp”,不然会报错。
演示:
4月20日