A simple brainfuck interpreter for the game's idea.

master
Zed A. Shaw 2 months ago
parent 984031bf33
commit 1fb99618bf
  1. 94
      game_engine.cpp
  2. 17
      game_engine.hpp
  3. 22
      tests/game_engine.cpp

@ -4,10 +4,102 @@
#include <fmt/color.h> #include <fmt/color.h>
#include "game_engine.hpp" #include "game_engine.hpp"
const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red);
using namespace fmt; using namespace fmt;
using namespace std; using namespace std;
const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red); /* 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) {}; GameEngine::GameEngine(int hp) : hit_points(hp) {};

@ -1,8 +1,25 @@
#include <string> #include <string>
#include <map> #include <map>
#include <vector>
#include <array>
using namespace std; using namespace std;
class Brainfucker {
size_t dp = 0;
size_t ip = 0;
public:
array<int, 100> data = {};
string code = {};
Brainfucker();
void run(int count);
void set_code(string &code);
void reset();
};
class GameEngine { class GameEngine {
int hit_points = 0; int hit_points = 0;
map<string, int> damage_types{ map<string, int> damage_types{

@ -1,6 +1,28 @@
#include <doctest.h> #include <doctest.h>
#include "../game_engine.hpp" #include "../game_engine.hpp"
TEST_CASE("brainfuck test") {
Brainfucker bf;
string code{"+.>+.>+.>"};
bf.set_code(code);
// this is actually ticks, not code length
bf.run(code.size());
CHECK(bf.data[0] == 1);
CHECK(bf.data[1] == 1);
CHECK(bf.data[2] == 1);
bf.reset();
CHECK(bf.data[0] == 0);
CHECK(bf.data[1] == 0);
CHECK(bf.data[2] == 0);
CHECK(bf.code.empty());
}
TEST_CASE("game engine can start and take hit") { TEST_CASE("game engine can start and take hit") {
// test fails on purpose right now // test fails on purpose right now
GameEngine game{4}; GameEngine game{4};

Loading…
Cancel
Save