aboutsummaryrefslogtreecommitdiff
path: root/src/game/entry.c
diff options
context:
space:
mode:
authorSopár Adrián <adrian.sopar@protonmail.com>2024-06-20 09:28:14 +0200
committerSopár Adrián <adrian.sopar@protonmail.com>2024-06-20 09:28:14 +0200
commit74ea6dc86646cee9915292d73d8c7afef01ef3e0 (patch)
tree9a58866f7765dad8ba56f1f40b1fa031e9d2687d /src/game/entry.c
First commit. This is mostly the state of the project as I left it around the end of 2019.HEADmaster
Diffstat (limited to 'src/game/entry.c')
-rw-r--r--src/game/entry.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/game/entry.c b/src/game/entry.c
new file mode 100644
index 0000000..50cf78c
--- /dev/null
+++ b/src/game/entry.c
@@ -0,0 +1,152 @@
+#include "entry.h"
+#include "game.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ncurses.h>
+#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;
+}