您的位置:首页 > 编程语言

自己研究的有关推箱子的--接近完美的代码

2015-08-04 00:06 344 查看
/**
 *  main.c
 * 推箱子3.0
 *
 *  Created by LongMa on 15/8/3.
 *  Copyright (c) 2015年 itcast. All rights reserved
 *     功能:
        1.各种小bug已解决,比如 推到边缘后小人不再推自己绕到边缘也判定成功的bug……
        2.现在可以手动改地图的长,宽了!
 *      3.四面都可能又出口,已解决
 *      4.箱子推出去才算结束。已解决。
       问题:
        1.地图尚不能自己生成
        2.多个return 0;有没有影响?
 
 *  3.0旨在实现 可手动修改地图大小的目标,done!
 *  @param map 宏定义 行和列,修改宏定义值,再修改迷宫的大小
 *
 *  @return 成功/失败
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define  iLength  8
#define  jLength  9
/**
 *  打印地图
 *
 *  @param map 存放地图的数组
 */
void printMap(char map[iLength][jLength])
{
    for(int i =0; i < iLength;i++)
    {
        printf("%s\n",map[i]);/* 按行,字符串输出法,简单! */
    }
}

/**
 *  通过指针实现 交换map数组中两个不同元素中的值
 *
 *  @param map 存放地图的数组
 *  @param i   原位置行坐标
 *  @param j   原位置列坐标
 *  @param iC  下一位置行坐标
 *  @param jC  下一位置列坐标
 */
void exchange (char map[iLength][jLength],int i, int j, int iC,int jC)
{
    
    char *p= &map[i][j],*pC = &map[iC][jC];
    *p  =  *p ^ *pC;
    *pC =  *p ^ *pC;
    *p  =  *p ^ *pC;
}
/**
 *  判断用户是否把箱子推到角落无法再推了
 *
 *  @param map 存放地图的数组
 *  @param cX  箱子 行坐标
 *  @param cY  箱子 列坐标
 *
 *  @return 1:推死了 0:没有推死
 */
int  endOrnot(char map[iLength][jLength],int cX,int cY)
{
    if (  ( '#' == map[cX - 1][cY] && ('#' == map[cX][cY - 1] || '#' == map[cX][cY + 1])  )
        ||( '#' == map[cX + 1][cY] && ('#' == map[cX][cY - 1] || '#' == map[cX][cY + 1])  )
        )
    {
        printf("推箱子失败!");
        return 1;
    }else
    {
        return 0;
    }
}

/**
 *  判定推成功时,进行的操作,输出地图和鼓励!
 *
 *  @param map    地图
 *  @param cX     箱子行坐标
 *  @param cY     箱子列坐标
 *  @param bX     小人横坐标
 *  @param bY     小人列坐标
 *  @param flagBs 计算步数
 */
void success(char map[iLength][jLength], int cX, int cY, int bX, int bY,int flagBs)
{
    map[cX][cY] = map[bX][bY];
    map[bX][bY]     = ' ';
    printMap(map);
    printf("哇,只运动了 %d 下就结束了?!\n恭喜您,已获得“终极快男”荣誉称号!",flagBs);
    //    return 0;//没有意义,要去掉!被调函数返回值 并不能结束主调函数中的循环!
}

/**
 *  main函数
 *
 *  @param argc  返回 int型 数据
 *  @param argv  返回 指针数组变量
 *
 *  @return 0
 */
