diff --git a/backend/dojo_examples/combat_game/src/models/battle.cairo b/backend/dojo_examples/combat_game/src/models/battle.cairo index 0378e89..62f4e14 100644 --- a/backend/dojo_examples/combat_game/src/models/battle.cairo +++ b/backend/dojo_examples/combat_game/src/models/battle.cairo @@ -2,9 +2,7 @@ use starknet::{ContractAddress, get_block_timestamp}; use core::num::traits::zero::Zero; use combat_game::{ helpers::{pseudo_random::PseudoRandom::generate_random_u8}, - types::{ - battle_status::BattleStatus, - }, + types::{battle_status::BattleStatus}, }; #[derive(Copy, Drop, Serde, Debug, Introspect, PartialEq)] @@ -19,12 +17,14 @@ pub struct Battle { pub winner_id: ContractAddress, pub battle_type: u8, pub timestamp_start: u64, - pub timestamp_last_action: u64 + pub timestamp_last_action: u64, } #[generate_trait] pub impl BattleImpl of BattleTrait { - fn new(id: u256, player1: ContractAddress, player2: ContractAddress, battle_type: u8) -> Battle { + fn new( + id: u256, player1: ContractAddress, player2: ContractAddress, battle_type: u8, + ) -> Battle { let current_timestamp = get_block_timestamp(); let players = array![player1, player2]; Battle { @@ -39,14 +39,14 @@ pub impl BattleImpl of BattleTrait { .into(), ), status: BattleStatus::Waiting, - winner_id: Zero::zero(), + winner_id: Zero::zero(), battle_type: battle_type, timestamp_start: current_timestamp, - timestamp_last_action: current_timestamp + timestamp_last_action: current_timestamp, } } - fn end(ref self: Battle, winner: ContractAddress ) { + fn end(ref self: Battle, winner: ContractAddress) { self.status = BattleStatus::Finished.into(); self.winner_id = winner; self.timestamp_last_action = get_block_timestamp(); @@ -65,15 +65,22 @@ pub impl BattleImpl of BattleTrait { } fn switch_turn(ref self: Battle) { - self.current_turn = if self.current_turn == self.player1 { self.player2 } else { self.player1 }; + self + .current_turn = + if self.current_turn == self.player1 { + self.player2 + } else { + self.player1 + }; } - } #[cfg(test)] mod tests { + use core::num::traits::zero::Zero; use starknet::{contract_address_const}; use super::{Battle, BattleTrait}; + use combat_game::types::battle_status::BattleStatus; #[test] fn test_end() { @@ -82,8 +89,23 @@ mod tests { battle.end(winner); assert!(battle.winner_id == winner); + assert!(battle.status == BattleStatus::Finished); } + // #[test] + // fn test_update_timestamp() { + // let mut battle = testing_battle(); + // let timestamp_before = battle.timestamp_last_action; + // let winner = contract_address_const::<0x1>(); + // battle.end(winner); + // let timestamp_after = battle.timestamp_last_action; + + // println!("timestamp_before: {}", timestamp_before); + // println!("timestamp_after: {}", timestamp_after); + + // assert!(timestamp_after > timestamp_before); + // } + #[test] fn test_is_active() { let mut battle = testing_battle(); @@ -98,6 +120,35 @@ mod tests { assert!(battle.is_finished() == false, "Wrong battle status"); } + #[test] + fn test_is_finished_after_end() { + let mut battle = testing_battle(); + + assert!(battle.is_finished() == false, "Wrong battle status"); + let winner = contract_address_const::<0x1>(); + battle.end(winner); + + assert!(battle.is_finished() == true, "Battle should be finished after end"); + assert!(battle.status == BattleStatus::Finished, "Battle status should be Finished"); + } + + #[test] + fn test_switch_turn_multiple_times() { + let mut battle = testing_battle(); + let initial_turn = battle.current_turn; + + // First switch + battle.switch_turn(); + let after_first_switch = battle.current_turn; + assert!(after_first_switch != initial_turn, "Turn should switch"); + + // Second switch - should return to original player + battle.switch_turn(); + let after_second_switch = battle.current_turn; + assert!(after_second_switch == initial_turn, "Turn should switch back"); + assert!(after_second_switch != after_first_switch, "Turn should be different"); + } + #[test] fn test_switch_turn() { let mut battle = testing_battle(); @@ -108,10 +159,82 @@ mod tests { assert!(battle.current_turn != current_turn); } + #[test] + fn test_switch_turn_alternates_correctly() { + let mut battle = testing_battle(); + let player1 = battle.player1; + let player2 = battle.player2; + + // Ensure we know the starting turn + if battle.current_turn == player1 { + battle.switch_turn(); + assert!(battle.current_turn == player2, "Switch to player2"); + battle.switch_turn(); + assert!(battle.current_turn == player1, "Switch to player1"); + } else { + battle.switch_turn(); + assert!(battle.current_turn == player1, "Switch to player1"); + battle.switch_turn(); + assert!(battle.current_turn == player2, "Switch to player2"); + } + } + + #[test] + fn test_battle_status_transitions() { + let mut battle = testing_battle(); + + // Initial status should be Waiting + assert!(battle.status == BattleStatus::Waiting, "Initial status Waiting"); + + // End the battle + let winner = battle.player1; + battle.end(winner); + + // Status should now be Finished + assert!(battle.status == BattleStatus::Finished, "Status should be Finished"); + assert!(battle.is_finished(), "is_finished should return true"); + assert!(!battle.is_active(), "is_active should return false"); + } + + #[test] + fn test_battle_with_zero_addresses() { + let zero_address = Zero::zero(); + let battle = BattleTrait::new(1, zero_address, zero_address, 1); + + assert!(battle.player1 == zero_address, "Player1 should be zero"); + assert!(battle.player2 == zero_address, "Player2 should be zero"); + assert!(battle.current_turn == zero_address, "Current turn should be zero"); + } + + + #[test] + fn test_battle_consistency_after_operations() { + let mut battle = testing_battle(); + let original_id = battle.id; + let original_player1 = battle.player1; + let original_player2 = battle.player2; + let original_battle_type = battle.battle_type; + let original_timestamp_start = battle.timestamp_start; + + // Perform various operations + battle.switch_turn(); + battle.update_timestamp(); + battle.end(battle.player1); + + // Verify that core properties remain unchanged + assert!(battle.id == original_id, "ID should remain unchanged"); + assert!(battle.player1 == original_player1, "Player1 should remain unchanged"); + assert!(battle.player2 == original_player2, "Player2 should remain unchanged"); + assert!(battle.battle_type == original_battle_type, "Battle type should remain unchanged"); + assert!( + battle.timestamp_start == original_timestamp_start, + "Start timestamp should remain unchanged", + ); + } + // MOCK fn testing_battle() -> Battle { BattleTrait::new(1, contract_address_const::<0x1>(), contract_address_const::<0x2>(), 1) } } -