feature/rla-11_AlgorithmsP1 #12

Merged
conco merged 2 commits from feature/rla-11_AlgorithmsP1 into master 2023-07-23 05:04:16 +00:00
9 changed files with 145 additions and 15 deletions
Showing only changes of commit d7fa6069f8 - Show all commits

View File

@@ -23,5 +23,6 @@ Necessary:
init_function(map_w, map_h)
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.
Returns true if finished, else false

View File

@@ -0,0 +1,34 @@
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()
self.curr_x = self.curr_x + math.random(-1, 1)
self.curr_y = self.curr_y + math.random(-1, 1)
while self.curr_x >= self.map_w or self.curr_x < 0 or self.curr_y >= self.map_h or self.curr_y < 0 do
self.curr_x = self.curr_x + math.random(-1, 1)
self.curr_y = self.curr_y + math.random(-1, 1)
end
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)

View 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)

View File

@@ -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
std::shared_ptr<sol::state> LuaContextManager::load_resource(std::string args) {
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;
}

View File

@@ -3,8 +3,10 @@
//
#include "algorithmmanager.hpp"
#include "../engine/modules/logger.hpp"
#include <utility>
#include <fmt/format.h>
void AlgorithmManager::register_algorithm(std::string name, sol::function initialize, sol::function update,
unsigned int updates_per_second) {
@@ -19,6 +21,39 @@ void AlgorithmManager::register_algorithm(std::string name, sol::function initia
}
ranges::any_view<DungeonAlgorithm> AlgorithmManager::get_algorithms() {
return algorithms;
ranges::any_view<DungeonAlgorithm*, ranges::category::random_access | ranges::category::sized> AlgorithmManager::get_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;
}
else {
algorithm_done = true;
sol::error err = update_result;
Logger::log(LogLevel::ERROR, fmt::format("An error occurred while running update: {}", err.what()));
}
}
ticks++;
}

View File

@@ -8,8 +8,8 @@
#include <range/v3/view.hpp>
struct DungeonAlgorithm {
unsigned int frames_per_update=1;
sol::function update;
sol::function initialize;
sol::protected_function update;
sol::protected_function initialize;
std::string name;
};
@@ -17,17 +17,15 @@ class AlgorithmManager {
private:
std::vector<DungeonAlgorithm> algorithms;
unsigned int target_fps=1;
unsigned int ticks=0;
DungeonAlgorithm* loaded_algorithm = nullptr;
bool algorithm_done = false;
public:
void register_algorithm(std::string name, sol::function initialize, sol::function update, unsigned int updates_per_second);
void setTargetFps(unsigned int targetFps) {
target_fps = targetFps;
}
ranges::any_view<DungeonAlgorithm> get_algorithms();
ranges::any_view<DungeonAlgorithm*, ranges::category::random_access | ranges::category::sized> get_algorithms();
void load_algorithm(DungeonAlgorithm* algorithm, int w, int h);
void tick_algorithm();
explicit AlgorithmManager(unsigned int targetFps) : target_fps(targetFps) {}
AlgorithmManager() = default;
};

View File

@@ -4,12 +4,16 @@
#include "tilemap.hpp"
#include "../engine/utility/point.hpp"
#include "../engine/modules/logger.hpp"
#include <fmt/format.h>
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);
}
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);
}
@@ -18,6 +22,7 @@ char TileMap::get_tile(int x, int y) {
}
void TileMap::fill(bool wall) {
Logger::log(LogLevel::DEBUG, fmt::format("Running fill with wall: {}", wall));
for(Point p : grid.get_range()) {
if(wall) {
draw_wall(p.x, p.y);

View File

@@ -2,6 +2,7 @@
// Created by m on 12/3/21.
//
#include <filesystem>
#include "visualizer.hpp"
#include "tilemap.hpp"
@@ -9,6 +10,7 @@ bool Visualizer::update(InputResult input) {
if(input.keycode == KEY_ESCAPE) {
return true;
}
this->algorithm_manager.tick_algorithm();
switch(input.keycode) {
case KEY_RIGHT: x += 1; break;
case KEY_LEFT: x -= 1; break;
@@ -16,6 +18,12 @@ bool Visualizer::update(InputResult input) {
case KEY_DOWN: y += 1; 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->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->algorithm_manager = AlgorithmManager(args.target_fps);
this->initialize_context();
this->load_algorithms();
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);
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;

View File

@@ -38,8 +38,9 @@ private:
int window_height = 0;
TileMap tile_map = TileMap(0, 0, DEFAULT_WALL_CHAR[0], DEFAULT_FLOOR_CHAR[0]);
Camera camera = Camera();
LuaContextManager lua_context_manager = LuaContextManager();
LuaContextManager lua_context_manager;
AlgorithmManager algorithm_manager;
std::unordered_map<InputProcessorKeycode, DungeonAlgorithm*> keycode_to_algorithm;
int x = 0;
int y=0;
@@ -54,6 +55,7 @@ private:
void initialize_map(int width, int height);
void initialize_context();
void load_algorithms();
};