|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#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;
|
|
|
|
|
|
|
|
/* 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() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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] = 1;
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
data[dp] = 0;
|
|
|
|
break;
|
|
|
|
case '.':
|
|
|
|
print("{}", data.at(dp));
|
|
|
|
break;
|
|
|
|
case ',':
|
|
|
|
print(ERROR, "Not implemented.\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
print(ERROR, "Unknown operation {}\n", op);
|
|
|
|
}
|
|
|
|
|
|
|
|
++ticks;
|
|
|
|
++ip; // not really used but do it anyway
|
|
|
|
}
|
|
|
|
|
|
|
|
println("\nEXIT: dp={}, ip={}", dp, ip);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Brainfucker::set_code(string &new_code) {
|
|
|
|
code.assign(new_code);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Brainfucker::reset() {
|
|
|
|
dp=0;
|
|
|
|
ip=0;
|
|
|
|
code.erase();
|
|
|
|
data.fill(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if(is_dead()) {
|
|
|
|
print(ERROR, "YOU DIED!\n");
|
|
|
|
} else {
|
|
|
|
println("DAMAGE {}, HP: {}", damage, hit_points);
|
|
|
|
}
|
|
|
|
|
|
|
|
// super dumb but I'll clean it up later
|
|
|
|
return is_dead();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GameEngine::is_dead() {
|
|
|
|
return hit_points <= 0;
|
|
|
|
}
|