Skip to content

Instantly share code, notes, and snippets.

@tbfleming
Last active April 20, 2018 01:26
Show Gist options
  • Save tbfleming/805cd85eb21970633c4a617c56d22159 to your computer and use it in GitHub Desktop.
Save tbfleming/805cd85eb21970633c4a617c56d22159 to your computer and use it in GitHub Desktop.
cib eos demo: Conway's Game of Life
{
"structs": [{
"name": "remove",
"base": "",
"fields": [
{"name":"user", "type":"account_name"},
{"name":"game", "type":"name"}
]
},{
"name": "removeall",
"base": "",
"fields": [
{"name":"user", "type":"account_name"}
]
},{
"name": "create",
"base": "",
"fields": [
{"name":"user", "type":"account_name"},
{"name":"game", "type":"name"},
{"name":"num_rows", "type":"uint32"},
{"name":"num_cols", "type":"uint32"},
{"name":"seed", "type":"uint32"}
]
},{
"name": "step",
"base": "",
"fields": [
{"name":"user", "type":"account_name"},
{"name":"game", "type":"name"}
]
},{
"name": "board",
"base": "",
"fields": [
{"name":"game", "type":"name"},
{"name":"rows", "type":"string[]"}
]
}
],
"actions": [{
"name": "create",
"type": "create"
},{
"name": "remove",
"type": "remove"
},{
"name": "removeall",
"type": "removeall"
},{
"name": "step",
"type": "step"
}
],
"tables": [{
"name": "boards",
"type": "board",
"index_type": "i64",
"key_names" : ["game"],
"key_types" : ["name"]
}
]
}
// Todd Fleming 2018
#include <eosiolib/eosio.hpp>
// board content is in strings to look reasonable in json
struct board {
uint64_t game;
std::vector<std::string> rows;
uint64_t primary_key() const { return game; }
};
void print(board& b) {
for (auto& row: b.rows)
eosio::print(row.c_str(), "\n");
}
// <random> header is missing. This implements MINSTD.
auto rnd(uint32_t& seed) {
seed = (16807ull * seed) % 2147483647u;
return seed;
}
void randomize(board& b, uint32_t num_rows, uint32_t num_cols, uint32_t seed) {
b.rows.resize(num_rows);
for (auto& row : b.rows) {
row.clear();
for (int i = 0; i < num_cols; ++i)
row.push_back((rnd(seed) & 1) ? '*' : ' ');
}
print(b);
}
auto get_size(board& b) {
int num_rows = b.rows.size();
eosio_assert(num_rows >= 3, "game is corrupt");
int num_cols = b.rows[0].size();
eosio_assert(num_cols >= 3, "game is corrupt");
for (auto& row : b.rows)
eosio_assert(row.size() == num_cols, "game is corrupt");
return std::make_pair(num_rows, num_cols);
}
void step(board& b) {
auto [num_rows, num_cols] = get_size(b);
auto old = b;
for (int r = 0; r < num_rows; ++r) {
for (int c = 0; c < num_cols; ++c) {
auto alive = [&, num_rows=num_rows, num_cols=num_cols](int dr, int dc) {
return old.rows[(r + dr + num_rows) % num_rows]
[(c + dc + num_cols) % num_cols] != ' ';
};
auto neighbors = alive(-1, -1) + alive(-1, 0) + alive(-1, 1) +
alive(0, -1) + alive(0, 1) + alive(1, -1) +
alive(1, 0) + alive(1, 1);
if (neighbors == 3 || (alive(0, 0) && neighbors == 2))
b.rows[r][c] = '*';
else
b.rows[r][c] = ' ';
}
}
print(b);
}
struct gameoflife : eosio::contract {
gameoflife(account_name self) : contract{self} {}
void removeall(account_name user) {
require_auth(user);
// multi_index can't erase when the format changed
auto it = db_lowerbound_i64(_self, user, N(boards), 0);
while (it >= 0) {
auto del = it;
uint64_t dummy;
it = db_next_i64(it, &dummy);
db_remove_i64(del);
}
}
void remove(account_name user, eosio::name game) {
require_auth(user);
auto it = db_find_i64(_self, user, N(boards), game);
if (it >= 0)
db_remove_i64(it);
}
void create(account_name user, eosio::name game, uint32_t num_rows,
uint32_t num_cols, uint32_t seed) {
remove(user, game);
eosio_assert(num_rows >= 3 && num_rows <= 100,
"num_rows out of range [3, 100]");
eosio_assert(num_cols >= 3 && num_cols <= 100,
"num_cols out of range [3, 100]");
eosio::multi_index<N(boards), board> boards(_self, user);
boards.emplace(user, [&](auto& b) {
b.game = game;
randomize(b, num_rows, num_cols, seed);
});
}
void step(account_name user, eosio::name game) {
require_auth(user);
eosio::multi_index<N(boards), board> boards(_self, user);
boards.modify(boards.get(game), user, ::step);
}
};
EOSIO_ABI(gameoflife, (removeall)(remove)(create)(step))
{
"actions": [{
"account": "gameoflife",
"name": "create",
"authorization": [{"actor": "test", "permission": "active"}],
"data": {
"user": "test",
"game": "mygame",
"num_rows": 10,
"num_cols": 20,
"seed": 4536
}
},{
"account": "gameoflife",
"name": "step",
"authorization": [{"actor": "test", "permission": "active"}],
"data": {
"user": "test",
"game": "mygame"
}
},{
"account": "gameoflife",
"name": "step",
"authorization": [{"actor": "test", "permission": "active"}],
"data": {
"user": "test",
"game": "mygame"
}
}]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment