# Provably Fair

## Context

We define a function `getHash` that computes the SHA256 hash of an input string and returns the bytes as a hex string:

{% code fullWidth="false" %}

```typescript
import * as crypto from "crypto";

export function getHash(input: string) {
  return crypto.createHash("sha256").update(input).digest("hex");
}
```

{% endcode %}

When a game is created, the `server_seed` and `battle_id` are generated. `battle_id` is publicly shared, and the hash of the `server_seed` is displayed on the battle. The `server_seed` is revealed only after a battle has finished. You may verify that the `server_seed` and hash match [here.](https://emn178.github.io/online-tools/sha256.html)

`player_number` is assigned 1 for the creator, and 2 for the joiner.

## Picking Moves

Moves can be randomly chosen in two scenarios:

* For a user who runs out of time in a round
* By the bot (if called by the battle creator)

The move is chosen with the following procedure:

* Generate the input string.
* Compute the SHA256 hash of the input.
* Convert the first 4 bytes of the hex string to an integer and apply modulo 3.
* Choose fire for result 0, grass for result 1, and water for result 2.

{% code fullWidth="false" %}

```typescript
const input: string = "move:{server_seed}:{battle_id}:{player_address}:{round_num}:{player_number}";
const hash: string = getHash(input);
const moveNumber: number = parseInt(hash.substring(0, 8), 16) % 3;

if (moveNumber == 0) {
  return AttackTypeEnum.FIRE;
} else if (moveNumber == 1) {
  return AttackTypeEnum.GRASS;
} else {
  return AttackTypeEnum.WATER;
}
```

{% endcode %}

## Calculating Miss, Hit, Super Active Chances

After every round that isn't a draw, the winning player assigned a chance to either miss, hit a normal attack, or land a super active attack. The attack type is chosen with the following procedure:

* Generate the input string.
* Compute the SHA256 hash of the input.
* Convert the first 4 bytes of the hex string to an integer and apply modulo 100.
* Ticket ranges for the result (inclusive) and respective attack types:
  * 0 - 19: Miss
  * 20 - 51: Super Active
  * 52 - 99: Regular&#x20;

{% code fullWidth="false" %}

```typescript
const input: string = "attack_probability:{server_seed}:{battle_id}:{player_address}:{round_num}:{player_number}";
const hash: string = getHash(input);
const ticket: number = parseInt(hash.substring(0, 8), 16) % 100;

if (ticket <= 19) {
  return "Miss";
} else if (ticket >= 20 && ticket <= 51) {
  return "Super Active";
} else {
  return "Hit";
}
```

{% endcode %}

## Calculating Damage

This is a bit more nuanced due to the slightly more complicated rules of battling and attack types. The damage ticket is generated with the following procedure:

* Generate the input string.
* Compute the SHA256 hash of the input.
* Convert the first 4 bytes of the hex string to an integer.

```typescript
const input: string = "damage:{server_seed}:{battle_id}:{player_address}:{round_num}:{player_number}";
const hash: string = getHash(input);
const ticket: number = parseInt(hash.substring(0, 8), 16);
```

The ticket must now be confined within a range between the minimum and maximum possible attack damage values for the move type.

### Misses

They do 0 damage regardless.

### Regular Attacks

Take the ticket modulo 21 and add 25 to confine the normal attack damage possibilities between 25 and 45 inclusive.

```typescript
return (ticket % 21) + 25;
```

### Super Active Attacks

Take the ticket modulo 15 and add 46 to confine the super active attack damage possibilities between 46 and 60 inclusive.

```typescript
return (ticket % 15) + 46;
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notawhitepaper.pymons.com/pymons/provably-fair.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
