148 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Created by snapshot112 on 6/10/2025
 | |
|  */
 | |
| 
 | |
| #include "maze_runner.h"
 | |
| 
 | |
| #include <ncurses.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include "../../engine/engine/grid_game_engine.h"
 | |
| 
 | |
| #define EMPTY ' '
 | |
| #define WALL '#'
 | |
| #define LIVING_PLAYER '*'
 | |
| #define DEAD_PLAYER '@'
 | |
| #define MAZE_EXIT '$'
 | |
| #define TRAP 'X'
 | |
| 
 | |
| /*
 | |
|  * Reads in the maze from the assets file.
 | |
|  *
 | |
|  * Side Effects:
 | |
|  * Memory is allocated to store the grid in.
 | |
|  */
 | |
| static grid *get_maze(void) {
 | |
|     // Open het doolhof bestand en lees het rooster.
 | |
|     FILE *fh = fopen("assets/maze.txt", "r");
 | |
|     if (fh == NULL) {
 | |
|         perror("loading maze");
 | |
|         return NULL;
 | |
|     }
 | |
|     grid *gp = grid_create_from_file(fh);
 | |
|     fclose(fh);
 | |
| 
 | |
|     // Bepaal of het lezen van het rooster is gelukt.
 | |
|     if (gp == NULL) {
 | |
|         fprintf(stderr, "Kan rooster niet maken.\n");
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     return gp;
 | |
| }
 | |
| 
 | |
| /* Voert de benodigde veranderingen in het rooster door als de speler in een
 | |
|  * bepaalde richting probeert te bewegen.
 | |
|  * Input:
 | |
|  * gp   : een pointer naar het rooster
 | |
|  * dx,dy: de richting waarin de speler probeert te bewegen. De vier mogelijk-
 | |
|  *        heden voor (dx,dy) zijn (-1,0), (1,0), (0,-1), (0,1) voor resp.
 | |
|  *        links, rechts, omhoog en omlaag.
 | |
|  *
 | |
|  * Side effect: het rooster wordt aangepast op basis van de handeling van
 | |
|  *              de speler.
 | |
|  */
 | |
| static void maze_runner_move(grid *gp, const int dx, const int dy) {
 | |
|     coordinate player_position = {0, 0};
 | |
|     grid_find(gp, LIVING_PLAYER, &player_position.x, &player_position.y);
 | |
| 
 | |
|     if (player_position.y == -1) {
 | |
|         printf("Player not found!");
 | |
|         grid_put_state(gp, STATE_BEGIN);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (grid_contains(gp, player_position.x + dx, player_position.y + dy) == 1) {
 | |
|         char new_location = grid_fetch(gp, player_position.x + dx, player_position.y + dy);
 | |
|         switch (new_location) {
 | |
|             case WALL:
 | |
|                 break;
 | |
|             case TRAP:
 | |
|                 grid_put_state(gp, STATE_VERLOREN);
 | |
| 
 | |
|                 enable_highlight(RED);
 | |
|                 update_grid(gp, DEAD_PLAYER, player_position.x, player_position.y);
 | |
|                 disable_highlight(RED);
 | |
|                 break;
 | |
|             case EMPTY:
 | |
|                 update_grid(gp, EMPTY, player_position.x, player_position.y);
 | |
|                 update_grid(gp, LIVING_PLAYER, player_position.x + dx, player_position.y + dy);
 | |
|                 break;
 | |
|             case MAZE_EXIT:
 | |
|                 update_grid(gp, EMPTY, player_position.x, player_position.y);
 | |
|                 grid_put_state(gp, STATE_GEWONNEN);
 | |
|                 break;
 | |
|         }
 | |
|         refresh();
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Speelt het spel met een gegeven rooster tot de toestand niet langer
 | |
|  * AAN_HET_SPELEN is.
 | |
|  *
 | |
|  * Input:
 | |
|  * gp: Een pointer naar het rooster.
 | |
|  *
 | |
|  * Side effects:
 | |
|  * Het rooster wordt ge-updated afhankelijk van de user input.
 | |
|  */
 | |
| static void speel_maze(grid *gp) {
 | |
|     switch (getch()) {
 | |
|         case KEY_UP: // fallthrough
 | |
|         case 'w':
 | |
|         case 'W':
 | |
|             maze_runner_move(gp, 0, -1);
 | |
|             break;
 | |
|         case KEY_DOWN: // fallthrough
 | |
|         case 's':
 | |
|         case 'S':
 | |
|             maze_runner_move(gp, 0, 1);
 | |
|             break;
 | |
|         case KEY_LEFT: // fallthrough
 | |
|         case 'a':
 | |
|         case 'A':
 | |
|             maze_runner_move(gp, -1, 0);
 | |
|             break;
 | |
|         case KEY_RIGHT: // fallthrough
 | |
|         case 'd':
 | |
|         case 'D':
 | |
|             maze_runner_move(gp, 1, 0);
 | |
|             break;
 | |
|         case 'p':
 | |
|         case KEY_BACKSPACE:
 | |
|         case KEY_ESCAPE:
 | |
|             grid_put_state(gp, STATE_QUIT);
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void maze_runner(void) {
 | |
|     // Voorbereiding.
 | |
|     grid *gp = get_maze();
 | |
|     if (gp == NULL) {
 | |
|         return;
 | |
|     }
 | |
|     show_grid(gp);
 | |
|     grid_put_state(gp, STATE_AAN_HET_SPELEN);
 | |
| 
 | |
|     // Game zelf.
 | |
|     while (grid_fetch_state(gp) == STATE_AAN_HET_SPELEN) {
 | |
|         speel_maze(gp);
 | |
|     }
 | |
| 
 | |
|     // Exit game.
 | |
|     game_exit_message(gp, (coordinate){0, grid_height(gp) + 2});
 | |
|     grid_cleanup(gp);
 | |
| }
 |