diff options
Diffstat (limited to 'dnglib')
-rw-r--r-- | dnglib/algs.lua | 151 | ||||
-rw-r--r-- | dnglib/constants.lua | 90 | ||||
-rw-r--r-- | dnglib/defaults.lua | 178 | ||||
-rw-r--r-- | dnglib/queue.lua | 55 |
4 files changed, 474 insertions, 0 deletions
diff --git a/dnglib/algs.lua b/dnglib/algs.lua new file mode 100644 index 0000000..9bb2542 --- /dev/null +++ b/dnglib/algs.lua @@ -0,0 +1,151 @@ +-- ----------------------------------------------------------------------- +-- dng +-- ------------------------------------------------------------------------ +-- Copyright (c) 2022 Steph Enders <steph@senders.io> +-- +-- This software is provided 'as-is', without any express or implied +-- warranty. In no event will the authors be held liable for any damages +-- arising from the use of this software. +-- +-- Permission is granted to anyone to use this software for any purpose, +-- including commercial applications, and to alter it and redistribute it +-- freely, subject to the following restrictions: +-- +-- 1. The origin of this software must not be misrepresented; you must not +-- claim that you wrote the original software. If you use this software +-- in a product, an acknowledgment in the product documentation would +-- be appreciated but is not required. +-- +-- 2. Altered source versions must be plainly marked as such, and must not +-- be misrepresented as being the original software. +-- +-- 3. This notice may not be removed or altered from any source +-- distribution. +-- +-- ----------------------------------------------------------------------- + +package.path="./?.lua;" .. package.path +require "dnglib.constants" +local Queue = require "dnglib.queue" + +---@param map table +local function print_map(map) + for i = 1, #map do + row = map[i] + line = "" + for j = 1, #row do + if row[j] == MAP_WALL then + line = line .. "# " + elseif row[j] == MAP_VISITED then + line = line .. "x " + else + line = line .. " " + end + end + print(line) + end +end + +local function can_move(x, y, map) + return map[y][x] == MAP_SPACE +end + +---@param x number +---@param y number +---@param origin table +---@param map table +---@param queue table +---@return boolean found goal +local function push_moves(x, y, origin, map, queue, target_pos) + map[y][x] = MAP_VISITED -- should be but just in case + -- UP + if can_move(x, y - 1, map) then + pos = { + x = x, + y = y - 1, + origin = origin + } + map[pos.y][pos.x] = MAP_VISITED + if (pos.x == target_pos.x and pos.y == target_pos.y) then + return true + end + queue:push(pos) + end + -- DOWN + if can_move(x, y + 1, map) then + pos = { + x = x, + y = y + 1, + origin = origin + } + map[pos.y][pos.x] = MAP_VISITED + if (pos.x == target_pos.x and pos.y == target_pos.y) then + return true + end + queue:push(pos) + end + -- LEFT + if can_move(x - 1, y, map) then + pos = { + x = x - 1, + y = y, + origin = origin + } + map[pos.y][pos.x] = MAP_VISITED + if (pos.x == target_pos.x and pos.y == target_pos.y) then + return true + end + queue:push(pos) + end + -- RIGHT + if can_move(x + 1, y, map) then + pos = { + x = x + 1, + y = y, + origin = origin + } + map[pos.y][pos.x] = MAP_VISITED + if (pos.x == target_pos.x and pos.y == target_pos.y) then + return true + end + queue:push(pos) + end + return false +end + +--- +---@param start_pos table [x, y] +---@param target_pos table [x, y] +---@param map table 2D map array +---@return table best move to target [x, y] +--- +local function pathfind(start_pos, target_pos, map) + local queue = Queue:new() + local visit_map = {} + for k, v in ipairs(map) do + row = {} + for ik, iv in ipairs(v) do + row[ik] = iv + end + visit_map[k] = row + end + + if (push_moves(start_pos.x, start_pos.y, nil, visit_map, queue, target_pos)) then + return { dx = target_pos.x - start_pos.x, dy = target_pos.y - start_pos.y } + end + + while queue:empty() ~= true do + local pos = queue:pop() + origin = pos.origin or { x = pos.x, y = pos.y } + hit_target = push_moves(pos.x, pos.y, origin, visit_map, queue, target_pos) + if hit_target then + return { dx = origin.x - start_pos.x, dy = origin.y - start_pos.y } + end + end + return { dx = 0, dy = 0 } +end + +return { + pathfind = pathfind, + print_map = print_map, +} diff --git a/dnglib/constants.lua b/dnglib/constants.lua new file mode 100644 index 0000000..df0c37a --- /dev/null +++ b/dnglib/constants.lua @@ -0,0 +1,90 @@ +-- ----------------------------------------------------------------------- +-- dng +-- ------------------------------------------------------------------------ +-- Copyright (c) 2022 Steph Enders <steph@senders.io> +-- +-- This software is provided 'as-is', without any express or implied +-- warranty. In no event will the authors be held liable for any damages +-- arising from the use of this software. +-- +-- Permission is granted to anyone to use this software for any purpose, +-- including commercial applications, and to alter it and redistribute it +-- freely, subject to the following restrictions: +-- +-- 1. The origin of this software must not be misrepresented; you must not +-- claim that you wrote the original software. If you use this software +-- in a product, an acknowledgment in the product documentation would +-- be appreciated but is not required. +-- +-- 2. Altered source versions must be plainly marked as such, and must not +-- be misrepresented as being the original software. +-- +-- 3. This notice may not be removed or altered from any source +-- distribution. +-- +-- ----------------------------------------------------------------------- +-- NOTICE +-- Keyboard enumeration values derived from: +-- https://github.com/SFML/SFML/blob/master/include/SFML/Window/Keyboard.hpp#L48 +-- Licensed under zlib/png license Copyright (C) 2007-2022 Laurent Gomila (laurent@sfml-dev.org) +-- ------------------------------------------------------------------------ +KEY_A = 0 +KEY_B = 1 +KEY_C = 2 +KEY_D = 3 +KEY_E = 4 +KEY_F = 5 +KEY_G = 6 +KEY_H = 7 +KEY_I = 8 +KEY_J = 9 +KEY_L = 10 +KEY_M = 11 +KEY_N = 12 +KEY_M = 13 +KEY_O = 14 +KEY_P = 15 +KEY_Q = 16 +KEY_R = 17 +KEY_S = 18 +KEY_T = 19 +KEY_U = 20 +KEY_V = 21 +KEY_W = 22 +KEY_X = 23 +KEY_Y = 24 +KEY_Z = 25 + +-- control keys +KEY_ESCAPE = 36 +KEY_LCONTROL = 37 +KEY_LSHIFT = 38 +KEY_LALT = 39 +KEY_LSYSTEM = 40 +KEY_RCONTROL = 41 +KEY_RSHIFT = 42 +KEY_RALT = 43 +KEY_RSYSTEM = 44 +KEY_MENU = 45 + +KEY_SPACE = 57 +KEY_ENTER = 58 + +-- directional keys +KEY_LEFT = 71 +KEY_RIGHT = 72 +KEY_UP = 73 +KEY_DOWN = 74 + +-- map values +MAP_WALL = 1 +MAP_SPACE = 0 +MAP_VISITED = -1 + +-- scene values +SCENE_INTRO = 0 +SCENE_LEVEL = 1 +SCENE_WIN = 2 +SCENE_LOSS = 3 + +MOV_TIME = 0.5
\ No newline at end of file diff --git a/dnglib/defaults.lua b/dnglib/defaults.lua new file mode 100644 index 0000000..77f688c --- /dev/null +++ b/dnglib/defaults.lua @@ -0,0 +1,178 @@ +-- ----------------------------------------------------------------------- +-- dng +-- ------------------------------------------------------------------------ +-- Copyright (c) 2022 Steph Enders <steph@senders.io> +-- +-- This software is provided 'as-is', without any express or implied +-- warranty. In no event will the authors be held liable for any damages +-- arising from the use of this software. +-- +-- Permission is granted to anyone to use this software for any purpose, +-- including commercial applications, and to alter it and redistribute it +-- freely, subject to the following restrictions: +-- +-- 1. The origin of this software must not be misrepresented; you must not +-- claim that you wrote the original software. If you use this software +-- in a product, an acknowledgment in the product documentation would +-- be appreciated but is not required. +-- +-- 2. Altered source versions must be plainly marked as such, and must not +-- be misrepresented as being the original software. +-- +-- 3. This notice may not be removed or altered from any source +-- distribution. +-- +-- ----------------------------------------------------------------------- + +--[[ +These are the default implementations of the override actions. +If you want to add custom logic into your game you can define a "proc.lua" in your map dir. + +The following functions are also available via our C library: + +void c_update_player_pos (dx, dy) +boolean c_player_can_move (dx, dy) +boolean c_enemy_can_move (id, dx, dy) +c_spawn_enemy (x, y) +c_destroy_enemy (id) +c_trigger_win() +c_trigger_loss(msg) +c_fatal(msg) + +--]] +package.path = "./?.lua;" .. package.path +require "dnglib.constants"; +local algs = require "dnglib.algs"; +local hasLost = false; +local hasWon = false; +local hasIntro = false; + +keys = { + up = KEY_UP, + down = KEY_DOWN, + left = KEY_LEFT, + right = KEY_RIGHT, + quit = KEY_ESCAPE, + start = KEY_SPACE, + restart = KEY_SPACE, +} + +--- setup random +--math.randomseed(os.time()) + +---@param pressedKey number +function onKeyPress(pressedKey) + scene = c_get_scene() + assert(type(scene) == "number", "scene is not a number") + if scene == SCENE_INTRO then + if pressedKey == keys.start then + c_trigger_level_start(); + end + elseif scene == SCENE_LEVEL then + dx = 0 + dy = 0 + if pressedKey == keys.up then + dy = -1 + elseif pressedKey == keys.left then + dx = -1 + elseif pressedKey == keys.down then + dy = 1 + elseif pressedKey == keys.right then + dx = 1 + end + + c_move_player(dx, dy) + elseif scene == SCENE_WIN or scene == SCENE_LOSS then + if pressedKey == keys.restart then + c_trigger_restart() + end + end +end + +local diff_time = 0 +---@param dt number +function onUpdate(dt) + diff_time = diff_time + dt + enemies = c_get_enemies() + assert(type(enemies) == "table", "Enemies not a table") + + player = c_get_player_position() + assert(type(player) == "table", "Player is not a table") + + map = c_get_map(); + assert(type(map) == "table", "map is not a table") + + for _, v in ipairs(enemies) do + local next; + if diff_time >= MOV_TIME then + next = algs.pathfind(v, player, map) + else + next = { dx = 0, dy = 0 } + end + new_pos = c_move_enemy(v.id, next.dx, next.dy) + assert(type(new_pos) == "table", "new_pos is not a table") + if new_pos.x == player.x and new_pos.y == player.y then + c_trigger_loss() + end + end + treasures = c_get_treasures() + assert(type(treasures) == "table", "treasures is not a table") + + for _, t in ipairs(treasures) do + if t.x == player.x and t.y == player.y then + c_score_treasure(t.id) + if #treasures == 1 then + c_trigger_win() + end + end + end + if diff_time > MOV_TIME then + diff_time = 0 + end +end + +function onWin() + if hasWon == false then + hasWon = true + print("You WIN!!!!!!!!!") + end +end + +function onLoss() + if hasLost == false then + hasLost = true + print("Oh no! You lost!") + end +end + +function onIntro() + if hasIntro == false then + hasIntro = true + print([[ +................... +.. dng .. +................... +.. controls .. +................... +.. start -- space.. +.. move -- wasd .. +.. quit -- q .. +................... +.. goal .. +................... +.. Find treasure .. +.. Avoid enemies .. +................... + ]]) + end +end + +--- allow for requiring in other files for usage +return { + onKeyPress = onKeyPress, + onUpdate = onUpdate, + onWin = onWin, + onLoss = onLoss, + onIntro = onIntro, + keys = keys, +} diff --git a/dnglib/queue.lua b/dnglib/queue.lua new file mode 100644 index 0000000..a3470e5 --- /dev/null +++ b/dnglib/queue.lua @@ -0,0 +1,55 @@ +-- ----------------------------------------------------------------------- +-- dng +-- ------------------------------------------------------------------------ +-- Copyright (c) 2022 Steph Enders <steph@senders.io> +-- +-- This software is provided 'as-is', without any express or implied +-- warranty. In no event will the authors be held liable for any damages +-- arising from the use of this software. +-- +-- Permission is granted to anyone to use this software for any purpose, +-- including commercial applications, and to alter it and redistribute it +-- freely, subject to the following restrictions: +-- +-- 1. The origin of this software must not be misrepresented; you must not +-- claim that you wrote the original software. If you use this software +-- in a product, an acknowledgment in the product documentation would +-- be appreciated but is not required. +-- +-- 2. Altered source versions must be plainly marked as such, and must not +-- be misrepresented as being the original software. +-- +-- 3. This notice may not be removed or altered from any source +-- distribution. +-- +-- ----------------------------------------------------------------------- + +Queue = {} + +function Queue:new() + o = { first = 1, top = 0, data = {} } + self.__index = self + return setmetatable(o, self) +end + +function Queue:push(val) + local top = self.top + 1 + self.top = top + self.data[top] = val +end + +function Queue:pop() + if self:empty() then + return nil + end + local val = self.data[self.first] + self.data[self.first] = nil + self.first = self.first + 1 + return val +end + +function Queue:empty() + return self.top < self.first +end + +return Queue |