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.
149 lines
2.8 KiB
149 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;
|
|
}
|
|
|