refresh
This commit is contained in:
		
							parent
							
								
									7ea4fe4500
								
							
						
					
					
						commit
						eb14c451e1
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
			
		||||
CC = gcc
 | 
			
		||||
CFLAGS = -Wall -Wextra -std=c99
 | 
			
		||||
dIRS = a1 du1 du2 du3 du4 du5
 | 
			
		||||
dIRS = a1 du1 du2 du3 du4 du5 a3
 | 
			
		||||
all: 
 | 
			
		||||
	@for %%d in ($(dIRS)) do \
 | 
			
		||||
		$(CC) $(CFLAGS) %%d\program.c -o %%d\program.exe
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								a3/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								a3/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
CC = gcc
 | 
			
		||||
CFLAGS = -Wall -Wextra -std=c99
 | 
			
		||||
 | 
			
		||||
OBJS = main.o snake.o world.o
 | 
			
		||||
 | 
			
		||||
snake: $(OBJS)
 | 
			
		||||
	$(CC) $(CFLAGS) -o snake $(OBJS)
 | 
			
		||||
 | 
			
		||||
main.o: main.c snake.h world.h
 | 
			
		||||
	$(CC) $(CFLAGS) -c main.c
 | 
			
		||||
 | 
			
		||||
snake.o: snake.c snake.h
 | 
			
		||||
	$(CC) $(CFLAGS) -c snake.c
 | 
			
		||||
 | 
			
		||||
world.o: world.c world.h snake.h
 | 
			
		||||
	$(CC) $(CFLAGS) -c world.c
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	del *.o *.exe
 | 
			
		||||
							
								
								
									
										42
									
								
								a3/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								a3/main.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "snake.h"
 | 
			
		||||
#include "world.h"
 | 
			
		||||
 | 
			
		||||
