# Simple contracts: Game of Dice

**Let's write game of dice simulation. Rules are the following:**

1. There is an usual six-sided dice. Player can can bet some amount of coins on a roll result.
2. If player tries to bet more coins than he actually has, he will lose all his coins (meaning they'll be transfered to game's contract). Dice roll result will be ignored.
3. The value that player bets on has to be an integer in range \[1,6]. Otherwise, player will be fined double the fee and roll result will be ignored.
4. If player guesses roll result, he'll get half of his bet on his account.
5. If he loses, amount of his bet will be transfered to contract's balance.

**We'll need to use a couple of pre-build vm functions here:**

* <mark style="color:purple;">**`getSender()`**</mark> - returns caller's (player's) wallet hash as a string.
* <mark style="color:purple;">**`addCustomField(key, value)`**</mark> - adds key-value pair to vm's response (tx->vmr->C).
* <mark style="color:purple;">**`getBalance(hash).Int64()`**</mark> - returns integer amount of coins on a balance of a wallet identified by given hash.
* <mark style="color:purple;">**`getContractHash()`**</mark> - returns hash of a contract which calls it.
* <mark style="color:purple;">**`currentFee()`**</mark> - returns integer amount of fee for executing contract. Does not work in a simulation (returns undefined).
* <mark style="color:purple;">**`transfer(hash, amount)`**</mark> - transfers the specified amount of coins to a wallet identified by a given hash from sender's account.
* <mark style="color:purple;">**`transferFromContract(wallet, amount)`**</mark> - transfers the specified amount of coins to a wallet identified by a given hash from current contract's (caller contract) balance.

[**Pre-build functions docs.**](http://164.68.127.226:3432/docs)

So we need to write a function, that takes two arguments: roll value player bets on (betOn) and amount of his bet (betAmount). Here's it's code:

<pre class="language-javascript"><code class="lang-javascript">function gameOfDice (betOn, betAmount){
<strong>    var wallet = getSender();
</strong><strong>    var winMult = 1.5;
</strong>    var feeMult = 2;
    var diceMin = 1;
    var diceMax = 6;
    var diceRoll = parseInt(Math.random() *(diceMax - diceMin + 1) + diceMin);
    addCustomField('roll', diceRoll); //to display roll's result
    var playerBalance = getBalance(wallet).Int64();
<strong>    var message = '';
</strong>    if (typeof betOn !== 'number' || parseInt(betOn) != betOn || betOn &#x3C; diceMin || betOn > diceMax) { //condition 3
<strong>        message = 'Bet value is out of expected range [' + diceMin + ', ' + diceMax + '] or not integer';
</strong><strong>        transfer(getContractHash(), currentFee() * feeMult);
</strong>    }
    else if (playerBalance &#x3C; betAmount) { //condition 2
        message = 'Insufficient funds';
        transfer(getContractHash(), playerBalance - currentFee());
    }
    else if (diceRoll == betOn){ 
        message = 'You won!';
        var contractBalance = getBalance(getContractHash()).Int64();
        var target = betAmount * (winMult - 1);
        transferFromContract(wallet, contractBalance >= target ? target : contractBalance);
    }
    else { 
       message = 'You lose!';
       transfer(getContractHash(), betAmount);
    }
     ddCustomField('message', message);
}
</code></pre>

Run a simulation with a function call before saving contract to avoid unnecessary waste of coins. Before running a simulation, make sure that there are some coins on your wallet's balance. Otherwise you'll get "insufficient balance" error. Free test coins can be gained [**here**](https://faucet.cyclonechain.com).

Note that it's better to turn "base64" switch on, or some basic things like comparison operators may not work and cause simulation failure. You can get answers to your questions about Otto js (which is default VM) features and limitations [**here**](https://chatgpt.com/g/g-ko3PBEUNR-ottojs-helper)**.**

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2F89jLS7146zvEd6gnCWy5%2Fimage.png?alt=media&#x26;token=ea058be8-5ea5-42c9-b644-1545f4ae15ab" alt=""><figcaption><p><a href="http://164.68.127.226:3432/">cyPlay developer tool</a></p></figcaption></figure>

If simulations went fine, it's time to save your contract (don't forget to remove function call before saving):

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2FOjePgvgvF5QmIabkiDg0%2Fimage.png?alt=media&#x26;token=3526d615-a592-4900-be39-17e2a9de4189" alt=""><figcaption><p><a href="http://164.68.127.226:3432/">cyPlay developer tool</a></p></figcaption></figure>

You can always find your contract in our Blockchain Explorer in a [history of your transactions](https://explorer.cyclonechain.com/wallet-history.html) or in a [transaction search section](https://explorer.cyclonechain.com/transaction-search.html).

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2FaB7p8chxvCFfGnnKPvkp%2Fimage.png?alt=media&#x26;token=89afde9d-18a2-4a2e-a077-48a9d7116766" alt=""><figcaption><p> <a href="https://explorer.cyclonechain.com/wallet-history.html">history of your transactions</a></p></figcaption></figure>

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2FmkVR7wU1GzKgyE7e5wQM%2Fimage.png?alt=media&#x26;token=7a25c145-87ac-4481-ac11-dff05541ce25" alt=""><figcaption><p><a href="https://explorer.cyclonechain.com/transaction-search.html">transaction search section</a></p></figcaption></figure>

To put a few coins from your wallet on a contract's balance:

```javascript
transfer('f4e481ae740161127561c3455412f1687f9a09b6ce0d9938d528caad82ea7a3d', 100)
```

Use "deploy" button:

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2FIckE7JX2oMi3a69xs0Ng%2Fimage.png?alt=media&#x26;token=029e6000-a8e4-420b-ab8f-c86b992a9c65" alt=""><figcaption><p><a href="http://164.68.127.226:3432/">cyPlay developer tool</a></p></figcaption></figure>

Contract balance can be checked at any time by simulating the following code:

{% code overflow="wrap" fullWidth="false" %}

```javascript
addCustomField('balance', getBalance('f4e481ae740161127561c3455412f1687f9a09b6ce0d9938d528caad82ea7a3d').Int64())
```

{% endcode %}

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2FU1xhIzEoXreQ3x9NIBmJ%2Fimage.png?alt=media&#x26;token=fb45abf8-bfb0-4d43-a2d5-064004dd039b" alt=""><figcaption><p><a href="http://164.68.127.226:3432/">cyPlay developer tool</a></p></figcaption></figure>

Finally, you can play your game by using <mark style="color:purple;">**`callContract()`**</mark> function:

{% code overflow="wrap" %}

```javascript
callContract('f4e481ae740161127561c3455412f1687f9a09b6ce0d9938d528caad82ea7a3d', 'gameOfDice', 3, 20)
```

{% endcode %}

<figure><img src="https://3931730355-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frxbe1N9Il2WjzwVFQGsb%2Fuploads%2Finr0DsJZN9HqMNUJac2e%2Fimage.png?alt=media&#x26;token=3ee49202-fc8a-406a-ab41-ca72a641ea39" alt=""><figcaption><p><a href="http://164.68.127.226:3432/">cyPlay developer tool</a></p></figcaption></figure>
