#include "entry.h" #include "game.h" #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); } } 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 (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; }