int main(void) {
 | 
			
		||||
    struct state game_state;
 | 
			
		||||
 | 
			
		||||
    setup_world(&game_state, 20, 10);
 | 
			
		||||
    draw_world(&game_state);
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        char command = read_input();
 | 
			
		||||
 | 
			
		||||
        change_direction(&game_state, command);
 | 
			
		||||
 | 
			
		||||
        int outcome = step_state(&game_state);
 | 
			
		||||
        draw_world(&game_state);
 | 
			
		||||
 | 
			
		||||
        if (outcome != END_CONTINUE) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        Sleep(1000);  
 | 
			
		||||
#else
 | 
			
		||||
        sleep(1);    
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free_snake(game_state.snake);
 | 
			
		||||
    printf("\n--- KONIEC HRY ---\n");
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								a3/snake.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								a3/snake.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "snake.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
struct snake* add_snake (struct snake* snake, int x, int y) {
 | 
			
		||||
    struct snake* head = NULL;
 | 
			
		||||
 | 
			
		||||
    head = malloc(sizeof(struct snake));
 | 
			
		||||
 | 
			
		||||
    if (!head) {
 | 
			
		||||
        return snake;
 | 
			
		||||
    }    
 | 
			
		||||
        head->x = x;
 | 
			
		||||
        head->y = y;
 | 
			
		||||
 | 
			
		||||
        head->next = NULL;
 | 
			
		||||
 | 
			
		||||
        if (snake !=NULL) {
 | 
			
		||||
            head->next = snake;
 | 
			
		||||
        }
 | 
			
		||||
        return head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct snake* remove_snake(struct snake* snake) {
 | 
			
		||||
    if (snake == NULL) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (snake->next == NULL) {
 | 
			
		||||
        free(snake);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct snake* temp = snake;
 | 
			
		||||
    while (temp->next->next != NULL) {
 | 
			
		||||
        temp = temp->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(temp->next);
 | 
			
		||||
    temp->next = NULL;
 | 
			
		||||
 | 
			
		||||
    return snake;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free_snake(struct snake* sn) {
 | 
			
		||||
    struct snake* walker = sn;
 | 
			
		||||
    struct snake* next_part = NULL;
 | 
			
		||||
    while (walker !=NULL) {
 | 
			
		||||
        next_part = walker->next;
 | 
			
		||||
        free(walker);
 | 
			
		||||
        walker = next_part;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int is_snake(struct snake* snake, int x, int y) {
 | 
			
		||||
    struct snake* current = snake;
 | 
			
		||||
 | 
			
		||||
    while (current !=NULL) {
 | 
			
		||||
        if ((current->x==x) && (current->y==y)) {
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        current = current->next;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int step_state(struct state* state) {
 | 
			
		||||
    int x = state->snake->x + state->sx;
 | 
			
		||||
    int y = state->snake->y + state->sy;
 | 
			
		||||
 | 
			
		||||
    if (x < 0) return END_WALL;
 | 
			
		||||
    if (x >= state->width) return END_WALL;
 | 
			
		||||
    if (y < 0) return END_WALL;
 | 
			
		||||
    if (y >= state->height) return END_WALL;
 | 
			
		||||
 | 
			
		||||
    if (is_snake(state->snake, x, y)) {
 | 
			
		||||
        return END_SNAKE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int food_found = -1;
 | 
			
		||||
    for (int idx = 0; idx < FOOD_COUNT; idx++) {
 | 
			
		||||
        if (state->foodx[idx] == x && state->foody[idx] == y) {
 | 
			
		||||
            food_found = idx;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (food_found != -1) {
 | 
			
		||||
        state->foodx[food_found] = -1;
 | 
			
		||||
        state->foody[food_found] = -1;
 | 
			
		||||
        state->snake = add_snake(state->snake, x, y);
 | 
			
		||||
 | 
			
		||||
        int remaining = 0;
 | 
			
		||||
        for (int k = 0; k < FOOD_COUNT; ++k) {
 | 
			
		||||
            remaining += (state->foodx[k] >= 0 && state->foody[k] >= 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (remaining == 0) {
 | 
			
		||||
            return END_FOOD;
 | 
			
		||||
        }
 | 
			
		||||
        return END_CONTINUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state->snake = add_snake(state->snake, x, y);
 | 
			
		||||
    state->snake = remove_snake(state->snake);
 | 
			
		||||
 | 
			
		||||
    return END_CONTINUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								a3/snake.exe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								a3/snake.exe
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										111
									
								
								a3/snake.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								a3/snake.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,111 @@
 | 
			
		||||
#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 means 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 should calculate new position of the snake head
 | 
			
		||||
 * from the current position and speed vector.
 | 
			
		||||
 * Then it should modify snake parts 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
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								a3/snake.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								a3/snake.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										109
									
								
								a3/world.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								a3/world.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include "world.h"
 | 
			
		||||
#include "snake.h"
 | 
			
		||||
 | 
			
		||||
static void place_food(struct state* s) {
 | 
			
		||||
    int placed = 0;
 | 
			
		||||
 | 
			
		||||
    while (placed < FOOD_COUNT) {
 | 
			
		||||
        int fx = rand() % s->width;
 | 
			
		||||
        int fy = rand() % s->height;
 | 
			
		||||
 | 
			
		||||
        if (!is_snake(s->snake, fx, fy)) {
 | 
			
		||||
            s->foodx[placed] = fx;
 | 
			
		||||
            s->foody[placed] = fy;
 | 
			
		||||
            placed++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setup_world(struct state* s, int w, int h) {
 | 
			
		||||
    if (!s) return;
 | 
			
		||||
 | 
			
		||||
    srand((unsigned int)time(NULL));
 | 
			
		||||
    s->width = w;
 | 
			
		||||
    s->height = h;
 | 
			
		||||
 | 
			
		||||
    s->sx = 1;
 | 
			
		||||
    s->sy = 0;
 | 
			
		||||
 | 
			
		||||
    s->snake = NULL;
 | 
			
		||||
    int start_x = w / 2;
 | 
			
		||||
    int start_y = h / 2;
 | 
			
		||||
 | 
			
		||||
    s->snake = add_snake(s->snake, start_x, start_y);
 | 
			
		||||
 | 
			
		||||
    place_food(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void draw_world(const struct state* s) {
 | 
			
		||||
    if (!s) return;
 | 
			
		||||
 | 
			
		||||
    system("clear"); // или "cls" на Windows
 | 
			
		||||
 | 
			
		||||
    for (int row = 0; row < s->height; row++) {
 | 
			
		||||
        for (int col = 0; col < s->width; col++) {
 | 
			
		||||
            int drawn = 0;
 | 
			
		||||
 | 
			
		||||
            if (is_snake(s->snake, col, row)) {
 | 
			
		||||
                putchar('O');
 | 
			
		||||
                drawn = 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                for (int i = 0; i < FOOD_COUNT; ++i) {
 | 
			
		||||
                    if (s->foodx[i] == col && s->foody[i] == row) {
 | 
			
		||||
                        putchar('*');
 | 
			
		||||
                        drawn = 1;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!drawn) {
 | 
			
		||||
                putchar('.');
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        putchar('\n');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char read_input(void) {
 | 
			
		||||
    char key = 0;
 | 
			
		||||
 | 
			
		||||
    printf("Zadaj smer (WASD): ");
 | 
			
		||||
    scanf(" %c", &key);
 | 
			
		||||
 | 
			
		||||
    return key;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void change_direction(struct state* s, char key) {
 | 
			
		||||
    if (!s) return;
 | 
			
		||||
 | 
			
		||||
    switch (key) {
 | 
			
		||||
        case 'w':
 | 
			
		||||
        case 'W':
 | 
			
		||||
            s->sx = 0;
 | 
			
		||||
            s->sy = -1;
 | 
			
		||||
            break;
 | 
			
		||||
        case 's':
 | 
			
		||||
        case 'S':
 | 
			
		||||
            s->sx = 0;
 | 
			
		||||
            s->sy = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'a':
 | 
			
		||||
        case 'A':
 | 
			
		||||
            s->sx = -1;
 | 
			
		||||
            s->sy = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'd':
 | 
			
		||||
        case 'D':
 | 
			
		||||
            s->sx = 1;
 | 
			
		||||
            s->sy = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            // ничего не делаем при некорректном вводе
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								a3/world.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								a3/world.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
#ifndef WORLD_MODULE_H
 | 
			
		||||
#define WORLD_MODULE_H
 | 
			
		||||
 | 
			
		||||
#include "snake.h"
 | 
			
		||||
 | 
			
		||||
void setup_world(struct state* s, int w, int h);
 | 
			
		||||
void draw_world(const struct state* s);
 | 
			
		||||
char read_input(void);
 | 
			
		||||
void change_direction(struct state* s, char key);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								a3/world.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								a3/world.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user