Skip to content

Commit

Permalink
Almost complete game logic + bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
rzhikharevich committed Apr 11, 2016
1 parent d99548c commit 0139b8e
Show file tree
Hide file tree
Showing 14 changed files with 687 additions and 81 deletions.
1 change: 1 addition & 0 deletions config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void Config::parse(const char *path, Json::Value &root) {
{"spriteHeight", Json::ValueType::intValue},
{"columnNumber", Json::ValueType::intValue},
{"rowNumber", Json::ValueType::intValue},
{"moveDelay", Json::ValueType::intValue},
{"unitsPerLeague", Json::ValueType::intValue},
{"leagues", Json::ValueType::objectValue}
});
Expand Down
15 changes: 11 additions & 4 deletions config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,17 @@ class Config {

bool override(const char *path);

int getSpriteWidth() const noexcept {return root.get("spriteWidth", 20).asInt();}
int getSpriteHeight() const noexcept {return root.get("spriteHeight", 20).asInt();}
int getColumnNumber() const noexcept {return root.get("columnNumber", 20).asInt();}
int getRowNumber() const noexcept {return root.get("rowNumber", 20).asInt();}
int getSpriteWidth() const {return root.get("spriteWidth", 20).asInt();}
int getSpriteHeight() const {return root.get("spriteHeight", 20).asInt();}
int getColumnNumber() const {return root.get("columnNumber", 20).asInt();}
int getRowNumber() const {return root.get("rowNumber", 20).asInt();}

void setSpriteSize(int w, int h) {
root["spriteWidth"] = w;
root["spriteHeight"] = h;
}

int getMoveDelay() const {return root.get("moveDelay", 1000).asInt();}

int getUnitsPerLeague() const noexcept {return root.get("unitsPerLeague", 10).asInt();}
const std::unordered_map<std::string, LeagueInfo> &getLeagueInfo() const noexcept {return leagueInfo;}
Expand Down
2 changes: 1 addition & 1 deletion deathgame/bees/README.start.png.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Author of the start.png texture: http://opengameart.org/users/awesomepenguin
License: CC BY 3.0
The image file had been modified with the pngcrush tool.
The image file had been cropped with Preview.app and modified with the pngcrush tool.
2 changes: 2 additions & 0 deletions deathgame/bees/start.dasm
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
turn r
go r
j 0
Binary file modified deathgame/bees/start.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
158 changes: 158 additions & 0 deletions executable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#include "executable.hpp"
#include <unordered_map>
#include <functional>
#include "util.hpp"


Executable::Executable(const std::string &path) {
auto in = FileOpenIn(path);

std::vector<Word> jmp;
Word offs = 0;

std::string line;
int n = 1;
while (std::getline(in, line)) {
jmp.push_back(offs);

std::vector<std::string> insn;

std::size_t i = 0;
std::size_t d;
do {
std::string s;
d = line.find(' ', i);
if (d == s.npos)
s = std::string(line, i);
else
s = std::string(line, i, d - i);

if (s.length())
insn.push_back(s);

i = d + 1;
} while (d != std::string::npos);

auto parseOpN = [this, insn, path, n] {
switch (insn.size()) {
case 1:
bytecode.push_back(1);
break;
case 2:
try {
bytecode.push_back((Word)std::stoul(insn[1]));
} catch (const std::invalid_argument &) {
throw ExecutableError(path, n);
}
break;
default:
throw ExecutableError(path, n);
}
};

auto parseOpR = [this, insn, path, n] {
if (insn.size() != 2 || insn[1] != "r")
throw ExecutableError(path, n);
};

auto parseOpNR = [this, insn, path, n] {
switch (insn.size()) {
case 1:
bytecode.push_back(1);
break;
case 2:
if (insn[1] == "r")
bytecode.push_back(0);
else {
try {
bytecode.push_back(static_cast<Word>(std::stoul(insn[1])));
} catch (const std::invalid_argument &) {
throw ExecutableError(path, n);
}

if (bytecode.back() < 2 || bytecode.back() > 99)
throw ExecutableError(path, n);
}

break;
default:
throw ExecutableError(path, n);
}
};

auto parseOpNN = [this, insn, path, n] {
try {
bytecode.push_back(static_cast<Word>(std::stoul(insn.at(1))));
bytecode.push_back(static_cast<Word>(std::stoul(insn.at(2))));
} catch (const std::logic_error &) {
throw ExecutableError(path, n);
}
};

auto parseOpNone = [this, insn, path, n] {
if (insn.size() != 1)
throw ExecutableError(path, n);
};

auto leaveJumpAddr = [this, jmp, path, n](Word pc) {
if (pc >= jmp.size())
throw ExecutableError(path, n);

bytecode.push_back(jmp[pc]);
};

auto parseOpNJ = [this, insn, path, n, leaveJumpAddr] {
try {
bytecode.push_back((Word)std::stoul(insn.at(1)));
leaveJumpAddr((Word)std::stoul(insn[2]));
} catch (const std::logic_error &) {
throw ExecutableError(path, n);
}
};

auto parseOpJ = [this, insn, path, n, leaveJumpAddr] {
try {
leaveJumpAddr((Word)std::stoul(insn.at(1)));
} catch (const std::logic_error &) {
throw ExecutableError(path, n);
}
};

std::unordered_map<std::string, std::function<void()>> handle = {
#define INSN(n, i, o) \
{#n, [this, parseOp ## o] {\
bytecode.push_back(Insn ## i);\
parseOp ## o();\
}}

INSN(eat, Eat, NR),
INSN(go, Go, NR),
INSN(clon, Clon, None),
INSN(str, Str, N),
INSN(left, Left, N),
INSN(right, Right, N),
INSN(back, Back, None),
INSN(turn, Turn, R),
INSN(jg, JG, NJ),
INSN(jl, JL, NJ),
INSN(j, J, J),
INSN(je, JE, J)

#undef INSN
};

try {
handle.at(insn[0])();
} catch (const std::out_of_range &) {
throw ExecutableError(path, n);
}

offs += bytecode[jmp.back()] == InsnTurn ? 1 : insn.size();

n++;
}
}

ExecutableError::ExecutableError(const std::string &path, int line) {
reason = path + ":" + std::to_string(line) + ": Syntax error.";
}
67 changes: 67 additions & 0 deletions executable.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef EXECUTABLE_HPP
#define EXECUTABLE_HPP


#include <vector>
#include <string>
#include <fstream>
#include <cstdint>
#include <exception>


/*
* Executable.
*/

class Executable {
public:
/*
* All opcodes and operands are 32-bit.
* Random values are specified by 0 if applicable.
*/
typedef std::uint32_t Word;
typedef std::vector<Word> Bytecode;

enum {
InsnEat,
InsnGo,
InsnClon,
InsnStr,
InsnLeft,
InsnRight,
InsnBack,
InsnTurn,
InsnJG,
InsnJL,
InsnJ,
InsnJE,
InsnMax = InsnJE
};

Executable() {}
Executable(const std::string &path);

const Bytecode &getBytecode() const {return bytecode;}
std::size_t size() const {return bytecode.size();}
Word operator[](std::size_t i) const {return bytecode[i];}

private:
Bytecode bytecode;
};

/*
* ExecutableError.
*/

class ExecutableError : public std::exception {
private:
std::string reason;

public:
ExecutableError(const std::string &path, int line);

virtual const char *what() const noexcept {return reason.c_str();}
};


#endif
Loading

0 comments on commit 0139b8e

Please sign in to comment.