nelson33

Untitled

Jan 13th, 2023
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.16 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.         game_log("%s\n", filepath);
  116.         pFile = fopen("Assets/map_nthu.txt","r");
  117.         if (!pFile) {
  118.             game_abort("error to open map file\n");
  119.             return NULL;
  120.         }
  121.         if(fscanf(pFile,"%d %d", &M->row_num, &M->col_num) != 2) {
  122.             game_abort("Map format unmatched\n");
  123.             return NULL;
  124.         }
  125.         getc(pFile); // get the '\n'*/
  126.     }
  127.  
  128.     /*
  129.     [TODO]
  130.     Allocate a 2-Dimension dynamic char array for recording Map
  131.     */
  132.     M->map = (char**)malloc(sizeof(char*) * M->row_num);
  133.     if (!M->map) {
  134.         game_abort(stderr, "map char array malloc error\n");
  135.         return NULL;
  136.     }
  137.     for (int i = 0; i < M->row_num; i++) {
  138.         M->map[i] = (char*)malloc(sizeof(char) * (M->col_num));
  139.         if(!M->map[i]){
  140.             game_abort(stderr, "map char array malloc error\n");
  141.             return NULL;
  142.         }
  143.     }
  144.     /*
  145.         [TODO]
  146.         read file to map[row][col]
  147.         '#' -> wall
  148.         '.' -> beans
  149.         'B' -> room of ghost
  150.         'P' -> Power Pellets
  151.     */
  152.  
  153.     M->wallnum = M->beansCount = 0;
  154.     for (int i = 0; i < M->row_num; i++) {
  155.         for (int j = 0; j < M->col_num; j++) {
  156.             if (filepath == NULL)
  157.             // [HACKATHON 0-1]
  158.             // You can just switch to nthu_map if you want to finish HACKATHON 0 later.
  159.             //  M->map[i][j] = default_map[i][j];
  160.                 M->map[i][j] = nthu_map[i][j];
  161.             else
  162.                 // [HACKATHON 0-2]
  163.                 // read the map from file just like read from default_map
  164.                 fscanf(pFile,"%c",&M->map[i][j]);
  165.             switch(M->map[i][j]) {
  166.             case '#':
  167.                 M->wallnum++;
  168.                 break;
  169.             case '.':
  170.                 M->beansCount++;
  171.                 break;
  172.             default:
  173.                 break;
  174.             }
  175.         }
  176.         if(filepath != NULL)
  177.             getc(pFile);
  178.     }
  179.     M->beansNum = M->beansCount;
  180.     return M;
  181. }
  182.  
  183. void delete_map(Map* M) {
  184.     if (!M)
  185.         return;
  186.     // [TODO]
  187.     // you should free the dynamic allocated part of Map* M at here;
  188.     if (M->map)
  189.     {
  190.         for (int i = 0; i < M; i++)
  191.             free(M->map[i]);
  192.         free(M->map);
  193.     }
  194.     free(M);
  195. }
  196.  
  197.  
  198. void draw_map(Map const* M) {
  199.     if (M == NULL) {
  200.         game_abort("error map!\n");
  201.         return;
  202.     }
  203.     /*
  204.         [TODO]
  205.         draw the map according to M->map
  206.     */
  207.     for (int row = 0; row < M->row_num; row++) {
  208.         for (int col = 0; col < M->col_num; col++) {
  209.             switch (M->map[row][col])
  210.             {
  211.                 case '#':
  212.                     draw_block_index(M, row, col);
  213.                     break;
  214.                 // [ TODO ]
  215.                 // draw the power bean
  216.                 /*
  217.                 case 'P':
  218.                     draw_power_bean(...);
  219.                     break;
  220.                 */
  221.                 case '.':
  222.                     draw_bean(M, row, col);
  223.                     break;
  224.                 default:
  225.                     break;
  226.             }
  227.         }
  228.     }
  229.     /*
  230.         for(...){
  231.             for(...)
  232.                 switch(M->map[][])
  233.                 {
  234.                 case '#':
  235.                     ...
  236.                 case '.':
  237.                     ...
  238.                 case 'P':
  239.                     ...
  240.                 }
  241.         }
  242.     */
  243. }
  244.  
  245. static void draw_block_index(Map* M, const int row, const int col) {
  246.     bool U = is_wall_block(M, col, row - 1);
  247.     bool UR = is_wall_block(M, col + 1, row - 1);
  248.     bool UL = is_wall_block(M, col -1, row- 1);
  249.     bool B = is_wall_block(M, col, row+ 1);
  250.     bool BR = is_wall_block(M, col + 1, row + 1);
  251.     bool BL = is_wall_block(M, col - 1, row + 1);
  252.     bool R = is_wall_block(M, col + 1, row);
  253.     bool L = is_wall_block(M, col - 1,row);
  254.     if (!(U && UR && UL && B && BR && BL && R && L)) {
  255.     int s_x, s_y, e_x, e_y, dw;
  256.     int block_x = map_offset_x + block_width * col;
  257.     int block_y = map_offset_y + block_height * row;
  258.     dw = block_width / 3;
  259.         s_x = block_x + dw;
  260.         s_y = block_y+ dw;
  261.         e_x = s_x + dw;
  262.         e_y = s_y + dw;
  263.  
  264.         al_draw_filled_rectangle(s_x, s_y,
  265.             e_x, e_y, al_map_rgb(255, 204, 204));
  266.         if (row < M->row_num - 1 && B && !(BL && BR && R && L)) {
  267.             s_x = block_x + dw;
  268.             s_y = block_y + dw;
  269.             e_x = s_x + dw;
  270.             e_y = block_y + block_height;
  271.             al_draw_filled_rectangle(s_x, s_y,
  272.                 e_x, e_y, al_map_rgb(255, 204, 204));
  273.         }
  274.         if (row > 0 && U && !(UL && UR && R && L)) {
  275.             s_x = block_x + dw;
  276.             s_y = block_y + (dw << 1);
  277.             e_x = s_x + dw;
  278.             e_y = block_y;
  279.             al_draw_filled_rectangle(s_x, s_y,
  280.                 e_x, e_y, al_map_rgb(255, 204, 204));
  281.         }
  282.         if (col < M->col_num - 1 && R && !(UR && BR && U && B)) {
  283.             s_x = block_x + dw;
  284.             s_y = block_y + dw;
  285.             e_x = block_x + block_width;
  286.             e_y = s_y + dw;
  287.             al_draw_filled_rectangle(s_x, s_y,
  288.                 e_x, e_y, al_map_rgb(170,170,180));
  289.  
  290.         }
  291.         if (col > 0 && L && !(UL && BL && U && B)) {
  292.             s_x = block_x;
  293.             s_y = block_y + dw;
  294.             e_x = s_x + (dw << 1);
  295.             e_y = s_y + dw;
  296.             al_draw_filled_rectangle(s_x, s_y,
  297.                 e_x, e_y, al_map_rgb(170,170,180));
  298.         }
  299.     }
  300. }
  301.  
  302. static void draw_bean(Map* M, const int row, const int col) {
  303.     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(99, 99, 240));
  304. }
  305.  
  306. static void draw_power_bean(Map* M, const int row, const int col) {
  307.     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(99, 99, 240));
  308. }
  309.  
  310.  
  311. bool is_wall_block(Map* M, int index_x, int index_y) {
  312.     if (index_x < 0 || index_x >= M->col_num || index_y < 0 || index_y >= M->row_num)
  313.         return true;
  314.     return M->map[index_y][index_x] == '#';
  315. }
  316. bool is_room_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] == 'B';
  320. }
  321.  
  322.  
  323. Directions shortest_path_direc(Map* M, int startGridx, int startGridy, int endGridx, int endGridy) {
  324.     // [NOTODO]
  325.     // Here is a complete function return the next direction of the shorstest path.
  326.     // Given Map, start point and end point.
  327.     // It will tell you where to go for the shortest path.
  328.     // !NOTICE! if your map grow really large, the size of queue, may become not enough.
  329.     // Hint: You can alter this function and make it return direction and also the distance for your usage.
  330.  
  331.  
  332. static int8_t queue_x[QUEUE_SIZE];
  333. static int8_t queue_y[QUEUE_SIZE];
  334. static  uint16_t front;
  335. static  uint16_t end;
  336.  
  337.     static Directions steped[MAX_WALL_NUM_H][MAX_WALL_NUM_W];
  338.     memset(steped, 0, sizeof(steped)); // set as NONE;
  339.  
  340.     front = end = 0;
  341.     queue_x[end] = startGridx;
  342.     queue_y[end] = startGridy;
  343.     steped[startGridy][startGridx] = 1; /*  for dummy just means that startGrid have been visited.  */
  344.  
  345.     end++;
  346.  
  347.     for (size_t i = 0; i < 4; i++) {
  348.         int8_t x = queue_x[front] + four_probe[i][0];
  349.         int8_t y = queue_y[front] + four_probe[i][1];
  350.         if (is_wall_block(M, x, y) || steped[y][x])
  351.             continue;
  352.         queue_x[end] = x;
  353.         queue_y[end] = y;
  354.         switch (i) {
  355.             case 0:
  356.                 steped[y][x] = RIGHT;
  357.                 break;
  358.             case 1:
  359.                 steped[y][x] = DOWN;
  360.                 break;
  361.             case 2:
  362.                 steped[y][x] = LEFT;
  363.                 break;
  364.             case 3:
  365.                 steped[y][x] = UP;
  366.                 break;
  367.             default:
  368.                 break;
  369.         }
  370.         end++;
  371.     }
  372.     front++;
  373.  
  374.     while (front != end && steped[endGridy][endGridx] == NONE) {
  375.  
  376.         for (size_t i = 0; i < 4; i++) {
  377.             int8_t x = queue_x[front] + four_probe[i][0];
  378.             int8_t y = queue_y[front] + four_probe[i][1];
  379.             if (is_wall_block(M, x, y) || steped[y][x])
  380.                 continue;
  381.             queue_x[end] = x;
  382.             queue_y[end] = y;
  383.             steped[y][x] = steped[queue_y[front]][queue_x[front]];
  384.             end++;
  385.         }
  386.         front++;
  387.     }
  388.     return steped[endGridy][endGridx];
  389. }
Advertisement
Add Comment
Please, Sign In to add comment