forked from snapshot112/minigame-menu
Added initial project files
yeet
This commit is contained in:
34
CMakeLists.txt
Normal file
34
CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
cmake_minimum_required()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Define a custom target to run the default 'make' command
|
||||
# ------------------------------------------------------------------
|
||||
add_custom_target(
|
||||
Week6
|
||||
COMMAND ${MAKE_EXECUTABLE}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Running make in the project directory..."
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Define a custom target to run 'make clean'
|
||||
# ------------------------------------------------------------------
|
||||
add_custom_target(
|
||||
Week6Clean
|
||||
COMMAND ${MAKE_EXECUTABLE} clean
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Running make clean in the project directory..."
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Define a custom target to run 'make clean'
|
||||
# ------------------------------------------------------------------
|
||||
add_custom_target(
|
||||
Week6Tarball
|
||||
COMMAND ${MAKE_EXECUTABLE} tarball1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Running make tarball in the project directory..."
|
||||
VERBATIM
|
||||
)
|
||||
27
Makefile
Normal file
27
Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
CC = gcc
|
||||
CFLAGS = -std=c11 -Wextra -Wpedantic -g3 -fsanitize=address
|
||||
LDFLAGS = -lncursesw -fsanitize=address
|
||||
SRC = $(filter-out voorbeeld.c,$(wildcard *.c))
|
||||
HEADERS = $(wildcard *.h)
|
||||
|
||||
.PHONY: tarball1 tarball2 clean
|
||||
|
||||
all: spel
|
||||
|
||||
spel: $(SRC)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
voorbeeld:
|
||||
$(CC) -o voorbeeld voorbeeld.c $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
tarball1: deel1.tar.gz
|
||||
tarball2: deel2.tar.gz
|
||||
|
||||
deel1.tar.gz: spel.c rooster.h rooster.c Makefile
|
||||
tar czf $@ $^
|
||||
|
||||
deel2.tar.gz: $(SRC) $(HEADERS) Makefile
|
||||
tar czf $@ $^ assets
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o voorbeeld spel deel?.tar.gz
|
||||
224
rooster.c
Normal file
224
rooster.c
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "rooster.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
* The rooster type this program is build around.
|
||||
*/
|
||||
typedef struct rooster_data {
|
||||
char *rost;
|
||||
int height;
|
||||
int width;
|
||||
toestand state;
|
||||
} rooster;
|
||||
|
||||
/*
|
||||
* Sets a grids width and height
|
||||
*
|
||||
* Input:
|
||||
* fh: the stream to read the grid from.
|
||||
* rost: a rooster file to store the width and height in.
|
||||
*
|
||||
* Side effects:
|
||||
* the rooster gets its width and height set
|
||||
*
|
||||
* Output:
|
||||
* 1 if the file width and height seem to match with its size
|
||||
* 0 otherwise
|
||||
*/
|
||||
static int get_grid_sizes(FILE *fh, rooster *rost) {
|
||||
if (fh == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (getc(fh) != '\n') {
|
||||
if (feof(fh)) {
|
||||
return 0;
|
||||
}
|
||||
rost->width++;
|
||||
}
|
||||
|
||||
if (rost->width == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fh, 0, SEEK_END);
|
||||
|
||||
// Get file size (- 1 for the blank newline and EOF at the end)
|
||||
if (ftell(fh) % (rost->width + 1) != 0) {
|
||||
// Not all lines are the same width
|
||||
return 0;
|
||||
}
|
||||
|
||||
rost->height = (int)ftell(fh) / (int)sizeof(char) / rost->width;
|
||||
fseek(fh, 0, SEEK_SET);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rooster *rooster_lees(FILE *fh) {
|
||||
if (fh == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rooster rost = {
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
BEGIN
|
||||
};
|
||||
|
||||
// Sets the width and height of the rooster.
|
||||
if (get_grid_sizes(fh, &rost) != 1) {
|
||||
// Unlogical file structure.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int grid_size = (rost.width + 1) * rost.height + 1;
|
||||
|
||||
rost.rost = malloc(grid_size * sizeof(char));
|
||||
if (rost.rost == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This makes the strncat() work.
|
||||
rost.rost[0] = '\0';
|
||||
|
||||
char *line = malloc((rost.width + 2) * sizeof(char));
|
||||
if (line == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rost.height; i++) {
|
||||
if (fgets(line, rost.width + 2, fh) == NULL) {
|
||||
free(rost.rost);
|
||||
free(line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Validate that the line length is correct
|
||||
if ((int)strcspn(line, "\n") != rost.width) {
|
||||
free(rost.rost);
|
||||
free(line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Width is without the newline at the end.
|
||||
strncat(rost.rost, line, rost.width + 1);
|
||||
}
|
||||
|
||||
free(line);
|
||||
|
||||
rooster *return_rooster = malloc(sizeof(rost));
|
||||
if (return_rooster == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(return_rooster, &rost, sizeof(rost));
|
||||
|
||||
return return_rooster;
|
||||
}
|
||||
|
||||
toestand rooster_vraag_toestand(const rooster *rp) {
|
||||
if (rp != NULL) {
|
||||
return rp->state;
|
||||
}
|
||||
return VERLOREN;
|
||||
}
|
||||
|
||||
void rooster_zet_toestand(rooster *rp, toestand t) {
|
||||
if (rp != NULL) {
|
||||
switch (t) {
|
||||
case BEGIN:
|
||||
rp->state = BEGIN;
|
||||
break;
|
||||
case AAN_HET_SPELEN:
|
||||
rp->state = AAN_HET_SPELEN;
|
||||
break;
|
||||
case GEWONNEN:
|
||||
rp->state = GEWONNEN;
|
||||
break;
|
||||
case VERLOREN:
|
||||
rp->state = VERLOREN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rooster_klaar(rooster *rp) {
|
||||
if (rp != NULL) {
|
||||
if (rp->rost != NULL)
|
||||
{
|
||||
free(rp->rost);
|
||||
}
|
||||
free(rp);
|
||||
}
|
||||
}
|
||||
|
||||
int rooster_breedte(const rooster *rp) {
|
||||
if (rp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return rp->width;
|
||||
}
|
||||
|
||||
int rooster_hoogte(const rooster *rp) {
|
||||
if (rp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return rp->height;
|
||||
}
|
||||
|
||||
static int internal_location(const rooster *rp, const int x, const int y) {
|
||||
return y * (rp->width + 1) + x;
|
||||
}
|
||||
|
||||
int rooster_bevat(const rooster *rp, int x, int y) {
|
||||
if (rp != NULL && rp->rost != NULL) {
|
||||
if (x >= 0 && y >= 0 && x < rp->width && y < rp->height)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char rooster_kijk(const rooster *rp, int x, int y) {
|
||||
if (rp != NULL && rp->rost != NULL && rooster_bevat(rp, x, y) == 1) {
|
||||
return rp->rost[internal_location(rp, x, y)];
|
||||
}
|
||||
return '\0';
|
||||
}
|
||||
|
||||
int rooster_plaats(rooster *rp, int x, int y, char c) {
|
||||
if (rp != NULL && rp->rost != NULL && rooster_bevat(rp, x, y) == 1) {
|
||||
rp->rost[internal_location(rp, x, y)] = c;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rooster_zoek(const rooster *rp, char c, int *x, int *y) {
|
||||
if (rp == NULL || rp->rost == NULL) {
|
||||
*x = -1;
|
||||
*y = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const char search[2] = {c};
|
||||
|
||||
int strpos = strcspn(rp->rost, search);
|
||||
|
||||
if (rp->rost[strpos] == '\0')
|
||||
{
|
||||
*x = -1;
|
||||
*y = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
*x = strpos % (rp->width + 1);
|
||||
*y = strpos / (rp->width + 1);
|
||||
}
|
||||
152
rooster.h
Normal file
152
rooster.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* rooster.h
|
||||
|
||||
Deze module verzorgt het datatype "rooster". Een rooster representeert een
|
||||
rechthoekig grid van objecten. Elk object is in dit rooster een char.
|
||||
|
||||
Deze header file beschrijft het interface voor "rooster".
|
||||
De implementatie, in "rooster.c", moet je grotendeels zelf schrijven.
|
||||
*/
|
||||
|
||||
#ifndef _ROOSTER_H
|
||||
#define _ROOSTER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// Dankzij de typedef hoef je niet telkens "struct rooster_data" te schrijven.
|
||||
// Definieer struct rooster_data in rooster.c.
|
||||
struct rooster_data;
|
||||
typedef struct rooster_data rooster;
|
||||
|
||||
typedef enum {
|
||||
BEGIN,
|
||||
AAN_HET_SPELEN,
|
||||
GEWONNEN,
|
||||
VERLOREN
|
||||
} toestand;
|
||||
|
||||
/* Maak een rooster op basis van de data in de gegeven stream.
|
||||
|
||||
fh: de stream waaruit het doolhof gelezen moet worden.
|
||||
|
||||
Uitvoer: als alles goed gaat, een pointer naar een rooster (die op de heap is
|
||||
gealloceerd), dat overeenkomt met de gegeven beschrijving.
|
||||
De begintoestand is BEGIN.
|
||||
|
||||
Als de beschrijving niet consistent is (bijvoorbeeld
|
||||
niet alle rijen zijn even lang, of er klopt iets anders niet), of
|
||||
als niet voldoende geheugen kan worden gereserveerd, dan wordt
|
||||
NULL teruggegeven. (In dat geval blijft geen gereserveerd geheugen
|
||||
achter.)
|
||||
*/
|
||||
rooster *rooster_lees(FILE *fh);
|
||||
|
||||
/*
|
||||
* Maak een rooster op basis van een gegeven string.
|
||||
*
|
||||
* Uitvoer: als alles goed gaat, een pointer naar een rooster (die op de heap is
|
||||
* gealloceerd), dat overeenkomt met de gegeven beschrijving.
|
||||
* De begintoestand is BEGIN.
|
||||
*
|
||||
* Als de beschrijving niet consistent is (bijvoorbeeld
|
||||
* niet alle rijen zijn even lang, of er klopt iets anders niet), of
|
||||
* als niet voldoende geheugen kan worden gereserveerd, dan wordt
|
||||
* NULL teruggegeven. (In dat geval blijft geen gereserveerd geheugen
|
||||
* achter.)
|
||||
*/
|
||||
rooster *rooster_maak(char* template);
|
||||
|
||||
/* Vraag de huidige toestand van het spel op.
|
||||
|
||||
rp: een pointer naar het rooster.
|
||||
|
||||
Uitvoer: de toestand.
|
||||
*/
|
||||
toestand rooster_vraag_toestand(const rooster *rp);
|
||||
|
||||
|
||||
/* Verander de huidige toestand van het spel.
|
||||
|
||||
rp: een pointer naar het rooster.
|
||||
t: de nieuwe toestand.
|
||||
*/
|
||||
void rooster_zet_toestand(rooster *rp, toestand t);
|
||||
|
||||
|
||||
/* Geef alle resources vrij die zijn gealloceerd voor een rooster.
|
||||
De rooster pointer is na aanroep van deze functie niet meer bruikbaar.
|
||||
|
||||
rp: een pointer naar het rooster.
|
||||
*/
|
||||
void rooster_klaar(rooster *rp);
|
||||
|
||||
|
||||
/* Vraag de breedte van het rooster op, dat wil zeggen, het aantal kolommen.
|
||||
|
||||
rp: een pointer naar het rooster.
|
||||
|
||||
Uitvoer: de breedte.
|
||||
*/
|
||||
int rooster_breedte(const rooster *rp);
|
||||
|
||||
|
||||
/* Vraag de hoogte van het rooster op, dat wil zeggen, het aantal rijen.
|
||||
|
||||
rp: een pointer naar het rooster.
|
||||
|
||||
Uitvoer: de hoogte.
|
||||
*/
|
||||
int rooster_hoogte(const rooster *rp);
|
||||
|
||||
|
||||
/* Kijk of de gegeven positie binnen het rooster valt.
|
||||
|
||||
rp: een pointer naar het rooster.
|
||||
x,y: de positie.
|
||||
|
||||
Uitvoer: 1 als de positie binnen het rooster valt, anders 0.
|
||||
*/
|
||||
int rooster_bevat(const rooster *rp, int x, int y);
|
||||
|
||||
|
||||
/* Kijk welk object er staat op een bepaalde positie in het rooster.
|
||||
|
||||
rp : een pointer naar het rooster
|
||||
x,y: de betreffende positie.
|
||||
|
||||
Uitvoer: het object op die positie, of '\0' als de positie buiten het
|
||||
rooster valt.
|
||||
*/
|
||||
char rooster_kijk(const rooster *rp, int x, int y);
|
||||
|
||||
|
||||
/* Schrijf een bepaald object op een bepaalde positie in het rooster.
|
||||
|
||||
rp : een pointer naar het rooster
|
||||
x,y: de betreffende positie.
|
||||
c : het object.
|
||||
|
||||
Effect: als (x,y) binnen het rooster ligt, wordt het object op
|
||||
de opgegeven positie geplaatst, anders verandert er niets.
|
||||
|
||||
Uitvoer: 1 als het object is geplaatst, of 0 als het buiten de grenzen lag.
|
||||
*/
|
||||
int rooster_plaats(rooster *rp, int x, int y, char c);
|
||||
|
||||
|
||||
/* Zoek een bepaald object in het rooster, en geef de coordinaten van het
|
||||
object terug via de gegeven pointers. Let op: als er meerdere objecten van
|
||||
het gezochte soort in het rooster voorkomen, is niet gedefinieerd van welke
|
||||
de positie wordt gevonden.
|
||||
|
||||
rp : een pointer naar het rooster
|
||||
c : het object dat moet worden gezocht
|
||||
x,y: pointers naar de geheugenlocaties waar de gevonden positie moet worden
|
||||
geschreven.
|
||||
|
||||
Uitvoer: via de pointers x en y. Als het object niet wordt gevonden worden
|
||||
*x en *y op -1 gezet.
|
||||
*/
|
||||
void rooster_zoek(const rooster *rp, char c, int *x, int *y);
|
||||
|
||||
|
||||
#endif
|
||||
265
spel.c
Normal file
265
spel.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <wchar.h>
|
||||
#include <locale.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
44
voorbeeld.c
Normal file
44
voorbeeld.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Voorbeeldje van het gebruik van ncurses.
|
||||
In dit voorbeeld kun je alleen met een + naar links en naar rechts wandelen
|
||||
over een lijn van -.
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
|
||||
int RANGE = 20;
|
||||
|
||||
/* Toont de situatie met ncurses.
|
||||
|
||||
pos: de positie van de +.
|
||||
*/
|
||||
void laat_zien(int pos) {
|
||||
clear(); // begin met een nieuw ncurses scherm
|
||||
for (int i = 0; i < RANGE; i++) {
|
||||
addch(i == pos ? '+' : '-');
|
||||
}
|
||||
refresh(); // zorg dat het scherm ook echt getoond wordt
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// Initialiseer ncurses
|
||||
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
|
||||
|
||||
int pos = RANGE / 2; // begin in het midden van de lijn.
|
||||
while (1) {
|
||||
laat_zien(pos);
|
||||
int toets = getch();
|
||||
switch (toets) {
|
||||
case KEY_LEFT:
|
||||
pos--;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
13
voorbeeld_doolhof.txt
Normal file
13
voorbeeld_doolhof.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
#######################
|
||||
#*# #
|
||||
# # $ ########### #
|
||||
# ######## #
|
||||
# # ############
|
||||
# ###### # #
|
||||
# # # ############ #
|
||||
# #### # # #
|
||||
# # ##### # XXXXXX#
|
||||
# XXX# # #
|
||||
# #########XXXXXXX #
|
||||
# X #
|
||||
#######################
|
||||
Reference in New Issue
Block a user