diff --git a/src/interfaces/IWorld.cairo b/src/interfaces/IWorld.cairo index 4d80bd9..1a30e81 100644 --- a/src/interfaces/IWorld.cairo +++ b/src/interfaces/IWorld.cairo @@ -7,7 +7,13 @@ use starknet::{ContractAddress}; // define the interface #[starknet::interface] pub trait IWorld { - fn register_new_player(ref self: T, username: felt252, is_bot: bool); + fn register_new_player( + ref self: T, + username: felt252, + is_bot: bool, + player_symbol: PlayerSymbol, + initial_balance: u256, + ); fn get_username_from_address(self: @T, address: ContractAddress) -> felt252; fn retrieve_player(ref self: T, addr: ContractAddress) -> Player; fn create_new_game( diff --git a/src/lib.cairo b/src/lib.cairo index b472b96..03bc662 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -13,4 +13,5 @@ pub mod model { pub mod tests { mod test_world; + mod test_player_model; } diff --git a/src/model/player_model.cairo b/src/model/player_model.cairo index a840195..e4c0613 100644 --- a/src/model/player_model.cairo +++ b/src/model/player_model.cairo @@ -1,5 +1,9 @@ use starknet::{ContractAddress, contract_address_const}; +pub fn zero_address() -> ContractAddress { + contract_address_const::<0>() +} + // #[derive(Copy, Drop, Serde, Debug)] #[derive(Drop, Copy, Serde)] #[dojo::model] @@ -8,6 +12,11 @@ pub struct Player { pub player: ContractAddress, pub username: felt252, pub is_bot: bool, + pub new_owner: ContractAddress, + pub balance: u256, + pub position: u8, + pub jailed: bool, + pub player_symbol: PlayerSymbol, pub total_games_played: u256, pub total_games_completed: u256, pub total_games_won: u256, @@ -19,20 +28,306 @@ pub trait PlayerTrait { // `username` - Username to assign to the new player // `owner` - Account owner of player // returns the created player - fn new(username: felt252, player: ContractAddress, is_bot: bool) -> Player; + fn new( + username: felt252, + player: ContractAddress, + is_bot: bool, + player_symbol: PlayerSymbol, + initial_balance: u256, + ) -> Player; + fn move_player(ref self: Player, steps: u8, board_size: u8); + fn pay_rent_to(ref self: Player, ref recipient: Player, amount: u256) -> bool; + fn buy_property(ref self: Player, ref seller: Player, amount: u256) -> bool; + fn update_stats(ref self: Player, played: u256, completed: u256, won: u256); + fn set_jail_status(ref self: Player, jailed: bool); + fn transfer_ownership(ref self: Player, new_owner: ContractAddress); + fn collect_go_money(ref self: Player, amount: u256); + fn pay_fee(ref self: Player, amount: u256) -> bool; + fn can_afford(self: @Player, amount: u256) -> bool; + fn is_bankrupt(self: @Player) -> bool; + fn get_win_rate(self: @Player) -> u256; } -impl PlayerImpl of PlayerTrait { - fn new(username: felt252, player: ContractAddress, is_bot: bool) -> Player { +pub impl PlayerImpl of PlayerTrait { + fn new( + username: felt252, + player: ContractAddress, + is_bot: bool, + player_symbol: PlayerSymbol, + initial_balance: u256, + ) -> Player { Player { player, username, is_bot, + new_owner: zero_address(), + balance: initial_balance, + position: 0, + jailed: false, + player_symbol, total_games_played: 0, total_games_completed: 0, total_games_won: 0, } } + + fn move_player(ref self: Player, steps: u8, board_size: u8) { + assert(board_size > 0, 'Board not greater than 0'); + + let old_position = self.position; + let total_steps = old_position + steps; + let new_position = total_steps % board_size; + + let laps = total_steps / board_size; + self.balance += 200_u256 * laps.into(); + + self.position = new_position; + } + fn pay_rent_to(ref self: Player, ref recipient: Player, amount: u256) -> bool { + if !self.can_afford(amount) { + return false; + } + + if self.player == recipient.player { + return false; + } + + if amount == 0 { + return false; + } + + self.balance -= amount; + recipient.balance += amount; + + true + } + + fn buy_property(ref self: Player, ref seller: Player, amount: u256) -> bool { + if !self.can_afford(amount) { + return false; + } + + if self.player == seller.player { + return false; + } + + if amount == 0 { + return false; + } + + self.balance -= amount; + seller.balance += amount; + + true + } + + fn update_stats(ref self: Player, played: u256, completed: u256, won: u256) { + self.total_games_played += played; + self.total_games_completed += completed; + self.total_games_won += won; + } + + fn set_jail_status(ref self: Player, jailed: bool) { + self.jailed = jailed; + if jailed { + self.position = 10; + } + } + + fn transfer_ownership(ref self: Player, new_owner: ContractAddress) { + self.new_owner = new_owner; + } + + fn collect_go_money(ref self: Player, amount: u256) { + self.balance += amount; + } + + fn pay_fee(ref self: Player, amount: u256) -> bool { + if !self.can_afford(amount) { + return false; + } + + self.balance -= amount; + true + } + + fn can_afford(self: @Player, amount: u256) -> bool { + *self.balance >= amount + } + + fn is_bankrupt(self: @Player) -> bool { + *self.balance == 0 + } + + fn get_win_rate(self: @Player) -> u256 { + if *self.total_games_completed == 0 { + return 0; + } + (*self.total_games_won * 100) / *self.total_games_completed + } +} + +pub trait PlayerSymbolTrait { + fn is_valid(symbol: PlayerSymbol) -> bool; + fn get_name(symbol: PlayerSymbol) -> felt252; + fn from_felt(value: felt252) -> Option; +} + +pub impl PlayerSymbolImpl of PlayerSymbolTrait { + fn is_valid(symbol: PlayerSymbol) -> bool { + match symbol { + PlayerSymbol::Hat => true, + PlayerSymbol::Car => true, + PlayerSymbol::Dog => true, + PlayerSymbol::Thimble => true, + PlayerSymbol::Iron => true, + PlayerSymbol::Battleship => true, + PlayerSymbol::Boot => true, + PlayerSymbol::Wheelbarrow => true, + } + } + + fn get_name(symbol: PlayerSymbol) -> felt252 { + match symbol { + PlayerSymbol::Hat => 'Hat', + PlayerSymbol::Car => 'Car', + PlayerSymbol::Dog => 'Dog', + PlayerSymbol::Thimble => 'Thimble', + PlayerSymbol::Iron => 'Iron', + PlayerSymbol::Battleship => 'Battleship', + PlayerSymbol::Boot => 'Boot', + PlayerSymbol::Wheelbarrow => 'Wheelbarrow', + } + } + + fn from_felt(value: felt252) -> Option { + if value == 'Hat' { + Option::Some(PlayerSymbol::Hat) + } else if value == 'Car' { + Option::Some(PlayerSymbol::Car) + } else if value == 'Dog' { + Option::Some(PlayerSymbol::Dog) + } else if value == 'Thimble' { + Option::Some(PlayerSymbol::Thimble) + } else if value == 'Iron' { + Option::Some(PlayerSymbol::Iron) + } else if value == 'Battleship' { + Option::Some(PlayerSymbol::Battleship) + } else if value == 'Boot' { + Option::Some(PlayerSymbol::Boot) + } else if value == 'Wheelbarrow' { + Option::Some(PlayerSymbol::Wheelbarrow) + } else { + Option::None + } + } +} + + +pub trait PlayerValidation { + fn validate_creation( + username: felt252, + player: ContractAddress, + player_symbol: PlayerSymbol, + initial_balance: u256, + ) -> bool; + + fn validate_transaction(payer: @Player, recipient: @Player, amount: u256) -> bool; + + fn validate_username(username: felt252) -> bool; +} + +pub impl PlayerValidationImpl of PlayerValidation { + fn validate_creation( + username: felt252, + player: ContractAddress, + player_symbol: PlayerSymbol, + initial_balance: u256, + ) -> bool { + if player == zero_address() { + return false; + } + + if username == 0 { + return false; + } + + if !PlayerSymbolImpl::is_valid(player_symbol) { + return false; + } + + true + } + + fn validate_transaction(payer: @Player, recipient: @Player, amount: u256) -> bool { + if !payer.can_afford(amount) { + return false; + } + + if *payer.player == *recipient.player { + return false; + } + + if amount == 0 { + return false; + } + + true + } + + fn validate_username(username: felt252) -> bool { + username != 0 + } +} + +pub trait PlayerActions { + fn go_to_jail(ref self: Player); + fn get_out_of_jail(ref self: Player, pay_fee: bool, fee_amount: u256) -> bool; + fn pass_go(ref self: Player, go_amount: u256); + fn pay_tax(ref self: Player, tax_amount: u256) -> bool; + fn receive_money(ref self: Player, amount: u256); + fn reset_position(ref self: Player); +} + +pub impl PlayerActionsImpl of PlayerActions { + fn go_to_jail(ref self: Player) { + self.jailed = true; + self.position = 10; + } + + fn get_out_of_jail(ref self: Player, pay_fee: bool, fee_amount: u256) -> bool { + if pay_fee { + if !self.can_afford(fee_amount) { + return false; + } + self.balance -= fee_amount; + } + + self.jailed = false; + true + } + + fn pass_go(ref self: Player, go_amount: u256) { + self.balance += go_amount; + } + + fn pay_tax(ref self: Player, tax_amount: u256) -> bool { + if !self.can_afford(tax_amount) { + return false; + } + + self.balance -= tax_amount; + true + } + + fn receive_money(ref self: Player, amount: u256) { + self.balance += amount; + } + + fn reset_position(ref self: Player) { + self.position = 0; + self.jailed = false; + } } #[derive(Serde, Copy, Drop, Introspect, PartialEq)] diff --git a/src/systems/world.cairo b/src/systems/world.cairo index 90da236..1eef943 100644 --- a/src/systems/world.cairo +++ b/src/systems/world.cairo @@ -73,7 +73,13 @@ pub mod world { address_map.username } - fn register_new_player(ref self: ContractState, username: felt252, is_bot: bool) { + fn register_new_player( + ref self: ContractState, + username: felt252, + is_bot: bool, + player_symbol: PlayerSymbol, + initial_balance: u256, + ) { assert(!is_bot, 'Bot detected'); let mut world = self.world_default(); @@ -93,7 +99,9 @@ pub mod world { assert(existing_username == 0, 'USERNAME ALREADY CREATED'); - let new_player: Player = PlayerTrait::new(username, caller, is_bot); + let new_player: Player = PlayerTrait::new( + username, caller, is_bot, player_symbol, initial_balance, + ); let username_to_address: UsernameToAddress = UsernameToAddress { username, address: caller, }; diff --git a/src/tests/test_player_model.cairo b/src/tests/test_player_model.cairo new file mode 100644 index 0000000..cd8d224 --- /dev/null +++ b/src/tests/test_player_model.cairo @@ -0,0 +1,504 @@ +use dojo_starter::model::player_model::{ + Player, PlayerTrait, PlayerImpl, PlayerSymbol, PlayerSymbolTrait, PlayerSymbolImpl, + PlayerValidation, PlayerValidationImpl, PlayerActions, PlayerActionsImpl, zero_address, +}; + +use starknet::{ContractAddress, contract_address_const}; + + +fn create_test_player() -> Player { + PlayerImpl::new( + 'TestPlayer', contract_address_const::<0x123>(), false, PlayerSymbol::Hat, 1500_u256, + ) +} + +fn create_test_bot() -> Player { + PlayerImpl::new( + 'TestBot', contract_address_const::<0x456>(), true, PlayerSymbol::Car, 1500_u256, + ) +} + +#[test] +fn test_player_creation() { + let player = create_test_player(); + + assert(player.username == 'TestPlayer', 'Wrong username'); + assert(player.player == contract_address_const::<0x123>(), 'Wrong address'); + assert(!player.is_bot, 'Should not be bot'); + assert(player.balance == 1500_u256, 'Wrong initial balance'); + assert(player.position == 0, 'Wrong initial position'); + assert(!player.jailed, 'Should not be jailed'); + assert(player.player_symbol == PlayerSymbol::Hat, 'Wrong symbol'); + assert(player.total_games_played == 0, 'Wrong games played'); + assert(player.total_games_completed == 0, 'Wrong games completed'); + assert(player.total_games_won == 0, 'Wrong games won'); + assert(player.new_owner == zero_address(), 'Wrong new owner'); +} + +#[test] +fn test_bot_creation() { + let bot = create_test_bot(); + + assert(bot.is_bot, 'Should be bot'); + assert(bot.player_symbol == PlayerSymbol::Car, 'Wrong bot symbol'); +} + +#[test] +fn test_move_player_normal() { + let mut player = create_test_player(); + let initial_balance = player.balance; + + player.move_player(5, 40); + + assert(player.position == 5, 'Wrong position after move'); + assert(player.balance == initial_balance, 'Balance should not change'); +} + +#[test] +fn test_move_player_pass_go() { + let mut player = create_test_player(); + player.position = 38; + let initial_balance = player.balance; + + player.move_player(5, 40); + + assert(player.position == 3, 'Wrong position after passing go'); + assert(player.balance == initial_balance + 200, 'Should receive go money'); +} + +#[test] +fn test_move_player_multiple_laps() { + let mut player = create_test_player(); + let initial_balance = player.balance; + + player.move_player(85, 40); + + assert(player.position == 5, 'Wrong position'); + assert(player.balance == initial_balance + 400, 'Should receive money for 2 laps'); +} + +#[test] +#[should_panic(expected: ('Board not greater than 0',))] +fn test_move_player_zero_board_size() { + let mut player = create_test_player(); + player.move_player(5, 0); +} + +#[test] +fn test_pay_rent_successful() { + let mut payer = create_test_player(); + let mut recipient = create_test_bot(); + let rent_amount = 100_u256; + let payer_initial = payer.balance; + let recipient_initial = recipient.balance; + + let result = payer.pay_rent_to(ref recipient, rent_amount); + + assert(result, 'Rent payment should succeed'); + assert(payer.balance == payer_initial - rent_amount, 'Payer balance wrong'); + assert(recipient.balance == recipient_initial + rent_amount, 'Recipient balance wrong'); +} + +#[test] +fn test_pay_rent_insufficient_funds() { + let mut payer = create_test_player(); + let mut recipient = create_test_bot(); + let rent_amount = 2000_u256; + + let result = payer.pay_rent_to(ref recipient, rent_amount); + + assert(!result, 'Rent payment should fail'); +} + +#[test] +fn test_pay_rent_to_self() { + let mut player = create_test_player(); + let mut player_copy = create_test_player(); + + let result = player.pay_rent_to(ref player_copy, 100_u256); + + assert(!result, 'Should not pay rent to self'); +} + +#[test] +fn test_pay_rent_zero_amount() { + let mut payer = create_test_player(); + let mut recipient = create_test_bot(); + + let result = payer.pay_rent_to(ref recipient, 0_u256); + + assert(!result, 'Should not pay zero rent'); +} + +#[test] +fn test_buy_property_successful() { + let mut buyer = create_test_player(); + let mut seller = create_test_bot(); + let price = 200_u256; + let buyer_initial = buyer.balance; + let seller_initial = seller.balance; + + let result = buyer.buy_property(ref seller, price); + + assert(result, 'Should succeed'); + assert(buyer.balance == buyer_initial - price, 'Buyer balance wrong'); + assert(seller.balance == seller_initial + price, 'Seller balance wrong'); +} + +#[test] +fn test_buy_property_insufficient_funds() { + let mut buyer = create_test_player(); + let mut seller = create_test_bot(); + let price = 2000_u256; + + let result = buyer.buy_property(ref seller, price); + + assert(!result, 'Property purchase should fail'); +} + +#[test] +fn test_update_stats() { + let mut player = create_test_player(); + + player.update_stats(1, 1, 0); + assert(player.total_games_played == 1, 'Wrong games played'); + assert(player.total_games_completed == 1, 'Wrong games completed'); + assert(player.total_games_won == 0, 'Wrong games won'); + + player.update_stats(2, 1, 1); + assert(player.total_games_played == 3, 'Wrong cumulative games played'); + assert(player.total_games_completed == 2, 'Wrong cumulative games'); + assert(player.total_games_won == 1, 'Wrong cumulative games won'); +} + +#[test] +fn test_jail_status() { + let mut player = create_test_player(); + + player.set_jail_status(true); + assert(player.jailed, 'Should be jailed'); + assert(player.position == 10, 'Should be at jail position'); + + player.set_jail_status(false); + assert(!player.jailed, 'Should not be jailed'); + assert(player.position == 10, 'Position should remain at jail'); +} + +#[test] +fn test_transfer_ownership() { + let mut player = create_test_player(); + let new_owner = contract_address_const::<0x789>(); + + player.transfer_ownership(new_owner); + assert(player.new_owner == new_owner, 'Wrong new owner'); +} + +#[test] +fn test_collect_go_money() { + let mut player = create_test_player(); + let initial_balance = player.balance; + let go_amount = 200_u256; + + player.collect_go_money(go_amount); + assert(player.balance == initial_balance + go_amount, 'Wrong balance after go'); +} + +#[test] +fn test_pay_fee_successful() { + let mut player = create_test_player(); + let initial_balance = player.balance; + let fee = 50_u256; + + let result = player.pay_fee(fee); + + assert(result, 'Fee payment should succeed'); + assert(player.balance == initial_balance - fee, 'Wrong balance after fee'); +} + +#[test] +fn test_pay_fee_insufficient_funds() { + let mut player = create_test_player(); + let fee = 2000_u256; + + let result = player.pay_fee(fee); + + assert(!result, 'Fee payment should fail'); +} + +#[test] +fn test_can_afford() { + let player = create_test_player(); + + assert(player.can_afford(1500_u256), 'Should afford exact balance'); + assert(player.can_afford(1000_u256), 'Should afford less than balance'); + assert(!player.can_afford(2000_u256), 'Should not afford'); +} + +#[test] +fn test_is_bankrupt() { + let mut player = create_test_player(); + + assert(!player.is_bankrupt(), 'Should not be bankrupt'); + + player.balance = 0; + assert(player.is_bankrupt(), 'Should be bankrupt'); +} + +#[test] +fn test_get_win_rate() { + let mut player = create_test_player(); + + assert(player.get_win_rate() == 0, 'Win rate should be 0'); + + player.total_games_completed = 5; + player.total_games_won = 2; + assert(player.get_win_rate() == 40, 'Win rate should be 40%'); + + player.total_games_completed = 3; + player.total_games_won = 3; + assert(player.get_win_rate() == 100, 'Win rate should be 100%'); +} + +#[test] +fn test_player_symbol_is_valid() { + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Hat), 'Hat should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Car), 'Car should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Dog), 'Dog should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Thimble), 'Thimble should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Iron), 'Iron should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Battleship), 'Battleship should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Boot), 'Boot should be valid'); + assert(PlayerSymbolImpl::is_valid(PlayerSymbol::Wheelbarrow), 'Wheelbarrow should be valid'); +} + +#[test] +fn test_player_symbol_get_name() { + assert(PlayerSymbolImpl::get_name(PlayerSymbol::Hat) == 'Hat', 'Wrong hat name'); + assert(PlayerSymbolImpl::get_name(PlayerSymbol::Car) == 'Car', 'Wrong car name'); + assert(PlayerSymbolImpl::get_name(PlayerSymbol::Dog) == 'Dog', 'Wrong dog name'); + assert(PlayerSymbolImpl::get_name(PlayerSymbol::Thimble) == 'Thimble', 'Wrong thimble name'); + assert(PlayerSymbolImpl::get_name(PlayerSymbol::Iron) == 'Iron', 'Wrong iron name'); + assert( + PlayerSymbolImpl::get_name(PlayerSymbol::Battleship) == 'Battleship', + 'Wrong battleship name', + ); + assert(PlayerSymbolImpl::get_name(PlayerSymbol::Boot) == 'Boot', 'Wrong boot name'); + assert( + PlayerSymbolImpl::get_name(PlayerSymbol::Wheelbarrow) == 'Wheelbarrow', + 'Wrong wheelbarrow name', + ); +} + +#[test] +fn test_player_symbol_from_felt() { + assert( + PlayerSymbolImpl::from_felt('Hat') == Option::Some(PlayerSymbol::Hat), + 'Wrong hat conversion', + ); + assert( + PlayerSymbolImpl::from_felt('Car') == Option::Some(PlayerSymbol::Car), + 'Wrong car conversion', + ); + assert( + PlayerSymbolImpl::from_felt('Dog') == Option::Some(PlayerSymbol::Dog), + 'Wrong dog conversion', + ); + assert( + PlayerSymbolImpl::from_felt('Invalid') == Option::None, 'Should return None for invalid', + ); +} + +#[test] +fn test_validate_creation_success() { + let result = PlayerValidationImpl::validate_creation( + 'TestPlayer', contract_address_const::<0x123>(), PlayerSymbol::Hat, 1500_u256, + ); + assert(result, 'Valid creation should pass'); +} + +#[test] +fn test_validate_creation_zero_address() { + let result = PlayerValidationImpl::validate_creation( + 'TestPlayer', zero_address(), PlayerSymbol::Hat, 1500_u256, + ); + assert(!result, 'Should fail validation'); +} + +#[test] +fn test_validate_creation_empty_username() { + let result = PlayerValidationImpl::validate_creation( + 0, contract_address_const::<0x123>(), PlayerSymbol::Hat, 1500_u256, + ); + assert(!result, 'Should fail validation'); +} + +#[test] +fn test_validate_transaction_success() { + let payer = create_test_player(); + let recipient = create_test_bot(); + + let result = PlayerValidationImpl::validate_transaction(@payer, @recipient, 100_u256); + assert(result, 'Valid transaction should pass'); +} + +#[test] +fn test_validate_transaction_insufficient_funds() { + let payer = create_test_player(); + let recipient = create_test_bot(); + + let result = PlayerValidationImpl::validate_transaction(@payer, @recipient, 2000_u256); + assert(!result, 'Should fail validation'); +} + +#[test] +fn test_validate_transaction_same_player() { + let player = create_test_player(); + + let result = PlayerValidationImpl::validate_transaction(@player, @player, 100_u256); + assert(!result, 'Should fail validation'); +} + +#[test] +fn test_validate_transaction_zero_amount() { + let payer = create_test_player(); + let recipient = create_test_bot(); + + let result = PlayerValidationImpl::validate_transaction(@payer, @recipient, 0_u256); + assert(!result, 'Should fail validation'); +} + +#[test] +fn test_validate_username() { + assert(PlayerValidationImpl::validate_username('ValidName'), 'Valid username should pass'); + assert(!PlayerValidationImpl::validate_username(0), 'Zero username should fail'); +} + +// PlayerActions Tests +#[test] +fn test_go_to_jail() { + let mut player = create_test_player(); + + player.go_to_jail(); + + assert(player.jailed, 'Should be jailed'); + assert(player.position == 10, 'Should be at jail position'); +} + +#[test] +fn test_get_out_of_jail_with_payment() { + let mut player = create_test_player(); + player.jailed = true; + let initial_balance = player.balance; + let fee = 50_u256; + + let result = player.get_out_of_jail(true, fee); + + assert(result, 'Should get out of jail'); + assert(!player.jailed, 'Should not be jailed'); + assert(player.balance == initial_balance - fee, 'Wrong balance after fee'); +} + +#[test] +fn test_get_out_of_jail_without_payment() { + let mut player = create_test_player(); + player.jailed = true; + let initial_balance = player.balance; + + let result = player.get_out_of_jail(false, 0); + + assert(result, 'Should get out of jail'); + assert(!player.jailed, 'Should not be jailed'); + assert(player.balance == initial_balance, 'Balance should not change'); +} + +#[test] +fn test_get_out_of_jail_insufficient_funds() { + let mut player = create_test_player(); + player.jailed = true; + let fee = 2000_u256; + + let result = player.get_out_of_jail(true, fee); + + assert(!result, 'Should fail to get out of jail'); + assert(player.jailed, 'Should still be jailed'); +} + +#[test] +fn test_pass_go() { + let mut player = create_test_player(); + let initial_balance = player.balance; + let go_amount = 200_u256; + + player.pass_go(go_amount); + + assert(player.balance == initial_balance + go_amount, 'Wrong balance after passing go'); +} + +#[test] +fn test_pay_tax_successful() { + let mut player = create_test_player(); + let initial_balance = player.balance; + let tax = 100_u256; + + let result = player.pay_tax(tax); + + assert(result, 'Tax payment should succeed'); + assert(player.balance == initial_balance - tax, 'Wrong balance after tax'); +} + +#[test] +fn test_pay_tax_insufficient_funds() { + let mut player = create_test_player(); + let tax = 2000_u256; + + let result = player.pay_tax(tax); + + assert(!result, 'Tax payment should fail'); +} + +#[test] +fn test_receive_money() { + let mut player = create_test_player(); + let initial_balance = player.balance; + let amount = 300_u256; + + player.receive_money(amount); + + assert(player.balance == initial_balance + amount, 'Wrong balance'); +} + +#[test] +fn test_reset_position() { + let mut player = create_test_player(); + player.position = 25; + player.jailed = true; + + player.reset_position(); + + assert(player.position == 0, 'Position should be reset to 0'); + assert(!player.jailed, 'Should not be jailed'); +} + + +#[test] +fn test_multiple_operations() { + let mut player1 = create_test_player(); + let mut player2 = create_test_bot(); + + player1.move_player(42, 40); + assert(player1.position == 2, 'Wrong position after move'); + assert(player1.balance == 1700, 'Wrong balance after passing go'); + + let rent_paid = player1.pay_rent_to(ref player2, 150_u256); + assert(rent_paid, 'Rent payment should succeed'); + assert(player1.balance == 1550, 'Wrong balance after rent'); + assert(player2.balance == 1650, 'Wrong recipient balance'); + + player1.go_to_jail(); + assert(player1.jailed, 'Should be jailed'); + assert(player1.position == 10, 'Should be at jail'); + + let jail_exit = player1.get_out_of_jail(true, 50_u256); + assert(jail_exit, 'Should get out of jail'); + assert(player1.balance == 1500, 'Wrong balance after jail fee'); +} diff --git a/src/tests/test_world.cairo b/src/tests/test_world.cairo index 4e5f51f..e93f86e 100644 --- a/src/tests/test_world.cairo +++ b/src/tests/test_world.cairo @@ -72,7 +72,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); let player: Player = actions_system.retrieve_player(caller_1); println!("username: {}", player.username); @@ -94,10 +94,10 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_2); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); } #[test] @@ -115,10 +115,10 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); - actions_system.register_new_player(username1, false); + actions_system.register_new_player(username1, false, PlayerSymbol::Car, 100); } #[test] #[should_panic] @@ -135,10 +135,10 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); - actions_system.register_new_player(username1, false); + actions_system.register_new_player(username1, false, PlayerSymbol::Car, 100); } #[test] @@ -155,7 +155,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, true); + actions_system.register_new_player(username, true, PlayerSymbol::Car, 100); } #[test] @@ -171,7 +171,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -197,7 +197,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let _game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -264,7 +264,7 @@ mod tests { assert(property.id == 1, 'wrong id'); testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id: u256 = actions_system @@ -296,7 +296,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -322,7 +322,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -357,7 +357,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -390,7 +390,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -422,7 +422,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -459,7 +459,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -489,7 +489,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -520,7 +520,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -552,7 +552,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -585,7 +585,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -617,7 +617,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -652,7 +652,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); @@ -685,7 +685,7 @@ mod tests { let actions_system = IWorldDispatcher { contract_address }; testing::set_contract_address(caller_1); - actions_system.register_new_player(username, false); + actions_system.register_new_player(username, false, PlayerSymbol::Dog, 100); testing::set_contract_address(caller_1); let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4);