diff --git a/ftxtest.cpp b/ftxtest.cpp index 639378e..4a41ed5 100644 --- a/ftxtest.cpp +++ b/ftxtest.cpp @@ -1,4 +1,3 @@ - // 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. @@ -15,8 +14,10 @@ #include "ftxui/component/component.hpp" // for CatchEvent, Renderer, operator|= #include "ftxui/component/loop.hpp" // for Loop #include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive +#include using namespace ftxui; +using namespace std; ButtonOption Style() { auto option = ButtonOption::Animated(); @@ -32,26 +33,35 @@ ButtonOption Style() { int main() { auto screen = ScreenInteractive::Fullscreen(); + screen.TrackMouse(true); + vector lines; // Create a component counting the number of frames drawn and event handled. int custom_loop_count = 0; int frame_count = 0; int event_count = 0; + float scroll_x = 0.1; + float scroll_y = 1.0; int hp = 100; int row = 0; - auto hit_button = Button("Hit", [&] { hp -= 1; }, Style()); - auto hard_button = Button("Hard", [&] { hp -= 10; }, Style()); - auto heal_button = Button("Heal", [&] { hp += 10; }, Style()); + auto hit_button = Button("Hit", [&] { + hp -= 1; + lines.push_back(fmt::format("You were hit! HP now {}", hp)); + }, Style()); + auto hard_button = Button("Hard", [&] { + hp -= 10; + lines.push_back(fmt::format("You were hit HARD! HP now {}", hp)); + }, Style()); + auto heal_button = Button("Heal", [&] { + hp += 10; + lines.push_back(fmt::format("You healed! HP now {}", hp)); + }, Style()); auto buttons = Container::Horizontal({ hit_button, hard_button, heal_button}, &row); - auto component = Renderer(buttons, [&] { - frame_count++; - - return vbox({ - paragraph("I'm baby mustache hammock squid, stumptown echo park lumbersexual PBR&B glossier iceland pabst irony mlkshk skateboard migas kombucha. Lyft meggings organic tacos. IPhone microdosing bodega boys, fit locavore jawn cloud bread neutral milk hotel trust fund live-edge selfies portland lyft vice. Pug swag af slow-carb."), - separator(), + auto status = Renderer([&] { + return vbox({ paragraph(fmt::format("HP {} frames {} events {} custom {}", hp, frame_count, event_count, custom_loop_count)), separator(), @@ -59,8 +69,34 @@ int main() { text("HP"), gauge(hp / 100.0f), }), + }); + }); + + auto content = Renderer([&] { + vector output; + + for(const auto line : lines) { + output.push_back(text(line)); + } + + return vbox(output); + }); + + auto scrollable_content = Renderer(content, + [&, content] { + return content->Render() + | focusPositionRelative(scroll_x, scroll_y) + | frame | flex; + }); + + auto component = Renderer(buttons, [&] { + frame_count++; + + return vbox({ + status->Render(), separator(), buttons->Render(), + scrollable_content->Render() | vscroll_indicator | yframe | size(HEIGHT, LESS_THAN, 20), }) | border; }); diff --git a/game_engine.cpp b/game_engine.cpp index 893890b..607e488 100644 --- a/game_engine.cpp +++ b/game_engine.cpp @@ -10,46 +10,7 @@ const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red); using namespace fmt; using namespace std; -/* Idea, the game's combat is based on brainfuck. - BF operations: - - > move data pointer +1 - < move data pointer -1 - + inc data pointer cell - - dec data pointer cell - . output byte - , input byte - [ - if 0 jump to after ] - ] if not 0 jump to after [ - -Ideas: - - Your hitpoints vs. the boss's hitpoints could be - the data. The data could be bits instead of bytes - that you turn off/on during combat. - - You then receive items you use to build your code - and the boss also receives items each round. Your - code runs at the end of the round, and the results - calculated. - - I can then come up with old school tech for the - different operations so like an old transistor - could be the output (.) operation. - - Alright so let's say there's two grids: - - (HP: 100 1's) - (CODE: Nothing.) - - At the start of each round you receive maybe 4 items - you can place on the code bar. So you could do this: - - (CODE: [+>+>+>.]) - */ - Brainfucker::Brainfucker() { - } /* @@ -144,11 +105,9 @@ void Brainfucker::run(int ticks) { print(ERROR, "Unknown operation {}\n", op); } - ++ticks; + --ticks; ++ip; // not really used but do it anyway } - - println("\nEXIT: dp={}, ip={}", dp, ip); } void Brainfucker::set_code(string &new_code) { @@ -162,6 +121,10 @@ void Brainfucker::reset() { data.fill(0); } +string Brainfucker::to_string() { + return out.str(); +} + GameEngine::GameEngine(int hp) : hit_points(hp) {}; int GameEngine::determine_damage(string &type) { diff --git a/game_engine.hpp b/game_engine.hpp index 112890e..7224199 100644 --- a/game_engine.hpp +++ b/game_engine.hpp @@ -22,6 +22,7 @@ class Brainfucker { void reset(); void jump_backward(); void jump_forward(); + string to_string(); }; class GameEngine { diff --git a/tests/game_engine.cpp b/tests/game_engine.cpp index b5ceb9b..8a75759 100644 --- a/tests/game_engine.cpp +++ b/tests/game_engine.cpp @@ -10,7 +10,6 @@ TEST_CASE("basic brainfuck test", "[brainfuck]") { bf.set_code(code); - // this is actually ticks, not code length bf.run(code.size()); REQUIRE(bf.data[0] == 1); @@ -35,9 +34,10 @@ TEST_CASE("brainfuck loop test", "[brainfuck]") { string code{"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."}; bf.set_code(code); - bf.run(code.size()); + // have it run a bunch of times + bf.run(10000); - string output = bf.out.str(); + string output = bf.to_string(); REQUIRE(output == expected); }