From 230d58e9c3ece30a0f0062938735c18cbac3da76 Mon Sep 17 00:00:00 2001 From: Racoonicorn Date: Mon, 2 Jan 2017 22:21:52 +0100 Subject: [PATCH] First version --- IcePath.c | 420 ++++++++++++++++++++++++++++++++++++++++++++++++++ icelevels.txt | 180 ++++++++++++++++++++++ 2 files changed, 600 insertions(+) create mode 100644 IcePath.c create mode 100644 icelevels.txt diff --git a/IcePath.c b/IcePath.c new file mode 100644 index 0000000..13f6cd0 --- /dev/null +++ b/IcePath.c @@ -0,0 +1,420 @@ +#define VERSION "0.01" + +#define N 512 +#define SPEED 50000 // less is more + +#include +#include +#include +#include +#include +#include + +void printm(); +void play(); +void move_ptr(int direction); +void waitfor(int delay); +void menu(); +void readfiles(); +void ranking(); +void rules(); +void selectlevel(); +int checkwin(); +int searchlevel(); + +typedef struct { + int x; + int y; +} point; + +struct selctd { + int level; + int world; + int pos; // position in level[] +} selected; + +struct dataresult { + int moves; + int world; + int level; + time_t time; +} data[100]; + +struct infolevel { // level[0] empty + char name[15]; + int world; + int num; + int height; + int width; + int matrix[N][N]; + point start; + point exit; +} level[100]; + +int win = 0; +int moves = 0; +int totallevels; // number of levels available +point ptr; + +FILE *f_info; +FILE *f_data; + +int main() { + initscr(); + noecho(); + cbreak(); + keypad(stdscr, true); + f_info = fopen("icelevels.txt", "r"); + f_data = fopen("icedata.txt", "a+"); + if (f_info == NULL || f_data == NULL) { + printw("Error opening file. Please put icelevels.txt in the same folder of IcePath.c"); + refresh(); + getch(); + endwin(); + return 1; + } else { + readfiles(); + menu(); + fclose(f_info); + fclose(f_data); + } + endwin(); + return 0; +} + +void readfiles() { + int u = 1, i = 0, j, lines = 0; + char ch; + // read f_data + rewind(f_data); + do { // count lines + ch = fgetc(f_data); + if (ch == '\n') + lines++; + } while (ch != EOF); + if (ch != '\n' && lines != 0) + lines++; + rewind(f_data); + do { + fscanf(f_data, "%li %d %d %d", &data[i].time, &data[i].world, &data[i].level, &data[i].moves); + i++; + } while (i < lines - 1); + selected.world = data[i-1].world; + selected.level = data[i-1].level + 1; + // read f_info + lines = 0; + do { // read from line 4 + ch = fgetc(f_info); + if (ch == '\n') + lines++;; + } while (lines < 4); + do { + + fscanf(f_info, "%d.%d %s %dx%d", &level[u].world, &level[u].num, level[u].name, &level[u].height, &level[u].width); + if (level[u].world != 999) { + for (i = 0; i < level[u].height; i++){ + for (j = 0; j < level[u].width; j++) { + fscanf(f_info, "%d ", &level[u].matrix[i][j]); + if(level[u].matrix[i][j] == 1){ + level[u].matrix[i][j] = 0; + level[u].start.x = j; + level[u].start.y = i; + } + if (level[u].matrix[i][j] == 3) { + level[u].exit.x = j; + level[u].exit.y = i; + } + } + } + } + u++; + } while (level[u-1].world != 999); + totallevels = u - 1; + selected.pos = searchlevel(); +} + +void menu() { + while (1) { + clear(); + printw("~~~ ICE PATH ~~~\n\n" + "[1] Play\n" + "[2] Select level\n" + "[3] Ranking\n" + //"[4] Settings\n" + "[5] Rules\n" + "[q] Quit\n\nv%s\n\n", VERSION); + switch (getch()) { + case 'q': return; + case '1': play(); break; + case '2': selectlevel(); break; + case '3': ranking(); break; + //case '4': settings(); break; + case '5': rules(); break; + } + } +} + +void play() { + int direction; + int win, again = 0; + char *text = malloc(sizeof(text) * N); + do { + selected.pos = searchlevel(); + moves = 0; + again = 0; + ptr.x = level[selected.pos].start.x; + ptr.y = level[selected.pos].start.y; + do { + printm(); + refresh(); + direction = getch(); + if (direction == 'q') { + printw ("\nDo you really want to exit? [y/n] "); + refresh (); + if (getch () == 'y') { + return; + } else { + direction = 0; + } + } + if (direction == 'r') { + printw ("\nDo you really want to retry this level? [y/n] "); + refresh (); + if (getch () == 'y') { + again = 1; + } else { + direction = 0; + } + } + if (direction != 0 && direction != 'r') { + move_ptr(direction); + } + win = checkwin(); + } while (win == 0 && direction != 'r'); + if (win == 1) { + sprintf(text, "%li %d %d %d\n", time(NULL), selected.world, selected.level, moves); + fseek(f_data, 0, SEEK_END); + fputs(text, f_data); + printw("You win! Moves: %d. Retry [r]. Next level? [y/n]\n", moves); + refresh(); + char ch = getchar(); + if (ch == 'y') { + again = 1; + } else if (ch == 'r') { + again = 1; + selected.level--; + } + selected.level++; + } + } while (again); + free(text); + return; +} + +void move_ptr(int direction) { + int temp_x = ptr.x, temp_y = ptr.y, tempmoves = moves; + switch (direction) { + case KEY_LEFT: + moves++; + while (ptr.x != 0 && level[selected.pos].matrix[ptr.y][ptr.x-1] != 3) { + ptr.x--; + printm(); + refresh(); + if (checkwin() == 1) { + break; + } else { + waitfor(SPEED); + } + } break; + case KEY_RIGHT: + moves++; + while (ptr.x < level[selected.pos].width - 1 && level[selected.pos].matrix[ptr.y][ptr.x+1] != 3){ + ptr.x++; + printm(); + refresh(); + if (checkwin() == 1) { + break; + } else { + waitfor(SPEED); + } + } break; + case KEY_UP: + moves++; + while (ptr.y > 0 && level[selected.pos].matrix[ptr.y-1][ptr.x] != 3) { + ptr.y--; + printm(); + refresh(); + if (checkwin() == 1) { + break; + } else { + waitfor(SPEED); + } + } break; + case KEY_DOWN: + moves++; + while (ptr.y < level[selected.pos].height - 1 && level[selected.pos].matrix[ptr.y+1][ptr.x] != 3) { + ptr.y++; + printm(); + refresh(); + if (checkwin() == 1) { + break; + } else { + waitfor(SPEED); + } + } break; + default: return; + } + if (temp_x == ptr.x && temp_y == ptr.y) + moves = tempmoves; +} + +void printm() { + int i, j; + clear(); + printw("Level %d.%d: %s. Moves: %d. Use arrows to move.\nRetry [r]. Quit [q]\n\n", level[selected.pos].world, level[selected.pos].num, level[selected.pos].name, moves); + if (level[selected.pos].height > 9 || level[selected.pos].width > 9) + printw("Warning! Keep this window in fullscreen mode please\n\n\n"); + for (i = 0; i < level[selected.pos].height; i++) { + for (j = 0; j < level[selected.pos].width; j++) { + if (i == ptr.y && j == ptr.x) { + printw("YOU"); + } else { + switch (level[selected.pos].matrix[i][j]) { + case 0: printw(" "); break; + case 3: printw("|/|"); break; + case 2: printw("( )"); break; + default: printw("?"); break; + } + } + printw("\t"); + } + printw("\n\n"); + } + refresh(); +} + +int searchlevel() { + int i; + for (i = 0; i < totallevels; i++) { + if (level[i].num == selected.level && level[i].world == selected.world) + return i; + } + // else go to level 1 of next world + selected.world++; + selected.level = 1; + for (i = 0; i < totallevels; i++) { + if (level[i].num == selected.level && level[i].world == selected.world) + return i; + } + // else go to level 1.1 + selected.level = selected.world = 1; + return 1; +} + +void selectlevel() { + while (1) { + int again; + clear(); + printw("> Select level. Menu [q]\n\n"); + do { + again = 0; + clear(); + printw("World? [1/2] "); + refresh(); + switch (getch()) { + case 'q': return; + case '0': selected.world = 0; break; + case '1': selected.world = 1; break; + case '2': selected.world = 2; break; + default: again = 1; break; + } + } while (again); + do { + again = 0; + clear(); + printw("> World %d\n\n", selected.world); + printw("Level? "); + refresh(); + switch (getch()) { + case 'q': selected.level = 1; return; + case '1': selected.level = 1; return; + case '2': selected.level = 2; return; + case '3': selected.level = 3; return; + case '4': selected.level = 4; return; + case '5': selected.level = 5; return; + case '6': selected.level = 6; return; + case '7': selected.level = 7; return; + default: again = 1; break; + } + } while (again); + } +} + +void ranking() { + int i, j, templevel = selected.level, tempworld = selected.world, printed; + struct dataresult temp; + char *time_string[N]; + readfiles(); + // reord data + for (i = 0; data[i].moves != 0; i++) { + for (j = i + 1; data[j].moves != 0; j++) { + if (data[i].moves > data[j].moves) { + temp = data[i]; + data[i] = data[j]; + data[j] = temp; + } + } + } + do { + if (templevel == 'w'-'0') { + printw("\nSelect world: [1/2] "); + tempworld = getch() - '0'; + templevel = 1; + refresh(); + } + clear(); + printw("Best results level %d.%d:\n\n", tempworld, templevel); + printed = 0; + for (i = 0; data[i].moves != 0; i++) { + if ((data[i].level == templevel && data[i].world == tempworld) && printed < 5) { + time_string[i] = ctime(&data[i].time); + printw("# %d - %3d moves\t- level %d.%d \t- %s", printed + 1, data[i].moves, tempworld, data[i].level, time_string[i]); + refresh(); + printed++; + } + } + if (printed == 0) { + printw("Nothing to show...\n"); + refresh(); + } + printw("\nMenu [q]; To filter by level [1-?]; Change world [w]"); + refresh(); + do { + templevel = getch() - '0'; + } while ((templevel < 0 || templevel > 9) && templevel != 0 && templevel != 'q'-'0' && templevel != 'w'-'0'); + } while (templevel != ('q'-'0')); +} + + +void rules() { + clear(); + printw("> Rules\n\n"); + printw("Reach the escape door ( )\n"); + refresh(); + getch(); +} + +int checkwin() { + if (level[selected.pos].matrix[ptr.y][ptr.x] == 2){ + return 1; + } + else return 0; +} + +void waitfor(int delay) { + int time_a, time_b; + time_a = clock(); + do { + time_b = clock(); + } while (time_b < time_a + delay); +} diff --git a/icelevels.txt b/icelevels.txt new file mode 100644 index 0000000..6bf0f29 --- /dev/null +++ b/icelevels.txt @@ -0,0 +1,180 @@ +// Demo. No playable levels +// Do not add or remove any comment line +// Legend: ice = 0; starting point = 1; ending point = 2; rock = 3. +// How to add levels: go to the end of this file + +0.1 Demo1 9x9 +3 3 3 3 3 3 3 3 3 +3 1 0 3 0 0 0 2 3 +3 0 0 3 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 3 0 0 0 0 3 +3 3 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 3 3 +3 0 3 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 + +0.2 Demo2 9x9 +3 3 3 3 3 3 3 3 3 +3 0 0 0 0 0 3 2 3 +3 0 0 0 0 3 3 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 1 0 0 3 0 0 0 3 +3 0 0 0 0 0 0 3 3 +3 3 3 3 3 3 3 3 3 + +0.3 Notsquare 6x9 +3 3 3 3 3 3 3 3 3 +3 1 3 0 0 3 0 2 3 +3 0 3 0 0 0 0 0 3 +3 0 0 3 0 0 0 0 3 +3 3 0 0 0 3 0 0 3 +3 3 3 3 3 3 3 3 3 + +0.4 Another9 9x9 +3 3 3 3 3 3 3 3 3 +3 1 3 0 0 0 0 3 3 +3 0 3 0 0 3 0 0 3 +3 0 3 0 0 0 0 0 3 +3 0 0 3 0 3 0 0 3 +3 3 0 3 0 0 0 0 3 +3 3 0 0 0 3 0 0 3 +3 3 0 0 3 0 0 2 3 +3 3 3 3 3 3 3 3 3 + +0.5 DemoBig 15x15 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +3 3 0 0 0 0 3 0 3 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 0 0 1 0 3 0 0 0 0 0 0 0 3 3 +3 3 0 0 0 0 3 0 3 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 0 0 1 0 3 0 0 0 0 0 0 0 0 3 +3 3 0 0 0 0 3 0 3 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 2 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 0 0 3 0 0 0 3 0 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + +1.1 Empty 17x17 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + + +999.0 EndingLine 0x0 // MUST BE THE LAST LEVEL ALWAYS + + + +// HOW TO ADD LEVELS + +// program should not arrive here +// last line of this file (before these comments) MUST be "999.0 EndingLine 0x0" always. +// Remember borders, starting position (1) and ending position (2) +// Title format: "%d.%d %s %dx%d", world, level, name, height, width + +/* Matrix examples: + +0.0 levelname9 9x9 +3 3 3 3 3 3 3 3 3 +3 1 0 0 0 0 0 2 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 + +0.0 levelname15 15x15 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +3 1 0 0 0 0 0 0 0 0 0 0 0 2 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + +0.0 levelname17 17x17 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + +0.0 levelname34 34x34 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 +3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + +*/