课后作业
作业要求:制作一个扫雷游戏
扫雷程序流程图
头文件game.h
主要包含了基本库函数,宏定义和函数声明
#ifndef __GAME_H__
#define __GAME_H__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LINE 5
#define ROW 5
void IntialBoard(char board[LINE][ROW], int line, int row);//初始化区数组
void IntialMine(char board[LINE][ROW], int line, int row);//设置雷数组
void DisplayBoard(char board[LINE][ROW], int line, int row);//打印区数组
void PlayerClick(char board[LINE][ROW], int line, int row);//判断玩家点击
int ClickResult(char topboard[LINE][ROW], char bottomboard[LINE][ROW], int line, int row);//判断选中遮挡区格子所对应的雷区格子是什么
#endif __GAME_H__
游戏相关源文件game.c
主要包含了头文件中声明函数的定义部分
#include "game.h"
void IntialBoard(char board[LINE][ROW], int line, int row)
{
int i = 0;
int j = 0;
for(i=0; i<line; i++)
{
for(j=0; j<row; j++)
{
board[i][j] = ' ';//遍历遮挡区数组每一个元素,赋值' '
}
}
}
void IntialMine(char board[LINE][ROW], int line, int row)
{
int i = 0;
int x = 0;
int y = 0;
srand((unsigned int)time(NULL));//设置随机种子
for(i=0; i<line; )//随机设置line个雷
{
x = rand()%line;
y = rand()%row;
if(board[x][y] != '*')
{
board[x][y] = '*';
i++;
}
}
}
void DisplayBoard(char board[LINE][ROW], int line, int row)
{
int i = 0;
int j = 0;
int tmp = 0;
for(i=0; i<line; i++)//打印line行区数组
{
if(i == 0)
{
printf(" ");
for(j=0; j<row; j++)
printf("%d ",j+1);
printf("\n");
}
for(j=0; j<row; j++)//打印row列区数组
{
if(j == 0)
printf(" %d ",i+1);
printf(" %c ",board[i][j]);
if(j < row-1)
printf("|");
}
printf("\n ");//打印完区行数据,换行打印分割行
if(i < line-1)
{
for(j=0; j<row; j++)//打印row列下方分割行
{
printf("---");
if(j < row-1)
printf("|");
}
}
printf("\n");//打印完分割行,换行打印棋盘
}
}
void PlayerClick(char board[LINE][ROW], int line, int row)
{
int x = 0;
int y = 0;
do
{
printf("* 玩家回合 *\n");
printf("* 请输入座标(例如1 1): *\n");
scanf("%d %d", &x, &y);
if(x>=1 && x<=line && y>=1 && y<=row)//判断座标合法性
{
if(board[x-1][y-1] == ' ')//判断座标处格子是否被挖掘
{
board[x-1][y-1] = '?';
break;
}
else
printf("* 此座标已被挖掘 *\n");
}
else
printf("* 座标非法 *\n");
}while(1);
}
char CountMine(char board[LINE][ROW],int x,int y,int line, int row)
{
int count = 0;
int i = 0;
int j = 0;
for(i=x-1;i<=x+1 ;i++)//判断xy对应座标周围九个格子的雷数
{
if(i>=0 && i<=line -1)//判断x座标合法性
{
for(j=y-1; j<=y+1; j++)
{
if(j>=0 && j<=row -1)//判断y座标合法性
if('*' == board[i][j])
count++;
}
}
}
return 48 + count;//返回0的ascii码值加上雷数,也就是对应雷数的ascii码值
}
int IsWin(char board[LINE][ROW], int line, int row)
{
int i = 0;
int j = 0;
for(i=0; i<line; i++)
{
for(j=0; j<row; j++)
{
if(' ' == board[i][j])//还有空位说明雷未排完
return 0;
}
}
return 1;
}
int ClickResult(char topboard[LINE][ROW], char bottomboard[LINE][ROW], int line, int row)
{
int x = 0;
int y = 0;
int find = 0;
findxy:
if(find==0)
{
for(x=0; x<line; x++)
{
for(y=0; y<row; y++)
{
if('?' == topboard[x][y])
{
find = 1;
goto findxy;//找到玩家选择的座标
}
}
}
}
if(bottomboard[x][y] == '*')//如果该座标是雷,打印遮挡区数组,返回-1
{
topboard[x][y] = '*';
DisplayBoard(bottomboard, LINE, ROW);
return -1;
}
else//如果该座标不是雷,计算它周围的雷数并返回给两个区数组
topboard[x][y] = bottomboard[x][y] = CountMine(bottomboard, x, y, line, row);
DisplayBoard(topboard, LINE, ROW);
}
if(1 == IsWin(bottomboard, line, row))//判断是否胜出
return -2;
}
游戏主体源文件test.c
包含了主函数和基本游戏思路
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Introduction()
{
printf("................................................\n");
printf(".. 本游戏名为扫雷,在5*5的雷区随机埋藏了5颗雷..\n");
printf("..,玩家需要通过选择格子排雷,格子中的内容可能..\n");
printf("..是地雷也可能是提示(该格子周围雷数),如果选..\n");
printf("..到地雷游戏结束,选择到提示,玩家根据提示继续..\n");
printf("..游戏,直至排除所有地雷 ..\n");
printf("................................................\n");
}
int GameContinue()
{
int choose = 0;
printf("是否要继续游戏? (是1/否0)");
scanf("%d",&choose);
system("CLS");
if(1 == choose)
return 1;
else
return 3;
}
int Game()
{
char bottomboard[LINE][ROW];//定义雷区数组
char topboard[LINE][ROW];//定义遮挡区数组
int choose = 1;
int click_relsut = 0;
IntialBoard(topboard, LINE, ROW);//初始化遮挡区数组
IntialBoard(bottomboard, LINE, ROW);//初始化雷区数组
IntialMine(bottomboard, LINE, ROW);//设置雷区数组
DisplayBoard(topboard, LINE, ROW);//打印遮挡区
do
{
click_relsut = 0;
PlayerClick(topboard, LINE, ROW);//玩家进行点击
// DisplayBoard(board, LINE, ROW);//打印遮挡区
system("CLS");
click_relsut = ClickResult(topboard, bottomboard, LINE, ROW);//点击结果
if(-1 == click_relsut)//游戏结束
{
printf("踩到雷了!!!\n");
}
else if(-2 == click_relsut)//排雷成功
{
printf("排雷成功!!!\n");
}
}while(0 <= click_relsut);
return GameContinue();
}
int Menu()//菜单函数,进行选择
{
int choose = 0;
do
{
printf("................................................\n");
printf(".MMM.....MMMM...................................\n");
printf("......................MMMMMMMMMMMMM.............\n");
printf("M..MMMMMMMMMM......MMMMM.........MMMMM..........\n");
printf("..........MMMMM.MMMMM..............MMMMMM.......\n");
printf("...MMMM.....MMMMM.......扫雷.v1.0......MMMMM....\n");
printf("...........MMMMM.........................MMMM...\n");
printf("..........MMM.MMMMMMMM..1.菜单.............MMMM.\n");
printf(".........MMM....MMMMMMM.....................MMM.\n");
printf("........MMM.............2.说明...............MMM\n");
printf("........MMM..................................MMM\n");
printf("........MMM.............3.退出...............MMM\n");
printf(".........MMM................................MMM.\n");
printf("..........MMM..............................MMMM.\n");
printf("..........MMMM.......请输入您的选择.......MMMM..\n");
printf("............MMMMM.......................MMMM....\n");
printf("..............MMMMM..................MMMMM......\n");
printf("..................MMMMM...........MMMMM.........\n");
printf("......................MMMMMMMMMMMMM.............\n");
printf("................................................\n");
scanf("%d",&choose);
system("CLS");
switch(choose)//根据choose的值,进入各项功能
{
case 1: choose = Game();//进入游戏函数
break;
case 2: Introduction();//进入游戏说明
break;
case 3: //退出游戏
{
printf("........................退出游戏................\n");
return 0;
}
default:printf("........................输入错误................\n");;//默认提示
break;
}
}while(choose !=3);
}
int main()
{
Menu();
return 0;
}
课后作业源文件下载
链接: 资源下载