mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-10 10:05:56 +03:00
Some bug fixes; update some examples
This commit is contained in:
parent
e15e8f05d6
commit
8283c922f6
@ -51,8 +51,6 @@ pub struct Compiler<'a> {
|
||||
pub input_ast: Option<InputAst>,
|
||||
/// Compiler options on some optional output files.
|
||||
output_options: OutputOptions,
|
||||
/// Whether or not we are compiling an imported program.
|
||||
is_import: bool,
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
@ -64,7 +62,6 @@ impl<'a> Compiler<'a> {
|
||||
main_file_path: PathBuf,
|
||||
output_directory: PathBuf,
|
||||
output_options: Option<OutputOptions>,
|
||||
is_import: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
handler,
|
||||
@ -75,7 +72,6 @@ impl<'a> Compiler<'a> {
|
||||
ast: Ast::new(Program::default()),
|
||||
input_ast: None,
|
||||
output_options: output_options.unwrap_or_default(),
|
||||
is_import,
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,8 +103,8 @@ impl<'a> Compiler<'a> {
|
||||
let program_scope = self.ast.ast.program_scopes.values().next().unwrap();
|
||||
let program_scope_name =
|
||||
with_session_globals(|s| program_scope.name.name.as_str(s, |string| string.to_string()));
|
||||
if self.is_import && program_scope_name != self.program_name {
|
||||
return Err(CompilerError::imported_program_name_does_not_match_filename(
|
||||
if program_scope_name != self.program_name {
|
||||
return Err(CompilerError::program_scope_name_does_not_match(
|
||||
program_scope_name,
|
||||
self.program_name.clone(),
|
||||
program_scope.name.span,
|
||||
|
@ -60,7 +60,6 @@ fn new_compiler(handler: &Handler, main_file_path: PathBuf) -> Compiler<'_> {
|
||||
ssa_ast: true,
|
||||
flattened_ast: true,
|
||||
}),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,9 @@ create_messages!(
|
||||
}
|
||||
|
||||
@formatted
|
||||
imported_program_name_does_not_match_filename {
|
||||
program_scope_name_does_not_match {
|
||||
args: (program_scope_name: impl Display, file_name: impl Display),
|
||||
msg: format!("The program scope `{program_scope_name}` does not match its filename `{file_name}`."),
|
||||
msg: format!("The program scope name `{program_scope_name}` must match `{file_name}`."),
|
||||
help: None,
|
||||
}
|
||||
);
|
||||
|
@ -1,67 +1,70 @@
|
||||
// A bid in an auction.
|
||||
// - `owner` : The address of the account that owns the record associated with this bid.
|
||||
// This is separate from the address of the account that placed the bid.
|
||||
// - `gates` : The value associated with the record (always zero).
|
||||
// - `bidder` : The address of the account that placed the bid.
|
||||
// - `amount` : The amount of the bid.
|
||||
// - `is_winner` : Whether the bid is the winning bid.
|
||||
record Bid {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
bidder: address,
|
||||
amount: u64,
|
||||
is_winner: bool,
|
||||
}
|
||||
program auction.aleo {
|
||||
// A bid in an auction.
|
||||
// - `owner` : The address of the account that owns the record associated with this bid.
|
||||
// This is separate from the address of the account that placed the bid.
|
||||
// - `gates` : The value associated with the record (always zero).
|
||||
// - `bidder` : The address of the account that placed the bid.
|
||||
// - `amount` : The amount of the bid.
|
||||
// - `is_winner` : Whether the bid is the winning bid.
|
||||
record Bid {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
bidder: address,
|
||||
amount: u64,
|
||||
is_winner: bool,
|
||||
}
|
||||
|
||||
// Returns a new bid.
|
||||
// - `bidder` : The address of the account that placed the bid.
|
||||
// - `amount` : The amount of the bid.
|
||||
// Requires that `bidder` matches the function caller.
|
||||
// The owner of the record is set to the entity responsible for running the auction (auction runner).
|
||||
// The address of the auction runner is aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh.
|
||||
transition place_bid(bidder: address, amount: u64) -> Bid {
|
||||
// Ensure the caller is the auction bidder.
|
||||
console.assert_eq(self.caller, bidder);
|
||||
// Return a new 'Bid' record for the auction bidder.
|
||||
return Bid {
|
||||
owner: aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh,
|
||||
gates: 0u64,
|
||||
bidder: bidder,
|
||||
amount: amount,
|
||||
is_winner: false,
|
||||
};
|
||||
}
|
||||
// Returns a new bid.
|
||||
// - `bidder` : The address of the account that placed the bid.
|
||||
// - `amount` : The amount of the bid.
|
||||
// Requires that `bidder` matches the function caller.
|
||||
// The owner of the record is set to the entity responsible for running the auction (auction runner).
|
||||
// The address of the auction runner is aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh.
|
||||
transition place_bid(bidder: address, amount: u64) -> Bid {
|
||||
// Ensure the caller is the auction bidder.
|
||||
console.assert_eq(self.caller, bidder);
|
||||
// Return a new 'Bid' record for the auction bidder.
|
||||
return Bid {
|
||||
owner: aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh,
|
||||
gates: 0u64,
|
||||
bidder: bidder,
|
||||
amount: amount,
|
||||
is_winner: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the winning bid.
|
||||
// - `first` : The first bid.
|
||||
// - `second` : The second bid.
|
||||
// Requires that the function caller is the auction runner.
|
||||
// Assumes that the function is invoked only after the bidding period has ended.
|
||||
// In the event of a tie, the first bid is selected.
|
||||
transition resolve(first: Bid, second: Bid) -> Bid {
|
||||
// Ensure the caller is the auctioneer.
|
||||
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
|
||||
// Resolve the winner of the auction.
|
||||
if (first.amount >= second.amount) {
|
||||
return first;
|
||||
} else {
|
||||
return second;
|
||||
// Returns the winning bid.
|
||||
// - `first` : The first bid.
|
||||
// - `second` : The second bid.
|
||||
// Requires that the function caller is the auction runner.
|
||||
// Assumes that the function is invoked only after the bidding period has ended.
|
||||
// In the event of a tie, the first bid is selected.
|
||||
transition resolve(first: Bid, second: Bid) -> Bid {
|
||||
// Ensure the caller is the auctioneer.
|
||||
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
|
||||
// Resolve the winner of the auction.
|
||||
if (first.amount >= second.amount) {
|
||||
return first;
|
||||
} else {
|
||||
return second;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns ownership of the bid to bidder.
|
||||
// - `bid` : The winning bid.
|
||||
// Requires that the function caller is the auction runner.
|
||||
// Assumes that the function is invoked only after all bids have been resolved.
|
||||
transition finish(bid: Bid) -> Bid {
|
||||
// Ensure the caller is the auctioneer.
|
||||
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
|
||||
// Return 'is_winner' as 'true' in the winning 'Bid'.
|
||||
return Bid {
|
||||
owner: bid.bidder,
|
||||
gates: bid.gates,
|
||||
bidder: bid.bidder,
|
||||
amount: bid.amount,
|
||||
is_winner: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Returns ownership of the bid to bidder.
|
||||
// - `bid` : The winning bid.
|
||||
// Requires that the function caller is the auction runner.
|
||||
// Assumes that the function is invoked only after all bids have been resolved.
|
||||
transition finish(bid: Bid) -> Bid {
|
||||
// Ensure the caller is the auctioneer.
|
||||
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
|
||||
// Return 'is_winner' as 'true' in the winning 'Bid'.
|
||||
return Bid {
|
||||
owner: bid.bidder,
|
||||
gates: bid.gates,
|
||||
bidder: bid.bidder,
|
||||
amount: bid.amount,
|
||||
is_winner: true,
|
||||
};
|
||||
}
|
||||
|
@ -1,104 +1,103 @@
|
||||
// A token, issued by a bank.
|
||||
// - 'owner' : The address of the account that owns the record associated with this token.
|
||||
// - 'gates' : The value associated with the record (always zero).
|
||||
// - 'amount' : The amount of tokens owned by the account.
|
||||
record Token {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
amount: u64,
|
||||
}
|
||||
|
||||
// An on-chain mapping, storing the amount of tokens owned by each account
|
||||
// The account is stored as a to preserve user privacy.
|
||||
mapping balances: field => u64;
|
||||
|
||||
// Returns a new Token.
|
||||
// - `owner` : The address of the account to issue the token to.
|
||||
// - `amount`: The amount of tokens to issue.
|
||||
// Requires that the function caller is the bank.
|
||||
// The bank's address is aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a.
|
||||
transition issue(owner: address, amount: u64) -> Token {
|
||||
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
|
||||
return Token {
|
||||
owner: owner,
|
||||
gates: 0u64,
|
||||
amount: amount,
|
||||
};
|
||||
}
|
||||
|
||||
// Deposits some amount of money into the bank.
|
||||
// Returns a new Token with the remaining amount of money.
|
||||
// - `token` : A record containing tokens to deposit.
|
||||
// - `amount`: The amount of tokens to deposit.
|
||||
transition deposit(token: Token, amount: u64) -> Token {
|
||||
let difference: u64 = token.amount - amount;
|
||||
|
||||
let remaining: Token = Token {
|
||||
owner: token.owner,
|
||||
gates: token.gates,
|
||||
amount: difference,
|
||||
};
|
||||
|
||||
// Compute the hash of the token owner.
|
||||
let hash: field = BHP256::hash(token.owner);
|
||||
|
||||
async finalize(hash, amount);
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
// Updates on-chain state by the amount of tokens deposited.
|
||||
// - `hash` : The hash of the token owner.
|
||||
// - `amount`: The amount of tokens that were deposited.
|
||||
finalize deposit(hash: field, amount: u64) {
|
||||
increment(balances, hash, amount);
|
||||
}
|
||||
|
||||
// Returns a new Token containing the amount of money withdrawn.
|
||||
// - `recipient`: The address of the account to withdraw the tokens to.
|
||||
// - `amount` : The amount of tokens to withdraw.
|
||||
// - `rate` : The compound interest rate.
|
||||
// - `periods` : The number of periods to compound the interest over.
|
||||
// Requires that the function caller is the bank.
|
||||
transition withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> Token {
|
||||
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
|
||||
let hash: field = BHP256::hash(recipient);
|
||||
|
||||
let total: u64 = calculate_interest(amount, rate, periods);
|
||||
|
||||
let token: Token = Token {
|
||||
owner: recipient,
|
||||
gates: 0u64,
|
||||
amount: total,
|
||||
};
|
||||
|
||||
async finalize(hash, amount);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
// Updates on-chain state by the amount of tokens withdrawn.
|
||||
// - `hash` : The hash of the token owner.
|
||||
// - `amount`: The amount of tokens that were withdrawn.
|
||||
finalize withdraw(hash: field, amount: u64) {
|
||||
decrement(balances, hash, amount);
|
||||
}
|
||||
|
||||
// Returns the total amount of tokens after compounding interest.
|
||||
// - `principal`: The amount of tokens to compound interest over.
|
||||
// - `rate` : The compound interest rate.
|
||||
// - `periods` : The number of periods to compound the interest over.
|
||||
function calculate_interest(principal: u64, rate: u64, periods: u64) -> u64 {
|
||||
let amount: u64 = principal;
|
||||
|
||||
for i:u64 in 0u64..100u64 {
|
||||
if i < periods {
|
||||
amount += (amount * rate) / 10000u64;
|
||||
}
|
||||
program basic_bank.aleo {
|
||||
// A token, issued by a bank.
|
||||
// - 'owner' : The address of the account that owns the record associated with this token.
|
||||
// - 'gates' : The value associated with the record (always zero).
|
||||
// - 'amount' : The amount of tokens owned by the account.
|
||||
record Token {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
amount: u64,
|
||||
}
|
||||
|
||||
return amount;
|
||||
// An on-chain mapping, storing the amount of tokens owned by each account
|
||||
// The account is stored as a to preserve user privacy.
|
||||
mapping balances: field => u64;
|
||||
|
||||
// Returns a new Token.
|
||||
// - `owner` : The address of the account to issue the token to.
|
||||
// - `amount`: The amount of tokens to issue.
|
||||
// Requires that the function caller is the bank.
|
||||
// The bank's address is aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a.
|
||||
transition issue(owner: address, amount: u64) -> Token {
|
||||
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
|
||||
return Token {
|
||||
owner: owner,
|
||||
gates: 0u64,
|
||||
amount: amount,
|
||||
};
|
||||
}
|
||||
|
||||
// Deposits some amount of money into the bank.
|
||||
// Returns a new Token with the remaining amount of money.
|
||||
// - `token` : A record containing tokens to deposit.
|
||||
// - `amount`: The amount of tokens to deposit.
|
||||
transition deposit(token: Token, amount: u64) -> Token {
|
||||
let difference: u64 = token.amount - amount;
|
||||
|
||||
let remaining: Token = Token {
|
||||
owner: token.owner,
|
||||
gates: token.gates,
|
||||
amount: difference,
|
||||
};
|
||||
|
||||
// Compute the hash of the token owner.
|
||||
let hash: field = BHP256::hash(token.owner);
|
||||
|
||||
async finalize(hash, amount);
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
// Updates on-chain state by the amount of tokens deposited.
|
||||
// - `hash` : The hash of the token owner.
|
||||
// - `amount`: The amount of tokens that were deposited.
|
||||
finalize deposit(hash: field, amount: u64) {
|
||||
increment(balances, hash, amount);
|
||||
}
|
||||
|
||||
// Returns a new Token containing the amount of money withdrawn.
|
||||
// - `recipient`: The address of the account to withdraw the tokens to.
|
||||
// - `amount` : The amount of tokens to withdraw.
|
||||
// - `rate` : The compound interest rate.
|
||||
// - `periods` : The number of periods to compound the interest over.
|
||||
// Requires that the function caller is the bank.
|
||||
transition withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> Token {
|
||||
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
|
||||
let hash: field = BHP256::hash(recipient);
|
||||
|
||||
let total: u64 = calculate_interest(amount, rate, periods);
|
||||
|
||||
let token: Token = Token {
|
||||
owner: recipient,
|
||||
gates: 0u64,
|
||||
amount: total,
|
||||
};
|
||||
|
||||
async finalize(hash, amount);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
// Updates on-chain state by the amount of tokens withdrawn.
|
||||
// - `hash` : The hash of the token owner.
|
||||
// - `amount`: The amount of tokens that were withdrawn.
|
||||
finalize withdraw(hash: field, amount: u64) {
|
||||
decrement(balances, hash, amount);
|
||||
}
|
||||
|
||||
// Returns the total amount of tokens after compounding interest.
|
||||
// - `principal`: The amount of tokens to compound interest over.
|
||||
// - `rate` : The compound interest rate.
|
||||
// - `periods` : The number of periods to compound the interest over.
|
||||
function calculate_interest(principal: u64, rate: u64, periods: u64) -> u64 {
|
||||
let amount: u64 = principal;
|
||||
|
||||
for i:u64 in 0u64..100u64 {
|
||||
if i < periods {
|
||||
amount += (amount * rate) / 10000u64;
|
||||
}
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,113 +1,115 @@
|
||||
// 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,
|
||||
gates: u64,
|
||||
// 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,
|
||||
}
|
||||
|
||||
// Returns a new board_state.
|
||||
transition new_board_state(
|
||||
ships: u64,
|
||||
opponent: address,
|
||||
) -> board_state {
|
||||
return board_state {
|
||||
owner: self.caller,
|
||||
gates: 0u64,
|
||||
hits_and_misses: 0u64,
|
||||
played_tiles: 0u64,
|
||||
ships,
|
||||
player_1: self.caller,
|
||||
player_2: opponent,
|
||||
game_started: false,
|
||||
};
|
||||
}
|
||||
|
||||
// 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.
|
||||
console.assert(!board.game_started);
|
||||
|
||||
return board_state {
|
||||
owner: board.owner,
|
||||
gates: board.gates,
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
// 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;
|
||||
console.assert_eq(check_move, 0u64);
|
||||
|
||||
// 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;
|
||||
console.assert_eq(check_tiles, 0u64);
|
||||
|
||||
// Update played tiles.
|
||||
let played_tiles: u64 = board.played_tiles | shoot;
|
||||
|
||||
return board_state {
|
||||
owner: board.owner,
|
||||
gates: board.gates,
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
return board_state {
|
||||
owner: board.owner,
|
||||
gates: board.gates,
|
||||
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,
|
||||
};
|
||||
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,
|
||||
gates: u64,
|
||||
// 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,
|
||||
}
|
||||
|
||||
// Returns a new board_state.
|
||||
transition new_board_state(
|
||||
ships: u64,
|
||||
opponent: address,
|
||||
) -> board_state {
|
||||
return board_state {
|
||||
owner: self.caller,
|
||||
gates: 0u64,
|
||||
hits_and_misses: 0u64,
|
||||
played_tiles: 0u64,
|
||||
ships,
|
||||
player_1: self.caller,
|
||||
player_2: opponent,
|
||||
game_started: false,
|
||||
};
|
||||
}
|
||||
|
||||
// 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.
|
||||
console.assert(!board.game_started);
|
||||
|
||||
return board_state {
|
||||
owner: board.owner,
|
||||
gates: board.gates,
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
// 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;
|
||||
console.assert_eq(check_move, 0u64);
|
||||
|
||||
// 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;
|
||||
console.assert_eq(check_tiles, 0u64);
|
||||
|
||||
// Update played tiles.
|
||||
let played_tiles: u64 = board.played_tiles | shoot;
|
||||
|
||||
return board_state {
|
||||
owner: board.owner,
|
||||
gates: board.gates,
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
return board_state {
|
||||
owner: board.owner,
|
||||
gates: board.gates,
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1,49 @@
|
||||
record move {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
incoming_fire_coordinate: u64,
|
||||
player_1: address,
|
||||
player_2: address,
|
||||
// One flipped bit indicates a hit. No flipped bits indicates a miss.
|
||||
prev_hit_or_miss: u64,
|
||||
program move.aleo {
|
||||
record move {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
incoming_fire_coordinate: u64,
|
||||
player_1: address,
|
||||
player_2: address,
|
||||
// One flipped bit indicates a hit. No flipped bits indicates a miss.
|
||||
prev_hit_or_miss: u64,
|
||||
}
|
||||
|
||||
// Returns new move record owned by the opponent.
|
||||
transition create_move(
|
||||
// The move record created by the opponent.
|
||||
move_record: move,
|
||||
// The u64 representation of incoming_fire_coordinate, the bitstring fire coordinate to send to the opponent.
|
||||
incoming_fire_coordinate: u64,
|
||||
// The u64 representation of prev_hit_or_miss, this player's previous fire coordinate as a hit or miss.
|
||||
prev_hit_or_miss: u64,
|
||||
) -> move {
|
||||
// A new move record should be created and owned by the opponent.
|
||||
let one_is_owner: bool = move_record.player_1 == move_record.owner;
|
||||
let opponent: address = one_is_owner ? move_record.player_2 : move_record.player_1;
|
||||
|
||||
return move {
|
||||
owner: opponent,
|
||||
gates: move_record.gates,
|
||||
incoming_fire_coordinate,
|
||||
player_1: move_record.player_2,
|
||||
player_2: move_record.player_1,
|
||||
prev_hit_or_miss,
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the move record owned by the opponent.
|
||||
// Note, this move record contains dummy fire coordinates and previous hit or miss.
|
||||
transition start_game(player_2: address) -> move {
|
||||
return move {
|
||||
owner: player_2,
|
||||
gates: 0u64,
|
||||
incoming_fire_coordinate: 0u64,
|
||||
player_1: self.caller,
|
||||
player_2: player_2,
|
||||
prev_hit_or_miss: 0u64,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Returns new move record owned by the opponent.
|
||||
transition create_move(
|
||||
// The move record created by the opponent.
|
||||
move_record: move,
|
||||
// The u64 representation of incoming_fire_coordinate, the bitstring fire coordinate to send to the opponent.
|
||||
incoming_fire_coordinate: u64,
|
||||
// The u64 representation of prev_hit_or_miss, this player's previous fire coordinate as a hit or miss.
|
||||
prev_hit_or_miss: u64,
|
||||
) -> move {
|
||||
// A new move record should be created and owned by the opponent.
|
||||
let one_is_owner: bool = move_record.player_1 == move_record.owner;
|
||||
let opponent: address = one_is_owner ? move_record.player_2 : move_record.player_1;
|
||||
|
||||
return move {
|
||||
owner: opponent,
|
||||
gates: move_record.gates,
|
||||
incoming_fire_coordinate,
|
||||
player_1: move_record.player_2,
|
||||
player_2: move_record.player_1,
|
||||
prev_hit_or_miss,
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the move record owned by the opponent.
|
||||
// Note, this move record contains dummy fire coordinates and previous hit or miss.
|
||||
transition start_game(player_2: address) -> move {
|
||||
return move {
|
||||
owner: player_2,
|
||||
gates: 0u64,
|
||||
incoming_fire_coordinate: 0u64,
|
||||
player_1: self.caller,
|
||||
player_2: player_2,
|
||||
prev_hit_or_miss: 0u64,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,123 +1,125 @@
|
||||
// Returns the number of flipped bits.
|
||||
// E.g. 17870283321406128128u64, in binary 11111000 00000000 00000000 00000000 00000000 00000000 00000000 00000000,
|
||||
// returns 5u64;
|
||||
function bitcount(bits: u64) -> u64 {
|
||||
let r1: u64 = bits / 2u64;
|
||||
let r2: u64 = bits / 4u64;
|
||||
let r3: u64 = bits / 8u64;
|
||||
program verify.aleo {
|
||||
// Returns the number of flipped bits.
|
||||
// E.g. 17870283321406128128u64, in binary 11111000 00000000 00000000 00000000 00000000 00000000 00000000 00000000,
|
||||
// returns 5u64;
|
||||
function bitcount(bits: u64) -> u64 {
|
||||
let r1: u64 = bits / 2u64;
|
||||
let r2: u64 = bits / 4u64;
|
||||
let r3: u64 = bits / 8u64;
|
||||
|
||||
let r4: u64 = r1 & 8608480567731124087u64;
|
||||
let r5: u64 = r2 & 3689348814741910323u64;
|
||||
let r6: u64 = r3 & 1229782938247303441u64;
|
||||
let r4: u64 = r1 & 8608480567731124087u64;
|
||||
let r5: u64 = r2 & 3689348814741910323u64;
|
||||
let r6: u64 = r3 & 1229782938247303441u64;
|
||||
|
||||
let r7: u64 = bits - r4 - r5 - r6;
|
||||
let r7: u64 = bits - r4 - r5 - r6;
|
||||
|
||||
let r8: u64 = r7 / 16u64;
|
||||
let r9: u64 = r7 + r8;
|
||||
let r10: u64 = r9 & 1085102592571150095u64;
|
||||
let r11: u64 = r10 % 255u64;
|
||||
let r8: u64 = r7 / 16u64;
|
||||
let r9: u64 = r7 + r8;
|
||||
let r10: u64 = r9 & 1085102592571150095u64;
|
||||
let r11: u64 = r10 % 255u64;
|
||||
|
||||
return r11;
|
||||
}
|
||||
|
||||
// Returns boolean of whether all the flipped bits in location are "adjacent". Horizontally, this means all flipped bits are
|
||||
// directly next to each other (111). Vertically, this means all flipped bits are separated by 7 unflipped bits
|
||||
// (10000000100000001).
|
||||
function adjacency_check(
|
||||
// The u64 representation of a ship's placement in an 8x8 grid.
|
||||
ship: u64,
|
||||
// The u64 representation of a ship's bitstring, either horizontally or vertically.
|
||||
// E.g. a ship of length 3's bit string horizontally would be: 000111 = 7u64. Vertically, the bit string would be:
|
||||
// 10000000100000001 = 65793u64.
|
||||
orientation: u64,
|
||||
) -> bool {
|
||||
// This may result in 0.
|
||||
let division: u64 = ship / orientation;
|
||||
|
||||
// subtracting 1 from 0 will cause an underflow, so we should check for this edge case.
|
||||
let is_eq: bool = division == 0u64;
|
||||
|
||||
// if the above division resulted in 0, we know the adjacency check should return false.
|
||||
// Setting to r4 to 3 (11) will guarantee failure here.
|
||||
let ternary: u64 = is_eq ? 3u64 : division;
|
||||
let subtraction: u64 = ternary - 1u64;
|
||||
let and: u64 = subtraction & ternary;
|
||||
|
||||
let bits_are_adjacent: bool = and == 0u64;
|
||||
|
||||
return bits_are_adjacent;
|
||||
}
|
||||
|
||||
// Returns boolean of whether adjacent flipped bits don't split a row of size 8.
|
||||
// E.g. 111000000 has adjacent flipped bits but splits a row: 00000001 11000000
|
||||
function horizontal_check(
|
||||
// The u64 representation of a ship's placement in an 8x8 grid.
|
||||
ship: u64,
|
||||
// The u64 representation of a ship's bitstring horizontally.
|
||||
horizontal: u64,
|
||||
) -> bool {
|
||||
let remainder: u64 = ship % 255u64;
|
||||
// This may result in 0.
|
||||
let division: u64 = remainder / horizontal;
|
||||
|
||||
// Subtracting 1 from 0 will cause an underflow.
|
||||
let is_eq: bool = division == 0u64;
|
||||
|
||||
// Setting to 3 will guarantee failure.
|
||||
let ternary: u64 = is_eq ? 3u64 : division;
|
||||
let subtraction: u64 = ternary - 1u64;
|
||||
let and: u64 = subtraction & ternary;
|
||||
|
||||
let bits_split_row: bool = and == 0u64;
|
||||
|
||||
return bits_split_row;
|
||||
}
|
||||
|
||||
// Returns `true` if the ship placement is valid.
|
||||
transition validate_ship(
|
||||
// The u64 representation of a ship's placement in an 8x8 grid.
|
||||
ship: u64,
|
||||
// The length of the placed ship.
|
||||
length: u64,
|
||||
// The u64 equivalent of a ship's horizontal bitstring representation.
|
||||
horizontal: u64,
|
||||
// The u64 equivalent of a ship's vertical bitstring representation.
|
||||
vertical: u64,
|
||||
) -> bool {
|
||||
// Check bitcount -- all other validations depend on the bitcount being correct.
|
||||
let num_bits: u64 = bitcount(ship);
|
||||
console.assert_eq(num_bits, length);
|
||||
|
||||
// Check horizontal bits of ship.
|
||||
let is_adjacent: bool = adjacency_check(ship, horizontal); // True if bits are adjacent horizontally.
|
||||
let is_horizontal: bool = horizontal_check(ship, horizontal); // True if those horizontal bits are not split across rows.
|
||||
let valid_horizontal: bool = is_adjacent && is_horizontal; // True if bits are adjacent horizontally and not split across rows.
|
||||
|
||||
// Check vertical bits of ship.
|
||||
let valid_vertical: bool = adjacency_check(ship, vertical); // True if bits are adjacent vertically.
|
||||
|
||||
let ship_is_valid: bool = valid_horizontal || valid_vertical; // Ship is valid if it is vertically or horizontally valid.
|
||||
|
||||
return ship_is_valid;
|
||||
}
|
||||
|
||||
// Returns the u64 representation of all the ships' placements in an 8x8 grid. This function will fail
|
||||
// if any of the ship placements overlap each other.
|
||||
transition create_board(
|
||||
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
|
||||
carrier: u64,
|
||||
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
|
||||
battleship: u64,
|
||||
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
|
||||
cruiser: u64,
|
||||
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
|
||||
destroyer: u64,
|
||||
) -> u64 {
|
||||
// Bitwise combine the ship placements together
|
||||
let ships: u64 = carrier | battleship | cruiser | destroyer;
|
||||
|
||||
let num_bits: u64 = bitcount(ships);
|
||||
console.assert_eq(num_bits, 14u64); // Given 4 individually-valid ships, a valid combination should yield exactly 14 flipped bits.
|
||||
|
||||
return ships;
|
||||
return r11;
|
||||
}
|
||||
|
||||
// Returns boolean of whether all the flipped bits in location are "adjacent". Horizontally, this means all flipped bits are
|
||||
// directly next to each other (111). Vertically, this means all flipped bits are separated by 7 unflipped bits
|
||||
// (10000000100000001).
|
||||
function adjacency_check(
|
||||
// The u64 representation of a ship's placement in an 8x8 grid.
|
||||
ship: u64,
|
||||
// The u64 representation of a ship's bitstring, either horizontally or vertically.
|
||||
// E.g. a ship of length 3's bit string horizontally would be: 000111 = 7u64. Vertically, the bit string would be:
|
||||
// 10000000100000001 = 65793u64.
|
||||
orientation: u64,
|
||||
) -> bool {
|
||||
// This may result in 0.
|
||||
let division: u64 = ship / orientation;
|
||||
|
||||
// subtracting 1 from 0 will cause an underflow, so we should check for this edge case.
|
||||
let is_eq: bool = division == 0u64;
|
||||
|
||||
// if the above division resulted in 0, we know the adjacency check should return false.
|
||||
// Setting to r4 to 3 (11) will guarantee failure here.
|
||||
let ternary: u64 = is_eq ? 3u64 : division;
|
||||
let subtraction: u64 = ternary - 1u64;
|
||||
let and: u64 = subtraction & ternary;
|
||||
|
||||
let bits_are_adjacent: bool = and == 0u64;
|
||||
|
||||
return bits_are_adjacent;
|
||||
}
|
||||
|
||||
// Returns boolean of whether adjacent flipped bits don't split a row of size 8.
|
||||
// E.g. 111000000 has adjacent flipped bits but splits a row: 00000001 11000000
|
||||
function horizontal_check(
|
||||
// The u64 representation of a ship's placement in an 8x8 grid.
|
||||
ship: u64,
|
||||
// The u64 representation of a ship's bitstring horizontally.
|
||||
horizontal: u64,
|
||||
) -> bool {
|
||||
let remainder: u64 = ship % 255u64;
|
||||
// This may result in 0.
|
||||
let division: u64 = remainder / horizontal;
|
||||
|
||||
// Subtracting 1 from 0 will cause an underflow.
|
||||
let is_eq: bool = division == 0u64;
|
||||
|
||||
// Setting to 3 will guarantee failure.
|
||||
let ternary: u64 = is_eq ? 3u64 : division;
|
||||
let subtraction: u64 = ternary - 1u64;
|
||||
let and: u64 = subtraction & ternary;
|
||||
|
||||
let bits_split_row: bool = and == 0u64;
|
||||
|
||||
return bits_split_row;
|
||||
}
|
||||
|
||||
// Returns `true` if the ship placement is valid.
|
||||
transition validate_ship(
|
||||
// The u64 representation of a ship's placement in an 8x8 grid.
|
||||
ship: u64,
|
||||
// The length of the placed ship.
|
||||
length: u64,
|
||||
// The u64 equivalent of a ship's horizontal bitstring representation.
|
||||
horizontal: u64,
|
||||
// The u64 equivalent of a ship's vertical bitstring representation.
|
||||
vertical: u64,
|
||||
) -> bool {
|
||||
// Check bitcount -- all other validations depend on the bitcount being correct.
|
||||
let num_bits: u64 = bitcount(ship);
|
||||
console.assert_eq(num_bits, length);
|
||||
|
||||
// Check horizontal bits of ship.
|
||||
let is_adjacent: bool = adjacency_check(ship, horizontal); // True if bits are adjacent horizontally.
|
||||
let is_horizontal: bool = horizontal_check(ship, horizontal); // True if those horizontal bits are not split across rows.
|
||||
let valid_horizontal: bool = is_adjacent && is_horizontal; // True if bits are adjacent horizontally and not split across rows.
|
||||
|
||||
// Check vertical bits of ship.
|
||||
let valid_vertical: bool = adjacency_check(ship, vertical); // True if bits are adjacent vertically.
|
||||
|
||||
let ship_is_valid: bool = valid_horizontal || valid_vertical; // Ship is valid if it is vertically or horizontally valid.
|
||||
|
||||
return ship_is_valid;
|
||||
}
|
||||
|
||||
// Returns the u64 representation of all the ships' placements in an 8x8 grid. This function will fail
|
||||
// if any of the ship placements overlap each other.
|
||||
transition create_board(
|
||||
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
|
||||
carrier: u64,
|
||||
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
|
||||
battleship: u64,
|
||||
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
|
||||
cruiser: u64,
|
||||
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
|
||||
destroyer: u64,
|
||||
) -> u64 {
|
||||
// Bitwise combine the ship placements together
|
||||
let ships: u64 = carrier | battleship | cruiser | destroyer;
|
||||
|
||||
let num_bits: u64 = bitcount(ships);
|
||||
console.assert_eq(num_bits, 14u64); // Given 4 individually-valid ships, a valid combination should yield exactly 14 flipped bits.
|
||||
|
||||
return ships;
|
||||
}
|
||||
}
|
@ -1,102 +1,105 @@
|
||||
// The 'battleship.leo' program.
|
||||
import board.leo;
|
||||
import move.leo;
|
||||
import verify.leo;
|
||||
|
||||
// Returns a new record representing a new game of battleship.
|
||||
transition initialize_board(
|
||||
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
|
||||
carrier: u64,
|
||||
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
|
||||
battleship: u64,
|
||||
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
|
||||
cruiser: u64,
|
||||
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
|
||||
destroyer: u64,
|
||||
// The address of the opponent.
|
||||
player: address,
|
||||
) -> board.leo/board_state.record {
|
||||
// Verify that each individual ship placement bitstring is valid.
|
||||
let valid_carrier: bool = verify.leo/validate_ship(carrier, 5u64, 31u64, 4311810305u64);
|
||||
console.assert(valid_carrier);
|
||||
// The 'battleship.leo' program.
|
||||
program battleship.aleo {
|
||||
// Returns a new record representing a new game of battleship.
|
||||
transition initialize_board(
|
||||
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
|
||||
carrier: u64,
|
||||
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
|
||||
battleship: u64,
|
||||
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
|
||||
cruiser: u64,
|
||||
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
|
||||
destroyer: u64,
|
||||
// The address of the opponent.
|
||||
player: address,
|
||||
) -> board.leo/board_state.record {
|
||||
// Verify that each individual ship placement bitstring is valid.
|
||||
let valid_carrier: bool = verify.leo/validate_ship(carrier, 5u64, 31u64, 4311810305u64);
|
||||
console.assert(valid_carrier);
|
||||
|
||||
let valid_battleship: bool = verify.leo/validate_ship(battleship, 4u64, 15u64, 16843009u64);
|
||||
console.assert(valid_battleship);
|
||||
let valid_battleship: bool = verify.leo/validate_ship(battleship, 4u64, 15u64, 16843009u64);
|
||||
console.assert(valid_battleship);
|
||||
|
||||
let valid_cruiser: bool = verify.leo/validate_ship(cruiser, 3u64, 7u64, 65793u64);
|
||||
console.assert(valid_cruiser);
|
||||
let valid_cruiser: bool = verify.leo/validate_ship(cruiser, 3u64, 7u64, 65793u64);
|
||||
console.assert(valid_cruiser);
|
||||
|
||||
let valid_destroyer: bool = verify.leo/validate_ship(destroyer, 2u64, 3u64, 257u64);
|
||||
console.assert(valid_destroyer);
|
||||
let valid_destroyer: bool = verify.leo/validate_ship(destroyer, 2u64, 3u64, 257u64);
|
||||
console.assert(valid_destroyer);
|
||||
|
||||
// Create the board with all the ship placements combined.
|
||||
let board: u64 = verify.leo/create_board(carrier, battleship, cruiser, destroyer);
|
||||
// Create the board with all the ship placements combined.
|
||||
let board: u64 = verify.leo/create_board(carrier, battleship, cruiser, destroyer);
|
||||
|
||||
// Initialize the board state record.
|
||||
let state: board_state = board.leo/new_board_state(board, player);
|
||||
// Initialize the board state record.
|
||||
let state: board_state = board.leo/new_board_state(board, player);
|
||||
|
||||
return state;
|
||||
return state;
|
||||
}
|
||||
|
||||
// Returns an updated board state record that has been started. This board cannot be used to start any other games.
|
||||
// Returns a dummy move record owned by the opponent.
|
||||
// This function commits a given board to a game with an opponent and creates the initial dummy move.
|
||||
transition offer_battleship(
|
||||
// The board record to start a game with.
|
||||
board: board.leo/board_state.record,
|
||||
) -> (board.leo/board_state.record, move.leo/move.record) {
|
||||
let state: board_state = board.leo/start_board(board);
|
||||
let dummy: move = move.leo/start_game(board.player_2);
|
||||
|
||||
return (state, dummy);
|
||||
}
|
||||
|
||||
// Returns updated board_state.record that has been started and can no longer be used to join or start new games.
|
||||
// Returns dummy move record owned by the opponent.
|
||||
transition start_battleship(
|
||||
// The board record to play the game with.
|
||||
board: board.leo/board_state.record,
|
||||
// The move record to play to begin the game. This should be the dummy move record created from offer_battleship.
|
||||
move_start: move.leo/move.record,
|
||||
) -> (board.leo/board_state.record, move.leo/move.record) {
|
||||
// Validate that the move players and board players match each other.
|
||||
console.assert_eq(board.player_1, move_start.player_2);
|
||||
console.assert_eq(board.player_2, move_start.player_1);
|
||||
|
||||
let state: board_state = board.leo/start_board(board);
|
||||
let dummy: move = move.leo/start_game(board.player_2);
|
||||
|
||||
return (state, dummy);
|
||||
}
|
||||
|
||||
// Returns updated board record.
|
||||
// Returns new move record owned by opponent.
|
||||
transition play(
|
||||
// The board record to update.
|
||||
board: board.leo/board_state.record,
|
||||
// The incoming move from the opponent.
|
||||
move_incoming: move.leo/move.record,
|
||||
// The u64 equivalent of the bitwise representation of the next coordinate to play on the opponent's board.
|
||||
shoot: u64,
|
||||
) -> (board.leo/board_state.record, move.leo/move.record) {
|
||||
// Verify the board has been started. This prevents players from starting a game and then creating
|
||||
// a brand new board to play with.
|
||||
console.assert(board.game_started);
|
||||
|
||||
// Validate that the move players and board players match each other.
|
||||
console.assert_eq(board.player_1, move_incoming.player_2);
|
||||
console.assert_eq(board.player_2, move_incoming.player_1);
|
||||
|
||||
// Play coordinate on own board. Will fail if not a valid move.
|
||||
let hit_or_miss: board_state = board.leo/update_played_tiles(board, shoot);
|
||||
|
||||
// Update own board with result of last shot.
|
||||
let next_board: board_state = board.leo/update_hits_and_misses(hit_or_miss, move_incoming.prev_hit_or_miss);
|
||||
|
||||
// Assess whether incoming fire coordinate is a hit.
|
||||
let is_hit: u64 = move_incoming.incoming_fire_coordinate & board.ships;
|
||||
|
||||
let next_move: move = move.leo/create_move(move_incoming, shoot, is_hit);
|
||||
|
||||
return (next_board, next_move);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an updated board state record that has been started. This board cannot be used to start any other games.
|
||||
// Returns a dummy move record owned by the opponent.
|
||||
// This function commits a given board to a game with an opponent and creates the initial dummy move.
|
||||
transition offer_battleship(
|
||||
// The board record to start a game with.
|
||||
board: board.leo/board_state.record,
|
||||
) -> (board.leo/board_state.record, move.leo/move.record) {
|
||||
let state: board_state = board.leo/start_board(board);
|
||||
let dummy: move = move.leo/start_game(board.player_2);
|
||||
|
||||
return (state, dummy);
|
||||
}
|
||||
|
||||
// Returns updated board_state.record that has been started and can no longer be used to join or start new games.
|
||||
// Returns dummy move record owned by the opponent.
|
||||
transition start_battleship(
|
||||
// The board record to play the game with.
|
||||
board: board.leo/board_state.record,
|
||||
// The move record to play to begin the game. This should be the dummy move record created from offer_battleship.
|
||||
move_start: move.leo/move.record,
|
||||
) -> (board.leo/board_state.record, move.leo/move.record) {
|
||||
// Validate that the move players and board players match each other.
|
||||
console.assert_eq(board.player_1, move_start.player_2);
|
||||
console.assert_eq(board.player_2, move_start.player_1);
|
||||
|
||||
let state: board_state = board.leo/start_board(board);
|
||||
let dummy: move = move.leo/start_game(board.player_2);
|
||||
|
||||
return (state, dummy);
|
||||
}
|
||||
|
||||
// Returns updated board record.
|
||||
// Returns new move record owned by opponent.
|
||||
transition play(
|
||||
// The board record to update.
|
||||
board: board.leo/board_state.record,
|
||||
// The incoming move from the opponent.
|
||||
move_incoming: move.leo/move.record,
|
||||
// The u64 equivalent of the bitwise representation of the next coordinate to play on the opponent's board.
|
||||
shoot: u64,
|
||||
) -> (board.leo/board_state.record, move.leo/move.record) {
|
||||
// Verify the board has been started. This prevents players from starting a game and then creating
|
||||
// a brand new board to play with.
|
||||
console.assert(board.game_started);
|
||||
|
||||
// Validate that the move players and board players match each other.
|
||||
console.assert_eq(board.player_1, move_incoming.player_2);
|
||||
console.assert_eq(board.player_2, move_incoming.player_1);
|
||||
|
||||
// Play coordinate on own board. Will fail if not a valid move.
|
||||
let hit_or_miss: board_state = board.leo/update_played_tiles(board, shoot);
|
||||
|
||||
// Update own board with result of last shot.
|
||||
let next_board: board_state = board.leo/update_hits_and_misses(hit_or_miss, move_incoming.prev_hit_or_miss);
|
||||
|
||||
// Assess whether incoming fire coordinate is a hit.
|
||||
let is_hit: u64 = move_incoming.incoming_fire_coordinate & board.ships;
|
||||
|
||||
let next_move: move = move.leo/create_move(move_incoming, shoot, is_hit);
|
||||
|
||||
return (next_board, next_move);
|
||||
}
|
@ -1,285 +1,287 @@
|
||||
// Executes the bubble sorting algorithm.
|
||||
// The original algorithm is given below.
|
||||
//
|
||||
// for i in 0..7 {
|
||||
// for j in 0..7-i {
|
||||
// // Move the smaller elements forward
|
||||
// if arr[j+1] < arr[j] {
|
||||
// // Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
// let swap = arr[j];
|
||||
// arr[j] = arr[j+1];
|
||||
// arr[j+1] = swap;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Note that the implementation below uses tuples instead of arrays.
|
||||
// The implementation also manually unrolls the loop.
|
||||
program bubblesort.aleo {
|
||||
// Executes the bubble sorting algorithm.
|
||||
// The original algorithm is given below.
|
||||
//
|
||||
// for i in 0..7 {
|
||||
// for j in 0..7-i {
|
||||
// // Move the smaller elements forward
|
||||
// if arr[j+1] < arr[j] {
|
||||
// // Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
// let swap = arr[j];
|
||||
// arr[j] = arr[j+1];
|
||||
// arr[j+1] = swap;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Note that the implementation below uses tuples instead of arrays.
|
||||
// The implementation also manually unrolls the loop.
|
||||
|
||||
transition bubble_sort(
|
||||
arr0: u32,
|
||||
arr1: u32,
|
||||
arr2: u32,
|
||||
arr3: u32,
|
||||
arr4: u32,
|
||||
arr5: u32,
|
||||
arr6: u32,
|
||||
arr7: u32,
|
||||
) -> (u32, u32, u32, u32, u32, u32, u32, u32) {
|
||||
transition bubble_sort(
|
||||
arr0: u32,
|
||||
arr1: u32,
|
||||
arr2: u32,
|
||||
arr3: u32,
|
||||
arr4: u32,
|
||||
arr5: u32,
|
||||
arr6: u32,
|
||||
arr7: u32,
|
||||
) -> (u32, u32, u32, u32, u32, u32, u32, u32) {
|
||||
|
||||
// Unroll the loops.
|
||||
// Unroll the loops.
|
||||
|
||||
// (i, j) = (0, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
// (i, j) = (0, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 4).
|
||||
// Move the smaller elements forward.
|
||||
if arr5 < arr4 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr4;
|
||||
arr4 = arr5;
|
||||
arr5 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 5).
|
||||
// Move the smaller elements forward.
|
||||
if arr6 < arr5 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr5;
|
||||
arr5 = arr6;
|
||||
arr6 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 6).
|
||||
// Move the smaller elements forward.
|
||||
if arr7 < arr6 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr6;
|
||||
arr6 = arr7;
|
||||
arr7 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 4).
|
||||
// Move the smaller elements forward.
|
||||
if arr5 < arr4 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr4;
|
||||
arr4 = arr5;
|
||||
arr5 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 5).
|
||||
// Move the smaller elements forward.
|
||||
if arr6 < arr5 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr5;
|
||||
arr5 = arr6;
|
||||
arr6 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 4).
|
||||
// Move the smaller elements forward.
|
||||
if arr5 < arr4 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr4;
|
||||
arr4 = arr5;
|
||||
arr5 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (4, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (4, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (4, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (5, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (5, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (6, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
return (arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7);
|
||||
}
|
||||
|
||||
// (i, j) = (0, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 4).
|
||||
// Move the smaller elements forward.
|
||||
if arr5 < arr4 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr4;
|
||||
arr4 = arr5;
|
||||
arr5 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 5).
|
||||
// Move the smaller elements forward.
|
||||
if arr6 < arr5 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr5;
|
||||
arr5 = arr6;
|
||||
arr6 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (0, 6).
|
||||
// Move the smaller elements forward.
|
||||
if arr7 < arr6 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr6;
|
||||
arr6 = arr7;
|
||||
arr7 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 4).
|
||||
// Move the smaller elements forward.
|
||||
if arr5 < arr4 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr4;
|
||||
arr4 = arr5;
|
||||
arr5 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (1, 5).
|
||||
// Move the smaller elements forward.
|
||||
if arr6 < arr5 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr5;
|
||||
arr5 = arr6;
|
||||
arr6 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (2, 4).
|
||||
// Move the smaller elements forward.
|
||||
if arr5 < arr4 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr4;
|
||||
arr4 = arr5;
|
||||
arr5 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (3, 3).
|
||||
// Move the smaller elements forward.
|
||||
if arr4 < arr3 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr3;
|
||||
arr3 = arr4;
|
||||
arr4 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (4, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (4, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (4, 2).
|
||||
// Move the smaller elements forward.
|
||||
if arr3 < arr2 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr2;
|
||||
arr2 = arr3;
|
||||
arr3 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (5, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (5, 1).
|
||||
// Move the smaller elements forward.
|
||||
if arr2 < arr1 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr1;
|
||||
arr1 = arr2;
|
||||
arr2 = temp;
|
||||
}
|
||||
|
||||
// (i, j) = (6, 0).
|
||||
// Move the smaller elements forward.
|
||||
if arr1 < arr0 {
|
||||
// Swap the elements at indexes ‘j‘ and ‘j+1‘
|
||||
let temp: u32 = arr0;
|
||||
arr0 = arr1;
|
||||
arr1 = temp;
|
||||
}
|
||||
|
||||
return (arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7);
|
||||
}
|
@ -217,59 +217,36 @@ fn compile_leo_file(
|
||||
.and_then(|name| name.to_str())
|
||||
.ok_or_else(PackageError::failed_to_get_file_name)?;
|
||||
|
||||
// Construct program name from file_path name `foo`.
|
||||
let program_name = file_name
|
||||
.strip_suffix(".leo")
|
||||
.ok_or_else(PackageError::failed_to_get_file_name)?;
|
||||
// If the program is an import, construct program name from file_path
|
||||
// Otherwise, use the program_id found in `package.json`.
|
||||
let program_name = match is_import {
|
||||
false => program_id.name().to_string(),
|
||||
true => file_name
|
||||
.strip_suffix(".leo")
|
||||
.ok_or_else(PackageError::failed_to_get_file_name)?
|
||||
.to_string(),
|
||||
};
|
||||
|
||||
// Create the path to the Aleo file.
|
||||
let mut aleo_file_path = build.to_path_buf();
|
||||
aleo_file_path.push(match is_import {
|
||||
true => format!("{}.{}", program_name, program_id.network()),
|
||||
false => format!("main.{}", program_id.network()),
|
||||
});
|
||||
|
||||
// Create a new instance of the Leo compiler.
|
||||
let mut compiler = Compiler::new(
|
||||
program_name.to_string(),
|
||||
program_name,
|
||||
program_id.network().to_string(),
|
||||
handler,
|
||||
file_path.clone(),
|
||||
outputs.to_path_buf(),
|
||||
Some(options.into()),
|
||||
is_import,
|
||||
);
|
||||
|
||||
// TODO: Temporarily removing checksum files. Need to redesign this scheme.
|
||||
// // Check if we need to compile the Leo program.
|
||||
// let checksum_differs = {
|
||||
// // Compute the current program checksum.
|
||||
// let program_checksum = program.checksum()?;
|
||||
//
|
||||
// // Get the current program checksum.
|
||||
// let checksum_file = ChecksumFile::new(program_name);
|
||||
//
|
||||
// // If a checksum file exists, check if it differs from the new checksum.
|
||||
// let checksum_differs = if checksum_file.exists_at(package_path) {
|
||||
// let previous_checksum = checksum_file.read_from(package_path)?;
|
||||
// program_checksum != previous_checksum
|
||||
// } else {
|
||||
// // By default, the checksum differs if there is no checksum to compare against.
|
||||
// true
|
||||
// };
|
||||
//
|
||||
// // If checksum differs, compile the program
|
||||
// if checksum_differs {
|
||||
// // Write the new checksum to the output directory
|
||||
// checksum_file.write_to(package_path, program_checksum)?;
|
||||
//
|
||||
// tracing::debug!("Checksum saved ({:?})", package_path);
|
||||
// }
|
||||
//
|
||||
// checksum_differs
|
||||
// };
|
||||
|
||||
// if checksum_differs {
|
||||
// Compile the Leo program into Aleo instructions.
|
||||
let (symbol_table, instructions) = compiler.compile_and_generate_instructions()?;
|
||||
|
||||
// Create the path to the Aleo file.
|
||||
let mut aleo_file_path = build.to_path_buf();
|
||||
aleo_file_path.push(format!("{}.aleo", program_name));
|
||||
|
||||
// Write the instructions.
|
||||
std::fs::File::create(&aleo_file_path)
|
||||
.map_err(CliError::failed_to_load_instructions)?
|
||||
|
@ -80,7 +80,6 @@ fn new_compiler(handler: &Handler) -> Compiler<'_> {
|
||||
PathBuf::from(String::new()),
|
||||
PathBuf::from(String::new()),
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user