#include "game.hpp" #include #include #include #include #include Game::Game( std::shared_ptr scene, std::shared_ptr cursor_controller, std::shared_ptr generation_tracker, std::shared_ptr status_manager, std::shared_ptr user_input_observer, IStatusLineSubscriberAdapterFactory vector2_statusline_subscriber_adapter_factory) noexcept : _scene(std::move(scene)), _cursor_controller(std::move(cursor_controller)), _generation_tracker(std::move(generation_tracker)), _status_manager(std::move(status_manager)), _user_input_observer(std::move(user_input_observer)), _vector2_statusline_subscriber_adapter_factory( vector2_statusline_subscriber_adapter_factory) { } void Game::on_start() noexcept { _status_manager->initialize(); _status_manager->set_section_title(StatusLineSection::A, ""); _status_manager->set_section_title(StatusLineSection::B, "X: "); _status_manager->set_section_title(StatusLineSection::C, "Y: "); _status_manager->set_section_title(StatusLineSection::D, "Paused: "); _status_manager->set_section_title(StatusLineSection::E, "Generation: "); _status_manager->set_section_title(StatusLineSection::F, "Time since last frame: "); std::shared_ptr> vector2_statusline_subscriber_adapter = _vector2_statusline_subscriber_adapter_factory( _status_manager, {StatusLineSection::B, StatusLineSection::C}); _cursor_controller->subscribe( CursorEvent::POSITION_CHANGE, vector2_statusline_subscriber_adapter); const auto scene_size = _scene->size(); const auto center_position = Vector2( {.x = static_cast(scene_size.get_width()) / 2, .y = static_cast(scene_size.get_height()) / 2}); _cursor_controller->move_to(center_position); _status_manager->set_section_body( StatusLineSection::B, fmt::format("{}", center_position.get_x())); _status_manager->set_section_body( StatusLineSection::C, fmt::format("{}", center_position.get_y())); _status_manager->set_section_body( StatusLineSection::D, _generation_tracker->get_is_paused() ? "yes" : "no"); _status_manager->set_section_body(StatusLineSection::E, "0"); _status_manager->set_section_body(StatusLineSection::F, "0"); _status_manager->set_section_body(StatusLineSection::G, "lol"); _last_update_time = std::chrono::system_clock::now(); } void Game::on_update() noexcept { if (_user_input_observer->is_key_pressed('q')) { std::exit(EXIT_SUCCESS); } if (_user_input_observer->is_key_pressed('i')) { const auto position = _cursor_controller->where(); std::cout.put('x'); std::cout.flush(); _cursor_controller->move_to(position); auto matrix = _scene->get_matrix(); const auto pos_offset = Vector2({.x = 0U, .y = 1U}); matrix->set(position - pos_offset, "#"); } if (_user_input_observer->is_key_pressed('h')) { _move_cursor(Vector2::left()); } if (_user_input_observer->is_key_pressed('j')) { _move_cursor(Vector2::down()); } if (_user_input_observer->is_key_pressed('k')) { _move_cursor(Vector2::up()); } if (_user_input_observer->is_key_pressed('l')) { _move_cursor(Vector2::right()); } if (_user_input_observer->is_key_pressed('p')) { auto onoff = !_generation_tracker->get_is_paused(); _generation_tracker->set_is_paused(onoff); _status_manager->set_section_body(StatusLineSection::D, onoff ? "yes" : "no"); } const auto time_since_last_update = std::chrono::system_clock::now() - _last_update_time; _status_manager->set_section_body( StatusLineSection::F, fmt::format("{} nanoseconds", time_since_last_update.count())); _last_update_time = std::chrono::system_clock::now(); _status_manager->set_section_body( StatusLineSection::G, fmt::format("{}", _user_input_observer->is_key_pressed('v'))); } void Game::on_exit() const noexcept { for (auto row : *_scene->get_matrix()) { for (auto &col : row) { fmt::print("{}", col); } fmt::print("\n"); } std::cout.flush(); } void Game::_move_cursor(const Vector2 &direction) noexcept { const auto new_position = _cursor_controller->where().to_direction(direction, 1); const auto scene_size = _scene->size(); if (scene_size.validate_coords(new_position) != CoordsValidation::VALID) { return; } _cursor_controller->move_to(new_position); }