数字迷宫实训

数字迷宫

第一部分 案例描述

案例目的

本案例为实现动态的刷新Dos界面,使用用户控制头像“消灭”窗口中出现的数字(无固定顺序)的游戏,来使学员加深对一维数组、二维数组、循环语句、选择程序设计以及相关系统函数的使用。

案例难度

★★★★

案例覆盖技能点

a) 选择程序设计

b) 循环程序设计

c) 用户、屏幕窗口的输入输出

d) 相关系统函数

e) 一维、二维数组

推荐案例完成时间

4

适用课程和对象

C语言案例(T阶段)

第二部分需求和开发环境

使用技术和开发环境

Microsoft Visual C++ 6.0

案例需求

本案例要求制作一个《数字迷宫》的游戏,该游戏的玩法描述为:

1、 系统主要地图为固定模式

2、 地图内部包含墙体、走廊、阿拉伯数字(1~7)、玩家头像(1)四种不同内容

3、 用户通过上、下、左、右按键来控制玩家头像在地图范围内的走动

4、 在玩家走动过程中,碰撞墙壁时,该步的走动无效,玩家头像原地不变

5、 玩家允许在设计走廊内部进行走动

6、 玩家头像遇到阿拉布数字时,数字消失,并且对玩家走动无影响

7、 玩家头像遭遇所有数字之后(地图上无阿拉伯数字),该局游戏结束,并自动开始下一局游戏

8、 在某一局游戏中,游戏走廊、墙体与其他游戏相同,但数字位置会随机产生

9、 阿拉伯数字产生在走廊内而非墙体上

10、 在玩家游戏过程中按下Esc键,游戏无条件退出。

11、 在玩家未使用Esc键时,程序正常运行

程序运行截图

1、 程序初始状态


2、 玩家运行中


3、 退出

 

数字迷宫工作原理

1. 本程序分为初始——玩家运行——重启一局——结束四个阶段

a) 初始化阶段

i. 程序当中存在一18*24大小的固定地图数组

ii. 该数组以0/-1分别标识程序地图当中的“墙体”以及“走廊”

iii. 通过随机函数在走廊中产生17阿拉伯数字,并且将该系列数字写入二维数组的相应位置当中,对-1(走廊)进行覆盖

iv. 产生玩家位置:数组的(1,1)

v. 使用循环语句遍历打印出数组元素,元素包括

1. 墙体(0):■

2. 走廊(-1): 空格*2

3. 数字(1~7):数字本身+空格*1

4. 玩家头像:\1 即:J+空格*1

b) 玩家运行阶段

i. 玩家使用上下左右键进行头像控制

ii. 与墙体碰撞时,走动无效,原地不动(通过玩家头像位置标示与数组内部数据是否为墙体(0)来判断)

iii. 为一般走廊时,玩家原头像位置清空为双空格(通过玩家头像位置标示与数组内部数据是否为走廊(-1)来判断),玩家当前位置输出玩家头像,并更新玩家头像位置全局变量。

iv. 为数字时(通过玩家头像位置标示与数组内部数据是否为数字(>0)来判断),该数字消失,玩家原位置头像消失,新位置出现玩家头像,并将数组内消失数字位置置为走廊(-1), 并更新玩家头像位置全局变量。

v. 每走动一次系统遍历数组元素,判断数字(>0)多少,当数字存在数量>0时,该局继续,=0时,进入重启一局步骤。

c) 重启一局

i. 重复初始化阶段(注意要移动头像到(1,1)位置)

d) 结束程序

i. 用户点击Esc或强行关闭应用程序时,程序无条件退出。

第三部分功能点介绍

头文件引用列表

头文件名

功能简述

#include <stdio.h>

使用一般输入输出函数

#include <conio.h>

使用getch函数达到输入数据不敲回车进行下步计算功能

#include <time.h>

使用time(int)函数

#include "windows.h"

使用光标移动函数对光标进行编码定位

系统函数使用列表

函数名称

功能简述

getch();

 

printf

 

srand();

设置系统rand函数随机引资

time(NULL);

以时间作为随机因子产生不重复的随机数,提高程序效率

rand()

得到随机数

GetStdHandle

得到该程序HANDLE的函数

GetLastError();

得到系统最近错误编号函数

SetConsoleCursorPosition(Handle, {x,y});

代码设置系统光标位置函数

 

公共变量列表

变量名称

初始值

功能简述

int code[17][24]

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,-1,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,

0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,-1,0,0,0,0,0,-1,-1,-1,0,0,

0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,0,

0,-1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,-1,-1,0,0,

0,-1,0,0,-1,0,-1,0,0,0,0,-1,0,-1,-1,-1,0,0,0,0,0,0,0,0,

0,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,0,

0,-1,0,0,0,0,0,0,0,0,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,0,

0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,0,0,-1,0,0,0,0,

0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,0,0,-1,0,0,0,0,

0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,-1,-1,-1,0,-1,-1,0,

0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,

0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,

0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,

0,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,

0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

};

地图数组,0表示墙体,-1表示走廊

int postionX, postionY

postionX=1;  postionY=1;

玩家的初始位置

 

函数功能列表

函数名称

功能简述

void main()

程序接口函数,负责程序整体运行

void SetCode(int num);

该函数通过传入的num值来判断并输出为:■,空格*2,或者数字本身

void SetWindow();

生成地图主体函数:遍历公共数组,在位置部位(1,1)时,调用SetCode函数,并在(1,1)位置输出玩家头像

void SetNum();

程序初始化时,用于使用随机函数在数组“走廊”位置生成17的阿拉伯数字

void Begin();

初始化主体函数,设置玩家头像初始位置,调用SetNum函数

void LeftKey();

void UpKey();

void DownKey()

void RightKey();

