• 推箱子(简易版)


    游戏简介

    经典的推箱子是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。箱子只可以推, 不可以拉, 而且一次只能推动一个,胜利条件就是把所有的箱子都推到目的地。

    思路

    模拟题。难点在于推箱子的动作,如果箱子前方是箱子或者墙壁都不能被推动,是目的地或空地可以。撤回操作是通过一个三维数组记录每一步来实现的,貌似使用起来非常玄学,我都懒得调了。

    代码

    main.cpp

     1 #include"main.h"
     2 #include"GoBack.h"
     3 #include"Intruduce.h"
     4 #include"PlayGame.h"
     5 
     6 int map1[ROW][COL] = {
     7     { 0,0,1,1,1,0,0,0}, //0代表空白
     8     { 0,0,1,2,1,0,0,0},  //1代表墙
     9     { 0,0,1,0,1,1,1,1},  //3代表箱子
    10     { 1,1,1,3,3,0,2,1},
    11     { 1,2,0,3,6,1,1,1},
    12     { 1,1,1,1,3,1,0,0},
    13     { 0,0,0,1,2,1,0,0},
    14     { 0,0,0,1,1,1,0,0} };
    15 int map2[ROW][COL] = {
    16     { 0,1,1,1,1,1,1,0 }, //0代表空白
    17 { 0,1,0,0,0,0,1,1 }, //1代表墙
    18 { 1,1,2,1,1,3,0,1 },  //2代表目的地
    19 { 1,0,2,2,3,0,0,1 },  //3代表箱子
    20 { 1,0,0,1,3,0,0,1 },  //6代表人
    21 { 1,0,0,6,0,1,1,1 },
    22 { 1,1,1,1,1,1,0,0 } };
    23 int map3[ROW][COL] = {
    24     { 1,1,1,1,1,1,1,1}, //0代表空白
    25     { 1,1,0,6,0,1,1,1}, //1代表墙
    26     { 1,1,3,1,3,0,0,1},  //2代表目的地
    27     { 1,0,0,0,0,1,0,1},  //3代表箱子
    28     { 1,1,2,2,3,3,2,1},  //6代表人
    29 
    30     { 1,1,0,2,0,1,1,1},
    31     { 1,1,1,0,0,1,1,1},
    32     { 1,1,1,1,1,1,1,1} };
    33 
    34 int lastmap1[STEP][ROW][COL];
    35 int lastmap2[STEP][ROW][COL];
    36 int lastmap3[STEP][ROW][COL];
    37 int stepNumber = 0;  //步数
    38 int flag = 0;  //是否按ESC退出
    39 
    40 
    41 int main()
    42 {
    43     int select;
    44 
    45     intruduce();
    46     scanf_s("%d", &select);
    47     system("cls");
    48     switch (select)
    49     {
    50     case 1:
    51         gotoxy(0, 0);
    52         playGame(map1, lastmap1);
    53         break;
    54     case 2:
    55         gotoxy(0, 0);
    56         playGame(map2, lastmap2);
    57         break;
    58     case 3:
    59         gotoxy(0, 0);
    60         playGame(map3, lastmap3);
    61         break;
    62     default:
    63         break;
    64     }
    65 
    66     getchar();
    67     return 0;
    68 }
    View Code

    PlayGame.cpp

      1 #include"main.h"
      2 #include"PlayGame.h"
      3 #include"GoBack.h"
      4 #include"Intruduce.h"
      5 
      6 //打印当前地图
      7 void DrawMap(int map[][COL])
      8 {
      9     for (int i = 0; i < ROW; i++)
     10     {
     11         for (int j = 0; j < COL; j++)
     12         {
     13             switch (map[i][j])
     14             {
     15             case 0:
     16                 printf("  ");
     17                 break;
     18             case 1:
     19                 printf("");
     20                 break;
     21             case 2:
     22                 printf("");
     23                 break;
     24             case 3:
     25             case 5:
     26                 printf("");
     27                 break;
     28             case 6:
     29             case 8:
     30                 printf("");
     31                 break;
     32             }
     33         }
     34         printf("
    ");
     35     }
     36 }
     37 
     38 //得到人的当前位置
     39 void position(int *pRow, int *pCol, int map[][COL])  
     40 {
     41     for (int i = 0; i < ROW; i++)
     42     {
     43         for (int j = 0; j < COL; j++)
     44         {
     45             if (map[i][j] == 6 || map[i][j] == 8)
     46             {
     47                 *pRow = i;
     48                 *pCol = j;
     49                 break; //由于最多只有一个,所以找到一个即可以跳出循环
     50             }
     51         }
     52     }
     53 }
     54 
     55 //控制人的移动
     56 void move(int *pRow, int *pCol, int map[][COL], int lastmap[][ROW][COL])
     57 {
     58     int r = *pRow, c = *pCol;
     59     char ch = _getch();
     60 
     61     reserveMap(map, lastmap);
     62     switch (ch)
     63     {
     64     case 'W':
     65     case 'w':
     66         if ((r > 0) && (map[r - 1][c] == 0 || map[r - 1][c] == 2))  //上面第一个为空地或目的地,人上移
     67         {
     68             map[r - 1][c] += 6;
     69             map[r][c] -= 6;
     70         }
     71         else if ((r > 0) && (map[r - 1][c] == 3 || map[r - 1][c] == 5))   //上面一个是箱子,要先判断箱子上方的情况
     72         {
     73             if ((r > 1) && (map[r - 2][c] == 0 || map[r - 2][c] == 2))  //如果箱子箱子上方是空的或目的地
     74             {
     75                 map[r - 2][c] += 3;  //箱子移来标值加3
     76                 map[r - 1][c] += 3;  //箱子移走-3,人以来+6
     77                 map[r][c] -= 6;
     78             }
     79         }
     80         system("cls");
     81         DrawMap(map);
     82         stepNumber++;
     83         break;
     84     case 'S':
     85     case 's':
     86         if ((r < ROW - 1) && (map[r + 1][c] == 0 || map[r + 1][c] == 2))  //上面第一个为空地或目的地,人上移
     87         {
     88             map[r + 1][c] += 6;
     89             map[r][c] -= 6;
     90         }
     91         else if ((r < ROW - 1) && (map[r + 1][c] == 3 || map[r + 1][c] == 5))   //上面一个是箱子,要先判断箱子上方的情况
     92         {
     93             if ((r < ROW - 2) && (map[r + 2][c] == 0 || map[r + 2][c] == 2))  //如果箱子箱子上方是空的或目的地
     94             {
     95                 map[r + 2][c] += 3;  //箱子移来标值加3
     96                 map[r + 1][c] += 3;  //箱子移走-3,人以来+6
     97                 map[r][c] -= 6;
     98             }
     99         }
    100         system("cls");
    101         DrawMap(map);
    102         stepNumber++;
    103         break;
    104     case 'A':
    105     case 'a':
    106         if ((c > 0) && (map[r][c - 1] == 0 || map[r][c - 1] == 2))  //上面第一个为空地或目的地,人上移
    107         {
    108             map[r][c - 1] += 6;
    109             map[r][c] -= 6;
    110         }
    111         else if ((c > 0) && (map[r][c - 1] == 3 || map[r][c - 1] == 5))   //上面一个是箱子,要先判断箱子上方的情况
    112         {
    113             if ((c > 1) && (map[r][c - 2] == 0 || map[r][c - 2] == 2))  //如果箱子箱子上方是空的或目的地
    114             {
    115                 map[r][c - 2] += 3;  //箱子移来标值加3
    116                 map[r][c - 1] += 3;  //箱子移走-3,人以来+6
    117                 map[r][c] -= 6;
    118             }
    119         }
    120         system("cls");
    121         DrawMap(map);
    122         stepNumber++;
    123         break;
    124     case 'D':
    125     case 'd':
    126         if ((c < COL - 1) && (map[r][c + 1] == 0 || map[r][c + 1] == 2))  //上面第一个为空地或目的地,人上移
    127         {
    128             map[r][c + 1] += 6;
    129             map[r][c] -= 6;
    130         }
    131         else if ((c < COL - 1) && (map[r][c + 1] == 3 || map[r][c + 1] == 5))   //上面一个是箱子,要先判断箱子上方的情况
    132         {
    133             if ((c < COL - 2) && (map[r][c + 2] == 0 || map[r][c + 2] == 2))  //如果箱子箱子上方是空的或目的地
    134             {
    135                 map[r][c + 2] += 3;  //箱子移来标值加3
    136                 map[r][c + 1] += 3;  //箱子移走-3,人以来+6
    137                 map[r][c] -= 6;
    138             }
    139         }
    140         system("cls");
    141         DrawMap(map);
    142         stepNumber++;
    143         break;
    144     case 'K':
    145     case 'k':
    146         stepNumber--;
    147         if (stepNumber < 0)        //处理第一步就撤回的情况
    148         {
    149             printf("Can not back!");
    150             stepNumber++;
    151             break;
    152         }
    153         goBack(map, lastmap);
    154         system("cls");
    155         DrawMap(map);
    156         if (stepNumber == 0)
    157         {
    158             gotoxy(20, 20);
    159             printf("Can not back!");
    160             stepNumber++;
    161         }
    162         break;
    163     case 'Q':
    164     case 'q':
    165         flag = 1;
    166         break;
    167     default:
    168         break;
    169     }
    170 }
    171 
    172 //判断是否已获胜
    173 bool testWin(int *pRow, int *pCol, int map[][COL])
    174 {
    175     int i, j, count = 0;  //count表示未填目的地的数量
    176     int r = *pRow, c = *pCol;
    177     for (i = 0; i < ROW; i++)
    178         for (j = 0; j < COL; j++)
    179             if (map[i][j] == 2)
    180                 count++;
    181     if ((!count) && (map[r][c] != 8))  //
    182         return true;  //目的地被填满,返回true
    183     else
    184         return false;  //还未被填满,放回flase
    185 }
    186 
    187 //玩游戏
    188 void playGame(int map[][COL], int lastmap[][ROW][COL])
    189 {
    190     int pRow, pCol;
    191 
    192     DrawMap(map);
    193     position(&pRow, &pCol, map);
    194     do
    195     {
    196         move(&pRow, &pCol, map, lastmap);
    197         position(&pRow, &pCol, map);
    198     } while (!testWin(&pRow, &pCol, map) && (flag == 0));
    199     if (testWin(&pRow, &pCol, map) == 1)
    200     {
    201         printf("You win!
    ");
    202         getchar();
    203     }
    204 }
    View Code

    Intruduce.cpp

     1 #include"main.h"
     2 #include"Intruduce.h"
     3 
     4 void gotoxy(int x, int y)//函数gotoxy:定义光标位置
     5 {
     6     COORD coord;//坐标系coord 
     7     HANDLE handle;
     8 
     9     coord.X = x;//横坐标X 
    10     coord.Y = y;//纵坐标 y
    11     handle = GetStdHandle(STD_OUTPUT_HANDLE);
    12     SetConsoleCursorPosition(handle, coord);
    13 }
    14 
    15 void hidecursor()//函数hidecursor:隐藏光标
    16 {
    17     CONSOLE_CURSOR_INFO curinfo;
    18     HANDLE Out;
    19 
    20     Out = GetStdHandle(STD_OUTPUT_HANDLE);
    21     curinfo.dwSize = 1;//光标百分比厚度:1~100
    22     curinfo.bVisible = 0;//是否可见
    23     SetConsoleCursorInfo(Out, &curinfo);
    24 } 
    25 
    26 void intruduce()
    27 {
    28     int i;
    29     system("cls");
    30     HANDLE consolehwnd;//创建句柄
    31     consolehwnd = GetStdHandle(STD_OUTPUT_HANDLE);
    32     SetConsoleTextAttribute(consolehwnd, FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    33     //设置为亮白色 
    34 
    35     hidecursor();
    36     for (i = 14; i < 39; i++)
    37     {
    38         gotoxy(i * 2, 4);
    39         printf("");
    40     }
    41 
    42     for (i = 5; i < 20; i++)
    43     {
    44         gotoxy(28, i);
    45         printf("");
    46         gotoxy(76, i);
    47         printf("");
    48     }
    49 
    50     gotoxy(47, 5);
    51     printf("推箱子1.0");
    52 
    53     for (i = 15; i < 38; i++)
    54     {
    55         gotoxy(i * 2, 6);
    56         printf("");
    57     }
    58     gotoxy(47, 7);
    59     printf("规则说明");
    60 
    61     gotoxy(30, 9);
    62     printf("1.共有三个关卡");
    63     gotoxy(30, 10);
    64     printf("2.按1选择关卡,按2选择关卡二,按3选择关卡三");
    65     gotoxy(30, 11);
    66     printf("3.WSAD控制上下左右,K撤回,Q退出");
    67     gotoxy(30, 12);
    68     printf("4.进入游戏前请关闭中文输入法");
    69 
    70 
    71 
    72     for (i = 15; i < 38; i++)
    73     {
    74         gotoxy(i * 2, 17);
    75         printf("");
    76     }
    77 
    78     for (i = 14; i < 39; i++)
    79     {
    80         gotoxy(i * 2, 20);
    81         printf("");
    82     }
    83 
    84     gotoxy(49, 18);
    85     printf("关卡:");
    86 }
    View Code

    GoBack.cpp

     1 #include"main.h"
     2 #include"GoBack.h"
     3 
     4 //将map保存到lastmap
     5 void reserveMap(int map[][COL], int lastmap[][ROW][COL])
     6 {
     7     for (int i = 0; i < ROW; i++)
     8         for (int j = 0; j < COL; j++)
     9             lastmap[stepNumber][i][j] = map[i][j];
    10 }
    11 
    12 //将lastmap还原到map
    13 void goBack(int map[][COL], int lastmap[][ROW][COL])
    14 {
    15     //reserveMap(map, lastmap1, stepNumber);
    16     for (int i = 0; i < ROW; i++)
    17         for (int j = 0; j < COL; j++)
    18             map[i][j] = lastmap[stepNumber][i][j];
    19 }
    View Code

    main.h

     1 #include<stdio.h>
     2 #include<Windows.h>
     3 #include<conio.h>
     4 #define KIND 3
     5 #define STEP 20
     6 #define ROW 20
     7 #define COL 20
     8 
     9 extern int map1[ROW][COL], map2[ROW][COL], map3[ROW][COL];        //记录初始地图
    10 extern int lastmap1[STEP][ROW][COL],lastmap2[STEP][ROW][COL],lastmap3[STEP][ROW][COL];    //记录当前地图的前一幅
    11 extern int stepNumber;        //步数
    12 extern int flag;            //是否按ESC退出
    View Code

    PlayGame.h

    1 void DrawMap(int map[][COL]);
    2 void position(int *pRow, int *pCol, int map[][COL]);
    3 void move(int *pRow, int *pCol, int map[][COL], int lastmap[][ROW][COL]);
    4 bool testWin(int *pRow, int *pCol, int map[][COL]);
    5 void playGame(int map[][COL], int lastmap[][ROW][COL]);
    View Code

    Intruduce.h

    1 void gotoxy(int x, int y);
    2 void hidecursor();
    3 void intruduce();
    View Code

    GoBack.h

    1 #include"main.h"
    2 void reserveMap(int map[][COL], int lastmap[][ROW][COL]);
    3 void goBack(int map[][COL], int lastmap[][ROW][COL]);
    View Code

    在VS2017里新建项目,添加上面的每一项,复制粘贴,实测能够运行。

    参考链接:百度百科  推箱子

  • 相关阅读:
    HashMap原理
    高并发架构系列:MQ消息队列的12点核心原理总结
    大话程序员系列:一张图道尽程序员的出路
    java面试题
    SpringBoot框架的使用
    java开发定时任务执行时间
    OpenLayers 3 扩展插件收集
    Vue-cli webpack模板
    Spring的属性文件properties使用注意
    FullBg-网页图片背景自适应大小
  • 原文地址:https://www.cnblogs.com/lfri/p/9888788.html
Copyright © 2020-2023  润新知