mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
Update README for tictactoe
This commit is contained in:
parent
93307b1446
commit
48cb481d73
@ -1,8 +1,33 @@
|
||||
# tictactoe.aleo
|
||||
# Tic Tac Toe
|
||||
|
||||
## Build Guide
|
||||
A simple Tic Tac Toe game written in Leo.
|
||||
|
||||
To compile this Aleo program, run:
|
||||
## Representing State
|
||||
Leo allows users to define composite data types with the `circuit` keyword.
|
||||
The game board is represented by a circuit called `Board`, which contains three `Row`s.
|
||||
An alternative representation would be to use an array, however, these are not yet supported in Leo.
|
||||
|
||||
## Language Features
|
||||
- `circuit` declarations
|
||||
- conditional statements
|
||||
- early termination. Leo allows users to return from a function early using the `return` keyword.
|
||||
|
||||
## Running the Program
|
||||
|
||||
Leo provides users with a command line interface for compiling and running Leo programs.
|
||||
Users may either specify input values via the command line or provide an input file in `inputs/`.
|
||||
|
||||
### Providing inputs via the command line.
|
||||
1. Run
|
||||
```bash
|
||||
aleo build
|
||||
leo run <function_name> <input_1> <input_2> ...
|
||||
```
|
||||
See `./run.sh` for an example.
|
||||
|
||||
|
||||
### Using an input file.
|
||||
1. Modify `inputs/tictactoe.in` with the desired inputs.
|
||||
2. Run
|
||||
```bash
|
||||
leo run <function_name>
|
||||
```
|
||||
|
@ -1,5 +1,11 @@
|
||||
// The `new` function does not take any inputs.
|
||||
[new]
|
||||
|
||||
// Inputs for the `make_move` function.
|
||||
// - `player` : A u8 representing the player making the move. 1 for player 1, 2 for player 2.
|
||||
// - `row` : A u8 representing the row to make the move in.
|
||||
// - `column` : A u8 representing the column to make the move in.
|
||||
// - `board` : A representation of the board state.
|
||||
[make_move]
|
||||
player: u8 = 1u8;
|
||||
row: u8 = 1u8;
|
||||
|
@ -1,15 +1,26 @@
|
||||
// A row in a tic tac toe board.
|
||||
// - `c1` : The first entry in the row.
|
||||
// - `c2` : The second entry in the row.
|
||||
// - `c3` : The third entry in the row.
|
||||
// A valid entry is either 0, 1, or 2, where 0 is empty, 1 corresponds to player 1, and 2 corresponds to player 2.
|
||||
// Any other values are invalid.
|
||||
circuit Row {
|
||||
c1: u8,
|
||||
c2: u8,
|
||||
c3: u8
|
||||
}
|
||||
|
||||
// A tic tac toe board.
|
||||
// - `r1` : The first row in the board.
|
||||
// - `r2` : The second row in the board.
|
||||
// - `r3` : The third row in the board.
|
||||
circuit Board {
|
||||
r1: Row,
|
||||
r2: Row,
|
||||
r3: Row,
|
||||
}
|
||||
|
||||
// Returns an empty board.
|
||||
@program
|
||||
function new() -> Board {
|
||||
return Board {
|
||||
@ -19,6 +30,9 @@ function new() -> Board {
|
||||
};
|
||||
}
|
||||
|
||||
// Returns `true` if there exists a row, column, or diagonal with all entries occupied by the same player.
|
||||
// - `b` : A tic tac toe board.
|
||||
// - `p` : A number corresponding to a player.
|
||||
function check_for_win(b: Board, p: u8) -> bool {
|
||||
return
|
||||
(b.r1.c1 == p && b.r1.c2 == p && b.r1.c3 == p) || // row 1
|
||||
@ -31,12 +45,23 @@ function check_for_win(b: Board, p: u8) -> bool {
|
||||
(b.r1.c3 == p && b.r2.c2 == p && b.r3.c1 == p); // other diagonal
|
||||
}
|
||||
|
||||
// Returns an updated tic tac toe board with a move made by a player.
|
||||
// Returns a `u8` corresponding to the player who won the game, or 0 if no one has won yet.
|
||||
// - `player` : A number corresponding to a player.
|
||||
// - `row` : The row of the move.
|
||||
// - `col` : The column of the move.
|
||||
// - `board` : A tic tac toe board.
|
||||
// Assumes that `player` is either 1 or 2.
|
||||
// Assumes that `row` and `col` are valid indices into the board.
|
||||
// If an entry is already occupied, the move is invalid and the board is returned unchanged.
|
||||
@program
|
||||
function make_move(player: u8, row: u8, col: u8, board: Board) -> (Board, u8) {
|
||||
console.assert(player == 1u8 || player == 2u8); // 1 for X, 2 for O
|
||||
// Check that inputs are valid.
|
||||
console.assert(player == 1u8 || player == 2u8);
|
||||
console.assert(1u8 <= row && row <= 3u8);
|
||||
console.assert(1u8 <= col && col <= 3u8);
|
||||
|
||||
// Unpack the entries in the board into variables.
|
||||
let r1c1: u8 = board.r1.c1;
|
||||
let r1c2: u8 = board.r1.c2;
|
||||
let r1c3: u8 = board.r1.c3;
|
||||
@ -47,6 +72,7 @@ function make_move(player: u8, row: u8, col: u8, board: Board) -> (Board, u8) {
|
||||
let r3c2: u8 = board.r3.c2;
|
||||
let r3c3: u8 = board.r3.c3;
|
||||
|
||||
// Update the appropriate entry with the given move.
|
||||
if row == 1u8 && col == 1u8 && r1c1 == 0u8 {
|
||||
r1c1 = player;
|
||||
} else if row == 1u8 && col == 2u8 && r1c2 == 0u8 {
|
||||
@ -67,12 +93,14 @@ function make_move(player: u8, row: u8, col: u8, board: Board) -> (Board, u8) {
|
||||
r3c3 = player;
|
||||
}
|
||||
|
||||
// Construct the updated game board.
|
||||
let updated: Board = Board {
|
||||
r1: Row { c1: r1c1, c2: r1c2, c3: r1c3 },
|
||||
r2: Row { c1: r2c1, c2: r2c2, c3: r2c3 },
|
||||
r3: Row { c1: r3c1, c2: r2c2, c3: r2c3 },
|
||||
};
|
||||
|
||||
// Check if the game is over.
|
||||
if check_for_win(updated, 1u8) {
|
||||
return (updated, 1u8);
|
||||
} else if check_for_win(updated, 2u8) {
|
||||
|
Loading…
Reference in New Issue
Block a user