1
This commit is contained in:
		
							parent
							
								
									9bcb69b7ff
								
							
						
					
					
						commit
						545c2481f1
					
				
							
								
								
									
										14
									
								
								a3/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								a3/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								a3/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								a3/README.md
									
									
									
									
									
										Normal file
									
								
							@ -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).
 | 
				
			||||||
							
								
								
									
										103
									
								
								a3/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								a3/main.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include "snake.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct snake* add_snake(struct snake* snake, int x, int y){
 | 
				
			||||||
 | 
					    struct snake* nova_cast = (struct snake*) calloc(1, sizeof(struct snake));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (nova_cast == NULL){
 | 
				
			||||||
 | 
					        return snake;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nova_cast->x = x;
 | 
				
			||||||
 | 
					    nova_cast->y = y;
 | 
				
			||||||
 | 
					    nova_cast->next = snake;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return nova_cast;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct snake* remove_snake(struct snake* snake){
 | 
				
			||||||
 | 
					    if (snake == NULL){
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (snake->next == NULL){
 | 
				
			||||||
 | 
					        free(snake);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct snake* predposledny = snake;
 | 
				
			||||||
 | 
					    struct snake* posledny = snake->next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (posledny->next != NULL){
 | 
				
			||||||
 | 
					        predposledny = posledny;
 | 
				
			||||||
 | 
					        posledny = posledny->next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(posledny);
 | 
				
			||||||
 | 
					    predposledny->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return snake;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int is_snake(struct snake* snake, int x, int y){
 | 
				
			||||||
 | 
					    struct snake* aktualny = snake;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (aktualny != NULL){
 | 
				
			||||||
 | 
					        if (aktualny->x == x && aktualny->y == y){
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        aktualny = aktualny->next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void free_snake(struct snake* sn){
 | 
				
			||||||
 | 
					    struct snake* dalsi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (sn != NULL){
 | 
				
			||||||
 | 
					        dalsi = sn->next;
 | 
				
			||||||
 | 
					        free(sn);
 | 
				
			||||||
 | 
					        sn = dalsi;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int step_state(struct state* state){
 | 
				
			||||||
 | 
					    int nova_x = state->snake->x + state->sx;
 | 
				
			||||||
 | 
					    int nova_y = state->snake->y + state->sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (nova_x < 0 || nova_y < 0 || nova_x >= state->width || nova_y >= state->height){
 | 
				
			||||||
 | 
					        return END_WALL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_snake(state->snake, nova_x, nova_y)){
 | 
				
			||||||
 | 
					        return END_SNAKE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < FOOD_COUNT; i++){
 | 
				
			||||||
 | 
					        if (state->foodx[i] == nova_x && state->foody[i] == nova_y){
 | 
				
			||||||
 | 
					            state->snake = add_snake(state->snake, nova_x, nova_y);
 | 
				
			||||||
 | 
					            state->foodx[i] = -1;
 | 
				
			||||||
 | 
					            state->foody[i] = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int jedlo_ostalo = 0;
 | 
				
			||||||
 | 
					            for (int j = 0; j < FOOD_COUNT; j++){
 | 
				
			||||||
 | 
					                if (state->foodx[j] != -1 && state->foody[j] != -1){
 | 
				
			||||||
 | 
					                    jedlo_ostalo = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (jedlo_ostalo == 0){
 | 
				
			||||||
 | 
					                return END_FOOD;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return END_CONTINUE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state->snake = add_snake(state->snake, nova_x, nova_y);
 | 
				
			||||||
 | 
					    state->snake = remove_snake(state->snake);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return END_CONTINUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								a3/snake.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								a3/snake.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					#include "snake.h"
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										114
									
								
								a3/snake.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								a3/snake.h
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										198
									
								
								a3/world.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								a3/world.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,198 @@
 | 
				
			|||||||
 | 
					#include "world.h"
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										122
									
								
								a3/world.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								a3/world.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					#ifndef _WORLD_H_
 | 
				
			||||||
 | 
					#define _WORLD_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <curses.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user