diff --git a/src/interfaces/IWorld.cairo b/src/interfaces/IWorld.cairo index 3a28672..d246e1e 100644 --- a/src/interfaces/IWorld.cairo +++ b/src/interfaces/IWorld.cairo @@ -9,4 +9,9 @@ pub trait IWorld { fn register_new_player(ref self: T, username: felt252, is_bot: bool); fn get_username_from_address(self: @T, address: ContractAddress) -> felt252; fn retrieve_player(ref self: T, addr: ContractAddress) -> Player; + fn create_new_game( + ref self: T, game_mode: GameMode, player_symbol: PlayerSymbol, number_of_players: u8, + ) -> u64; + fn create_new_game_id(ref self: T) -> u64; + fn retrieve_game(ref self: T, game_id: u64) -> Game; } diff --git a/src/systems/world.cairo b/src/systems/world.cairo index a7201ae..21ba787 100644 --- a/src/systems/world.cairo +++ b/src/systems/world.cairo @@ -105,6 +105,99 @@ pub mod world { ); } + fn create_new_game_id(ref self: ContractState) -> u64 { + let mut world = self.world_default(); + let mut game_counter: GameCounter = world.read_model('v0'); + let new_val = game_counter.current_val + 1; + game_counter.current_val = new_val; + world.write_model(@game_counter); + new_val + } + + fn create_new_game( + ref self: ContractState, + game_mode: GameMode, + player_symbol: PlayerSymbol, + number_of_players: u8, + ) -> u64 { + // Get default world + let mut world = self.world_default(); + + assert(number_of_players >= 2 && number_of_players <= 8, 'invalid no of players'); + + // Get the account address of the caller + let caller_address = get_caller_address(); + let caller_username = self.get_username_from_address(caller_address); + assert(caller_username != 0, 'PLAYER NOT REGISTERED'); + + let game_id = self.create_new_game_id(); + let timestamp = get_block_timestamp(); + + let player_hat = match player_symbol { + PlayerSymbol::Hat => caller_username, + _ => 0, + }; + + let player_car = match player_symbol { + PlayerSymbol::Car => caller_username, + _ => 0, + }; + let player_dog = match player_symbol { + PlayerSymbol::Dog => caller_username, + _ => 0, + }; + let player_thimble = match player_symbol { + PlayerSymbol::Thimble => caller_username, + _ => 0, + }; + let player_iron = match player_symbol { + PlayerSymbol::Iron => caller_username, + _ => 0, + }; + let player_battleship = match player_symbol { + PlayerSymbol::Battleship => caller_username, + _ => 0, + }; + let player_boot = match player_symbol { + PlayerSymbol::Boot => caller_username, + _ => 0, + }; + let player_wheelbarrow = match player_symbol { + PlayerSymbol::Wheelbarrow => caller_username, + _ => 0, + }; + + // Create a new game + let mut new_game: Game = GameTrait::new( + game_id, + caller_username, + game_mode, + player_hat, + player_car, + player_dog, + player_thimble, + player_iron, + player_battleship, + player_boot, + player_wheelbarrow, + number_of_players, + ); + + // If it's a multiplayer game, set status to Pending, + // else mark it as Ongoing (for single-player). + if game_mode == GameMode::MultiPlayer { + new_game.status = GameStatus::Pending; + } else { + new_game.status = GameStatus::Ongoing; + } + + world.write_model(@new_game); + + world.emit_event(@GameCreated { game_id, timestamp }); + + game_id + } + fn retrieve_player(ref self: ContractState, addr: ContractAddress) -> Player { // Get default world @@ -113,6 +206,14 @@ pub mod world { player } + + fn retrieve_game(ref self: ContractState, game_id: u64) -> Game { + // Get default world + let mut world = self.world_default(); + //get the game state + let game: Game = world.read_model(game_id); + game + } } #[generate_trait] @@ -124,4 +225,3 @@ pub mod world { } } } - diff --git a/src/tests/test_world.cairo b/src/tests/test_world.cairo index b48802a..8ad49d9 100644 --- a/src/tests/test_world.cairo +++ b/src/tests/test_world.cairo @@ -149,5 +149,72 @@ mod tests { testing::set_contract_address(caller_1); actions_system.register_new_player(username, true); } -} + #[test] + fn test_create_game() { + let caller_1 = contract_address_const::<'aji'>(); + let username = 'Ajidokwu'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"world").unwrap(); + let actions_system = IWorldDispatcher { contract_address }; + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username, false); + + testing::set_contract_address(caller_1); + let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); + assert(game_id == 1, 'Wrong game id'); + println!("game_id: {}", game_id); + + let game: Game = actions_system.retrieve_game(game_id); + assert(game.created_by == username, 'Wrong game id'); + println!("creator: {}", game.created_by); + } + + #[test] + fn test_create_two_games() { + let caller_1 = contract_address_const::<'aji'>(); + + let username = 'Ajidokwu'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"world").unwrap(); + let actions_system = IWorldDispatcher { contract_address }; + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username, false); + + testing::set_contract_address(caller_1); + let _game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_1); + let game_id_1 = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); + assert(game_id_1 == 2, 'Wrong game id'); + println!("game_id: {}", game_id_1); + } + + #[test] + #[should_panic] + fn test_create_game_unregistered_player() { + let caller_1 = contract_address_const::<'aji'>(); + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"world").unwrap(); + let actions_system = IWorldDispatcher { contract_address }; + + testing::set_contract_address(caller_1); + let game_id = actions_system.create_new_game(GameMode::MultiPlayer, PlayerSymbol::Hat, 4); + assert(game_id == 1, 'Wrong game id'); + println!("game_id: {}", game_id); + } +}