黑马程序员_用C写的小游戏

---------------------- ASP.Net+Unity开发 .Net培训 、期待与您交流!----------------------

走迷宫

        走迷宫是游戏中相当常见的游戏了,大多数游戏都是一大段迷宫走来走去,然后再走出迷宫,闯下一关。我摘取了一个游戏迷宫的代码,来巩固一下自己学习过的c基础知识。

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

int visit(int,int);

int maze[7][7] = {                                      //地图
    {2,2,2,2,2,2,2},
    {2,0,0,0,0,0,2},
    {2,0,2,0,2,0,2},
    {2,0,0,2,0,2,2},
    {2,2,0,2,0,2,2},
    {2,0,0,0,0,0,2},
    {2,2,2,2,2,2,2}
};

int starti = 1, startj = 1;
int endi = 5, endj = 5;
int success = 0;

int main(int argc, const char * argv[])
{

    int i,j;
    printf("display:\n");                              //输出原始地图
    for(i = 0; i < 7; i++)
    {
        for(j = 0; j < 7; j++)
        {
            if(maze[i][j] == 2)
                printf("#");
            else
                printf(" ");
        }
        printf("\n");
    }
    
    if(visit(starti,startj) == 0)
        printf("\nno way\n");
    else
    {
        printf("\ndisplay way:\n");                   //输出路线
        for(i = 0; i < 7; i++)
        {
            for(j = 0; j < 7; j++)
            {
                if(maze[i][j] == 2)
                    printf("#");
                else if(maze[i][j] == 1)
                    printf("@");
                else
                    printf(" ");
                    
            }
            printf("\n");
        }
    }

    return 0;
}

int visit(int i,int j)
{
    maze[i][j] = 1;
    
    if(i == endi && j == endj)
        success = 1;
    
    if(success != 1 && maze[i][j+1] == 0)             //递归先向右走,循环走到尽头之后是否能到终点
        visit(i,j+1);
    if(success != 1 && maze[i+1][j] == 0)
        visit(i+1,j);
    if(success != 1 && maze[i][j-1] == 0)
        visit(i,j-1);
    if(success != 1 && maze[i-1][j] == 0)
        visit(i-1,j);
        if(success != 1)
            maze[i][j] = 0;
    return success;
}

        运行结果:

display:
#######
#     #
# # # #
#  # ##
## # ##
#     #
#######

display way:
#######
#@    #
#@# # #
#@@# ##
##@# ##
# @@@@#
#######

走迷宫改进

        由于之前的走迷宫游戏只能输出一条路线,现在做了一下修改,把所有路线都输出出来。

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

void visit(int,int);

int maze[9][9] = {
    {2,2,2,2,2,2,2,2,2},
    {2,0,0,0,0,0,0,0,2},
    {2,0,2,2,0,2,2,0,2},
    {2,0,2,0,0,2,0,0,2},
    {2,0,2,0,2,0,2,0,2},
    {2,0,0,0,0,0,2,0,2},
    {2,2,0,2,2,0,2,2,2},
    {2,0,0,0,0,0,0,0,2},
    {2,2,2,2,2,2,2,2,2}
};

int starti = 1, startj = 1;
int endi = 7, endj = 7;
int main(int argc, const char * argv[])
{
    int i,j;
    printf("display:\n");
    for(i = 0; i < 9; i++)
    {
        for(j = 0; j < 9; j++)
        {
            if(maze[i][j] == 2)
                printf("#");
            else
                printf(" ");
        }
        printf("\n");
    }
    
    visit(starti,startj);
    return 0;
}

void visit(int i,int j)
{
    int m,n;
    maze[i][j] = 1;
    
    if(i == endi && j == endj)
    {
        printf("\ndisplay way:\n");
        for(m = 0; m < 9; m++)
        {
            for(n = 0; n < 9; n++)
            {
                if(maze[m][n] == 2)
                    printf("#");
                else if(maze[m][n] == 1)
                    printf("@");
                else
                    printf(" ");
            }
            printf("\n");
        }
    }
    
    if(maze[i][j+1] == 0)                    //直接遍历所有路线,去掉了原来判断是否到达终点的条件
        visit(i,j+1);
    if(maze[i+1][j] == 0)
        visit(i+1,j);
    if(maze[i][j-1] == 0)
        visit(i,j-1);
    if(maze[i-1][j] == 0)
        visit(i-1,j);
    
    maze[i][j] = 0;
}

        运行结果:

display:
#########
#       #
# ## ## #
# #  #  #
# # # # #
#     # #
## ## ###
#       #
#########

