// Copyright 2020 Arthur Sonzogni. All rights reserved. // Use of this source code is governed by the MIT license that can be found in // the LICENSE file. #include // for operator""s, chrono_literals #include // for cout, ostream #include // for allocator, shared_ptr #include // for string, operator<< #include // for sleep_for #include // for hflow, paragraph, separator, hbox, vbox, filler, operator|, border, Element #include // for Render #include // for ftxui #include #include #include #include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include #include "map.hpp" #include "dbc.hpp" using std::string; using namespace fmt; using namespace std::chrono_literals; int main() { using namespace ftxui; std::string reset_position; auto c = Canvas(60 * 2, 27 * 4); Map game_map(50, 27); game_map.generate(); Matrix &walls = game_map.walls(); Room &start = game_map.room(0); Room &bad_room = game_map.room(1); Room &gold_room = game_map.room(game_map.room_count() - 1); Point me = {.x=start.x+1, .y=start.y+1}; Point enemy = {.x=bad_room.x+1, .y=bad_room.y+1}; Point goal = {.x=gold_room.x+1, .y=gold_room.y+1}; string dead_yet = "NOT DEAD"; bool show_paths = false; auto map = Renderer([&] { game_map.set_target(me); game_map.make_paths(); Matrix &paths = game_map.paths(); for(size_t x = 0; x < walls[0].size(); ++x) { for(size_t y = 0; y < walls.size(); ++y) { string tile = walls[y][x] == 1 ? "#" : format("{}", paths[y][x]); if(tile == "#") { c.DrawText(x*2, y*4, tile, Color::GrayDark); } else if(show_paths) { int pnum = paths[y][x]; c.DrawText(x*2, y*4, tile, Color::Palette16(pnum % 7 + 1)); } else { c.DrawText(x*2, y*4, ".", Color::GrayDark); } } } c.DrawText(enemy.x*2, enemy.y*4, "!", Color::Red); c.DrawText(me.x*2, me.y*4, "@", Color::Blue); c.DrawText(goal.x*2, goal.y*4, "$", Color::Yellow); return canvas(c); }); auto document = Renderer([&]{ return hbox({ hflow( vbox( gauge(0.5) | border, text(dead_yet) | border ) | xflex_grow ), separator(), hbox(map->Render()), }) | border; }); document |= CatchEvent([&](Event e) -> bool { size_t x = me.x; size_t y = me.y; if(e == Event::ArrowLeft) { x -= 1; } else if(e == Event::ArrowRight) { x += 1; } else if(e == Event::ArrowDown) { y += 1; } else if(e == Event::ArrowUp) { y -= 1; } else { return false; } if(game_map.inmap(x,y) && !game_map.iswall(x,y)) { game_map.clear_target(me); me.x = x; me.y = y; } // move enemy here bool found = game_map.neighbors(enemy, true); if(enemy.x == me.x && enemy.y == me.y) { dead_yet = "YOU DIED!"; } else if(goal.x == me.x && goal.y == me.y) { dead_yet = "YOU WIN!"; } return true; }); auto screen = ScreenInteractive::Fullscreen(); Loop loop(&screen, document); while(!loop.HasQuitted()) { loop.RunOnceBlocking(); } return 0; }