zadanie_3
This commit is contained in:
		
							parent
							
								
									273e1aef67
								
							
						
					
					
						commit
						4c68213568
					
				
							
								
								
									
										54
									
								
								a4/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								a4/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
game
 | 
			
		||||
 | 
			
		||||
# Prerequisites
 | 
			
		||||
*.d
 | 
			
		||||
 | 
			
		||||
# Object files
 | 
			
		||||
*.o
 | 
			
		||||
*.ko
 | 
			
		||||
*.obj
 | 
			
		||||
*.elf
 | 
			
		||||
 | 
			
		||||
# Linker output
 | 
			
		||||
*.ilk
 | 
			
		||||
*.map
 | 
			
		||||
*.exp
 | 
			
		||||
 | 
			
		||||
# Precompiled Headers
 | 
			
		||||
*.gch
 | 
			
		||||
*.pch
 | 
			
		||||
 | 
			
		||||
# Libraries
 | 
			
		||||
*.lib
 | 
			
		||||
*.a
 | 
			
		||||
*.la
 | 
			
		||||
*.lo
 | 
			
		||||
 | 
			
		||||
# Shared objects (inc. Windows DLLs)
 | 
			
		||||
*.dll
 | 
			
		||||
*.so
 | 
			
		||||
*.so.*
 | 
			
		||||
*.dylib
 | 
			
		||||
 | 
			
		||||
# Executables
 | 
			
		||||
*.exe
 | 
			
		||||
*.out
 | 
			
		||||
*.app
 | 
			
		||||
*.i*86
 | 
			
		||||
*.x86_64
 | 
			
		||||
*.hex
 | 
			
		||||
 | 
			
		||||
# Debug files
 | 
			
		||||
*.dSYM/
 | 
			
		||||
*.su
 | 
			
		||||
*.idb
 | 
			
		||||
*.pdb
 | 
			
		||||
 | 
			
		||||
# Kernel Module Compile Results
 | 
			
		||||
*.mod*
 | 
			
		||||
*.cmd
 | 
			
		||||
.tmp_versions/
 | 
			
		||||
modules.order
 | 
			
		||||
Module.symvers
 | 
			
		||||
Mkfile.old
 | 
			
		||||
dkms.conf
 | 
			
		||||
							
								
								
									
										29
									
								
								a4/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								a4/LICENSE
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
BSD 3-Clause License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2019, Daniel Hládek
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
* Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
  list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
* Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
  this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
  and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
* Neither the name of the copyright holder nor the names of its
 | 
			
		||||
  contributors may be used to endorse or promote products derived from
 | 
			
		||||
  this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										14
									
								
								a4/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								a4/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 game.o world.o
 | 
			
		||||
	gcc main.o game.o world.o -lcurses -lm -o game
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										78
									
								
								a4/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								a4/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
# World Game Library
 | 
			
		||||
 | 
			
		||||
Learn asycnronous C programming by a game.
 | 
			
		||||
 | 
			
		||||
The library implements a game loop for a character-based ncurses game;
 | 
			
		||||
 | 
			
		||||
The library finds out the event types:
 | 
			
		||||
 | 
			
		||||
- start and end
 | 
			
		||||
- mouse events
 | 
			
		||||
- keyboard events
 | 
			
		||||
- screen resize events
 | 
			
		||||
 | 
			
		||||
It can print colors and arbitrary characters on the screen. 
 | 
			
		||||
Running is interrupted when character is drawn out of the screen.
 | 
			
		||||
 | 
			
		||||
## Installation and Running
 | 
			
		||||
 | 
			
		||||
Make sure, that `ncurses` is installed.
 | 
			
		||||
 | 
			
		||||
Clone this repository.
 | 
			
		||||
 | 
			
		||||
Compile:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
make
 | 
			
		||||
