The Rule 110 cellular automaton is a 1-dimensional elementary CA, where a linear pattern of 0s and 1s evolves according to a simple set of rules. Whether a point in the pattern will be 0 or 1 in the new generation depends on its current value and on those of its two neighbors. The Rule 110 has the following set of rules:
Current pattern | 111 | 110 | 101 | 100 | 011 | 010 | 001 | 000 |
---|---|---|---|---|---|---|---|---|
New state for center cell | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
contract rule110 {
static const int N = 5; //size of board
static const int N2 = 3; //size of board
static bytes LIVE = b'01';
static bytes DEAD = b'00';
@state
bytes board;
public function play(int amount, SigHashPreimage txPreimage) {
SigHashType sigHashType = SigHash.ANYONECANPAY | SigHash.SINGLE | SigHash.FORKID;
// this ensures the preimage is for the current tx
require(Tx.checkPreimageSigHashType(txPreimage, sigHashType));
this.board = this.computeNewBoard(this.board);
bytes newScriptCode = this.getStateScript();
bytes output = Utils.buildOutput(newScriptCode, amount);
require(hash256(output) == SigHash.hashOutputs(txPreimage));
}
function computeNewBoard(bytes board) : bytes {
bytes res = b'';
res += DEAD;
loop (N2) : i {
res += this.newState(board[i : i + 3]);
}
res += DEAD;
return res;
}
function newState(bytes arg) : bytes {
/*
Current pattern 111 110 101 100 011 010 001 000
New state for center cell 0 1 1 0 1 1 1 0
*/
bytes a = arg[0 : 1];
bytes b = arg[1 : 2];
bytes c = arg[2 : 3];
bytes res = LIVE;
if (a == LIVE && b == LIVE && c == LIVE) {
res = DEAD;
}
if (a == LIVE && b == DEAD && c == DEAD) {
res = DEAD;
}
if (a == DEAD && b == DEAD && c == DEAD) {
res = DEAD;
}
return res;
}
}