#include "entry.h" #include "game.h" #include #include #include #include #include "utilities.h" #include "color.h" #include "maze_solver.h" static inline int mvaddwch(int y, int x, wchar_t wch) { wchar_t arr[2]; arr[0] = wch; arr[1] = 0; return mvaddwstr(y, x, arr); } static inline int addwch(wchar_t wch) { wchar_t arr[2]; arr[0] = wch; arr[1] = 0; return addwstr(arr); } static void darw_block(struct block *block) { attron(COLOR_PAIR(block->color)); if (block->bold) attron(A_BOLD); addwch(block->chr); if (block->bold) attroff(A_BOLD); } static void mv_draw_block(int y, int x, struct block *block) { int width = getmaxx(stdscr); int height = getmaxy(stdscr) - 1; if (x >= 0 && x < width && y >= 0 && y < height) { move(y, x); darw_block(block); } } bool visible(struct maze* maze, struct point player, int x, int y) { if (player.x == x && player.y == y) return true; else if (player.x == x) { int step = player.y - y >= 0 ? -1 : 1; for (int i = player.y + step; i != y; i += step) if (maze->map[x][i]) return false; return true; } else if (player.y == y) { int step = player.x - x >= 0 ? -1 : 1; for (int i = player.x + step; i != x; i += step) if (maze->map[i][y]) return false; return true; } else if (player.y == y - 1) return visible(maze, player, x, y - 1); else if (player.y == y + 1) return visible(maze, player, x, y + 1); else if (player.x == x - 1) return visible(maze, player, x - 1, y); else if (player.x == x + 1) return visible(maze, player, x + 1, y); return false; } void draw_maze(struct maze_display *maze_draw, struct game_blocks *blocks) { int width = getmaxx(stdscr); int height = getmaxy(stdscr) - 1; enum signs path_sign; for (int y = 0; y < maze_draw->maze->height; y++) { int real_y = maze_draw->maze_pos.y + y; if (real_y >= 0 && real_y < height) { if (maze_draw->maze_pos.x >= 0) move(real_y, maze_draw->maze_pos.x); for (int x = 0; x < maze_draw->maze->width && y < width; x++) { int real_x = maze_draw->maze_pos.x + x; if (real_x == 0 && x > 0) { move(real_y, 0); } if (real_x >= 0 && real_x < width) { path_sign = maze_draw->signs[x][y]; if (!visible(maze_draw->maze, maze_draw->player_pos, x, y)) { darw_block(&(blocks->hidden)); } else if (path_sign == RS_NONE || (path_sign == RS_PATH && !maze_draw->display_player_path)) //Maze { if (maze_draw->maze->map[x][y]) darw_block(&(blocks->wall)); else darw_block(&(blocks->road)); } else { if (path_sign == RS_PATH) darw_block(&(blocks->path)); else if (path_sign == RS_SOLVE) darw_block(&(blocks->solve)); } } } } } //Player mv_draw_block( maze_draw->maze_pos.y + maze_draw->player_pos.y, maze_draw->maze_pos.x + maze_draw->player_pos.x, &(blocks->player)); mv_draw_block( maze_draw->maze_pos.y + maze_draw->maze->starting_point.y, maze_draw->maze_pos.x + maze_draw->maze->starting_point.x, &(blocks->start)); mv_draw_block( maze_draw->maze_pos.y + maze_draw->maze->end_point.y, maze_draw->maze_pos.x + maze_draw->maze->end_point.x, &(blocks->target)); } static void own_clear() { attron(COLOR_PAIR(CI_DEFAULT)); int width = getmaxx(stdscr); int height = getmaxy(stdscr) - 1; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) mvaddch(y, x, ' '); } enum game_res game(struct app *app) { curs_set(0); noecho(); struct game_state *state = create_game_state(app->maze); while (1) { if (state->display->player_pos.x != state->new_player_pos.x || state->display->player_pos.y != state->new_player_pos.y) //Does player moved? { state->display->signs[state->display->player_pos.x][state->display->player_pos.y] = RS_PATH; state->display->player_pos = state->new_player_pos; if (state->center) state->new_maze_pos = get_player_center(state->display->player_pos); if (state->display->player_pos.x == state->display->maze->end_point.x && state->display->player_pos.y == state->display->maze->end_point.y) //Win? state->win = true; } state->display->maze_pos = state->new_maze_pos; //Draw! own_clear(); draw_maze(state->display, &(app->conf->blocks)); if (state->win) draw_line_win(); else draw_line_info(state->steps_taken, solve_maze(app->maze, state->display->player_pos, NULL)); wrefresh(stdscr); //Get user input! wchar_t c = wgetch(stdscr); struct binding *last_binding = &(app->conf->bindings[app->conf->count - 1]); for (struct binding *binding = app->conf->bindings; binding <= last_binding; binding++) { if ((*(binding->cname) != 0 && strcmp(keyname(c), binding->cname) == 0) || c == binding->c) { if (binding->operation(state, binding->param) == OPR_QUIT) { return state->result; } } } } return GR_QUIT; }