A smart contract written in Rust. It is a game even for a creatures with a single neuron. In which you should put 3 X or O in a row before your opponent. Why would I implement such simple game? Because I'm also a single cell organism.
-
Before you compile this code, you will need to install Rust with correct target
-
Before initializing the game you must deploy streaming smart contract. It's account Id will be passed to the game contract on start.
- Deploy the game contract.
near deploy \
--accountId tic-tac-near.YOURNAME.testnet \
--wasmFile ./out/tic_tac_near.wasm
- Then you must connect streaming contract.
near call tic-tac-near.YOURNAME.testnet connect_streaming_contract \
'{"streaming_id": "streaming-roketo.YOURNAME.testnet"}' \
--accountId tic-tac-near.YOURNAME.testnet \
--gas 300000000000000
- Then first player must deposit any amount of any token to the game contract account.
Message should contain JSON map with key
tokens_per_sec
and a value as a string. Example with wNEAR FT:
near call wrap.testnet ft_transfer_call \
'{"receiver_id": "tic-tac-near.YOURNAME.testnet", "amount": "300000000000000000000000", "msg": "{\"tokens_per_sec\": \"1000000\"}"}' \
--depositYocto 1 \
--gas 300000000000000 \
--accountId FIRST_PLAYER.testnet
- And the second player must do exactly the same: with the same token, with the same amount. Second player message unimportant, it won't be used anywhere. Example with wNEAR FT:
near call wrap.testnet ft_transfer_call \
'{"receiver_id": "tic-tac-near.YOURNAME.testnet", "amount": "300000000000000000000000", "msg": ""}' \
--depositYocto 1 \
--gas 300000000000000 \
--accountId SECOND_PLAYER.testnet
- Now you can start the game. It will start stream of tokens back to the second player's account. The faster the first player will make it's turn, the less tokens will the second recieve and vice versa.
near call tic-tac-near.YOURNAME.testnet start\
--accountId YOURNAME.testnet \
--gas 300000000000000
- One by on make turns with
make_turn
method (who would believe).
near call tic-tac-near.YOURNAME.testnet make_turn \
'{"x": 1, "y": 1}' \
--accountId FIRST_PLAYER.testnet \
--gas 300000000000000
-
Once any player have reached winning combination both streams will be stopped.
-
To claim reward, call
claim_reward
method signed by the winner. All remaining tokens on stream contract will be transferred to the winner as a reward for it's miserable life
near call tic-tac-near.YOURNAME.testnet claim_reward \
--accountId FIRST_PLAYER.testnet \
--gas 300000000000000
- Call:
./deploy_and_test.sh
-
Copy Ids of streams and pass them as arguments to the next script.
-
Run:
./test_game.sh $FIRST_STREAM $SECOND_STREAM
- Celebrate, you don't need to play this very complicated game. Blockchain will do everything for you!
Connects game contract with streaming contract.
near call tic-tac-near.YOURNAME.testnet connect_streaming_contract \
'{"streaming_id": "streaming-roketo.YOURNAME.testnet"}' \
--accountId YOURNAME.testnet \
--gas 300000000000000
Starts the game. Now first player should be quick to make first turn.
$ near call tic-tac-near.YOURNAME.testnet start\
--accountId YOURNAME.testnet \
--gas 300000000000000
Sets X or O, depends on signing account to the field. X coordinate - from left to right, Y - from up to down. You think why it's a whole u8 for a 3 bit state? Because, live with it. Field coordinates:
Y/X | 0 | 1 | 2 |
---|---|---|---|
0 | _ | _ | X |
1 | O | X | X |
2 | O | O | X |
near call tic-tac-near.YOURNAME.testnet make_turn \
'{"x": 1, "y": 1}' \
--accountId YOURNAME.testnet \
--gas 300000000000000
(you can choose your own coordinates for your moves, who would have thought).
Transfers remaining deposited money from both players to winner.
near call tic-tac-near.YOURNAME.testnet claim_reward \
--accountId FIRST_PLAYER.testnet \
--gas 300000000000000
Completely resets game state. No refunds! (yet).
Gets players information. If information is missing, some fields will be null
.
near call tic-tac-near.YOURNAME.testnet status \
--accountId YOURNAME.testnet
For example if both players are registered:
{
first_player: {
account: 'neuron0.testnet',
deposit: '300000000000000000000000',
stream: 'G6Z65ARQjYKsg9wATGLeqvwujWyr6yjzb61ALQ8CARgx'
},
second_player: {
account: 'neuron1.testnet',
deposit: '300000000000000000000000',
stream: '642BygkDkPj6gXRDFU6kLRrmh6NLT6yRbffrCpzxEQEz'
}
}
If you can't remember 9 3bit values, then it's your salvation.
call tic-tac-near.YOURNAME.testnet get_field
--accountId YOURNAME.testnet
Example output:
{
[
[ 'O', 'X', 'Empty' ],
[ 'O', 'X', 'Empty' ],
[ 'Empty', 'X', 'Empty' ]
]
}