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 }