nelson33

Untitled

Jan 13th, 2023
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.07 KB | Source Code | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <allegro5/allegro_primitives.h>
  5. #include "game.h"
  6. #include "map.h"
  7. #define QUEUE_SIZE 3000
  8.  
  9. /*global variables*/
  10. // [ NOTE ]
  11. const int block_width = 21,  block_height = 21;         // the pixel size of a "block"
  12. const int map_offset_x = 25, map_offset_y = 50;         // pixel offset of where to start draw map
  13. const int four_probe[4][2] = {{ 1, 0 }, { 0, 1 }, { -1,0 }, { 0, -1 }};
  14.  
  15. /* Declare static function prototypes. */
  16. static void draw_block_index(Map* M, int row, int col);
  17. static void draw_bean(Map* M, const int row, const int col);
  18. static void draw_power_bean(Map* M, const int row, const int col);
  19.  
  20. const char* nthu_map[] = {
  21.     "#####################################",
  22.     "#..................###.........#####",
  23.     "#.####.###########.....#######.....#",
  24.     "#.####.#...........###.....# #.###.#",
  25.     "#.P......#########.....#.#.###.# #.#",
  26.     "#.#####.###      ###.###.#.#P#.# #.#",
  27.     "#.#   #...#        #.###.#.#.#.# #.#",
  28.     "#.#   #.#.#        #.###.#...#.# #.#",
  29.     "#.#####.#.##########.###.#####.###.#",
  30.     "#..................................#",
  31.     "#.#######.########.##BBB##.##.####.#",
  32.     "#.###  ##.########.##BBB##.##.#P##.#",
  33.     "#.#### ##....##....##BBB##.##.#.##.#",
  34.     "#.## ####.##.##.##.#######.##.#.##.#",
  35.     "#.##  ###.##.##.##.#######.##...##.#",
  36.     "#.##   ##.##.##.##.##   ##.#######.#",
  37.     "#.#######.##.##.##.#######.#######.#",
  38.     "#..................................#",
  39.     "#.######.###.##########.######.###.#",
  40.     "#.#    #.###.#####   #.........# #.#",
  41.     "#.######.........#####.###.###.# #.#",
  42.     "#........#######.......# #.# #.# #.#",
  43.     "#.######.#     #####.### #.# #.###.#",
  44.     "#.#    #.###########.#####.###.....#",
  45.     "#.######.#.....P.............#.###.#",
  46.     "#..........#########.#######.#.# #.#",
  47.     "#.#######.##########.#     #...# #.#",
  48.     "#.#######............#######.#.###.#",
  49.     "#.........##########.........#.....#",
  50.     "####################################"
  51. };
  52.  
  53. const char* default_map[] = {
  54.     "####################################",
  55.     "#                                  #",
  56.     "#                                  #",
  57.     "#                                  #",
  58.     "#                                  #",
  59.     "#                                  #",
  60.     "#                                  #",
  61.     "#                                  #",
  62.     "#                                  #",
  63.     "#                                  #",
  64.     "#                    BBB           #",
  65.     "#                    BBB           #",
  66.     "#                    BBB           #",
  67.     "#                                  #",
  68.     "#                                  #",
  69.     "#                                  #",
  70.     "#                                  #",
  71.     "#                                  #",
  72.     "#                                  #",
  73.     "#                                  #",
  74.     "#                                  #",
  75.     "#                                  #",
  76.     "#                                  #",
  77.     "#                                  #",
  78.     "#                                  #",
  79.     "#                                  #",
  80.     "#                                  #",
  81.     "#                                  #",
  82.     "#                                  #",
  83.     "####################################",
  84. };
  85.  
  86.  
  87. Map* create_map(const char * filepath) {
  88.  
  89. // [HACKATHON 0]
  90. // TODO: Read the map from "Assets/map_nthu.txt"
  91. // ~~~~~~~~!!!!!!!!!!!!!!!!!!!!!!!!!!!~~~~~~~~~
  92. // Description: So for this part, you don't have to really finish them during hackathon.
  93. // You can just copy the map data in "map_nthu.txt" to the array `default_map`
  94. // Or just use the array `nthu_map` in your Map Data.
  95. // But we suggest you to finish this part if you have time since this is one of
  96. // the grading part in Basic part in Final_Project_Rules.
  97. /* ----------------------------- start of default map code*/
  98.  
  99.     Map* M = (Map*)malloc(sizeof(Map));
  100.     FILE* pFile = NULL;
  101.     if (!M) {
  102.         game_abort("Error when creating Map");
  103.         return NULL;
  104.     }
  105.     if (filepath == NULL) {
  106.         M->row_num = 30;
  107.         M->col_num = 36;
  108.         game_log("Creating from default map. row = %d col = %d", M->row_num, M->col_num);
  109.        
  110.     }
  111.     else {
  112.         // [HACKATHON 0-1]
  113.         // use fopen to create a file FILE* type
  114.         // use pFile can fscanf do reading from file just like read from command line.
  115.         /*
  116.         game_log("%s\n", filepath);
  117.         pFile = fopen(...);
  118.         if (!pFile) {
  119.             game_abort("error to open map file\n");
  120.             return NULL;
  121.         }
  122.         if(fscanf(...) != 2) {
  123.             game_abort("Map format unmatched\n");
  124.             return NULL;
  125.         }
  126.         getc(pFile); // get the '\n'
  127.         */
  128.     }
  129.  
  130.     /*
  131.     [TODO]
  132.     Allocate a 2-Dimension dynamic char array for recording Map
  133.     */
  134.     M->map = (char**)malloc(sizeof(char*) * M->row_num);
  135.     if (!M->map) {
  136.         game_abort(stderr, "map char array malloc error\n");
  137.         return NULL;
  138.     }
  139.     for (int i = 0; i < M->row_num; i++) {
  140.         M->map[i] = (char*)malloc(sizeof(char) * (M->col_num));
  141.         if(!M->map[i]){
  142.             game_abort(stderr, "map char array malloc error\n");
  143.             return NULL;
  144.         }
  145.     }
  146.     /*
  147.         [TODO]
  148.         read file to map[row][col]
  149.         '#' -> wall
  150.         '.' -> beans
  151.         'B' -> room of ghost
  152.         'P' -> Power Pellets
  153.     */
  154.  
  155.     M->wallnum = M->beansCount = 0;
  156.     for (int i = 0; i < M->row_num; i++) {
  157.         for (int j = 0; j < M->col_num; j++) {
  158.             if (filepath == NULL)
  159.             // [HACKATHON 0-1]
  160.             // You can just switch to nthu_map if you want to finish HACKATHON 0 later.
  161.             //  M->map[i][j] = default_map[i][j];
  162.                 M->map[i][j] = nthu_map[i][j];
  163.             else
  164.                 // [HACKATHON 0-2]
  165.                 // read the map from file just like read from default_map
  166.                 /*
  167.                 fscanf(...);
  168.                 */
  169.             switch(M->map[i][j]) {
  170.             case '#':
  171.                 M->wallnum++;
  172.                 break;
  173.             case '.':
  174.                 M->beansCount++;
  175.                 break;
  176.             default:
  177.                 break;
  178.             }
  179.         }
  180.         if(filepath != NULL)
  181.             getc(pFile);
  182.     }
  183.     M->beansNum = M->beansCount;
  184.     return M;
  185. }
  186.  
  187. void delete_map(Map* M) {
  188.     if (!M)
  189.         return;
  190.     // [TODO]
  191.     // you should free the dynamic allocated part of Map* M at here;
  192.     /*
  193.     if(M->map)
  194.     {
  195.         ...
  196.         free(...)
  197.         ...
  198.     */
  199.     free(M);
  200. }
  201.  
  202.  
  203. void draw_map(Map const* M) {
  204.     if (M == NULL) {
  205.         game_abort("error map!\n");
  206.         return;
  207.     }
  208.     /*
  209.         [TODO]
  210.         draw the map according to M->map
  211.     */
  212.     for (int row = 0; row < M->row_num; row++) {
  213.         for (int col = 0; col < M->col_num; col++) {
  214.             switch (M->map[row][col])
  215.             {
  216.                 case '#':
  217.                     draw_block_index(M, row, col);
  218.                     break;
  219.                 // [ TODO ]
  220.                 // draw the power bean
  221.                 /*
  222.                 case 'P':
  223.                     draw_power_bean(...);
  224.                     break;
  225.                 */
  226.                 case '.':
  227.                     draw_bean(M, row, col);
  228.                     break;
  229.                 default:
  230.                     break;
  231.             }
  232.         }
  233.     }
  234.     /*
  235.         for(...){
  236.             for(...)
  237.                 switch(M->map[][])
  238.                 {
  239.                 case '#':
  240.                     ...
  241.                 case '.':
  242.                     ...
  243.                 case 'P':
  244.                     ...
  245.                 }
  246.         }
  247.     */
  248. }
  249.  
  250. static void draw_block_index(Map* M, const int row, const int col) {
  251.     bool U = is_wall_block(M, col, row - 1);
  252.     bool UR = is_wall_block(M, col + 1, row - 1);
  253.     bool UL = is_wall_block(M, col -1, row- 1);
  254.     bool B = is_wall_block(M, col, row+ 1);
  255.     bool BR = is_wall_block(M, col + 1, row + 1);
  256.     bool BL = is_wall_block(M, col - 1, row + 1);
  257.     bool R = is_wall_block(M, col + 1, row);
  258.     bool L = is_wall_block(M, col - 1,row);
  259.     if (!(U && UR && UL && B && BR && BL && R && L)) {
  260.     int s_x, s_y, e_x, e_y, dw;
  261.     int block_x = map_offset_x + block_width * col;
  262.     int block_y = map_offset_y + block_height * row;
  263.     dw = block_width / 3;
  264.         s_x = block_x + dw;
  265.         s_y = block_y+ dw;
  266.         e_x = s_x + dw;
  267.         e_y = s_y + dw;
  268.  
  269.         al_draw_filled_rectangle(s_x, s_y,
  270.             e_x, e_y, al_map_rgb(25, 154, 25));
  271.         if (row < M->row_num - 1 && B && !(BL && BR && R && L)) {
  272.             s_x = block_x + dw;
  273.             s_y = block_y + dw;
  274.             e_x = s_x + dw;
  275.             e_y = block_y + block_height;
  276.             al_draw_filled_rectangle(s_x, s_y,
  277.                 e_x, e_y, al_map_rgb(25, 154, 25));
  278.         }
  279.         if (row > 0 && U && !(UL && UR && R && L)) {
  280.             s_x = block_x + dw;
  281.             s_y = block_y + (dw << 1);
  282.             e_x = s_x + dw;
  283.             e_y = block_y;
  284.             al_draw_filled_rectangle(s_x, s_y,
  285.                 e_x, e_y, al_map_rgb(25, 154, 25));
  286.         }
  287.         if (col < M->col_num - 1 && R && !(UR && BR && U && B)) {
  288.             s_x = block_x + dw;
  289.             s_y = block_y + dw;
  290.             e_x = block_x + block_width;
  291.             e_y = s_y + dw;
  292.             al_draw_filled_rectangle(s_x, s_y,
  293.                 e_x, e_y, al_map_rgb(25, 154, 25));
  294.  
  295.         }
  296.         if (col > 0 && L && !(UL && BL && U && B)) {
  297.             s_x = block_x;
  298.             s_y = block_y + dw;
  299.             e_x = s_x + (dw << 1);
  300.             e_y = s_y + dw;
  301.             al_draw_filled_rectangle(s_x, s_y,
  302.                 e_x, e_y, al_map_rgb(25, 154, 25));
  303.         }
  304.     }
  305. }
  306.  
  307. static void draw_bean(Map* M, const int row, const int col) {
  308.     al_draw_filled_circle(map_offset_x + col * block_width + block_width / 2.0, map_offset_y + row * block_height + block_height / 2.0, block_width/6.0,  al_map_rgb(234, 38, 38));
  309. }
  310.  
  311. static void draw_power_bean(Map* M, const int row, const int col) {
  312.     al_draw_filled_circle(map_offset_x + col * block_width + block_width / 2.0, map_offset_y + row * block_height + block_height / 2.0, block_width / 3.0, al_map_rgb(234, 178, 38));
  313. }
  314.  
  315.  
  316. bool is_wall_block(Map* M, int index_x, int index_y) {
  317.     if (index_x < 0 || index_x >= M->col_num || index_y < 0 || index_y >= M->row_num)
  318.         return true;
  319.     return M->map[index_y][index_x] == '#';
  320. }
  321. bool is_room_block(Map* M, int index_x, int index_y) {
  322.     if (index_x < 0 || index_x >= M->col_num || index_y < 0 || index_y >= M->row_num)
  323.         return true;
  324.     return M->map[index_y][index_x] == 'B';
  325. }
  326.  
  327.  
  328. Directions shortest_path_direc(Map* M, int startGridx, int startGridy, int endGridx, int endGridy) {
  329.     // [NOTODO]
  330.     // Here is a complete function return the next direction of the shorstest path.
  331.     // Given Map, start point and end point.
  332.     // It will tell you where to go for the shortest path.
  333.     // !NOTICE! if your map grow really large, the size of queue, may become not enough.
  334.     // Hint: You can alter this function and make it return direction and also the distance for your usage.
  335.  
  336.  
  337. static int8_t queue_x[QUEUE_SIZE];
  338. static int8_t queue_y[QUEUE_SIZE];
  339. static  uint16_t front;
  340. static  uint16_t end;
  341.  
  342.     static Directions steped[MAX_WALL_NUM_H][MAX_WALL_NUM_W];
  343.     memset(steped, 0, sizeof(steped)); // set as NONE;
  344.  
  345.     front = end = 0;
  346.     queue_x[end] = startGridx;
  347.     queue_y[end] = startGridy;
  348.     steped[startGridy][startGridx] = 1; /*  for dummy just means that startGrid have been visited.  */
  349.  
  350.     end++;
  351.  
  352.     for (size_t i = 0; i < 4; i++) {
  353.         int8_t x = queue_x[front] + four_probe[i][0];
  354.         int8_t y = queue_y[front] + four_probe[i][1];
  355.         if (is_wall_block(M, x, y) || steped[y][x])
  356.             continue;
  357.         queue_x[end] = x;
  358.         queue_y[end] = y;
  359.         switch (i) {
  360.             case 0:
  361.                 steped[y][x] = RIGHT;
  362.                 break;
  363.             case 1:
  364.                 steped[y][x] = DOWN;
  365.                 break;
  366.             case 2:
  367.                 steped[y][x] = LEFT;
  368.                 break;
  369.             case 3:
  370.                 steped[y][x] = UP;
  371.                 break;
  372.             default:
  373.                 break;
  374.         }
  375.         end++;
  376.     }
  377.     front++;
  378.  
  379.     while (front != end && steped[endGridy][endGridx] == NONE) {
  380.  
  381.         for (size_t i = 0; i < 4; i++) {
  382.             int8_t x = queue_x[front] + four_probe[i][0];
  383.             int8_t y = queue_y[front] + four_probe[i][1];
  384.             if (is_wall_block(M, x, y) || steped[y][x])
  385.                 continue;
  386.             queue_x[end] = x;
  387.             queue_y[end] = y;
  388.             steped[y][x] = steped[queue_y[front]][queue_x[front]];
  389.             end++;
  390.         }
  391.         front++;
  392.     }
  393.     return steped[endGridy][endGridx];
  394. }
Advertisement
Add Comment
Please, Sign In to add comment