A weird game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
turings-tarpit/game_engine.cpp

150 lines
2.8 KiB

#include <map>
#include <string>
#include <iostream>
#include <fmt/core.h>
#include <fmt/color.h>
#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;
}