mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 10:41:57 +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
|
```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]
|
[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]
|
[make_move]
|
||||||
player: u8 = 1u8;
|
player: u8 = 1u8;
|
||||||
row: 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 {
|
circuit Row {
|
||||||
c1: u8,
|
c1: u8,
|
||||||
c2: u8,
|
c2: u8,
|
||||||
c3: 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 {
|
circuit Board {
|
||||||
r1: Row,
|
r1: Row,
|
||||||
r2: Row,
|
r2: Row,
|
||||||
r3: Row,
|
r3: Row,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns an empty board.
|
||||||
@program
|
@program
|
||||||
function new() -> Board {
|
function new() -> Board {
|
||||||
return 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 {
|
function check_for_win(b: Board, p: u8) -> bool {
|
||||||
return
|
return
|
||||||
(b.r1.c1 == p && b.r1.c2 == p && b.r1.c3 == p) || // row 1
|
(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
|
(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
|
@program
|
||||||
function make_move(player: u8, row: u8, col: u8, board: Board) -> (Board, u8) {
|
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 <= row && row <= 3u8);
|
||||||
console.assert(1u8 <= col && col <= 3u8);
|
console.assert(1u8 <= col && col <= 3u8);
|
||||||
|
|
||||||
|
// Unpack the entries in the board into variables.
|
||||||
let r1c1: u8 = board.r1.c1;
|
let r1c1: u8 = board.r1.c1;
|
||||||
let r1c2: u8 = board.r1.c2;
|
let r1c2: u8 = board.r1.c2;
|
||||||
let r1c3: u8 = board.r1.c3;
|
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 r3c2: u8 = board.r3.c2;
|
||||||
let r3c3: u8 = board.r3.c3;
|
let r3c3: u8 = board.r3.c3;
|
||||||
|
|
||||||
|
// Update the appropriate entry with the given move.
|
||||||
if row == 1u8 && col == 1u8 && r1c1 == 0u8 {
|
if row == 1u8 && col == 1u8 && r1c1 == 0u8 {
|
||||||
r1c1 = player;
|
r1c1 = player;
|
||||||
} else if row == 1u8 && col == 2u8 && r1c2 == 0u8 {
|
} 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;
|
r3c3 = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Construct the updated game board.
|
||||||
let updated: Board = Board {
|
let updated: Board = Board {
|
||||||
r1: Row { c1: r1c1, c2: r1c2, c3: r1c3 },
|
r1: Row { c1: r1c1, c2: r1c2, c3: r1c3 },
|
||||||
r2: Row { c1: r2c1, c2: r2c2, c3: r2c3 },
|
r2: Row { c1: r2c1, c2: r2c2, c3: r2c3 },
|
||||||
r3: Row { c1: r3c1, c2: r2c2, c3: r2c3 },
|
r3: Row { c1: r3c1, c2: r2c2, c3: r2c3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if the game is over.
|
||||||
if check_for_win(updated, 1u8) {
|
if check_for_win(updated, 1u8) {
|
||||||
return (updated, 1u8);
|
return (updated, 1u8);
|
||||||
} else if check_for_win(updated, 2u8) {
|
} else if check_for_win(updated, 2u8) {
|
||||||
|
Loading…
Reference in New Issue
Block a user