display way:
#########
#@@@@   #
# ##@## #
# #@@#  #
# #@# # #
#  @@@# #
## ##@###
#    @@@#
#########

display way:
#########
#@@@@   #
# ##@## #
# #@@#  #
# #@# # #
# @@  # #
##@## ###
# @@@@@@#
#########

display way:
#########
#@      #
#@## ## #
#@#  #  #
#@# # # #
#@@@@@# #
## ##@###
#    @@@#
#########

display way:
#########
#@      #
#@## ## #
#@#  #  #
#@# # # #
#@@   # #
##@## ###
# @@@@@@#
#########

推箱子游戏

        这个程序是在传智的基础班上课的时候学习到的程序,当时是作为作业自己写了一下。

#include <stdio.h>
//打印函数
void printMap(char map[][6], int row, int col);

int main(int argc, const char * argv[])
{
    char map[6][6] = {
        {'#','#','#','#','#','#'},
        {'#','0',' ',' ',' ',' '},//第一行的第一列
        {'#',' ','@',' ',' ','#'},//第二行的第一列
        {'#',' ',' ',' ',' ','#'},
        {'#',' ',' ',' ',' ','#'},
        {'#','#','#','#','#','#'}
    };


    int row = (sizeof(map)/sizeof(char))/(sizeof(map[0])/sizeof(char));
    int col = sizeof(map[0])/sizeof(char);
    printMap(map, row, col);

    char input;//接收用户输入的变量

    int startX = 1;
    int startY = 1;

    int endX = 1;
    int endY = 5;

    while (map[endX][endY] != '0') {

        input = getchar();//从输入缓冲区拿走一个字符
        getchar();//作用是从输入缓冲区取走\n
        printf("用户的输入 %c\n",input);
    
    switch (input) {
        case 's'://向下走
            //判断下一步是否是墙
            if(map[startX + 1][startY] != '#'){
                //当前小人所在的位置替换成空格
                map[startX][startY] = ' ';
                
                startX++;
                //替换下一步成"0"
                if(map[startX][startY] == '@' && map[startX+1][startY] != '#')
                    map[startX+1][startY] = '@';
                map[startX][startY] = '0';
            }
            break;
        case 'w'://向上走
            //判断下一步是否是墙
            if (map[startX - 1][startY] != '#' ) {
                //当前小人所在的位置替换成空格
                map[startX][startY] = ' ';
                startX--;
                //替换下一步成"0"
                if(map[startX][startY] == '@' && map[startX-1][startY] != '#')
                    map[startX-1][startY] = '@';
                map[startX][startY] = '0';
            }
            break;
        case 'a'://往左走
            //判断下一步是否是墙
            if(map[startX][startY - 1] != '#'){
                //当前小人所在的位置替换成空格
                map[startX][startY] = ' ';
                startY--;
                 //替换下一步成"0"
                if(map[startX][startY] == '@' && map[startX][startY-1] != '#')
                    map[startX][startY-1] = '@';
                map[startX][startY] = '0';
            }
            break;
        case 'd'://往右走
            if (map[startX][startY + 1] != '#') {
                //当前小人所在的位置替换成空格
                map[startX][startY] = ' ';
                startY++;
            //替换下一步成"0"
                if(map[startX][startY] == '@' && map[startX][startY+1] != '#')
                    map[startX][startY+1] = '@';
                map[startX][startY] = '0';
            }
            break;
        default:
            break;
    }
    


        printMap(map, row, col);

    }
    printf("你真的好NB哦。。。!!!\n");
    printf("想超越自己,请付费购买下一版\n");
    
   return 0;
}
void printMap(char map[][6], int row, int col)
{
    //遍历二维数组,打印地图
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }
    
}

        运行结果:

######
#0    
# @  #
#    #
#    #
######
d
用户的输入 d
######
# 0   
# @  #
#    #
#    #
######
s
用户的输入 s
######
#     
# 0  #
# @  #
#    #
######
s
用户的输入 s
######
#     
#    #
# 0  #
# @  #
######
s
用户的输入 s
######
#     
#    #
#    #
# 0  #
######

        我玩着玩的时候发现了箱子被我推没了,这是我遇到的第一个bug。这个bug让我感受到了程序在后台运作时有bug的灾难。


推箱子bug修复

        当发现bug之后我开了第一次对程序的bug修复工作,虽然很简单但是这个工作我还是认认真真地去对待地。

#include <stdio.h>
//打印函数
void printMap(char map[][6], int row, int col);