```
 | 
			
		||||
	
 | 
			
		||||
Run:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
./game
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Make your own game
 | 
			
		||||
 | 
			
		||||
The game happens in a rectangular world of colorful characters. 
 | 
			
		||||
Your goal as a programmer is to modify the world according to the pressed keys and the internal game state.
 | 
			
		||||
The library implements the game loop and draws the world to screen.
 | 
			
		||||
 | 
			
		||||
Your game in file `game.c` consists of two functions:
 | 
			
		||||
 | 
			
		||||
- `void* init_game()` is called in the beginning. Here you can initialize the internal state of the game.
 | 
			
		||||
The function should return  a pointer to an instance of the initial game state `game`.
 | 
			
		||||
- `int game_event(struct event* event,void* game)`
 | 
			
		||||
is called by the game loop in periodic interval or when a key was pressed. Non-zero return value or `Ctrl+C` key interrupts the game loop.
 | 
			
		||||
 | 
			
		||||
The world variable represents state of two-dimensional grid of characters on the screen. The screen matrix looks like this:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
   origin
 | 
			
		||||
   [0,0]     width
 | 
			
		||||
  +--------------------+
 | 
			
		||||
h |                    |
 | 
			
		||||
e |                    |
 | 
			
		||||
i |                    |
 | 
			
		||||
g |                    |
 | 
			
		||||
h |                    |
 | 
			
		||||
t |                    |
 | 
			
		||||
  +--------------------+
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The world  has the following parameters:
 | 
			
		||||
 | 
			
		||||
- `int height`: y-dimension of the grid.
 | 
			
		||||
- `int width`: x-dimension of the grid.
 | 
			
		||||
- `int interval`: maximum time between steps in milliseconds.
 | 
			
		||||
 | 
			
		||||
### The Event Function
 | 
			
		||||
 | 
			
		||||
The `int game_event(struct event* event,void* game)`
 | 
			
		||||
 function should:
 | 
			
		||||
 | 
			
		||||
1. Read the game state (from the `void* game`) pointer.
 | 
			
		||||
1. Examine the pressed key from event pointer. If the `key` variable is non-zero, a key was pressed. According to the pressed key, modify the game state `game`.
 | 
			
		||||
1. Draw the game state. In the beginning of the step function the screen is empty.
 | 
			
		||||
1. Returning non-zero value ends the game loop. 
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										152
									
								
								a4/game.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								a4/game.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,152 @@
 | 
			
		||||
#include <curses.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include "world.h"
 | 
			
		||||
#include "game.h"
 | 
			
		||||
 | 
			
		||||
// Start is called one in the beginning
 | 
			
		||||
void* init_game(){
 | 
			
		||||
    // Allocate memory for the state
 | 
			
		||||
    struct game* st = calloc(1,(sizeof(struct game)));
 | 
			
		||||
    // Initialize state
 | 
			
		||||
    
 | 
			
		||||
	int vygenerovaneCislo = 0, i;
 | 
			
		||||
	srand(time(NULL));
 | 
			
		||||
	
 | 
			
		||||
	for (i = 0; i < MOUSE_COUNT; i++) {
 | 
			
		||||
		vygenerovaneCislo = (COLS > LINES) ? ((rand() % (LINES - 4)) + 2) : ((rand() % (COLS - 4) + 2));
 | 
			
		||||
		st->mousex[i] = vygenerovaneCislo;
 | 
			
		||||
		st->mousey[i] = vygenerovaneCislo;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
    st->catx = 0;
 | 
			
		||||
    st->caty = 0;
 | 
			
		||||
    st->catx_position = 15;
 | 
			
		||||
    st->caty_position = 15;
 | 
			
		||||
    // Store pointer to the state to the world variable
 | 
			
		||||
    return st;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Step is called in a loop once in interval.
 | 
			
		||||
// It should modify the state and draw it.
 | 
			
		||||
int game_event(struct event* event,void* game){
 | 
			
		||||
    // Get state pointer
 | 
			
		||||
    struct game* state = game;
 | 
			
		||||
    char msg[200];
 | 
			
		||||
    sprintf(msg,"%d",event->type);
 | 
			
		||||
    set_message(msg,10,0);
 | 
			
		||||
    if ( event->type == EVENT_ESC){
 | 
			
		||||
        // Non zero means finish the loop and stop the game.
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    // Read game variable and update the  eventstate
 | 
			
		||||
 | 
			
		||||
    // Is mouse caught ?	
 | 
			
		||||
	int i, pocetChytenychMysi = 0;
 | 
			
		||||
	for (i = 0; i < MOUSE_COUNT; i++) {
 | 
			
		||||
		if (state->caty_position == state->mousey[i] && state->catx_position == state->mousex[i]) {
 | 
			
		||||
			state->mousey[i] = -1;
 | 
			
		||||
			state->mousex[i]= -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	for (i = 0; i < MOUSE_COUNT; i++) {
 | 
			
		||||
		if (state->mousex[i] == -1) pocetChytenychMysi++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (pocetChytenychMysi == MOUSE_COUNT) {
 | 
			
		||||
		clear_screen();
 | 
			
		||||
		set_message("Tom zjedol Jerryov.", (COLS / 2) - (strlen("Tom zjedol Jerryov.") / 2), LINES / 2);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
    if (event->type == EVENT_TIMEOUT) {
 | 
			
		||||
        // Move cat
 | 
			
		||||
        //state->catx_position += state->catx;
 | 
			
		||||
        //state->caty_position += state->caty;
 | 
			
		||||
        int cx = state->catx_position + state->catx;
 | 
			
		||||
        int cy = state->caty_position + state->caty;
 | 
			
		||||
		
 | 
			
		||||
		if (cx < 2) state->catx_position += abs(cx) + 10;
 | 
			
		||||
		else if (cy < 2) state->caty_position += abs(cy) + 10;
 | 
			
		||||
		else if (cx == COLS - 1) state->catx_position -= (cx - COLS + 10);
 | 
			
		||||
		else if (cy == LINES - 1) state->caty_position -= (cy - LINES + 10);
 | 
			
		||||
		else {
 | 
			
		||||
            state->catx_position = cx;
 | 
			
		||||
            state->caty_position = cy;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //state->catx_position += state->catx;
 | 
			
		||||
        //state->caty_position += state->caty;
 | 
			
		||||
        //state->caty_position += state->caty;
 | 
			
		||||
        // random mouse movement
 | 
			
		||||
        int m;
 | 
			
		||||
		
 | 
			
		||||
		for (i = 0; i < MOUSE_COUNT; i++) {
 | 
			
		||||
			if (state->mousey[i] == -1) continue;
 | 
			
		||||
			m = rand() % 4;
 | 
			
		||||
			switch (m) {
 | 
			
		||||
				case 0: if (state->mousey[i] == 2) state->mousey[i] = 2;
 | 
			
		||||
						else state->mousey[i] -= 1;
 | 
			
		||||
						break;
 | 
			
		||||
						
 | 
			
		||||
				case 1: if (state->mousey[i] == LINES - 1) state->mousey[i] = LINES - 10;
 | 
			
		||||
						else state->mousey[i] += 1;
 | 
			
		||||
						break;
 | 
			
		||||
						
 | 
			
		||||
				case 2: if (state->mousex[i] == 2) state->mousex[i] = 2;
 | 
			
		||||
						else state->mousex[i] -= 1;
 | 
			
		||||
						break;
 | 
			
		||||
						
 | 
			
		||||
				case 3: if (state->mousex[i] == COLS - 1) state->mousex[i] = COLS - 10;
 | 
			
		||||
						else state->mousex[i] += 1;
 | 
			
		||||
						break;
 | 
			
		||||
						
 | 
			
		||||
				default: break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
        // Je myska mimo plochy
 | 
			
		||||
    }
 | 
			
		||||
    else if (event->type == EVENT_KEY){
 | 
			
		||||
        // Move cat according to keyboard
 | 
			
		||||
        if ( event->key == KEY_UP){
 | 
			
		||||
            state->catx = 0;
 | 
			
		||||
            state->caty = -1;
 | 
			
		||||
        }
 | 
			
		||||
        else if ( event->key == KEY_DOWN){
 | 
			
		||||
            state->catx = 0;
 | 
			
		||||
            state->caty = 1;
 | 
			
		||||
        }
 | 
			
		||||
        else if ( event->key == KEY_LEFT){
 | 
			
		||||
            state->catx = -1;
 | 
			
		||||
            state->caty = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if ( event->key == KEY_RIGHT){
 | 
			
		||||
            state->catx = 1;
 | 
			
		||||
            state->caty = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
	// Draw world state 
 | 
			
		||||
    //
 | 
			
		||||
    // Draw cat
 | 
			
		||||
    clear_screen();
 | 
			
		||||
    set_color_cell('c',state->catx_position,state->caty_position,COLOR_YELLOW,COLOR_RED);
 | 
			
		||||
    set_color_cell('-',state->catx_position-1,state->caty_position,COLOR_YELLOW,COLOR_GREEN);
 | 
			
		||||
    //set_cell('c',state->catx_position,state->caty_position);
 | 
			
		||||
    // Draw mouses
 | 
			
		||||
	for (i = 0; i < MOUSE_COUNT; i++) {
 | 
			
		||||
		if (state->mousex[i] == -1) continue;
 | 
			
		||||
		set_cell('m', state->mousex[i], state->mousey[i]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	//vykresli stenu dookola
 | 
			
		||||
	for (i = 0; i < COLS; i++) set_color_cell('-', i, 0, 0, (rand() % 7) + 1);
 | 
			
		||||
	for (i = 0; i < LINES; i++) set_color_cell('-', 0, i, 0, (rand() % 7) + 1);
 | 
			
		||||
	for (i = 0; i < COLS; i++) set_color_cell('-', i, LINES - 1, 0, (rand() % 7) + 1);
 | 
			
		||||
	for (i = 0; i < LINES; i++) set_color_cell('-', COLS - 1, i, 0, (rand() % 7) + 1);
 | 
			
		||||
	
 | 
			
		||||
    set_message( state->message,1,0);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								a4/game.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								a4/game.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
#ifndef _GAME_H_INCLUDE_
 | 
			
		||||
#define _GAME_H_INCLUDE_
 | 
			
		||||
#include "world.h"
 | 
			
		||||
 | 
			
		||||
#define MOUSE_COUNT 5
 | 
			
		||||
 | 
			
		||||
// Set of variables that expresses state of the game.
 | 
			
		||||
// 
 | 
			
		||||
struct game {
 | 
			
		||||
    // X speed of the cat
 | 
			
		||||
    int catx;
 | 
			
		||||
    // Y speed  of the cat
 | 
			
		||||
    int caty;
 | 
			
		||||
    // X position of the cat
 | 
			
		||||
    int catx_position;
 | 
			
		||||
    // Y opsition of the cat
 | 
			
		||||
    int caty_position;;
 | 
			
		||||
    // X position of the mouses
 | 
			
		||||
    int mousex[MOUSE_COUNT];
 | 
			
		||||
    // Y position of the mouses
 | 
			
		||||
    int mousey[MOUSE_COUNT];
 | 
			
		||||
    // Funky message
 | 
			
		||||
    char message[100];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Returns pointer to  newly allocated state
 | 
			
		||||
void* init_game();
 | 
			
		||||
 | 
			
		||||
// Changes world according to the game state (pressed key, screen size or other event)
 | 
			
		||||
int game_event(struct event* event,void* game);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										9
									
								
								a4/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								a4/main.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
#include "game.h"
 | 
			
		||||
#include "world.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv){
 | 
			
		||||
    start_world(init_game,game_event,free);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										198
									
								
								a4/world.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								a4/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;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										113
									
								
								a4/world.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								a4/world.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,113 @@
 | 
			
		||||
#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));
 | 
			
		||||
 | 
			
		||||
void game_speed(int value);
 | 
			
		||||
 | 
			
		||||
void set_message(const char* message,int x,int y);
 | 
			
		||||
void clear_screen();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user