summaryrefslogtreecommitdiff
path: root/dnglib
diff options
context:
space:
mode:
Diffstat (limited to 'dnglib')
-rw-r--r--dnglib/algs.lua151
-rw-r--r--dnglib/constants.lua90
-rw-r--r--dnglib/defaults.lua178
-rw-r--r--dnglib/queue.lua55
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