2022-10-06 01:27:54 +03:00
|
|
|
program board.aleo {
|
|
|
|
// Battleship boards are represented by 8x8 squares.
|
|
|
|
// A u64 is all that is required to represent a hit or a miss on a single board.
|
|
|
|
// Starting from the top row, left to right, a hit is 1 and a miss is 0.
|
|
|
|
// A first move resulting in a hit in row 1, column 3 would be:
|
|
|
|
// 00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
|
|
// A second u64 is needed to represent which squares have been played, with 1s being played squares and 0s being
|
|
|
|
// unplayed squares.
|
|
|
|
record board_state {
|
|
|
|
owner: address,
|
|
|
|
// The hits and misses registered on the opponent's board.
|
|
|
|
hits_and_misses: u64,
|
|
|
|
// The squares that have been played on the opponent's board.
|
|
|
|
played_tiles: u64,
|
|
|
|
// The ship bitstring representing all ship positions on your own board
|
|
|
|
ships: u64,
|
|
|
|
player_1: address,
|
|
|
|
player_2: address,
|
|
|
|
game_started: bool,
|
|
|
|
}
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
// Returns a new board_state.
|
|
|
|
transition new_board_state(
|
|
|
|
ships: u64,
|
|
|
|
opponent: address,
|
|
|
|
) -> board_state {
|
|
|
|
return board_state {
|
|
|
|
owner: self.caller,
|
|
|
|
hits_and_misses: 0u64,
|
|
|
|
played_tiles: 0u64,
|
|
|
|
ships,
|
|
|
|
player_1: self.caller,
|
|
|
|
player_2: opponent,
|
|
|
|
game_started: false,
|
|
|
|
};
|
|
|
|
}
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
// Returns a new board state that has been started.
|
|
|
|
// Fails if this board has been started before.
|
|
|
|
transition start_board(
|
|
|
|
// The record of the board to start. A board can only be started once.
|
|
|
|
board: board_state,
|
|
|
|
) -> board_state {
|
|
|
|
// Ensure this board hasn't been used to start a game before.
|
2022-12-07 08:56:48 +03:00
|
|
|
assert(!board.game_started);
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
return board_state {
|
|
|
|
owner: board.owner,
|
|
|
|
hits_and_misses: board.hits_and_misses,
|
|
|
|
played_tiles: board.played_tiles,
|
|
|
|
ships: board.ships,
|
|
|
|
player_1: board.player_1,
|
|
|
|
player_2: board.player_2,
|
|
|
|
game_started: true,
|
|
|
|
};
|
|
|
|
}
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
// Returns a new board state record that includes all the played tiles.
|
|
|
|
// Fails if r1 has been played before.
|
|
|
|
transition update_played_tiles(
|
|
|
|
// The record of the board to update.
|
|
|
|
board: board_state,
|
|
|
|
// The u64 equivalent of a bitstring fire coordinate to send to the opponent.
|
|
|
|
shoot: u64,
|
|
|
|
) -> board_state {
|
|
|
|
// Need to make sure r1 is a valid move. Only one bit of r1 should be flipped.
|
|
|
|
let flip_bit: u64 = shoot - 1u64;
|
|
|
|
// bitwise and operation
|
|
|
|
let check_move: u64 = shoot & flip_bit;
|
2022-12-07 08:56:48 +03:00
|
|
|
assert_eq(check_move, 0u64);
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
// Need to make sure r1 is a valid move given the played_tiles. no bits should overlap.
|
|
|
|
let check_tiles: u64 = shoot & board.played_tiles;
|
2022-12-07 08:56:48 +03:00
|
|
|
assert_eq(check_tiles, 0u64);
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
// Update played tiles.
|
|
|
|
let played_tiles: u64 = board.played_tiles | shoot;
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
return board_state {
|
|
|
|
owner: board.owner,
|
|
|
|
hits_and_misses: board.hits_and_misses,
|
|
|
|
played_tiles,
|
|
|
|
ships: board.ships,
|
|
|
|
player_1: board.player_1,
|
|
|
|
player_2: board.player_2,
|
|
|
|
game_started: board.game_started,
|
|
|
|
};
|
|
|
|
}
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
// Returns a new board state record that includes all the hits and misses.
|
|
|
|
transition update_hits_and_misses(
|
|
|
|
// The record of the board to update.
|
|
|
|
board: board_state,
|
|
|
|
// The u64 equivalent of a bitstring of whether this player's previous move was a hit or miss.
|
|
|
|
hit_or_miss: u64,
|
|
|
|
) -> board_state {
|
|
|
|
// Update hits and misses.
|
|
|
|
let hits_and_misses: u64 = board.hits_and_misses | hit_or_miss;
|
2022-09-21 03:17:43 +03:00
|
|
|
|
2022-10-06 01:27:54 +03:00
|
|
|
return board_state {
|
|
|
|
owner: board.owner,
|
|
|
|
hits_and_misses,
|
|
|
|
played_tiles: board.played_tiles,
|
|
|
|
ships: board.ships,
|
|
|
|
player_1: board.player_1,
|
|
|
|
player_2: board.player_2,
|
|
|
|
game_started: board.game_started,
|
|
|
|
};
|
|
|
|
}
|
2022-09-21 03:17:43 +03:00
|
|
|
}
|