Merge pull request 'feature/rla-11_AlgorithmsP1' (#12) from feature/rla-11_AlgorithmsP1 into master
Reviewed-on: #12
This commit was merged in pull request #12.
This commit is contained in:
@@ -23,5 +23,6 @@ Necessary:
|
|||||||
init_function(map_w, map_h)
|
init_function(map_w, map_h)
|
||||||
Should initialize the function fresh with a given width and height.
|
Should initialize the function fresh with a given width and height.
|
||||||
|
|
||||||
update(map)
|
update()
|
||||||
Called updates_per_second times per second. Should calculate new map state and draw on the map as needed. The map will have the previous state retained.
|
Called updates_per_second times per second. Should calculate new map state and draw on the map as needed. The map will have the previous state retained.
|
||||||
|
Returns true if finished, else false
|
||||||
|
|||||||
36
scripts/algorithms/drunk_walk.lua
Normal file
36
scripts/algorithms/drunk_walk.lua
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
require "math"
|
||||||
|
DrunkenWalk = {
|
||||||
|
curr_x = 0,
|
||||||
|
curr_y = 0,
|
||||||
|
map_w = 0,
|
||||||
|
map_h = 0,
|
||||||
|
iterations = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
function DrunkenWalk:initialize(w, h)
|
||||||
|
math.randomseed(os.time())
|
||||||
|
self.map_w = w
|
||||||
|
self.map_h = h
|
||||||
|
visualizer.map:fill(true)
|
||||||
|
self.curr_x = math.random(0, w-1)
|
||||||
|
self.curr_y = math.random(0, h-1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function DrunkenWalk:update()
|
||||||
|
new_x = self.curr_x + math.random(-1, 1)
|
||||||
|
new_y = self.curr_y + math.random(-1, 1)
|
||||||
|
while new_x >= self.map_w or new_x < 0 or new_y >= self.map_h or new_y < 0 do
|
||||||
|
new_x = self.curr_x + math.random(-1, 1)
|
||||||
|
new_y = self.curr_y + math.random(-1, 1)
|
||||||
|
end
|
||||||
|
self.curr_x = new_x
|
||||||
|
self.curr_y = new_y
|
||||||
|
visualizer.map:draw_floor(self.curr_x, self.curr_y)
|
||||||
|
self.iterations = self.iterations - 1
|
||||||
|
if self.iterations == 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
visualizer.algorithm_manager:register_algorithm("Drunken Walk", function (w, h) DrunkenWalk:initialize(w, h) end, function () return DrunkenWalk:update() end, 5)
|
||||||
18
scripts/algorithms/test.lua
Normal file
18
scripts/algorithms/test.lua
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Test = {}
|
||||||
|
|
||||||
|
function Test.initialize(w, h)
|
||||||
|
visualizer.map:fill(false)
|
||||||
|
for mx = 0, w-1 do
|
||||||
|
for my = 0, h-1 do
|
||||||
|
if mx == 0 or mx == w-1 or my == 0 or my == h-1 then
|
||||||
|
visualizer.map:draw_wall(mx, my)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Test.update()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
visualizer.algorithm_manager:register_algorithm("Test", Test.initialize, Test.update, 1)
|
||||||
@@ -11,6 +11,6 @@ std::string LuaContextManager::get_key(std::string args) {
|
|||||||
// TODO: Switch the arg to a struct and use that to init libraries
|
// TODO: Switch the arg to a struct and use that to init libraries
|
||||||
std::shared_ptr<sol::state> LuaContextManager::load_resource(std::string args) {
|
std::shared_ptr<sol::state> LuaContextManager::load_resource(std::string args) {
|
||||||
auto lua = std::make_shared<sol::state>();
|
auto lua = std::make_shared<sol::state>();
|
||||||
lua->open_libraries(sol::lib::base, sol::lib::package);
|
lua->open_libraries(sol::lib::base, sol::lib::package, sol::lib::math, sol::lib::os);
|
||||||
return lua;
|
return lua;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "algorithmmanager.hpp"
|
#include "algorithmmanager.hpp"
|
||||||
|
#include "../engine/modules/logger.hpp"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
void AlgorithmManager::register_algorithm(std::string name, sol::function initialize, sol::function update,
|
void AlgorithmManager::register_algorithm(std::string name, sol::function initialize, sol::function update,
|
||||||
unsigned int updates_per_second) {
|
unsigned int updates_per_second) {
|
||||||
@@ -19,6 +21,42 @@ void AlgorithmManager::register_algorithm(std::string name, sol::function initia
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ranges::any_view<DungeonAlgorithm> AlgorithmManager::get_algorithms() {
|
ranges::any_view<DungeonAlgorithm*, ranges::category::random_access | ranges::category::sized> AlgorithmManager::get_algorithms() {
|
||||||
return algorithms;
|
auto view = algorithms | ranges::view::transform([](auto& algo) {
|
||||||
|
return &algo;
|
||||||
|
});
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlgorithmManager::load_algorithm(DungeonAlgorithm *algorithm, int w, int h) {
|
||||||
|
algorithm_done = false;
|
||||||
|
ticks = 0;
|
||||||
|
loaded_algorithm = algorithm;
|
||||||
|
auto init_result = loaded_algorithm->initialize(w, h);
|
||||||
|
if(!init_result.valid()) {
|
||||||
|
sol::error err = init_result;
|
||||||
|
Logger::log(LogLevel::ERROR, fmt::format("error while initializing lua: {}", err.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlgorithmManager::tick_algorithm() {
|
||||||
|
if(this->loaded_algorithm == nullptr || algorithm_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(ticks >= this->loaded_algorithm->frames_per_update) {
|
||||||
|
ticks = 0;
|
||||||
|
auto update_result = this->loaded_algorithm->update();
|
||||||
|
if(update_result.valid()) {
|
||||||
|
algorithm_done = update_result;
|
||||||
|
if(algorithm_done) {
|
||||||
|
Logger::log(LogLevel::DEBUG, "Finished running algorithm");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
algorithm_done = true;
|
||||||
|
sol::error err = update_result;
|
||||||
|
Logger::log(LogLevel::ERROR, fmt::format("An error occurred while running update: {}", err.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ticks++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#include <range/v3/view.hpp>
|
#include <range/v3/view.hpp>
|
||||||
struct DungeonAlgorithm {
|
struct DungeonAlgorithm {
|
||||||
unsigned int frames_per_update=1;
|
unsigned int frames_per_update=1;
|
||||||
sol::function update;
|
sol::protected_function update;
|
||||||
sol::function initialize;
|
sol::protected_function initialize;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -17,17 +17,15 @@ class AlgorithmManager {
|
|||||||
private:
|
private:
|
||||||
std::vector<DungeonAlgorithm> algorithms;
|
std::vector<DungeonAlgorithm> algorithms;
|
||||||
unsigned int target_fps=1;
|
unsigned int target_fps=1;
|
||||||
|
unsigned int ticks=0;
|
||||||
|
DungeonAlgorithm* loaded_algorithm = nullptr;
|
||||||
|
bool algorithm_done = false;
|
||||||
public:
|
public:
|
||||||
void register_algorithm(std::string name, sol::function initialize, sol::function update, unsigned int updates_per_second);
|
void register_algorithm(std::string name, sol::function initialize, sol::function update, unsigned int updates_per_second);
|
||||||
|
ranges::any_view<DungeonAlgorithm*, ranges::category::random_access | ranges::category::sized> get_algorithms();
|
||||||
void setTargetFps(unsigned int targetFps) {
|
void load_algorithm(DungeonAlgorithm* algorithm, int w, int h);
|
||||||
target_fps = targetFps;
|
void tick_algorithm();
|
||||||
}
|
|
||||||
|
|
||||||
ranges::any_view<DungeonAlgorithm> get_algorithms();
|
|
||||||
|
|
||||||
explicit AlgorithmManager(unsigned int targetFps) : target_fps(targetFps) {}
|
explicit AlgorithmManager(unsigned int targetFps) : target_fps(targetFps) {}
|
||||||
|
|
||||||
AlgorithmManager() = default;
|
AlgorithmManager() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,16 @@
|
|||||||
|
|
||||||
#include "tilemap.hpp"
|
#include "tilemap.hpp"
|
||||||
#include "../engine/utility/point.hpp"
|
#include "../engine/utility/point.hpp"
|
||||||
|
#include "../engine/modules/logger.hpp"
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
void TileMap::draw_floor(int x, int y) {
|
void TileMap::draw_floor(int x, int y) {
|
||||||
|
Logger::log(LogLevel::DEBUG, fmt::format("Drawing floor at x: {} y: {}", x, y));
|
||||||
grid.insert(x, y, floor_tile);
|
grid.insert(x, y, floor_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileMap::draw_wall(int x, int y) {
|
void TileMap::draw_wall(int x, int y) {
|
||||||
|
Logger::log(LogLevel::DEBUG, fmt::format("Drawing wall at x: {} y: {}", x, y));
|
||||||
grid.insert(x, y, wall_tile);
|
grid.insert(x, y, wall_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +22,7 @@ char TileMap::get_tile(int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TileMap::fill(bool wall) {
|
void TileMap::fill(bool wall) {
|
||||||
|
Logger::log(LogLevel::DEBUG, fmt::format("Running fill with wall: {}", wall));
|
||||||
for(Point p : grid.get_range()) {
|
for(Point p : grid.get_range()) {
|
||||||
if(wall) {
|
if(wall) {
|
||||||
draw_wall(p.x, p.y);
|
draw_wall(p.x, p.y);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Created by m on 12/3/21.
|
// Created by m on 12/3/21.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include "visualizer.hpp"
|
#include "visualizer.hpp"
|
||||||
#include "tilemap.hpp"
|
#include "tilemap.hpp"
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ bool Visualizer::update(InputResult input) {
|
|||||||
if(input.keycode == KEY_ESCAPE) {
|
if(input.keycode == KEY_ESCAPE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
this->algorithm_manager.tick_algorithm();
|
||||||
switch(input.keycode) {
|
switch(input.keycode) {
|
||||||
case KEY_RIGHT: x += 1; break;
|
case KEY_RIGHT: x += 1; break;
|
||||||
case KEY_LEFT: x -= 1; break;
|
case KEY_LEFT: x -= 1; break;
|
||||||
@@ -16,6 +18,12 @@ bool Visualizer::update(InputResult input) {
|
|||||||
case KEY_DOWN: y += 1; break;
|
case KEY_DOWN: y += 1; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
if(input.keycode >= InputProcessorKeycode::KEY_1 && input.keycode <= InputProcessorKeycode::KEY_9) {
|
||||||
|
if(this->keycode_to_algorithm.contains(input.keycode)) {
|
||||||
|
auto algorithm = this->keycode_to_algorithm[input.keycode];
|
||||||
|
this->algorithm_manager.load_algorithm(algorithm, this->map_size_w, this->map_size_h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->x = std::clamp(this->x, 0, (int)this->tile_map.get_width()-1);
|
this->x = std::clamp(this->x, 0, (int)this->tile_map.get_width()-1);
|
||||||
this->y = std::clamp(this->y, 0, (int)this->tile_map.get_height()-1);
|
this->y = std::clamp(this->y, 0, (int)this->tile_map.get_height()-1);
|
||||||
@@ -63,6 +71,7 @@ void Visualizer::initialize(GameInitArgs args) {
|
|||||||
this->camera = Camera(Point{x,y}, tilesx, tilesy, tile_map.get_width(), tile_map.get_height());
|
this->camera = Camera(Point{x,y}, tilesx, tilesy, tile_map.get_width(), tile_map.get_height());
|
||||||
this->algorithm_manager = AlgorithmManager(args.target_fps);
|
this->algorithm_manager = AlgorithmManager(args.target_fps);
|
||||||
this->initialize_context();
|
this->initialize_context();
|
||||||
|
this->load_algorithms();
|
||||||
Logger::log(LogLevel::DEBUG, "Game initialization finished");
|
Logger::log(LogLevel::DEBUG, "Game initialization finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +95,34 @@ void Visualizer::initialize_context() {
|
|||||||
|
|
||||||
auto algo_manager_lua = lua->new_usertype<AlgorithmManager>("AlgorithmManager", sol::no_constructor);
|
auto algo_manager_lua = lua->new_usertype<AlgorithmManager>("AlgorithmManager", sol::no_constructor);
|
||||||
algo_manager_lua["register_algorithm"] = &AlgorithmManager::register_algorithm;
|
algo_manager_lua["register_algorithm"] = &AlgorithmManager::register_algorithm;
|
||||||
|
|
||||||
|
auto game_state_lua = lua->new_usertype<Visualizer>("Visualizer", sol::no_constructor);
|
||||||
|
game_state_lua.set("algorithm_manager", sol::readonly(&Visualizer::algorithm_manager));
|
||||||
|
game_state_lua.set("map", &Visualizer::tile_map);
|
||||||
|
|
||||||
|
lua->set("visualizer", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Visualizer::load_algorithms() {
|
||||||
|
auto lua = lua_context_manager.get_default_context();
|
||||||
|
const std::string algorithms_directory = "scripts/algorithms";
|
||||||
|
|
||||||
|
for(const auto& file : std::filesystem::directory_iterator(algorithms_directory)) {
|
||||||
|
lua->script_file(file.path());
|
||||||
|
}
|
||||||
|
Logger::log(LogLevel::DEBUG, "finished loading lua files");
|
||||||
|
auto algorithms = this->algorithm_manager.get_algorithms();
|
||||||
|
auto algorithm_count = algorithms.size();
|
||||||
|
Logger::log(LogLevel::DEBUG, fmt::format("algorithms: {}", algorithm_count));
|
||||||
|
|
||||||
|
for(int code = InputProcessorKeycode::KEY_1;code < InputProcessorKeycode::KEY_9;code++) {
|
||||||
|
auto index = code-InputProcessorKeycode::KEY_1;
|
||||||
|
if(algorithms.size() <= index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto algo = algorithms[index];
|
||||||
|
this->keycode_to_algorithm[(InputProcessorKeycode)code] = algo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Visualizer::~Visualizer() = default;
|
Visualizer::~Visualizer() = default;
|
||||||
|
|||||||
@@ -38,8 +38,9 @@ private:
|
|||||||
int window_height = 0;
|
int window_height = 0;
|
||||||
TileMap tile_map = TileMap(0, 0, DEFAULT_WALL_CHAR[0], DEFAULT_FLOOR_CHAR[0]);
|
TileMap tile_map = TileMap(0, 0, DEFAULT_WALL_CHAR[0], DEFAULT_FLOOR_CHAR[0]);
|
||||||
Camera camera = Camera();
|
Camera camera = Camera();
|
||||||
LuaContextManager lua_context_manager = LuaContextManager();
|
LuaContextManager lua_context_manager;
|
||||||
AlgorithmManager algorithm_manager;
|
AlgorithmManager algorithm_manager;
|
||||||
|
std::unordered_map<InputProcessorKeycode, DungeonAlgorithm*> keycode_to_algorithm;
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y=0;
|
int y=0;
|
||||||
@@ -54,6 +55,7 @@ private:
|
|||||||
|
|
||||||
void initialize_map(int width, int height);
|
void initialize_map(int width, int height);
|
||||||
void initialize_context();
|
void initialize_context();
|
||||||
|
void load_algorithms();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user