A simple brainfuck interpreter for the game's idea.
This commit is contained in:
parent
984031bf33
commit
1fb99618bf
3 changed files with 132 additions and 1 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue