#define VERSION "0.20" #define N 512 #define DELAY 25 // milliseconds #include #include #include #include #include void printm(); void play(); void move_ptr(int direction); 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; char 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, lines = 0, j, k, newline; char ch, tile; // 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 5 ch = fgetc(f_info); if (ch == '\n') lines++; } while (lines < 5); do { fscanf(f_info, "%d.%d %s", &level[u].world, &level[u].num, level[u].name); newline = j = k = 0; if (level[u].world != 999) { level[u].width = level[u].height = 0; while (newline < 2) { if (level[u].width == 0) level[u].width = k; k = 0; while (1) { tile = fgetc(f_info); if (tile == '\n') { newline++; break; } newline = 0; level[u].matrix[j][k] = tile; if(level[u].matrix[j][k] == 'A') { level[u].matrix[j][k] = ' '; level[u].start.x = k; level[u].start.y = j; } if (level[u].matrix[i][j] == 'B') { level[u].exit.x = k; level[u].exit.y = j; } k++; } j++; level[u].height++; } level[u].height -= 2; } 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 { flushinp(); 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] != '+') { ptr.x--; printm(); refresh(); if (checkwin() == 1) { break; } else { napms(DELAY); } } break; case KEY_RIGHT: moves++; while (ptr.x < level[selected.pos].width - 1 && level[selected.pos].matrix[ptr.y][ptr.x+1] != '+'){ ptr.x++; printm(); refresh(); if (checkwin() == 1) { break; } else { napms(DELAY); } } break; case KEY_UP: moves++; while (ptr.y > 0 && level[selected.pos].matrix[ptr.y-1][ptr.x] != '+') { ptr.y--; printm(); refresh(); if (checkwin() == 1) { break; } else { napms(DELAY); } } break; case KEY_DOWN: moves++; while (ptr.y < level[selected.pos].height - 1 && level[selected.pos].matrix[ptr.y+1][ptr.x] != '+') { ptr.y++; printm(); refresh(); if (checkwin() == 1) { break; } else { napms(DELAY); } } break; default: return; } if (temp_x == ptr.x && temp_y == ptr.y) moves = tempmoves; } void printm() { int i, j, a = 1, b = 1; int left = 0, right = 0, up = 0, down = 0; 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"); while (left + right < 18 && (a == 1 || a == 2)) { a = 0; if (ptr.x - left > 0) { left++; a++; } if (ptr.x + right + 1 < level[selected.pos].width) { right++; a++; } } while (up + down < 18 && (b == 1 || b == 2)) { b = 0; if (ptr.y - up - 1 > 0) { up++; b++; } if (ptr.y + down < level[selected.pos].height) { down++; b++; } } for (i = ptr.y - up; i <= ptr.y + down; i++) { for (j = ptr.x - left; j <= ptr.x + right; j++) { if (i == ptr.y && j == ptr.x) { printw("YOU"); } else { switch (level[selected.pos].matrix[i][j]) { case 'B': printw("()"); break; default: printw("%c", level[selected.pos].matrix[i][j]); 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 0.1 selected.world = 0; selected.level = 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] == 'B'){ return 1; } else return 0; }