int main(int argc, const char * argv[])
{
    char map[6][6] = {
        {'#','#','#','#','#','#'},
        {'#','0',' ',' ',' ',' '},//第一行的第一列
        {'#',' ','@',' ',' ','#'},//第二行的第一列
        {'#',' ',' ',' ',' ','#'},
        {'#',' ',' ',' ',' ','#'},
        {'#','#','#','#','#','#'}
    };
    
    //    2.打印地图,展示给玩家
    int row = (sizeof(map)/sizeof(char))/(sizeof(map[0])/sizeof(char));
    int col = sizeof(map[0])/sizeof(char);
    printMap(map, row, col);
    
    char input;//接收用户输入的变量
    //  起始坐标
    int startX = 1;
    int startY = 1;
    //  终止坐标
    int endX = 1;
    int endY = 5;

    while (map[endX][endY] != '@') {
        
        input = getchar();//从输入缓冲区拿走一个字符
        getchar();//作用是从输入缓冲区取走\n
        printf("用户的输入 %c\n",input);
        
        switch (input) {
            case 's'://向下走
                //判断下一步是否是墙
                if(map[startX + 1][startY] != '#'){
                    if (map[startX+1][startY] == '@' && map[startX+2][startY] == '#') {
                        break;
                    }
                    
                    //当前小人所在的位置替换成空格
                    map[startX][startY] = ' ';
                    
                    startX++;
                    //替换下一步成"0"
                    if(map[startX][startY] == '@' && map[startX+1][startY] != '#')
                        map[startX+1][startY] = '@';
                    map[startX][startY] = '0';
                }
                break;
            case 'w'://向上走
                //判断下一步是否是墙
                if (map[startX - 1][startY] != '#' ) {
                    if (map[startX-1][startY] == '@' && map[startX-2][startY] == '#') {
                        break;
                    }
                    //当前小人所在的位置替换成空格
                    map[startX][startY] = ' ';
                    startX--;
                    //替换下一步成"0"
                    if(map[startX][startY] == '@' && map[startX-1][startY] != '#')
                        map[startX-1][startY] = '@';
                    map[startX][startY] = '0';
                }
                break;
            case 'a'://往左走
                //判断下一步是否是墙
                if(map[startX][startY - 1] != '#'){
                    if (map[startX][startY-1] == '@' && map[startX][startY-2] == '#') {
                        break;
                    }
                    //当前小人所在的位置替换成空格
                    map[startX][startY] = ' ';
                    startY--;
                    //替换下一步成"0"
                    if(map[startX][startY] == '@' && map[startX][startY-1] != '#')
                        map[startX][startY-1] = '@';
                    map[startX][startY] = '0';
                }
                break;
            case 'd'://往右走
                if (map[startX][startY + 1] != '#') {
                    if (map[startX][startY+1] == '@' && map[startX][startY+2] == '#') {
                        break;
                    }
                    //当前小人所在的位置替换成空格
                    map[startX][startY] = ' ';
                    startY++;
                    //替换下一步成"0"
                    if(map[startX][startY] == '@' && map[startX][startY+1] != '#')
                        map[startX][startY+1] = '@';
                    map[startX][startY] = '0';
                }
                break;
            default:
                break;
        }
        
        //    4.往下走
        
        printMap(map, row, col);

    }
    printf("你真的好NB哦。。。!!!\n");
    printf("想超越自己,请付费购买下一版\n");
    
    return 0;
}
void printMap(char map[][6], int row, int col)
{
    //遍历二维数组,打印地图
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }
    
}

        运行结果:

######
#0    
# @  #
#    #
#    #
######
d
用户的输入 d
######
# 0   
# @  #
#    #
#    #
######
d
用户的输入 d
######
#  0  
# @  #
#    #
#    #
######
d
用户的输入 d
######
#   0 
# @  #
#    #
#    #
######
d
用户的输入 d
######
#    0
# @  #
#    #
#    #
######
d
用户的输入 d
######
#    0
# @  #
#    #
#    #
######
a
用户的输入 a
######
#   0 
# @  #
#    #
#    #
######
a
用户的输入 a
######
#  0  
# @  #
#    #
#    #
######
a
用户的输入 a
######
# 0   
# @  #
#    #
#    #
######
a
用户的输入 a
######
#0    
# @  #
#    #
#    #
######
s
用户的输入 s
######
#     
#0@  #
#    #
#    #
######
s
用户的输入 s
######
#     
# @  #
#0   #
#    #
######
d
用户的输入 d
######
#     
# @  #
# 0  #
#    #
######
w
用户的输入 w
######
# @   
# 0  #
#    #
#    #
######
w
用户的输入 w
######
# @   
# 0  #
#    #
#    #
######
w
用户的输入 w
######
# @   
# 0  #
#    #
#    #
######
a
用户的输入 a
######
# @   
#0   #
#    #
#    #
######
w
用户的输入 w
######
#0@   
#    #
#    #
#    #
######
d
用户的输入 d
######
# 0@  
#    #
#    #
#    #
######
d
用户的输入 d
######
#  0@ 
#    #
#    #
#    #
######
d
用户的输入 d
######
#   0@
#    #
#    #
#    #
######
你真的好NB哦。。。!!!
想超越自己,请付费购买下一版

        经过自己地测试之后,我把游戏地异常退出和箱子被推没地bug都解决了。这回游戏玩起来舒畅多了,就是代码写的啰嗦了点,以后还会改进地。

