Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 30597505 authored by SZCZEPANSKI Marin's avatar SZCZEPANSKI Marin
Browse files

Add simple snake level

parent 3741a371
No related branches found
No related tags found
No related merge requests found
MAINPROG := main
OBJECTS := main.o \
../../engines/fullgame/map.o ../../engines/fullgame/action.o ../../engines/fullgame/common.o ../../engines/fullgame/events.o ../../engines/fullgame/read_input.o \
events_map.o input_manager.o
#DEFINES := -Dspontaneous_generation
DEFILES :=
CC := gcc
CFLAGS := -g -Wall -Wextra $(DEFINES)
all: main
main: $(OBJECTS)
$(CC) $(CFLAGS) $(DEFINES) -o $@ $(OBJECTS)
clean:
rm *.o
rm ../../engines/fullgame/*.o
clear: clean
rm main
.PHONY: all clean clear
#include "events_map.h"
bool no_apple = true;
int apple_id = 0;
void update_snake(void) {
map * m = current_map();
int i = coord_idx(m->player_y, m->player_x);
// snake ate itself, bad
if (m->entities[i]
&& m->entities[i]->category == NPC
&& m->entities[i]->id != head->body->id) {
printf("You chomped yourself!\n");
level_failed();
return;
}
// snake ate apple, good
if (m->entities[i]
&& m->entities[i]->category == ITEM) {
m->entities[i]->category = NPC;
snake * new_head = malloc(sizeof(snake));
new_head->body = m->entities[i];
new_head->next = head;
head = new_head;
no_apple = true;
return;
}
// snake moved
snake * pred = NULL;
snake * tail = head;
while (tail->next) {
pred = tail;
tail = tail->next;
}
tail->next = head;
pred->next = NULL;
head = tail;
int j = 0;
while (!m->entities[j]
|| m->entities[j]->id != head->body->id)
j++;
m->entities[j] = NULL;
m->entities[i] = head->body;
}
void spawn_apple(void) {
if (!no_apple)
return;
map * m = current_map();
int i = rand() % (m->width * m->height);
while (m->entities[i])
i = rand() % (m->width * m->height);
m->entities[i] = malloc(sizeof(entity));
m->entities[i]->category = ITEM;
m->entities[i]->id = apple_id++ + (m->width * m->height);
#ifndef spontaneous_generation
no_apple = false;
#endif
}
#ifndef EVENTS_MAP_H
#define EVENTS_MAP_H
#include "../../engines/fullgame/agdbentures.h"
typedef struct Snake {
entity * body;
struct Snake * next;
} snake;
snake * head;
/**
* moves the snake and makes it longer if it ate an apple.
* Have it crash and game over if it ate itself.
*/
void update_snake(void);
/**
* Creates an apple at a random location outside of the snake's body.
*/
void spawn_apple(void);
#endif // EVENTS_MAP_H
#include "input_manager.h"
void apply_input(command * c) {
map * m = current_map();
direction dir = m->player_direction;
if (!strncmp(c->command_buffer, "U", 1)) {
dir = UP;
} else if (!strncmp(c->command_buffer, "D", 1)) {
dir = DOWN;
} else if (!strncmp(c->command_buffer, "L", 1)) {
dir = LEFT;
} else if (!strncmp(c->command_buffer, "R", 1)) {
dir = RIGHT;
} else {
printf("Unknown input command. Continuing in the same direction\n");
}
int y, x;
coord_in_dir(m->player_y, m->player_x, dir, &y, &x);
// there is no wall in this game so collision will be 0 or -1
if (collision(x, y)) {
switch (dir) {
case UP:
m->player_y = m->height - 1;
break;
case DOWN:
m->player_y = 0;
break;
case LEFT:
m->player_x = m->width - 1;
break;
case RIGHT:
m->player_x = 0;
break;
default:
printf("apply_input: invalid direction\n");
break;
}
} else {
switch (dir) {
case UP:
up();
break;
case DOWN:
down();
break;
case LEFT:
left();
break;
case RIGHT:
right();
break;
default:
printf("apply_input: invalid direction\n");
break;
}
}
}
#ifndef INPUT_MANAGER_H
#define INPUT_MANAGER_H
#include "../../engines/fullgame/agdbentures.h"
// examine la commande c et appelle les fonctions d'action ou de déplacement correspondantes
void apply_input(command * c);
#endif // INPUT_MANAGER_H
\ No newline at end of file
/** @AGDB
* level_name: Snake
* program_name: main
* level_number: 1109
* available_commands: next step continue
* map_height: 10
* map_width: 10
*
* BUG: We forgot to reset no_apple to false in spawn_apple, so apples spawn at each step.
* tag: snake simple chained_list
*
* HINT1: Do 1 box at a time
*/
/**
* Entry point of the game. Manages the main loop, and apart from
* that only calls functions.
*
* Game design related tip:
* Snake is a weird game you can't win, yet many people like it, maybe
* because it is simplistic and allows you to pass time
* on your brand new Nokia phone, or TI82.
*/
#include "../../engines/fullgame/agdbentures.h"
#include "events_map.h"
#include "input_manager.h"
const char * str_map =
"\
\n\
^ \n\
A \n\
A \n\
A \n\
\n\
\n\
\n\
\n\
\n\
";
/**
* Generates a snake in the form of a linked list
*/
void create_snake(void) {
snake * cur;
snake * pred = NULL;
map * m = current_map();
for (int i = 0; i < m->width * m->height; i++) {
if (m->entities[i] && m->entities[i]->category == NPC) {
cur = malloc(sizeof(snake));
if (pred)
pred->next = cur;
else
head = cur;
cur->body = m->entities[i];
cur->next = NULL;
pred = cur;
}
}
// actual head is where the player is
int i = coord_idx(m->player_y, m->player_x);
m->entities[i] = malloc(sizeof(entity));
m->entities[i]->category = NPC;
m->entities[i]->id = pred->body->id + 1;
cur = malloc(sizeof(snake));
cur->next = head;
cur->body = m->entities[i];
head = cur;
}
/**
* Frees the body of a snake starting from its parameter
*/
void free_snake(snake * s) {
if (s->next)
free_snake(s->next);
free(s);
}
int main(int argc, char ** argv) {
bool manual_mode = true;
if (argc > 1)
manual_mode = false;
if (manual_mode) {
printf("Manual mode. Available commands: UP, DOWN, LEFT, RIGHT and *_N variants.\nUse Ctrl+C to quit.\n");
} else {
if (!init_inputs_file(argv[1])) {
printf("Error while reading the inputs!\n");
return EXIT_FAILURE;
}
}
load_map("torus", str_map);
create_snake();
srand(0xC0FF33); // random seed
spawn_apple();
add_event(update_snake);
add_event(spawn_apple);
if (manual_mode)
show_map();
command * com = get_next_input();
// The Holy Main Loop
while (!exit_main_loop) {
apply_input(com);
/* since the events may be applied if the input is FORWARD_N,
we need to check to avoid triggering the same event twice*/
if (!exit_main_loop)
apply_events();
if (manual_mode)
show_map();
if (!exit_main_loop)
com = get_and_free_input(com);
// plus aucun input mais on a pas encore gagné ou perdu -> défaite
if (!manual_mode && com == NULL && !exit_main_loop)
level_failed();
}
free_snake(head);
free_command(com);
remove_all_events();
free_map_stack();
close_inputs_file();
return EXIT_SUCCESS;
}
......@@ -43,7 +43,7 @@ int main(int argc, char ** argv) {
manual_mode = false;
if (manual_mode) {
printf("Manual mode. Available commands: UP, DOWN, LEFT, RIGHT and *_N variants; TOUCH.\nUse Ctrl+C to quit.\n");
printf("Manual mode. Available commands: UP, DOWN, LEFT, RIGHT and *_N variants.\nUse Ctrl+C to quit.\n");
} else {
if (!init_inputs_file(argv[1])) {
printf("Error while reading the inputs!\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment