From 1337f1e36b8ba8877adeff8960ad1b4c706ec1cb Mon Sep 17 00:00:00 2001 From: Oleksandr Hryshchenko Date: Mon, 26 Apr 2021 21:14:45 +0200 Subject: [PATCH] du7 --- du7/snake.c | 95 +++++++++++++++++++++ du7/snake/Makefile | 14 ++++ du7/snake/README.md | 16 ++++ du7/snake/game | Bin 0 -> 21408 bytes du7/snake/main.c | 110 ++++++++++++++++++++++++ du7/snake/main.o | Bin 0 -> 5884 bytes du7/snake/snake.c | 23 +++++ du7/snake/snake.h | 114 +++++++++++++++++++++++++ du7/snake/snake.o | Bin 0 -> 3636 bytes du7/snake/world.c | 198 ++++++++++++++++++++++++++++++++++++++++++++ du7/snake/world.h | 122 +++++++++++++++++++++++++++ du7/snake/world.o | Bin 0 -> 11408 bytes 12 files changed, 692 insertions(+) create mode 100644 du7/snake.c create mode 100644 du7/snake/Makefile create mode 100644 du7/snake/README.md create mode 100755 du7/snake/game create mode 100644 du7/snake/main.c create mode 100644 du7/snake/main.o create mode 100644 du7/snake/snake.c create mode 100644 du7/snake/snake.h create mode 100644 du7/snake/snake.o create mode 100644 du7/snake/world.c create mode 100644 du7/snake/world.h create mode 100644 du7/snake/world.o diff --git a/du7/snake.c b/du7/snake.c new file mode 100644 index 0000000..8a911c8 --- /dev/null +++ b/du7/snake.c @@ -0,0 +1,95 @@ +nclude "snake.h" +#include + +struct snake* add_snake(struct snake* snake,int x,int y){ + struct snake* newHead = (struct snake*) malloc(sizeof(struct snake)); + newHead-> = x; + newHead-> = y; + newHead->next = snake; + + struct snake* temp = snake; + int myX, myY; + + while(temp->next != NULL){ + myX = temp->x; // + myY = temp->y; + temp->x = temp->next->x; //указатель на позицию следующего элемента по Х + temp->y = temp->next->y;//указатель на позицию следующего элемента по У + temp = temp->next; + } + + //temp->next = (struct snake*) calloc(1, sizeof(struct snake)); + temp->next->x = temp->x - (myX - temp->x); + temp->next->y = temp->y - (myX - temp->y); + temp->next->next = NULL; + + return newHead; +} + +struct snake* remove_snake(struct snake* snake){ + struct snake* temp = snake; + + while(temp->next->next != NULL){ + temp = temp->next; // проход до последнего кусочка + } + + temp->next = NULL; + + return snake; +} + +void free_snake(struct snake* sn){ + struct snake* temp = sn; + + while(sn != NULL){ + temp = sn; + sn = sn->next; + temp->next = NULL; + } +} + +int is_snake(struct snake* snake,int x,int y){ + struct snake* temp = snake; + + while(temp->next != NULL){ + if(x == temp->x && y == temp->y){ + return 1; + } + temp = temp->next; + } + + return 0; +} + +int step_state(struct state* st){ + int nx = (st->snake->x + st->sx); + int ny = (st->snake->y + st->sy); + + for(int i = 0; i < FOOD_COUNT; i++){ + if(st->snake-> == st->foodx && st->snake->y == st->food[i]){ + add_snake(st->snake, st->foodx[i], st->foody[i]); + st->foodx[i] = -1; + st->foody[i] = -1; + for(int j = 0; j < FOOD_COUNT; j++){ + if(st->foodx[i] != -1 || st->foody[i] != -1){ + break; + } + else if(st->foodx[i] == -1 && st->foody[i] == -1 && j == FOOD_COUNT - 1){ + return END_FOOD; + } + } + } + } + + for(struct snake* temp = st->snake->next != NULL; temp = temp->next){ + if(nx == temp->x && ny == temp->y){ + return END_SNAKE; + } + } + + add_snake(st->snake, nx, ny); + remove_snake(st->snake); + + return END_CONTINUE; +} + diff --git a/du7/snake/Makefile b/du7/snake/Makefile new file mode 100644 index 0000000..d71d436 --- /dev/null +++ b/du7/snake/Makefile @@ -0,0 +1,14 @@ +CFLAGS=-std=c99 -Wall -g + +all: game + +%.o: %.c + gcc $(CFLAGS) -c $< -o $@ + +clean: + rm *.o + rm game + +game: main.o world.o snake.o + gcc -rdynamic -g main.o world.o snake.o -lcurses -lm -o game + diff --git a/du7/snake/README.md b/du7/snake/README.md new file mode 100644 index 0000000..79a2d67 --- /dev/null +++ b/du7/snake/README.md @@ -0,0 +1,16 @@ +# Snake Master + +Implement Snake game. + +Make the game to pass the automatic tests and make the game to be nice. + +## Files + +Please do not change file names. + +- `snake.h`: you implementation should follow this header. +- `snake.c`: implemement the game according to the documentation in header file in this file to pass automatic tests. +- `Makefile`: rules to build the game. +- `main.c`: trivial main function that runs the game, modify this file to change the appereance of the game and the initial state. +- `world.c`: world game loop and ASCII graphics library (do not change). +- `world.h`: world library interface (do not change). diff --git a/du7/snake/game b/du7/snake/game new file mode 100755 index 0000000000000000000000000000000000000000..8fd45891d9fdf90b1d0e1b99bee897ab3a7d0b98 GIT binary patch literal 21408 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 Koq^=k`F{bF38C@; literal 0 HcmV?d00001 diff --git a/du7/snake/main.c b/du7/snake/main.c new file mode 100644 index 0000000..9e5ec9a --- /dev/null +++ b/du7/snake/main.c @@ -0,0 +1,110 @@ +#include "world.h" +#include +#include +#include +#include +#include "snake.h" +// This file contains functions for drawing the the game and changing the state + +// Start is called one in the beginning +void* init_game(){ + // Allocate memory for the state + struct state* st = calloc(1,(sizeof(struct state))); + return st; +} + +// The first event +// Initialize game state +// - borders +// - snake position +// - food position +void init_snake(struct event* world, struct state* st){ + int cy = world->height/2; + int cx = world->width/2 - 5; + for (int i = 0; i < 5; i++){ + st->snake = add_snake(st->snake,cx + i ,cy); + } + + int h = world->height; + int w = world->width; + for (int i = 0; i < 5; i++){ + st->foodx[i] = rand() % w; + st->foody[i] = rand() % h; + } + // Initial game vector + st->sx = 1; + st->sy = 0; +} + +// Step is called in a loop once in interval. +// It should modify the state and draw it. +int world_event(struct event* w,void* game){ + // Get state pointer + struct state* st = game; + if (w->type == EVENT_START){ + // Called on beginning + init_snake(w,st); + } + // Called on key press + else if (w->type == EVENT_KEY){ + int key = w->key; + // Modifies vector of snake movement + if (key == KEY_RIGHT){ + st->sx = 1; + st->sy = 0; + } + else if (key == KEY_LEFT){ + st->sx = -1; + st->sy = 0; + } + else if (key == KEY_DOWN){ + st->sx = 0; + st->sy = 1; + } + else if (key == KEY_UP){ + st->sx = 0; + st->sy = -1; + } + } + // Called on esc key + else if (w->type == EVENT_ESC){ + // Non zero means finish the loop and stop the game. + return 1; + } + // Called on interval timeout + else if (w->type == EVENT_TIMEOUT){ + clear_screen(); + // Copy screen size + st->width = w->width; + st->height = w->height; + // Change game state + int r = step_state(st); + char ms[200]; + sprintf(ms,"r %d\n",r); + set_message(ms,9,9); + // Draw snake + struct snake* sn = st->snake; + while (sn != NULL){ + set_cell('x',sn->x,sn->y); + sn = sn->next; + } + // Draw food + for (int i = 0 ; i < FOOD_COUNT; i++){ + if (st->foodx[i] >= 0 && st->foody[i] >= 0){ + set_cell('*',st->foodx[i],st->foody[i]); + } + } + // Stop the game + if (r){ + char message[] = "Koniec"; + set_message(message,10,10); + } + } + return 0; +} + + +int main(int argc, char** argv){ + start_world(init_game,world_event,free); + return 0; +} diff --git a/du7/snake/main.o b/du7/snake/main.o new file mode 100644 index 0000000000000000000000000000000000000000..4c6e027b763d7b47616d0f99d465b42ce12cf98c GIT binary patch literal 5884 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 U{dX8_0^+xX;)(kW|A4{&0tPm}{Qv*} literal 0 HcmV?d00001 diff --git a/du7/snake/snake.c b/du7/snake/snake.c new file mode 100644 index 0000000..7038cdb --- /dev/null +++ b/du7/snake/snake.c @@ -0,0 +1,23 @@ +#include "snake.h" +#include + +struct snake* add_snake(struct snake* snake,int x,int y){ + return NULL; +} + +struct snake* remove_snake(struct snake* snake){ + return NULL; +} + +void free_snake(struct snake* sn){ +} + +int is_snake(struct snake* snake,int x,int y){ + return 0; +} + +int step_state(struct state* st){ + int nx = (st->snake->x + st->sx); + int ny = (st->snake->y + st->sy); + return END_CONTINUE; +} diff --git a/du7/snake/snake.h b/du7/snake/snake.h new file mode 100644 index 0000000..4d1ff74 --- /dev/null +++ b/du7/snake/snake.h @@ -0,0 +1,114 @@ +#ifndef snake_h_INCLUDED +#define snake_h_INCLUDED + +// Number of food items on the plane +#define FOOD_COUNT 5 + +/** + * One part of the snake; + * + * The snake is a linked list; + */ + +struct snake { + // x position of the snake part + int x; + // y position of the snake part + int y; + // Pointer to the next snake part. + // The last part of the snake has NULL pointer to the next part. + struct snake* next; +}; + +// End game reason constants, return value of step_state +enum endgame { + // Continue the game + END_CONTINUE = 0, + // Snake hit a wall + END_WALL, + // Snake hit itself + END_SNAKE, + // No food left + END_FOOD, + // Other reason to end + END_USER +}; + +/** + * State of the game. + * + * The state consists of the snake, its speed and food on the plane. + * + * The snake is a linked list of snake parts. + * + * Speed vector is a vector added to the last head position to create a new head. + * + * Food are points on the plane. Food with negative coordinates meads food is already eaten. + */ + +struct state { + // Snake as a linked list + struct snake* snake; + // X of the food positions + int foodx[FOOD_COUNT]; + // Y of the food positions + int foody[FOOD_COUNT]; + int sx; + int sy; + int width; + int height; +}; + +/** + * Add a new snake part with given position. The new snake part becomes the new head. + * + * @param head of the snake. + * @param x coordinate of the new head; + * @param y coordinate of the new head. + * @return new head of the snake. + */ +struct snake* add_snake(struct snake* snake,int x,int y); + +/** + * Remove the last snake part. + * The last snake part should always have NULL next pointer. + * + * @param head of the snake. + * @return new head of the snake. + */ +struct snake* remove_snake(struct snake* snake); + +/** + * Finds out if given coordinates are part of the snake. + * @param snake + * @param x coordinate to search in snake + * @param y coordinate to search in snake + * @return True, if there is a snake part with coordinates x,y. False otherwise + * + */ +int is_snake(struct snake* snake,int x, int y); +/** + * Remove and free each snake part; + * @param head of the snake. + */ +void free_snake(struct snake* sn); +/** + * Change game state. + * + * The function shoud calculate new posision of the snake head + * from the current position and speed vector. + * Then it should modify snake parst or food coordinates according to the rules: + * + * - If the new position is on the snake, end the game, return END_SNAKE. + * - If the new position is on the food, mark food as eaten + * (set its coordinates to -1) and add new snake part on the position of the food. If there is no food left, return END_FOOD. else return END_CONTINUE. + * - If the new position is on the plane, add new snake part on the new position and remove the last part of the snake, return END_CONTINUE. + * + * @param current state of the game + * @return reason to end the game according to enum endgame. + */ +int step_state(struct state* state); + + +#endif // snake_h_INCLUDED + diff --git a/du7/snake/snake.o b/du7/snake/snake.o new file mode 100644 index 0000000000000000000000000000000000000000..2b3efb3790a89265f00448774895a6a1705f7a4f GIT binary patch literal 3636 zcma)8%WqUw82`?l+j7f1+R~yZqD5XsaHe9B3MdpPSj3`0gG5c8c5XW(?VYA`2U`Rs zL5+we5*Nm(k%bGR{sFosEL><hZl;TsD7I4>zXMbutKMPP9I%-f1KWY!Ycz_tBD3bh-s?n&Krm=4ui2&M%|-X=qg(k$$VtKBOwZ z&YH?v6P20WGnHAMmEFOJ4xNMvxcA>uHH0L&S_~UG?}D^Nm|mxuUfdR8eoKuojqTV9LcSWw4`=#)jEw9J)+i?Z}wS>oS8KEM{l(Te~v! z&o(v2^iV<$qOFKxYcg^{TwCt~N6uH@UQc2ldxN`-*-9J`TQpw}h}>@a05nlXwOU8S zTyz`}<$BZN zXt-;4S8skxev^#PgyD!DL@G7Q6iX$`mBY$JIo3&b9~?R|I5a#U&sIut+0-Sq%E>UE zn+~Nh?o2pUJ>fE%;l``g(ySE9)v2%$*DQSvS5rw5L&WUq5JkP$vM9#pt1PYGH#_@PATnt#bid;XFvE*#~Av>O?FEOEI z358>iUFY{B2I^vfCFjSrO4j!qp3gSuSRdFsb+D*T0>fxbWXG|MnS6eDU-OD4Z3}M4<@oJ8`K+j;*k)Je$OoL~Q0-Yu|5i+~SNyeGic5c`LtY z@l}f#EWT&)V~d|zylU|mi*1-H>$=(E?H1Qq++guOBI?{~@j)WC^&xAYw)mX2zhLn! z5q_^*`+F8Yu=WovenN!bWoy4;^