int main(int argc, const char * argv[])
{
    /*  1.定义地图并输出,定义 小人和箱子位置    */
    
    
    char map[iLength][jLength] = {/*  ?jLength列是因为要存储‘\0’, iLength也可以?巧了?万一map【0】【iLength】存的不是'\0',程序就失败了 */
        "##   ###",
        "#0  # ##",
        "#  x ###",
        "  #   ##",
        "      ##",
        "   #    ",
        "##      ",
        "## #####"
    };
    
    char mapBeifen[iLength][jLength] = {/*  备份原始地图,以供推死箱子继续游戏时,刷新地图用  */
        "##   ###",
        "#0  # ##",
        "#  x ###",
        "  #   ##",
        "      ##",
        "   #    ",
        "##      ",
        "## #####"
    };
    int flagBushu = 0;/*  计算用了多少步. */
    int justify = 0; /*  标记箱子是否被推死了 */
    
    /* botX,botY: 小人行列坐标, chestX,chestY: 箱子行列坐标 */
    int botX = 1, botY = 1, chestX = 2, chestY = 3;/* 初值易错,不是 2 2 3 4 哦!小心,下标从零开始! */
    char ctl;/* 接收用户输入的移动按键 */
    char answer;/* 按下q后存储玩家回答 */
    char restart = 'y';/* 箱子被推死时,接收用户是否重新玩的回答 */
    char (*p)[jLength];
    p = map;/* p为了刷新地图,新建的指针变量 */
    
    printf("地图如下:\n");
    printMap(map);
    
    /* 2.循环 提示玩家输入按键“w:上,s:下,a:左,d:右\n” */
    
    while(2)//或者用 chest != '\0'
    {
        //* 3.提示并接收按键并  判断(重点,写成单独函数) 是否可以移动或推箱子 */
        printf("请按下一个键控制小人移动:w 往上,s 往下,a 往左,d 往右\n");
        scanf("%c",&ctl);
        flagBushu++;/* 加步数 */
        rewind(stdin);/* 清除缓冲区,消除 '\n'对下一次输入的影响。 */
        
        /* switch变量必须用 括号 括起来!规定向下x轴和向右y轴为正方向。xy方向必须这样,因为是按a【i】【j】对应a【x】【y】。
         按w时,向上,i变化,不是j!故x设置成列向,y行向!
         ①每次在switch最后判断箱子是否被推死,推死了提示用户是否重新开始玩。是就刷新地图和参数。否则跳出循环,提示结束。
         ②遇到路,交换路与小人的位置;更新小人坐标。
         ③遇到箱子且在推的方向上箱子下一个位置为路(不同方向的出口(左上 有口怎么办?),设置不同解决方案),
         则小人和箱子移动(交换箱子与路。再交换小人与路,注意更新它俩的坐标)
         ④判定 是否 输入的为q、Q,是的话做 是否退出 判定并执行。
         */
        switch (ctl)
        {
            case 'q':
            case 'Q':
                printf("真的要退出吗?再配淫家玩一会嘛!\n狠心退出请再次按 q ,取消请按其他键。");
                scanf("%c",&answer);
                rewind(stdin);
                if(answer == 'q')
                {
                    printf("臣妾恭送皇上!");
                    return 0;
                }
                break;
            case 'a':
            case 'A':
                if(map[botX][botY - 1] == ' ')/* 情况② */
                {
                    exchange (map,botX, botY, botX, botY - 1);
                    botY --;
                }else if(botX == chestX && (botY - 1) == chestY)/* 情况3 */
                {
                    if(map[chestX][chestY - 1] == ' ')
                    {
                        exchange (map,chestX, chestY, chestX, chestY - 1);
                        chestY --;
                        exchange (map,botX, botY, botX, botY - 1);
                        botY --;
                    }else if(0 == chestY) //判定箱子是否在边界,是的话跳出循环,结束
                    {
                        success(map, chestX, chestY, botX, botY, flagBushu);
                        return 0;
                    }
                }
                break;
            case 'd':
            case 'D':
                if(map[botX][botY + 1] == ' ')
                {
                    exchange (map,botX, botY, botX, botY + 1);
                    botY ++;
                }else if(botX == chestX && (botY + 1) == chestY)
                {
                    if(map[chestX][chestY + 1] == ' ')
                    {
                        exchange (map,chestX, chestY, chestX, chestY + 1);
                        chestY ++;
                        exchange (map,botX, botY, botX, botY + 1);
                        botY ++;
                    }else if(7 == chestY)
                    {
                        success(map, chestX, chestY, botX, botY, flagBushu);
                        return 0;
                    }
                }
                break;
            case 'w':
            case 'W':
                if(map[botX - 1][botY] == ' ')
                {
                    exchange (map,botX, botY, botX - 1, botY);
                    botX --;
                }else if((botX - 1) == chestX  &&  botY  == chestY)
                {
                    if (map[chestX - 1][chestY] == ' ')
                    {
                        exchange (map,chestX, chestY, chestX - 1, chestY);
                        chestX --;
                        exchange (map,botX, botY, botX - 1, botY);
                        botX --;
                    }else if (0 == chestX)
                    {
                        success(map, chestX, chestY, botX, botY, flagBushu);
                        return 0;
                    }
                }
                break;
            case 's':
            case 'S':
                if(map[botX + 1][botY] == ' ')
                {
                    exchange (map,botX, botY, botX + 1, botY);
             
a6f5
      botX ++;
                }else if((botX + 1) == chestX  &&  botY  == chestY)
                {
                    if(map[chestX + 1][chestY] == ' ')
                    {
                        exchange (map,chestX + 1, chestY, chestX, chestY);
                        chestX ++;
                        exchange (map,botX, botY, botX + 1, botY);
                        botX ++;
                    }else if (7 == chestX)
                    {
                        success(map, chestX, chestY, botX, botY, flagBushu);
                        return 0;
                    }
                    
                }
                break;
            default :
                break;/* break;能省去? key:不能!*/
                
        }
        
        /* 4.刷新地图 */
        printMap(map);
        justify = endOrnot(map, chestX, chestY);/* 判定是否推死了 */
        if ( 1 == justify)
        {
            printf("是否重新来一盘?y/n");
            scanf("%c",&restart);
            rewind(stdin);
            rewind(stdin);/* 多个scanf语句必须加上 */
            while ('n' !=restart && 'y' != restart)/* 输错时,提示重新输入 */
            {
                printf("您的输入错误,请重新输入,继续y/退出n:");
                scanf("%c",&restart);
                rewind(stdin);
            }
            if ('y' == restart)/* 重新玩 */
            {
                /* 初始化地图和参数 */
                memcpy(map, mapBeifen, sizeof(mapBeifen));
                printf("地图如下:\n");
                printMap(map);
                flagBushu = 0;
                justify = 0;
                botX = 1, botY = 1, chestX = 2, chestY = 3;
                restart = 'n';
            }else/* 退出 */
            {
                printf("臣妾恭送圣驾~~~\n");
                return 0;
            }
        }
    }
    
   
    /* 5.若箱子遇到出口,输入成功信息 */
    //return 0;已经都在while循环里

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: