// example: ./a.out ../../data/secret/101-handmade.in ../../data/secret/101-handmade.ans // press q to quit #include #include #include #include #define rep(E, F) for (E = 0; E < (F); E++) #define MAXK 100000 #define MIN_X -20 #define MIN_Y -20 #define MAX_X 50 #define MAX_Y 50 int min(int a, int b) { if (a > b) return b; return a; } int max(int a, int b) { if (a < b) return b; return a; } typedef int par[2]; par a[100], t, d[4] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}, last1, last2; int n, offset_x, offset_y; WINDOW* win; void burn() { // burns whats on the burner. returns the number of blocks that are left. int i, s; for (i = 1; i < n; i++) if (a[i][0] == t[0] && a[i][1] == t[1]) break; if (i == n) return; s = a[i][0], a[i][0] = a[n - 1][0], a[n - 1][0] = s; s = a[i][1], a[i][1] = a[n - 1][1], a[n - 1][1] = s; n--; } void make_move(int x, int y) { // moves xth block to (x + d.x, y + d.y). int i, z = a[x][0] + d[y][0], w = a[x][1] + d[y][1]; for (i = 0; i < n; i++) if (z == a[i][0] && w == a[i][1]) break; if (i < n) make_move(i, y); a[x][0] = z, a[x][1] = w; if (x == 0) burn(); } void left(int n) { make_move(0, 0); } void right(int n) { make_move(0, 1); } void up(int n) { make_move(0, 2); } void down(int n) { make_move(0, 3); } void draw_char(int x, int y, char c) { mvprintw(y + offset_y, x + offset_x, "%c", c); } void draw() { int i, j, x, y; getmaxyx(win, x, y); offset_x = y/2 - t[0]; offset_y = x/2 - t[1]; draw_char(last2[0], last2[1], '.'); draw_char(last1[0], last1[1], 'o'); last2[0] = last1[0], last2[1] = last1[1]; last1[0] = a[0][0], last1[1] = a[0][1]; draw_char(a[0][0], a[0][1], 'O'); draw_char(t[0], t[1], 'X'); rep(i, n - 1) draw_char(a[i + 1][0], a[i + 1][1], '#'); refresh(); } int main(int argc, char **argv) { int i, x, b[MAXK], k = 0; assert(argc > 2); FILE *fp = fopen(argv[1], "r"); assert(fp); fscanf(fp, "%d", &n); n++; fscanf(fp, "%d%d", &a[0][0], &a[0][1]); fscanf(fp, "%d%d", &t[0], &t[1]); last1[0] = last2[0] = a[0][0], last1[1] = last2[1] = a[0][1]; rep(i, n - 1) fscanf(fp, "%d%d", &a[i + 1][0], &a[i + 1][1]); fclose(fp); fp = fopen(argv[2], "r"); assert(fp); while (1) { char c = fgetc(fp); if (c == EOF || c == 10) break; while (fgetc(fp) != 10); switch (c) { case 'l': b[k++] = 0; break; case 'r': b[k++] = 1; break; case 'u': b[k++] = 2; break; case 'd': b[k++] = 3; break; default: assert(0); } } fclose(fp); int speed = 1 << 7; win = initscr(); noecho(); timeout(speed); curs_set(0); rep(i, k) { clear(); mvprintw(0, 0, "spped: %d", speed); draw(); char c = getch(); if (c == 'q') break; if (c == 'l') speed *= 2; if (c == 'o') speed = max(1, speed/2); timeout(speed); make_move(0, b[i]); } draw(); getch(); clear(); refresh(); endwin(); return 0; }