玩家按下,上下左右按键时,分别调用的函数,该函数可判断玩家是否为被墙体阻挡、正常行走、“吃”掉数字三种状态,并改变玩家头像的位置。

int CheckLeftNum();

该函数判断数组内剩余的数字(>0)数量,返回该数量

void GoToXY(int x, int y);

该函数用于在x,y位置输出用户头像

void GoToXYSpace(int x, int y);

该函数用于在x,y处输出空格*2,用于用户走动时,消除之前位置处头像。

 

第四部分考核评价点(系统验收标准)

序号

功能列表

功能描述

分数

说明

难度

1

正确创建系统原始地图

 

30

必做

★★

2

正确完成用户移动监测

 

50

必做

★★★★

3

正确完成数字剩余检测

 

10

必做

★★

4

正确完成系统重新开始

 

10

必做

7

系统退出

 

 

必做

 

 

#include <cstdio>
#include <cstring>
#include <conio.h>
#include <ctime>
#include <windows.h>


#define random(a, b) rand()%(b-a+1)+a/// rand为随机函数,在a~b中取随机数,且a、b都可以取到 


int mp[17][24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-1,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,-1,0,0,0,0,0,-1,-1,-1,0,0,
0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,0,
0,-1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,-1,-1,0,0,
0,-1,0,0,-1,0,-1,0,0,0,0,-1,0,-1,-1,-1,0,0,0,0,0,0,0,0,
0,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,0,
0,-1,0,0,0,0,0,0,0,0,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,0,
0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,0,0,-1,0,0,0,0,
0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,0,0,-1,0,0,0,0,
0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,-1,-1,-1,0,-1,-1,0,
0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,
0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,
0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,
0,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};

int postionX=1, postionY=1;///玩家位置坐标,全局变量

bool CheckLeftNum()///检查游戏是否结束
{
    int sum = 0;
    for(int i=0;i<17;++i)///遍历地图,检查是否存在1-7的数字
    {
        for(int j=0;j<23;++j)
        {
            if(mp[i][j] >= 0)
                sum += mp[i][j];
        }
    }
    if(sum > 0)
        return true;
    else
        return false;
}

void SetCode(int num)///绘制地图的基本元素
{
    if(num == 0)
        printf("■");
    else if(num == -1)
        printf("  ");
    else
        printf("%d ",num);
}

void SetNum()///生成随机数位置,并且将随机数覆盖到走廊上
{
    int num = 1;
    srand((unsigned)time(NULL));///以时间为基准设置随机数种子
    while(num <= 7)
    {
        int randi = random(1,15);
        int randj = random(1,22);
        if(mp[randi][randj] == -1 && (randi != 1 && randj != 1))///需为走廊位置,并且不能为玩家起始位置
        {
            mp[randi][randj] = num;
            num++;
        }
    }
}

void SetWindow()///绘制整个地图
{
    if(!CheckLeftNum())///判断游戏是否结束
    {
        SetNum();///生成随机数
        postionX = 1;///并且让玩家回到起始位置
        postionY = 1;
    }

    for(int i=0;i<17;++i){
        for(int j=0;j<24;++j){
            if(i==postionX && j==postionY)
                printf("%c ",char(1));
            else
                SetCode(mp[i][j]);
            if(j == 23)
                printf("\n");
        }
    }
    printf("\nEsc键退出游戏,Space键重新开始游戏\n");
}


void LeftKey()
{
    if(mp[postionX][postionY-1] == 0)
        return;
    else if(mp[postionX][postionY-1] == -1)
    {
        postionY -= 1;
    }
    else
    {
        postionY -= 1;
        mp[postionX][postionY] = -1;
    }
}
void UpKey()
{
    if(mp[postionX-1][postionY] == 0)
        return;
    else if(mp[postionX-1][postionY] == -1)
    {
        postionX -= 1;
    }
    else
    {
        postionX -= 1;
        mp[postionX][postionY] = -1;
    }
}
void DownKey()
{
    if(mp[postionX+1][postionY] == 0)
        return;
    else if(mp[postionX+1][postionY] == -1)
    {
        postionX += 1;
    }
    else
    {
        postionX += 1;
        mp[postionX][postionY] = -1;
    }
}
void RightKey()
{
    if(mp[postionX][postionY+1] == 0)
        return;
    else if(mp[postionX][postionY+1] == -1)
    {
        postionY += 1;
    }
    else
    {
        postionY += 1;
        mp[postionX][postionY] = -1;
    }
}



void run()
{
    char ch;
    while(true)
    {
        SetWindow();///每走一步就画一次界面
        ch = getch();///获取键盘的按键信息
        if (ch == -32)///上下左右的第一个ascll码值均为-32
        {
            ch = getch();///获取第二个asc码值
            switch (ch)
            {
            case 72:
                ///进行向上行走操作
                UpKey();
                break;
            case 80:
                ///进行向下行走操作
                DownKey();
                break;
            case 75:
                ///进行向左行走操作
                LeftKey();
                break;
            case 77:
                ///进行向右行走操作
                RightKey();
                break;
            default:
                break;
            }
        }
        else if(ch == 27)///如果为esc键,程序结束
			{
				printf("\n大爷再来玩!\n");
				return;	
			}
        else if(ch == 32)///如果为Space键
		{
			for(int i=0;i<17;++i)///将随机数重新设为走廊 
				for(int j=0;j<24;++j)
				{
					if(mp[i][j] > 0)
						mp[i][j] = -1;
				}
			
			SetNum();///生成随机数
        	postionX = 1;///并且让玩家回归起始位置
        	postionY = 1;
		}
		system("cls");///清空界面 
    }
}


int main()
{
    run();
    return 0;
}

新加入了space功能键,就是可以随时重新开始游戏。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值