#include <stdio.h> #include <string.h> #include <allegro.h> #include "lab.h" #include "title.h" char map[WIDTH][HEIGHT][SIZE]; char explored[WIDTH][HEIGHT][SIZE]; int pkeys, px, py, pz = -1; int skeys, sx, sy, sz = -1; int dest_search; //////////////////// DRAWING FUNCTIONS void draw(int x, int y) { int ch = (int)map[x][y][pz]; int fg = makecol(0, 255, 0); int bg = makecol(0, 64, 0); switch(ch) { case ']': // wall bg = fg; fg = makecol(0, 0, 0); ch = ' '; break; case '=': // explore case '.': // free ch = ' '; bg = makecol(0, 64, 0); break; case ',': // key ch = '#'; fg = makecol(0, 0, 255); break; case '/': // brick ch = ' '; fg = makecol(0, 0, 0); bg = makecol(0, 0, 255); break; case '`': // tnt ch = '*'; fg = makecol(255, 0, 0); break; case ';': // exit fg = makecol(255, 255, 255); ch = 'E'; break; default: if(ch >= 'a' && ch <= 'h') // stairs up go! ch = '^', fg = makecol(255, 255, 255); if(ch >= 'i' && ch <= 'p') // stairs down go! ch = 'v', fg = makecol(255, 255, 255); if(ch >= 'q' && ch <= 'u') // teleport go! ch = '*', fg = makecol(0, 0, 0), bg = makecol(0, 255, 255); if(ch >= 'v' && ch <= 'z') // hidden teleport go! ch = ' '; if(ch >= 'A' && ch <= 'Z') // teleport/stairs end ch = ' '; break; } if(!explored[x][y][pz]) { fg = bg = makecol(0, 0, 0); ch = ' '; } if(px == x && py == y && ch == ' ') { // this smile creation code is pretty ugly BITMAP *b; int c = makecol(255, 255, 0); int g = makecol(0, 64, 0); b = create_bitmap(8, 8); clear_to_color(b, makecol(0, 0, 0)); putpixel(b, 0, 0, g); putpixel(b, 1, 0, g); putpixel(b, 0, 1, g); putpixel(b, 6, 0, g); putpixel(b, 7, 0, g); putpixel(b, 7, 1, g); putpixel(b, 0, 6, g); putpixel(b, 0, 7, g); putpixel(b, 1, 7, g); putpixel(b, 6, 7, g); putpixel(b, 7, 7, g); putpixel(b, 7, 6, g); putpixel(b, 2, 2, c); putpixel(b, 5, 2, c); putpixel(b, 1, 4, c); putpixel(b, 6, 4, c); putpixel(b, 2, 5, c); putpixel(b, 5, 5, c); putpixel(b, 3, 6, c); putpixel(b, 4, 6, c); blit(b, screen, 0, 0, (x*8)+MAP_START_X, (y*8)+MAP_START_Y, 8, 8); destroy_bitmap(b); return; } else { char buf[2] = " "; buf[0] = ch; text_mode(bg); textout(screen, font, buf, (x*8)+MAP_START_X, (y*8)+MAP_START_Y, fg); } } #define STATUS_X (MAP_START_X+(WIDTH*8)+2) #define STATUS_Y (MAP_START_Y+(HEIGHT*8)+2) void clean_statusbar() { rectfill(screen, 0, STATUS_Y, SCREEN_W-1, STATUS_Y+8, makecol(0,0,0)); } void show_statusbar() { clean_statusbar(); text_mode(makecol(0, 0, 0)); textprintf(screen, font, MAP_START_X, STATUS_Y, makecol(0, 255, 0), "Pozicia [%d,%d]", px, py); textprintf_right(screen, font, STATUS_X, STATUS_Y, makecol(0, 255, 0), "Kluce: %d", pkeys); } //////////////////// PLAYING FUNCTIONS void explore(int x, int y) { explored[x][y][pz] = 1; draw(x, y); } void redraw_all() { int x, y; for(x = 0; x < WIDTH; x++) for(y = 0; y < HEIGHT; y++) draw(x, y); } // just helper function void exploration_hlp(int x, int y) { explore(x, y); if(map[x][y][pz] != ']') { explore(x-1, y); explore(x, y-1); explore(x+1, y); explore(x, y+1); } } void exploration() { explore(px, py); if(map[px][py][pz] != ']') { exploration_hlp(px-1, py); exploration_hlp(px, py-1); exploration_hlp(px+1, py); exploration_hlp(px, py+1); } } int brick_can_move(int x, int y, int dx, int dy) { int nx = x + dx, ny = y + dy; int nc = map[nx][ny][pz]; if(nc == '.') return 1; if(nc == '`') return 1; if(nc != '/') return 0; return brick_can_move(nx, ny, dx, dy); } int can_move(int x, int y) { int ch = map[x][y][pz]; if(ch == ']') return 0; if(ch == '.') return 1; if(ch == ',') return 1; if(ch >= 'a' && ch <= 'z') return 1; if(ch >= 'A' && ch <= 'Z') return 1; if(ch == ';') return !pkeys; if(ch == '/') // brick return brick_can_move(x, y, x - px, y - py); if(ch == '`') return 0; if(ch == '=') return 1; return 0; } void brick_move(int x, int y, int dx, int dy) { int mx = x, my = y; while(map[x][y][pz] == '/') x += dx, y += dy; if(map[x][y][pz] == '.') map[x][y][pz] = '/'; if(map[x][y][pz] == '`') map[x][y][pz] = '.'; map[mx][my][pz] = '.'; draw(x, y); draw(mx, my); } int move(int nx, int ny) { int ch = map[nx][ny][pz]; int wx, wy, wz = -1; // for teleports if(ch >= 'a' && ch <= 'z') { int x, y, z; int search; // searching for teleport desintation clean_statusbar(); textout_centre(screen, font, "searching for desintation... press Esc to quit", SCREEN_W/2, STATUS_Y, makecol(0, 255, 0)); dest_search = search = ch - 'a' + 'A'; for(x = 0; x < WIDTH; x++) { for(y = 0; y < HEIGHT; y++) { for(z = 0; z < SIZE; z++) { if(map[x][y][z] == search) wx = x, wy = y, wz = z; if(keypressed()) if(readkey() >> 8 == KEY_ESC) return 1; // game aborted } } } if(wz == -1) return 3; // desintation not found nx = wx; ny = wy; pz = wz; } if(ch == '/') brick_move(nx, ny, nx - px, ny - py); if(ch == ',') { if(pkeys) pkeys--; map[nx][ny][pz] = '.'; } if(ch == '=') { int x, y; for(x = 0; x < WIDTH; x++) for(y = 0; y < HEIGHT; y++) explored[x][y][pz] = 1; } px = nx; py = ny; show_statusbar(); if(ch == ';') return 2; // game solved if(ch == '=' || wz != -1) return 4; // redraw all return 0; // all right } void play_game() { int x, y, z; int end = 0; if(sz == -1) { clear_to_color(screen, makecol(0, 255, 255)); text_mode(-1); textout_centre(screen, font, "cannot find the player... exit with Esc", SCREEN_W/2, SCREEN_H/2, makecol(255, 0, 0)); rest(2000); return; } px = sx; py = sy; pz = sz; pkeys = skeys; for(z = 0; z < SIZE; z++) for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) explored[x][y][z] = 0; exploration(); show_statusbar(); while(!end) { if(keypressed()) { int scancode = readkey() >> 8; int nx = px, ny = py; int movekey = 1; switch(scancode) { case KEY_ESC: end = 1; movekey = 0; break; case KEY_LEFT: nx--; break; case KEY_UP: ny--; break; case KEY_RIGHT: nx++; break; case KEY_DOWN: ny++; break; default: movekey = 0; break; } if(movekey) { if(can_move(nx, ny)) { int r = move(nx, ny); switch(r) { case 0: exploration(); break; case 1: case 2: case 3: exploration(); end = r; break; case 4: exploration(); redraw_all(); break; } } } } } clean_statusbar(); text_mode(makecol(0,0,0)); switch(end) { case 1: textout_centre(screen, font, "GAME ABORTED", SCREEN_W/2, STATUS_Y, makecol(255, 0, 0)); rest(500); return; case 2: textout_centre(screen, font, "*** CONGRATULATIONS!!! YOU WON! ***", SCREEN_W/2, STATUS_Y, makecol(255, 0, 0)); rest(500); textout_centre(screen, font, "*** CONGRATULATIONS!!! YOU WON! ***", SCREEN_W/2, STATUS_Y, makecol(0, 255, 0)); rest(500); textout_centre(screen, font, "*** CONGRATULATIONS!!! YOU WON! ***", SCREEN_W/2, STATUS_Y, makecol(255, 255, 0)); rest(500); textout_centre(screen, font, "*** CONGRATULATIONS!!! YOU WON! ***", SCREEN_W/2, STATUS_Y, makecol(0, 0, 255)); rest(500); return; case 3: textprintf_centre(screen, font, SCREEN_W/2, STATUS_Y, makecol(255, 0, 0), "FATAL ERROR: desintation %c not found!", dest_search-'a'+'A'); rest(2000); return; } }