#include #include #include #include #include #include "game_engine.hpp" const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red); using namespace fmt; using namespace std; Brainfucker::Brainfucker() { } /* * Just a jank way to use a counter to find * the previous matching brace rather than * using a stack. Should work for now. */ void Brainfucker::jump_forward() { int counter = 1; for(++ip; // when counter hits 0 we found it counter > 0 && ip < code.size(); ++ip) { char op = code.at(ip); if(op == '[') { // new branch so increment ++counter; } else if(op == ']') { // close branch so decrement --counter; } } ++ip; // need to go 1 after } /* * Same jank style of using a counter to * jump back. */ void Brainfucker::jump_backward() { int counter = 1; for(--ip; // when counter hits 0 we found it counter > 0 && ip > 0; --ip) { char op = code.at(ip); if(op == '[') { // close branch so decrement --counter; } else if(op == ']') { // new branch so increment ++counter; } } } /* * Totally fragile but it seems to be working * enough to test the idea. */ void Brainfucker::run(int ticks) { while(ip >= 0 && ip < code.size() && ticks > 0) { char op = code.at(ip); switch(op) { case '>': ++dp; break; case '<': --dp; break; case '+': data[dp] = data[dp] + 1; break; case '-': data[dp] = data[dp] - 1; break; case '.': out << (char)data.at(dp); break; case ',': print(ERROR, "Not implemented.\n"); break; case '[': { // [ - if 0 jump to after ] if(data.at(dp) == 0) { jump_forward(); } } break; case ']': { // ] if not 0 jump to after [ if(data.at(dp) != 0) { jump_backward(); } } break; default: print(ERROR, "Unknown operation {}\n", op); } --ticks; ++ip; // not really used but do it anyway } } void Brainfucker::set_code(string &new_code) { code.assign(new_code); } void Brainfucker::reset() { dp=0; ip=0; code.erase(); data.fill(0); } string Brainfucker::to_string() { return out.str(); } GameEngine::GameEngine(int hp) : hit_points(hp) {}; int GameEngine::determine_damage(string &type) { try { return damage_types.at(type); } catch(std::out_of_range &err) { print(ERROR, "BAD DAMAGE TYPE {}\n", type); return 1000; } } bool GameEngine::hit(string &type) { int damage = determine_damage(type); hit_points -= damage; // super dumb but I'll clean it up later return is_dead(); } bool GameEngine::is_dead() { return hit_points <= 0; }