/* * Naam: Jeroen Boxhoorn * UvAnetID: 16333969 * Studie: BSc Informatica * * This program loads in a maze from a text file and then lets you play that maze. * * Params when running the program: * - The path to the text file containing the maze. * * How to play the game: * - You are the '*' character. * - Use either WSAD or the arrow keys to navigate through the maze. * - The exit of the maze is marked with a '$'. * - Walls are '#'. * - Traps are 'X'. These kill you. * * You can quit the program at any time by pressing CTRL + C. * * Have fun playing! */ #include #include #include #include #include #include #include "rooster.h" /* Toont het gegeven rooster met ncurses. * * Input: * rp: een pointer naar het rooster. * * Side effect: * De console wordt geleegd en het rooster wordt erin gezet. */ void toon_rooster(rooster *rp) { clear(); int height = rooster_hoogte(rp); int width = rooster_breedte(rp); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (rooster_bevat(rp, x, y) == 1) { mvaddch(y, x, rooster_kijk(rp, x, y)); } } } refresh(); } void update_grid(rooster *rp, char c, int x, int y) { if (rooster_plaats(rp, x, y, c) == 1) { mvaddch(y, x, c); } } /* Voert de benodigde veranderingen in het rooster door als de speler in een * bepaalde richting probeert te bewegen. * Input: * rp : 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. */ void beweeg(rooster *rp, int dx, int dy) { int playerx; int playery; rooster_zoek(rp, '*', &playerx, &playery); if (playerx == -1 || playery == -1) { printf("Player not found!"); exit(1); } if (rooster_bevat(rp, playerx + dx, playery + dy) == 1) { char new_location = rooster_kijk(rp, playerx + dx, playery + dy); switch (new_location) { case '#': break; case 'X': update_grid(rp, ' ', playerx, playery); rooster_zet_toestand(rp, VERLOREN); break; case ' ': update_grid(rp, ' ', playerx, playery); update_grid(rp, '*', playerx + dx, playery + dy); break; case '$': update_grid(rp, ' ', playerx, playery); rooster_zet_toestand(rp, GEWONNEN); break; } refresh(); } } /* * Speel een dolhof spel. * * Input: * rp: Een pointer naar een rooster met een valide doolhof erin. * * Side Effects: * Met WSAD en arrow keys kun je door het doolhof heen bewegen. */ void run_maze(rooster *rp) { while (rooster_vraag_toestand(rp) == AAN_HET_SPELEN) { switch (getch()) { case KEY_UP: // fallthrough case 'w': beweeg(rp, 0, -1); break; case KEY_DOWN: // fallthrough case 's': beweeg(rp, 0, 1); break; case KEY_LEFT: // fallthrough case 'a': beweeg(rp, -1, 0); break; case KEY_RIGHT: // fallthrough case 'd': beweeg(rp, 1, 0); break; case KEY_EXIT: rooster_zet_toestand(rp, VERLOREN); break; } } } /* * Toont het maze victory screen. * * Side Effect: * De victory message wordt op een schone console geprint. */ void display_maze_victory() { clear(); mvprintw(2,5, "YOU WON!!!!!"); refresh(); } /* * Toont het maze loss screen. * * Side Effect: * De loss message wordt op een schone console geprint. */ void display_maze_loss() { clear(); mvprintw(2,5, "RIP, YOU DIED..."); refresh(); } /* * Toont het maze broken screen. * * Side Effect: * De hackerman message wordt op een schone console geprint. */ void display_hackerman() { clear(); mvprintw(2,5, "The hacker man strikes again..."); refresh(); } /* * Bepaalt afhankelijk van de eindtoestand van het rooster * welk afsluitscherm er getoond moet worden en toont dan dat rooster. * * Input: Het rooster om de toestand uit af te lezen. * * Side Effects: * Het end-of-game scherm wordt op een blanke console geprint. */ void maze_exit_screen(rooster *rp) { toestand current_state = rooster_vraag_toestand(rp); switch (current_state) { case GEWONNEN: display_maze_victory(); return; case VERLOREN: display_maze_loss(); return; } display_hackerman(); } /* * Waits for the user to press an exit key 'q' before continuing. */ void graceful_exit() { mvprintw(5, 0, "Press 'q' to exit the game."); while (1) { switch (getch()) { case 'q': return; } } } /* * Speelt het spel met een gegeven rooster tot de toestand niet langer * AAN_HET_SPELEN is. */ void speel(rooster *rp) { toon_rooster(rp); rooster_zet_toestand(rp, AAN_HET_SPELEN); run_maze(rp); maze_exit_screen(rp); graceful_exit(); } int main(int argc, char *argv[]) { // 1. Controleer dat er een doolhofbestand is opgegeven op de command line. if (argc != 2) { fprintf(stderr, "gebruik: ./spel assets/voorbeeld_doolhof.txt\n"); return 1; } // 2. Open het doolhofbestand en lees het rooster. FILE *fh = fopen(argv[1], "r"); if (fh == NULL) { perror("main"); return 1; } rooster *rp = rooster_lees(fh); fclose(fh); // 3. Bepaal of het lezen van het rooster is gelukt. if (rp == NULL) { fprintf(stderr, "Kan rooster niet maken.\n"); return 1; } // 4. Initialiseer ncurses setlocale(LC_ALL, ""); initscr(); cbreak(); // zodat je kunt onderbreken met Ctrl+C keypad(stdscr, TRUE); // luister ook naar extra toetsen zoals pijltjes noecho(); // druk niet de letters af die je intypt curs_set(0); // hides the cursor // 5. Speel het spel. speel(rp); // 6. Sluit af. rooster_klaar(rp); endwin(); return 0; }