1#@fHL_Qj}0uO|`h7K +#include +#include +#include +#include + +int TIMEOUT; + +void abort_game(const char* message){ + endwin(); + puts(message); + exit(1); +} + +void check_bounds(const char* source,int x, int y){ + char msg[200]; + if (x < 0 || x >= COLS){ + sprintf(msg,"%s:: width %d is out of bounds (0,%d)",source,x,COLS); + abort_game(msg); + } + if (y < 0 || y >= LINES){ + sprintf(msg,"%s:: height %d is out of bounds (0,%d)",source,y,LINES); + abort_game(msg); + } +} + +void clear_screen(){ + // Clear screen + mvaddch(0,0,' '); + int screenchars = LINES*COLS; + for (int j = 1; j < screenchars;j++ ){ + addch(' '); + } +} + +void game_speed(int value){ + if (value < 0){ + abort_game("world_seed:: cannot be negative\n"); + } + TIMEOUT =value; +} + +void set_message(const char* message,int x,int y) { + int l = strlen(message); + for (int i = 0; i < l; i++){ + check_bounds("set_message",x+i,y); + set_cell(message[i],x+i,y); + } +} + +void assert_message(int event,const char* message){ + if (event == 0){ + abort_game(message); + } +} + + +void set_cell(int character,int x,int y) { + check_bounds("set_cell",x,y); + set_color_cell(character,x,y,COLOR_WHITE,COLOR_BLACK); +} + +void set_color_cell(int character,int x,int y,short front_color,short back_color){ + check_bounds("set_color_cell",x,y); + if (has_colors()){ + int pair = COLOR_COUNT * front_color + back_color; + attron(COLOR_PAIR(pair)); + mvaddch(y,x,character); + attroff(COLOR_PAIR(pair)); + } + else{ + mvaddch(y,x,character); + } +} + +int start_world(void* (*init_game)(),int (*world_event)(struct event* event,void* game),void (*destroy_game)(void*)){ + srand(time(NULL)); + int r = 1; + // Speed global variable + TIMEOUT = 100; + if (initscr() == NULL){ + // TODO Which Error? + puts("Curses Error."); + return -1; + } + noecho(); // Nevypisuj vstup na obrazovku + cbreak(); // Zabudni starý vstup + nodelay(stdscr,TRUE); // Nečakaj na stlačenie + keypad(stdscr,TRUE); // Aktivuje šípky + curs_set(FALSE); // Neviditeľný kurzor + /* Get all the mouse events */ + mousemask(ALL_MOUSE_EVENTS, NULL); + MEVENT mouse_event; + if (has_colors()){ // Zistenie či terminál podporuje farby + start_color(); + for (int i = 0; i < COLOR_COUNT;i++){ + for (int j = 0; j < COLOR_COUNT;j++){ + init_pair(i * COLOR_COUNT + j, i,j); + } + } + } + else { + puts("No colors!\n"); + } + void* game = NULL; + if (init_game != NULL){ + game = init_game(); + assert_message(game != NULL,"init_game:: should return non null pointer"); + } + timeout(TIMEOUT); + // Initial step + struct event event; + memset(&event,0,sizeof(struct event)); + event.height = LINES; + event.width = COLS; + event.type = EVENT_START; + clock_t start_time = clock(); + clock_t last_timeout = start_time; + clock_t next_timeout = last_timeout + TIMEOUT; + event.time_ms = start_time; + // Start event + r = world_event(&event,game); + refresh(); + while (!r) { + memset(&event,0,sizeof(struct event)); + event.height = LINES; + event.width = COLS; + event.key = getch(); + // No key was pressed + if (event.key == ERR){ + event.type = EVENT_TIMEOUT; + last_timeout = clock(); + next_timeout = last_timeout + TIMEOUT; + } + // Mouse event + else if (event.key == KEY_MOUSE ){ + event.type = EVENT_MOUSE; + if(getmouse(&mouse_event) == OK){ + event.mouse_x = mouse_event.x; + event.mouse_y = mouse_event.y; + if(mouse_event.bstate & BUTTON1_PRESSED){ + event.mouse_left = 1; + } + if(mouse_event.bstate & BUTTON2_PRESSED){ + event.mouse_middle = 1; + } + if(mouse_event.bstate & BUTTON3_PRESSED){ + event.mouse_right = 1; + } + } + } + else if (event.key == KEY_RESIZE) { + event.type = EVENT_RESIZE; + } + else{ + event.type = EVENT_KEY; + if (event.key == 27){ + int k = getch(); + if (k == -1){ + // Esc Was pressed + event.type = EVENT_ESC; + } + else { + // Alt was pressed + event.key = k; + event.alt_key = 1; + } + } + } + // Draw new world + event.time_ms = clock(); + r = world_event(&event,game); + refresh(); + event.time_ms = clock(); + // set new timeout + int nt = next_timeout - event.time_ms; + //printf("%d\n",nt); + if (nt > 0){ + timeout(nt); + } + else { + timeout(TIMEOUT); + next_timeout = event.time_ms + TIMEOUT; + } + } + memset(&event,0,sizeof(struct event)); + event.height = LINES; + event.width = COLS; + event.type = EVENT_END; + event.time_ms = clock(); + world_event(&event,game); + if (destroy_game != NULL){ + destroy_game(game); + } + endwin(); + return r; +}; diff --git a/du7/snake/world.h b/du7/snake/world.h new file mode 100644 index 0000000..e7a3fdb --- /dev/null +++ b/du7/snake/world.h @@ -0,0 +1,122 @@ +#ifndef _WORLD_H_ +#define _WORLD_H_ + +#include + +/** + * World represented as a rectangular matrix of colorful characters. + * + * Point [0,0] is displayed the upper left corner of the screen. + * + */ + +enum event_type { + EVENT_START, + EVENT_TIMEOUT, + EVENT_KEY, + EVENT_MOUSE, + EVENT_RESIZE, + EVENT_ESC, + EVENT_END, +}; + +struct event { + /** + * Last width of the screen. + */ + int width; + /** + * Last height of the screen. + */ + int height; + /** + * Last pressed key or Curses event. + * + * Special event values: + * ERR if timeout, + * KEY_RESIZE if screen resize + * KEY_EVENT, other event, + * KEY_MOUSE, mouse clicked + * + * Key values: + * + * ' ' Space + * KEY_DOWN Arrow down + * KEY_UP Arrow up + * KEY_LEFT Arrow left + * KEY_RIGHT Arrow right + * KEY_A1 Upper left of keypad + * KEY_A3 Upper right of keypad + * KEY_B2 Center of keypad + * KEY_C1 Lower left of keypad + * KEY_C3 Lower right of keypad + * + * KEY_ENTER + * KEY_BACKSPACE + */ + int key; + int alt_key; + enum event_type type; + int mouse_x; + int mouse_y; + int mouse_left; + int mouse_right; + int mouse_middle; + long int time_ms; +}; + +/** + * Sets cell to a state. + * @param event + * @param x coordinate of cell + * @param y coordinate of cell + * @param new state of the cell + */ +void set_cell(int character,int x,int y); + +/** + * COLOR_BLACK 0 + * COLOR_RED 1 + * COLOR_GREEN 2 + * COLOR_YELLOW 3 + * COLOR_BLUE 4 + * COLOR_MAGENTA 5 + * COLOR_CYAN 6 + * COLOR_WHITE 7 + */ + +#define COLOR_COUNT 8 + +void set_color_cell(int character,int x,int y,short front_color,short back_color); + + +/** + * + * @param event + * @param number of commandline arguments + * @param init_world + * @param destroy_world + * + * void init_world(struct event* w); + * Initializes user state. + * Free user state. + * @param event + */ + +int start_world(void* (*init_game)(),int (*world_event)(struct event* event,void* game),void (*destroy_game)(void* game)); +/** + * Set timeout interval in miliseconds + */ +void game_speed(int value); + +/* + * Prints a message in screen on a position x,y + */ + +void set_message(const char* message,int x,int y); +/* + * Clears screen + */ +void clear_screen(); + +#endif diff --git a/du7/snake/world.o b/du7/snake/world.o new file mode 100644 index 0000000000000000000000000000000000000000..51e4b7f496466016f04346d072d8ae2c94e6e61f GIT binary patch literal 11408 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