/ tests / tests / compiler / examples / board.adl
board.adl
  1  
  2  program test.alpha {
  3      // Battleship boards are represented by 8x8 squares.
  4      // A u64 is all that is required to represent a hit or a miss on a single board.
  5      // Starting from the top row, left to right, a hit is 1 and a miss is 0.
  6      // A first move resulting in a hit in row 1, column 3 would be:
  7      // 00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  8      // A second u64 is needed to represent which squares have been played, with 1s being played squares and 0s being
  9      // unplayed squares.
 10      record board_state {
 11          owner: address,
 12          // The hits and misses registered on the opponent's board.
 13          hits_and_misses: u64,
 14          // The squares that have been played on the opponent's board.
 15          played_tiles: u64,
 16          // The ship bitstring representing all ship positions on your own board
 17          ships: u64,
 18          player_1: address,
 19          player_2: address,
 20          game_started: bool,
 21      }
 22  
 23      // Returns a new board_state.
 24      transition new_board_state(
 25          ships: u64,
 26          opponent: address,
 27      ) -> board_state {
 28          return board_state {
 29              owner: self.signer,
 30              hits_and_misses: 0u64,
 31              played_tiles: 0u64,
 32              ships,
 33              player_1: self.caller,
 34              player_2: opponent,
 35              game_started: false,
 36          };
 37      }
 38  
 39      // Returns a new board state that has been started.
 40      // Fails if this board has been started before.
 41      transition start_board(
 42          // The record of the board to start. A board can only be started once.
 43          board: board_state,
 44      ) -> board_state {
 45          // Ensure this board hasn't been used to start a game before.
 46          assert(!board.game_started);
 47  
 48          return board_state {
 49              owner: board.owner,
 50              hits_and_misses: board.hits_and_misses,
 51              played_tiles: board.played_tiles,
 52              ships: board.ships,
 53              player_1: board.player_1,
 54              player_2: board.player_2,
 55              game_started: true,
 56          };
 57      }
 58  
 59      // Returns a new board state record that includes all the played tiles.
 60      // Fails if r1 has been played before.
 61      transition update_played_tiles(
 62          // The record of the board to update.
 63          board: board_state,
 64          // The u64 equivalent of a bitstring fire coordinate to send to the opponent.
 65          shoot: u64,
 66      ) -> board_state {
 67          // Need to make sure r1 is a valid move. Only one bit of r1 should be flipped.
 68          let flip_bit: u64 = shoot - 1u64;
 69          // bitwise and operation
 70          let check_move: u64 = shoot & flip_bit;
 71          assert_eq(check_move, 0u64);
 72  
 73          // Need to make sure r1 is a valid move given the played_tiles. no bits should overlap.
 74          let check_tiles: u64 = shoot & board.played_tiles;
 75          assert_eq(check_tiles, 0u64);
 76  
 77          // Update played tiles.
 78          let played_tiles: u64 = board.played_tiles | shoot;
 79  
 80          return board_state {
 81              owner: board.owner,
 82              hits_and_misses: board.hits_and_misses,
 83              played_tiles,
 84              ships: board.ships,
 85              player_1: board.player_1,
 86              player_2: board.player_2,
 87              game_started: board.game_started,
 88          };
 89      }
 90  
 91      // Returns a new board state record that includes all the hits and misses.
 92      transition update_hits_and_misses(
 93          // The record of the board to update.
 94          board: board_state,
 95          // The u64 equivalent of a bitstring of whether this player's previous move was a hit or miss.
 96          hit_or_miss: u64,
 97      ) -> board_state {
 98          // Update hits and misses.
 99          let hits_and_misses: u64 = board.hits_and_misses | hit_or_miss;
100  
101          return board_state {
102              owner: board.owner,
103              hits_and_misses,
104              played_tiles: board.played_tiles,
105              ships: board.ships,
106              player_1: board.player_1,
107              player_2: board.player_2,
108              game_started: board.game_started,
109          };
110      }
111  }