Skip to content
Snippets Groups Projects
snake.c 21.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • KosmX's avatar
    :D
    KosmX committed
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    161400@bme.hu's avatar
    161400@bme.hu committed
    #include<locale.h>
    
    KosmX's avatar
    KosmX committed
    #include<ctype.h>
    
    KosmX's avatar
    KosmX committed
    #include<time.h>
    
    KosmX's avatar
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
    #include "structs.h"
    #include "multiplatformLib.h"
    
    KosmX's avatar
    :D
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
    //debugmalloc from infoc
    #include "debugmalloc.h"
    
    
    KosmX's avatar
    KosmX committed
    #define green "\e[0;32m"
    #define blue "\e[0;34m"
    
    
    KosmX's avatar
    KosmX committed
    //There are lots of hints on https://infoc.eet.bme.hu/
    
    KosmX's avatar
    :D
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
    //#define windows 1 with #ifndef __linux__ solved...
    //typedef unsigned long long int pointer; //Not optimal and not required. sometimes even the worst idea...
    
    KosmX's avatar
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
    //-----------methods--------------
    
    KosmX's avatar
    KosmX committed
    
    
    161400@bme.hu's avatar
    161400@bme.hu committed
    int isUnicodeEncoding(int set){
        static int bl = 0;
        if(set){
            bl = 1;
        }
        return bl;
    }
    
    KosmX's avatar
    :D
    KosmX committed
    
    /**
     * Only the first byte is required
     */
    int checkUnicharLen(char c){
        int i = 0;
    
    KosmX's avatar
    KosmX committed
        if(!isUnicodeEncoding(0)){
    
    KosmX's avatar
    :D
    KosmX committed
            return 1; //int windows-xyzw every char has 1 len;
        }
        if(!(c & 0x80)){
            return 1;
        }
        while(c & 0x80){
            i++;
            c = c << 1;
            if(i > 8){
                return EOF;
            }
        }
        return i;
    }
    
    void printChar(unichar c){
        int len;
        len = checkUnicharLen(c.bytes.c[0]);
        for(int i = 0; i < len; i++){
            printf("%c", c.bytes.c[i]);
        }
    }
    
    
    KosmX's avatar
    KosmX committed
    //fueoetoeoecsoeoe *next //what to NOT do
    
    KosmX's avatar
    :D
    KosmX committed
    
    int readFile(FILE *file, Matrix *matrix){
    
    KosmX's avatar
    KosmX committed
        int c, len, maxLineLen = 0, lineCount = 1, lineLen = 0; //lineCount = (3,1) ??? why?... i was just bored
    
    KosmX's avatar
    :D
    KosmX committed
        struct Vec2i pos;
        pos.x = 0;
        pos.y = 0;
        linkedString *linkedStr = 0, *current = 0, *next;
        //linkedStr = malloc(sizeof(linkedString));
    
    KosmX's avatar
    KosmX committed
        while(c = fgetc(file), c != EOF){
    
    KosmX's avatar
    :D
    KosmX committed
            next = malloc(sizeof(linkedString));
            if(next == NULL){
                return EOF;
            }
            memset(next, 0, sizeof(linkedString)); //TODO remove after debugging
            next->next = 0;
            while (c == '\r')
            {
                c = fgetc(file);
                if(c == -1){
                    break;
                }
            }
            next->value.bytes.c[0] = c;
            len = checkUnicharLen(c);
    
    KosmX's avatar
    KosmX committed
            if(isUnicodeEncoding(0) && len -1){
    
    KosmX's avatar
    :D
    KosmX committed
                for (int i = 1; i < len; i++){
                    c = fgetc(file);
                    if(c == -1){
                        return EOF;
                    }
                    next->value.bytes.c[i] = c;
                }
            }
            else if(c == '\n'){       //checking newline (unichar can't be a newline char (\n))
                lineCount++;
                if(lineLen > maxLineLen){
                    maxLineLen = lineLen;
                }
                lineLen = -1;
            }
            lineLen++;
            //next.value = chars;
            if(current != 0){
                current->next = next;
            }
            else
            {
                linkedStr = next;
                //current = next;
            }
            current = next;
        }
        maxLineLen = maxLineLen / 2 + maxLineLen % 2;
        matrix->height = lineCount;
        matrix->width = maxLineLen;
        matrix->matrix = calloc(maxLineLen, sizeof(chunk*));
        if(matrix->matrix == NULL){
            printf("failed to allocate memory for the matrix");
            return EOF-1;
        }
        for (int i = 0; i < maxLineLen; i++){
            matrix->matrix[i] = calloc(lineCount, sizeof(chunk));
            if(matrix->matrix[i] == NULL){
                printf("failed to allocate memory for the matrix");
                return EOF-1;
            }
            for(int n = 0; n < lineCount; n++){
    
    KosmX's avatar
    KosmX committed
                matrix->matrix[i][n].isFood = 0; //That is NOT food
    
    KosmX's avatar
    :D
    KosmX committed
                for(int a = 0; a < 2; a++){
    
    KosmX's avatar
    KosmX committed
                    matrix->matrix[i][n].data.chars[a].bytes.c[0] = ' ';
    
    KosmX's avatar
    :D
    KosmX committed
                }
            }
        }
    
        current = linkedStr;
        while(current != 0){
            //tmp = current;
            //current = current->next;
            //free(tmp);
            if(current->value.bytes.c[0] == '\n'){
                pos.x = 0;
                pos.y++;
                //break;
            }
            else{
                for(int charPos = 0; charPos < 4; charPos++){
    
    KosmX's avatar
    KosmX committed
                    matrix->matrix[pos.x/2][pos.y].data.chars[pos.x%2].bytes.c[charPos] = current->value.bytes.c[charPos];
    
    KosmX's avatar
    :D
    KosmX committed
                }
                pos.x++; 
            }
            next = current;
            current = current->next;
            free(next);
        }
        return 0;
    }
    
    void rmMatrix(Matrix *map){
        for(int i = 0; i < map->width; i++){
            free(map->matrix[i]);
        }
        free(map->matrix);
    }
    
    
    KosmX's avatar
    KosmX committed
    //Use what chunk,
    //witch screen coordinates?
    //just the screen data
    
    KosmX's avatar
    KosmX committed
    void printChunk(chunk ch, Pos pos, screenData *scrDat){
    
    KosmX's avatar
    KosmX committed
        //pos.x -= scrDat->pos.x;
        //pos.y -= scrDat->pos.y;
        if(pos.x < 0 || pos.y < 0 || pos.x >= scrDat->size.x || pos.y >= scrDat->size.y){
    
    KosmX's avatar
    KosmX committed
            return; //if pos is not on the screen, just do nothing.
        }
    
    KosmX's avatar
    KosmX committed
        printf("\e[%d;%dH", pos.y+1, pos.x *2+1);
    
    KosmX's avatar
    KosmX committed
        for(int i = 0; i < 2; i++){
    
    KosmX's avatar
    KosmX committed
            printChar(ch.data.chars[i]);
    
    KosmX's avatar
    KosmX committed
        }
    
    KosmX's avatar
    KosmX committed
        #ifdef DEBUG
        printf("\e[0;0H\n"); //to update terminal after EVERY print but drasticlally slowing it down
        #endif
    
    KosmX's avatar
    KosmX committed
    }
    
    
    KosmX's avatar
    KosmX committed
    /**Print characters to a map pos
     * 
     * It will check if the character is on the screen
     * 
     */
    
    KosmX's avatar
    KosmX committed
    void print(chunk ch, Pos pos, screenData *scrDat, int width, int height){
        pos.x = pos.x - scrDat->pos.x;
        if(pos.x < 0){
            if(scrDat->isXRepeat){
                pos.x += width;
            }
            else{
                return;
            }
        }
        pos.y = pos.y - scrDat->pos.y;
        if(pos.y < 0){
            if(scrDat->isYRepeat){
                pos.y += height;
            }
            else{
                return;
            }
        }
        printChunk(ch, pos, scrDat);
    
    KosmX's avatar
    KosmX committed
    }
    
    
    KosmX's avatar
    KosmX committed
    void printSnakeChunk(snakeChain *snake){
        //TODO
    }
    
    
    KosmX's avatar
    KosmX committed
    int updateScreenSize(Matrix *map, screenData *scrDat){
        struct Vec2i size = getWindowSize();
    
    KosmX's avatar
    KosmX committed
        size.x = size.x / 2;
    
        size.y = size.y;// / 2;//Why half?
    
    KosmX's avatar
    KosmX committed
        if(size.x == scrDat->size.x && size.y == scrDat->size.y){
            return 0; //no change happened
        }
        scrDat->size.x = size.x;
        scrDat->size.y = size.y;
        if(scrDat->repeatMap){
            scrDat->isXRepeat = size.x < map->width;
            scrDat->isYRepeat = size.y < map->height;
        }
        return 1;
    }
    
    //Update screen if required 
    
    KosmX's avatar
    KosmX committed
    void updateScreen(Matrix *map, screenData *scrDat, snakeChain *head, Direction d){
    
    KosmX's avatar
    KosmX committed
        int do_update;
        do_update = updateScreenSize(map, scrDat);
    
    KosmX's avatar
    KosmX committed
    
        if(do_update){
            if(scrDat->size.x < map->width){
                scrDat->pos.x = mod((head->pos.x + scrDat->size.x) / 2 ,map->width, scrDat->repeatMap);
            }else{
                scrDat->pos.x = 0;
            }
            if(scrDat->size.y < map->height){
                scrDat->pos.y = mod((head->pos.y + scrDat->size.y) / 2 ,map->height, scrDat->repeatMap);
            }else{
                scrDat->pos.y = 0;
    
    KosmX's avatar
    KosmX committed
            }
        }
        else{
    
    KosmX's avatar
    KosmX committed
            int min_x = scrDat->pos.x;
            int max_x = scrDat->pos.x + scrDat->size.x;
            int min_y = scrDat->pos.y;
            int max_y = scrDat->pos.y + scrDat->size.y;
            switch (d)
            {
            case LEFT:
                if(scrDat->size.x < map->width && mod(head->pos.x - min_x, map->width, 1) < 6){
                    scrDat->pos.x = mod(min_x - 1, map->width, scrDat->isXRepeat);
                    do_update = 1;
                }
                break;
            case RIGHT:
                if(scrDat->size.x < map->width && mod(max_x - head->pos.x, map->width, 1) < 6){
                    scrDat->pos.x = mod(mod(max_x + 1, map->width, scrDat->isXRepeat) - scrDat->size.x, map->width, true);
                    do_update = 1; //1 equal true :D
                }
                break;
            case UP:
                if(scrDat->size.y < map->height && mod(head->pos.y - min_y, map->height, 1) < 6){
                    scrDat->pos.y = mod(min_y - 1, map->height, scrDat->isYRepeat);
                    do_update = 1;
                }
                break;
            case DOWN:
                if(scrDat->size.y < map->height && mod(max_y - head->pos.y, map->height, 1) < 6){
                    scrDat->pos.y = mod(mod(max_y + 1, map->height, scrDat->isYRepeat) - scrDat->size.y, map->height, true);
                    do_update = 1; //1 equal true :D
                }
                break;
            default:
                //printf("Something went wrong. Direction value is %d.\n", d);
                break;
            }
        }
    
        if(do_update){
            Pos pos;
            for (pos.y = scrDat->pos.y; pos.y < scrDat->pos.y + scrDat->size.y; pos.y++){
    
    KosmX's avatar
    KosmX committed
                printf("\e[%d;0H\e[K", pos.y - scrDat->pos.y + 1); //Clear the screen line
                if(pos.y >= map->height && !scrDat->isYRepeat){
                    break;
                }
    
                for (pos.x = scrDat->pos.x; pos.x < scrDat->pos.x + scrDat->size.x; pos.x++){
                    if(pos.x < map->width || scrDat->isXRepeat){
                        print(map->matrix[pos.x%map->width][pos.y%map->height], pos, scrDat, map->width, map->height);
    
    KosmX's avatar
    KosmX committed
                    }
                }
            }
    
    KosmX's avatar
    KosmX committed
        }
    }
    
    
    KosmX's avatar
    KosmX committed
    void getControl(screenData *scrDat, Direction *direction){
        int i;
        while(i = getNextChar(), i != EOF){
            Direction next = NONE;
            switch (i)
            {
            case 'a':
                next = LEFT;
                break;
            
            case 's':
                next = DOWN;
                break;
            
            case 'w':
                next = UP;
                break;
            
            case 'd':
                next = RIGHT;
                break;
            
            default:
                next = NONE;
                continue; //we don't have to registrane a non command...
            }
    
            if(next == *direction){
                scrDat->commands[0] = NONE;
                scrDat->commands[1] = NONE;
                continue;
            }
    
    KosmX's avatar
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
            // [a && b || c]  =  [c || a && b]  =  [(a && b) || c]
            if(((*direction == UP || *direction == DOWN) && (next == RIGHT || next == LEFT))
            || ((*direction == RIGHT || *direction == LEFT) && (next == UP || next == DOWN))){
                scrDat->commands[0] = next;
            }
            else
            {
                if(scrDat->commands[0] != NONE){
                    scrDat->commands[1] = next;
                }
            }
        }
    }
    
    
    KosmX's avatar
    KosmX committed
    int isNotWall(chunk c){
        return c.isFood || (c.data.chars[0].bytes.c[0] == ' ' && c.data.chars[1].bytes.c[0] == ' ');
    }
    
    
    KosmX's avatar
    KosmX committed
    int isAir(chunk c){
    
    KosmX's avatar
    KosmX committed
        return !c.isFood && isNotWall(c);
    
    KosmX's avatar
    KosmX committed
    }
    
    
    KosmX's avatar
    KosmX committed
    void updateFood(Matrix *map, int *foodTick, int feedAmount, snakeChain *firstSnake, screenData *scrDat){
    
    KosmX's avatar
    KosmX committed
        if((*foodTick)++ > feedAmount){
            for(int i = 0; i < 128; i++){
                Pos pos;
                int isFree = 1;
                snakeChain *snake = firstSnake;
                pos.x = rand()%map->width;
                pos.y = rand()%map->height;
    
    
    KosmX's avatar
    KosmX committed
                if(isAir(map->matrix[pos.x][pos.y])){
                    while(snake != NULL){
                        if(snake->pos.x == pos.x && snake->pos.y == pos.y){
                            isFree = false;
                            break;
                        }
                        snake = snake->next;
    
    KosmX's avatar
    KosmX committed
                    }
    
    KosmX's avatar
    KosmX committed
                    if(!isFree){
                        continue;
    
    KosmX's avatar
    KosmX committed
                    }
    
    KosmX's avatar
    KosmX committed
                    //pos is available
                    {
                        *foodTick = 0;
    
    KosmX's avatar
    KosmX committed
                        chunk c;
    
    KosmX's avatar
    KosmX committed
                        map->matrix[pos.x][pos.y].isFood = 1;
                        map->matrix[pos.x][pos.y].data.FRand = rand();
                        c.data.chars[0].bytes.c[0] = 'X';
                        c.data.chars[0].bytes.c[0] = 'X';
    
    KosmX's avatar
    KosmX committed
                        printf(green);
                        print(c, pos, scrDat, map->width, map->height);
                        printf("\e[0m");
    
    KosmX's avatar
    KosmX committed
                        break;
    
    KosmX's avatar
    KosmX committed
                    }
                }
            }
        }
    }
    
    //EOF fatal error, 1 game over
    
    KosmX's avatar
    KosmX committed
    int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, int canBite){
    
    KosmX's avatar
    KosmX committed
        Pos pos = head->pos;
        switch (d)
        {
        case UP:
            pos.y++;
            break;
        case DOWN:
            pos.y--;
            break;
        case LEFT:
            pos.x--;
            break;
        case RIGHT:
            pos.x++;
            break;
        default:
            return EOF;
            break;
        }
        if(pos.x < 0 || pos.x >= map->width){
            if(scrDat->repeatMap){
                pos.x = mod(pos.x, map->width, true);
            }
            else
            {
                return 1; //GAME OVER reached map end;
            }
        }
        if(pos.y < 0 || pos.y >= map->height){
            if(scrDat->repeatMap){
                pos.y = mod(pos.y, map->height, true);
            }
            else
            {
                return 1; //GAME OVER reached map end;
            }
        }
        
    
    KosmX's avatar
    KosmX committed
        if(isNotWall(map->matrix[pos.x][pos.y])){
            int isFood = map->matrix[pos.x][pos.y].isFood;
    
    KosmX's avatar
    KosmX committed
            snakeChain *snake = head;
            Pos tmp_pos1 = head->pos, tmp_pos2;
            while (snake->next != 0)
            {
    
    KosmX's avatar
    KosmX committed
                snake = snake->next;
    
    KosmX's avatar
    KosmX committed
                chunk c;
                if(snake != head && snake->pos.x == head->pos.x && snake->pos.y == head->pos.y){
                    if(snake->next != NULL){
                        if(canBite){
                            snakeChain *current = snake;
                            snake = snake->next;
                            current->next = NULL;
                            while (snake != NULL)
                            {
                                current = snake;
                                snake = snake->next;
                                free(current);
                            }
                        }
                        else
                        {
                            return 1; //GAME OVER snake hit itself;
                        }
                    }else
                    {
                        isFood = false;
                    }
                    
                    
                }
                tmp_pos2 = snake->pos;
                snake->pos = tmp_pos1;
                tmp_pos1 = tmp_pos2;
    
    
    KosmX's avatar
    KosmX committed
                c.data.chars[0].bytes.c[0] = '>';
                c.data.chars[0].bytes.c[0] = '<';            
    
    KosmX's avatar
    KosmX committed
                if(snake->next == NULL && isFood){
                    isFood = false;
                    snake->next = malloc(sizeof(snake));
                    if(snake->next == NULL){
                        return EOF;
                    }
                    snake->next->next = NULL;
                    snake->pos.x = -1;
                    snake->pos.y = -1;
                }
                if(snake->pos.x == -1){
                    continue;   //don't render snake part with initial position
                }
                printf(blue);
                print(c, snake->pos, scrDat, map->width, map->height); //TODO direction snake
                printf("\e[0m");
    
            }
            if(tmp_pos2.x != -1){
                chunk c; 
    
    KosmX's avatar
    KosmX committed
                c.data.chars[0].bytes.c[0] = ' ';
                c.data.chars[0].bytes.c[0] = ' ';
    
    KosmX's avatar
    KosmX committed
                print(c, tmp_pos2, scrDat, map->width, map->height); //set this to air.
            }
            chunk c;
    
    KosmX's avatar
    KosmX committed
            c.data.chars[0].bytes.c[0] = '(';
            c.data.chars[0].bytes.c[0] = ')';
    
    KosmX's avatar
    KosmX committed
            printf(blue);
            print(c, head->pos, scrDat, map->width, map->height); //TODO direction snake
            printf("\e[0m");
        }
        else
        {
            return 1; //GAME OVER hit the wall;
        }
        return 0;
    
    KosmX's avatar
    KosmX committed
    }
    
    KosmX's avatar
    KosmX committed
    
    //------------config loader------------
    
    
    KosmX's avatar
    KosmX committed
    int loadConfig(int *tickSpeed, int *repeatMap, int *feedAmount, int *canBite){
    
    KosmX's avatar
    KosmX committed
        FILE *config;
        config = fopen("config.cfg", "r");
        //int stillFile = 1; //boolean to show file is ended...
        if(config == NULL){
            return -1;
        }
        while(1){
            char name[32] = {0}, c; //it have to be enough;
            while(c = fgetc(config), c != -1 && isspace(c));
            if(c == -1){
                break;
            }
            //name[0] = c;
            for(int i = 0; i < 32 && !isspace(c) && c != '='; i++, c = fgetc(config)){
                name[i] = c;
            }
            //c = fgetc(config);
            while(c != '='){
                c = fgetc(config);
                if(c == -1){
                    printf("I can't  understand the config file: %s", name);
                    return EOF;
                }
            }
            if(strncmp(name, "use_utf8", 9) == 0){
                int bl;
                fscanf(config, " %d", &bl);
                isUnicodeEncoding(bl);
            }
            else if(strncmp(name, "tickspeed", 10) == 0){
                fscanf(config, " %d", tickSpeed);
            }
    
    KosmX's avatar
    KosmX committed
            else if(strncmp(name, "repeat_map", 10) == 0){
    
    KosmX's avatar
    KosmX committed
                fscanf(config, " %d", repeatMap);
            }
    
    KosmX's avatar
    KosmX committed
            else if(strncmp(name, "feed_amount", 12) == 0){
                fscanf(config, " %d", feedAmount);
            }
            else if(strncmp(name, "can_bite", 9) == 0){
                fscanf(config, " %d", canBite);
            }
    
    KosmX's avatar
    KosmX committed
            else{
                printf("Unknown keyword: %s", name);
            }
        }
        return 0;
    }
    
    
    
    
    KosmX's avatar
    KosmX committed
    //------------LOOP METHODs--------------
    
    //Tick the game, step the snake, collect and place food.
    //check new direction
    //update display
    //update food state
    //step snake
    
    KosmX's avatar
    KosmX committed
    int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int feedAmount, int canBite){
    
    KosmX's avatar
    KosmX committed
        static int foodTick = 0;
        getControl(scrDat, d);
        if(scrDat->commands[0] != NONE){
            *d = scrDat->commands[0];
        }
    
    KosmX's avatar
    KosmX committed
        updateScreen(map, scrDat, snake, *d);
        if(*d == NONE){
    
    KosmX's avatar
    KosmX committed
            chunk c;
    
    KosmX's avatar
    KosmX committed
            c.data.chars[0].bytes.c[0] = '(';
            c.data.chars[0].bytes.c[0] = ')';
    
    KosmX's avatar
    KosmX committed
            printf(blue);
            print(c, snake->pos, scrDat, map->width, map->height);
            printf("\e[0m");
            return 0; // waiting for user input.
        }
    
    KosmX's avatar
    KosmX committed
        updateFood(map, &foodTick, feedAmount, snake, scrDat);
        updateSnake(map, scrDat, *d, snake, canBite);
        //printf("\e[0;0H\n"); //Update the terminal (mostly on Unix based systems)
        fflush(stdout);
    
    KosmX's avatar
    KosmX committed
        return 0;
    }
    
    KosmX's avatar
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
    int loop(Matrix *matrix, int tickspeed, int repeatMap, int feedAmount, int canBite){
    
    KosmX's avatar
    KosmX committed
    
    
    KosmX's avatar
    KosmX committed
        Direction d = NONE; //Init with none
    
    KosmX's avatar
    a  
    KosmX committed
        screenData scrDat;
    
    KosmX's avatar
    KosmX committed
        snakeChain snake, *chain;
    
        while(true){
            Pos p;
            p.x = rand()%matrix->width;
            p.y = rand()&matrix->height;
    
    KosmX's avatar
    KosmX committed
            if(isNotWall(matrix->matrix[p.x][p.y])){
    
    KosmX's avatar
    KosmX committed
                snake.pos = p;
                break;
            }
        }
        chain = &snake;
        for(int i = 1; i < 3; i++){
            Pos p;
            p.x = -1;
            p.y = -1;
            chain->next = malloc(sizeof(snakeChain));
            if(chain->next == NULL){
                return -1;
            }
            chain = chain->next;
            chain->pos = p;
    
    KosmX's avatar
    KosmX committed
            chain->next = NULL;
    
    KosmX's avatar
    KosmX committed
        }
    
    
    KosmX's avatar
    KosmX committed
        scrDat.size.x = 0;
        scrDat.size.y = 0;
    
    KosmX's avatar
    KosmX committed
        scrDat.repeatMap = repeatMap;
    
    KosmX's avatar
    KosmX committed
        scrDat.commands[0] = NONE;
        scrDat.commands[1] = NONE;
    
    KosmX's avatar
    a  
    KosmX committed
        while(42){
    
    KosmX's avatar
    KosmX committed
            if(tick(matrix, &scrDat, &snake, &d, feedAmount, canBite)){
    
    KosmX's avatar
    KosmX committed
                break;
            }
    
    KosmX's avatar
    a  
    KosmX committed
            unisleep(tickspeed); //Special sleep to work both in windows and unix environment
        }
    
    KosmX's avatar
    KosmX committed
        return 0;
    }
    
    KosmX's avatar
    :D
    KosmX committed
    
    //------------TESTING METHODS-------------
    void _testprint(Matrix *map){
        for (int y = 0; y < map->height; y++){
            for(int x = 0; x < map->width; x++){
                for(int i = 0; i < 2; i++){
                    //printf("%c", map->matrix[x][y].chars->bytes.c[i * 4]); //WTF... I didn't indexed correctly, but accidentaly I've got the right value...
    
    KosmX's avatar
    KosmX committed
                    printChar(map->matrix[x][y].data.chars[i]);
                    //unisleep(1000);
    
    KosmX's avatar
    :D
    KosmX committed
                }
                //printf("|");
            }
            printf("\n");
        }
    }
    
    void _print1char(Matrix *map){
        int x, y;
        while(scanf(" %d%d", &x, &y) == 2){
            if(x >= 0 && y >= 0 && x < map->width && y < map->height){
                for(int i = 0;i < 2; i++){
    
    KosmX's avatar
    KosmX committed
                    printf("\nvalue: %hx, %hx, %hx, %hx\n",
    
    KosmX's avatar
    KosmX committed
                    (unsigned)map->matrix[x][y].data.chars[i].bytes.c[0],
                    (unsigned)map->matrix[x][y].data.chars[i].bytes.c[1],
                    (unsigned)map->matrix[x][y].data.chars[i].bytes.c[2],
                    (unsigned)map->matrix[x][y].data.chars[i].bytes.c[3]);
    
    KosmX's avatar
    :D
    KosmX committed
                    printf("as character: \"");
    
    KosmX's avatar
    KosmX committed
                    printChar(map->matrix[x][y].data.chars[i]);
    
    KosmX's avatar
    :D
    KosmX committed
                    printf("\"\n");
                }
            }
        }
    }
    
    
    //-------------CORE METHOD----------------
    
    int core(int argc, char const *argv[])
    {
        FILE *f;
        Matrix map;
    
    161400@bme.hu's avatar
    161400@bme.hu committed
    
    
    KosmX's avatar
    KosmX committed
        initMultiplatform(); // init stuff.
    
    
    KosmX's avatar
    KosmX committed
        srand(time(0)); // bee a bit more random
    
    
    KosmX's avatar
    KosmX committed
        int tickspeed = 100, repeatMap = 0, feedAmount = 20, canBite = true; // if no config, default value
    
    KosmX's avatar
    KosmX committed
    
        //----load config----
    
    
    KosmX's avatar
    KosmX committed
        if(loadConfig(&tickspeed, &repeatMap, &feedAmount, &canBite)){
    
    KosmX's avatar
    KosmX committed
            printf("Error while loading config...");
        }
    
    
    161400@bme.hu's avatar
    161400@bme.hu committed
        //----init tasks----
    
    
    KosmX's avatar
    KosmX committed
        if(isUnicodeEncoding(0)){
    
    KosmX's avatar
    KosmX committed
            #ifndef __linux__
    
    KosmX's avatar
    KosmX committed
            setlocale(LC_ALL, ".utf-8");
    
    KosmX's avatar
    KosmX committed
            #endif
    
    KosmX's avatar
    KosmX committed
        }
    
    161400@bme.hu's avatar
    161400@bme.hu committed
    
        //----import map----
    
    
    KosmX's avatar
    :D
    KosmX committed
        if(argc == 1){
            printf("Usage: snake <map name> [<snake skin>]");
            return 0;
        }
        else{
            f = fopen(argv[1], "rb");
            if(f == NULL){
                printf("Map file not found: %s", argv[1]);
                return EOF;
            }
            readFile(f, &map);
        }
    
    
    KosmX's avatar
    KosmX committed
        //----start game----
    
    
    KosmX's avatar
    KosmX committed
        loop(&map, tickspeed, repeatMap, feedAmount, canBite);
    
    
    KosmX's avatar
    :D
    KosmX committed
        //test code
    
    KosmX's avatar
    KosmX committed
        //printf("map:\n");
        //_print1char(&map);
    
    KosmX's avatar
    :D
    KosmX committed
        /* code */
        //free stuff
    
    KosmX's avatar
    :D
    KosmX committed
        rmMatrix(&map);
    
        return 0;
    }
    
    
    /*
    int main(int argc, char const *argv[])
    {
        return core(argc, argv);
    }
    */
    
    int main(int argc, char const *argv[])
    {
    
    KosmX's avatar
    KosmX committed
        //2 + 3;  //... this does nothing...
    
    KosmX's avatar
    KosmX committed
        #ifdef DEBUG
    
    KosmX's avatar
    :D
    KosmX committed
        int ret;
    
    161400@bme.hu's avatar
    161400@bme.hu committed
        char const *array[] = {argv[0], "map1.txt"};
    
    KosmX's avatar
    :D
    KosmX committed
        ret = core(2, array);
        printf("\npress any key to continue");
        getchar();
    
    KosmX's avatar
    KosmX committed
        //return 0, ret; //Miért van ez a függvény tele szeméttel??? pl 0, smt...
    
        return ret; // így szép.
    
    KosmX's avatar
    KosmX committed
        #else
        return core(argc, argv);
        #endif
    
    KosmX's avatar
    :D
    KosmX committed
    }