presenting�The Chain�of Life
Cryptolife�Hackathon
Why?
=> We are entering into the race for the first GAI with the chain of life, a distributed evolutionary algorithm run by humans for the survival of humanity.
How?
The chain of life is a competitive distributed market for life strategies.
It is played in a crypto petri dish and the life strategies that occupied the most space after x generations win.
The winners move on into further bigger dishes.
Game Of Life
2 Player Version
1) The cell has exactly three white neighbours and the number of black neighbours is different from three. In this case a white token is born in the cell.��2) The cell has exactly three white and three black neighbours. In this case an unbiased coin determines whether a white or black token is born in the cell.
3) If the difference between the number of white and black neighbours is two or three, then the white token survives.
4) If the difference between the number of white and black neighbours is one and the number of white neighbours is at least two, then the white token survive
https://arxiv.org/pdf/cond-mat/0207679.pdf
Demo
Verification Problem on Chain
Ideal case:�4 transactions
Life verification game
Life verification game
Gas Cost:
�1plife 32 x 32 = 1,756,519
1plife 48 x 48 = 3,925,663
1plife 32 x 64 = 3,501,567
2plife 32 x 32 = 2,864,709
Code
pragma solidity ^0.4.24;
contract Generation {
function life(bytes32[] _dish) public pure returns (bytes32[] _newGen) {
_newGen = new bytes32[](_dish.length);
uint256 color;
uint256 aN; // neighbours of alice
uint256 bN; // neighbours of bob
bytes32 prevRow;
bytes32 nextRow;
uint256 prevCell;
uint256 nextCell;
uint256 randHash;
// create a hash for randomnes
prevRow = _dish[_dish.length / 4];
nextRow = _dish[_dish.length / 2];
assembly {
mstore(0, prevRow)
mstore(0x20, nextRow)
randHash := keccak256(0, 0x40)
}
for (uint256 row = 0; row < _dish.length; row++) { //each row
for (uint256 cell = 0; cell < _dish.length * 2; cell+=2) { //each cell
color = (uint8(_dish[row] >> cell) & 0x03);
prevRow = (row > 0) ? _dish[row - 1] : _dish[_dish.length-1];
nextRow = (row < _dish.length - 1) ? _dish[row + 1] : _dish[0];
prevCell = (cell > 0) ? cell - 2 : _dish.length * 2 - 2;
nextCell = (cell < (_dish.length * 2) - 2) ? cell + 2 : 0;
aN = 0;
bN = 0;
// above
aN += uint8(prevRow >> prevCell) & 0x01;
aN += uint8(prevRow >> cell) & 0x01;
aN += uint8(prevRow >> nextCell) & 0x01;
bN += (uint8(prevRow >> prevCell) & 0x02) >> 1;
bN += (uint8(prevRow >> cell) & 0x02) >> 1;
bN += (uint8(prevRow >> nextCell) & 0x02) >> 1;
// same
aN += uint8(_dish[row] >> prevCell) & 0x01;
aN += uint8(_dish[row] >> nextCell) & 0x01;
bN += (uint8(_dish[row] >> prevCell) & 0x02) >> 1;
bN += (uint8(_dish[row] >> nextCell) & 0x02) >> 1;
// below
aN += uint8(nextRow >> prevCell) & 0x01;
aN += uint8(nextRow >> cell) & 0x01;
aN += uint8(nextRow >> nextCell) & 0x01;
bN += (uint8(nextRow >> prevCell) & 0x02) >> 1;
bN += (uint8(nextRow >> cell) & 0x02) >> 1;
bN += (uint8(nextRow >> nextCell) & 0x02) >> 1;
if (color == 0) { // empty
if (aN == 3) {
if (bN == 3) {
_newGen[row] = _newGen[row] | bytes32((randHash >> cell % 2 + 1) << cell);
} else {
_newGen[row] = _newGen[row] | bytes32(0x01 << cell);
}
} else if (bN == 3) {
_newGen[row] = _newGen[row] | bytes32(0x02 << cell);
}
}
// difference between aliceNeighbours and bobNeighbours
prevCell = (aN > bN) ? aN - bN : bN - aN;
if (color == 1) { // alice
if (prevCell == 2 || prevCell == 3) {
_newGen[row] = _newGen[row] | bytes32(0x01 << cell);
}
if (prevCell == 1 && aN >= 2) {
_newGen[row] = _newGen[row] | bytes32(0x01 << cell);
}
}
if (color == 2) { // bob
if (prevCell == 2 || prevCell == 3) {
_newGen[row] = _newGen[row] | bytes32(0x02 << cell);
}
if (prevCell == 1 && bN >= 2) {
_newGen[row] = _newGen[row] | bytes32(0x02 << cell);
}
}
}
}
}
}
Thank you!