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

187 lines
3.7 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;
/* 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() {
}
/*
* 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 '.':
cout << (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
}
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;
// super dumb but I'll clean it up later
return is_dead();
}
bool GameEngine::is_dead() {
return hit_points <= 0;
}