地图分离文件

        我们在玩游戏地时候只玩一个图太没意思了,所以我把程序又做了一个改动,将地图的数组的定义分离出去,现在拿迷宫的游戏为例。

main.c

#include <stdio.h>
#include <stdlib.h>
#include "map.h"

int visit(int,int);
int main(int argc, const char * argv[])
{
    
    int i,j;
    printf("display:\n");
    for(i = 0; i < len; i++)
    {
        for(j = 0; j < len; j++)
        {
            if(maze[i][j] == 2)
                printf("#");
            else
                printf(" ");
        }
        printf("\n");
    }
    
    if(visit(starti,startj) == 0)
        printf("\nno way\n");
    else
    {
        printf("\ndisplay way:\n");
        for(i = 0; i < len; i++)
        {
            for(j = 0; j < len; j++)
            {
                if(maze[i][j] == 2)
                    printf("#");
                else if(maze[i][j] == 1)
                    printf("@");
                else
                    printf(" ");
                    
            }
            printf("\n");
        }
    }

    return 0;
}

int visit(int i,int j)
{
    maze[i][j] = 1;
    
    if(i == endi && j == endj)
        success = 1;
    
    if(success != 1 && maze[i][j+1] == 0)
        visit(i,j+1);
    if(success != 1 && maze[i+1][j] == 0)
        visit(i+1,j);
    if(success != 1 && maze[i][j-1] == 0)
        visit(i,j-1);
    if(success != 1 && maze[i-1][j] == 0)
        visit(i-1,j);
        if(success != 1)
            maze[i][j] = 0;
    return success;
}

map.h

#ifndef struct_Header_h
#define struct_Header_h

int maze[7][7] = {
    {2,2,2,2,2,2,2},
    {2,0,0,0,0,0,2},
    {2,0,2,0,2,0,2},
    {2,0,0,2,0,2,2},
    {2,2,0,2,0,2,2},
    {2,0,0,0,0,0,2},
    {2,2,2,2,2,2,2}
};


int starti = 1, startj = 1;
int endi = 5, endj = 5;
int success = 0;
int len = sizeof(maze[0])/sizeof(int);

#endif

map2.h

#ifndef struct_Header_h
#define struct_Header_h

int maze[8][8] = {
    {2,2,2,2,2,2,2,2},
    {2,0,0,0,0,0,2,2},
    {2,0,2,0,2,0,0,2},
    {2,0,0,2,0,2,0,2},
    {2,2,0,2,0,2,2,2},
    {2,0,0,0,0,0,0,2},
    {2,0,2,0,0,0,0,2},
    {2,2,2,2,2,2,2,2}
};

int starti = 1, startj = 1;
int endi = 6, endj = 6;
int success = 0;
int len = sizeof(maze[0])/sizeof(int);

#endif

        当程序main.c文件中包含map.h文件时运行结果如下:

display:
#######
#     #
# # # #
#  # ##
## # ##
#     #
#######

display way:
#######
#@    #
#@# # #
#@@# ##
##@# ##
# @@@@#
#######

        #include就是原模原样把源文件拷贝到调用文件中,所以地图文件完全可以从main.c文件中释放出来单独处理。有的时候为了防止头文件重复包含,需要下段代码来支持:

#ifndef struct_Header_h
#define struct_Header_h



#endif

        中间的那部分代码可以不被重复包含,因为当头文件被包含时,#ifndef会判断有没有struct_Header_h这个宏的存在,如果有则中间内容不被包含,如果没有则中间内容包含并定义该宏。

        当头文件包含map2.h文件时的运行结果如下:

display:
########
#     ##
# # #  #
#  # # #
## # ###
#      #
# #    #
########

display way:
########
#@    ##
#@# #  #
#@@# # #
##@# ###
# @@@@@#
# #   @#
########

        这样就可以实现不同地图的游戏玩法了。


---------------------- ASP.Net+Unity开发 .Net培训 、期待与您交流!----------------------


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值