From 37995f9f8c3ccbb92a28b2107dc12db858495cfb Mon Sep 17 00:00:00 2001 From: Ajidokwu Sabo Date: Sun, 13 Jul 2025 00:25:47 +0100 Subject: [PATCH] feat: chance and community chest handling --- src/interfaces/IActions.cairo | 9 + src/systems/actions.cairo | 459 +++++++++++++++++++--------------- src/tests/test_world.cairo | 296 ++++++++++++++++++++++ 3 files changed, 566 insertions(+), 198 deletions(-) diff --git a/src/interfaces/IActions.cairo b/src/interfaces/IActions.cairo index dd9d5ec..f932f42 100644 --- a/src/interfaces/IActions.cairo +++ b/src/interfaces/IActions.cairo @@ -67,6 +67,15 @@ pub trait IActions { fn buy_house_or_hotel(ref self: T, property: Property) -> bool; fn sell_house_or_hotel(ref self: T, property_id: u8, game_id: u256) -> bool; + fn handle_community_chest(ref self: T, game_id: u256, random_index: u32) -> ByteArray; + fn handle_chance(ref self: T, game_id: u256, random_index: u32) -> ByteArray; + fn process_chance_card( + ref self: T, game: Game, player: GamePlayer, card: ByteArray, + ) -> (Game, GamePlayer); + + fn process_community_chest_card( + ref self: T, game: Game, player: GamePlayer, card: ByteArray, + ) -> (Game, GamePlayer); // Trading system // fn offer_trade( // ref self: T, diff --git a/src/systems/actions.cairo b/src/systems/actions.cairo index f96d1be..fa03da9 100644 --- a/src/systems/actions.cairo +++ b/src/systems/actions.cairo @@ -768,100 +768,23 @@ pub mod actions { world.write_model(@game); game } - } - - #[generate_trait] - impl InternalImpl of InternalTrait { - /// Use the default namespace "dojo_starter". This function is handy since the ByteArray - /// can't be const. - fn world_default(self: @ContractState) -> dojo::world::WorldStorage { - self.world(@"blockopoly") - } - - fn generate_chance_deck(ref self: ContractState) -> Array { - let mut deck: Array = array![]; - - deck.append("Advance to Go (Collect $200)"); - deck.append("Advance to Illinois Avenue - If you pass Go, collect $200"); - deck.append("Advance to St. Charles Place - If you pass Go, collect $200"); - deck.append("Advance token to nearest Utility. Pay 10x dice."); - deck.append("Advance token to nearest Railroad. Pay 2x rent."); - deck.append("Bank pays you dividend of $50"); - deck.append("Get out of Jail Free"); - deck.append("Go Back 3 Spaces"); - deck.append("Go to Jail dirctly do not pass Go do not collect $200"); - deck.append("Make general repairs - $25 house, $100 hotel"); - deck.append("Pay poor tax of $15"); - deck.append("Take a trip to Reading Railroad"); - deck.append("Take a walk on the Boardwalk"); - deck.append("Speeding fine $200"); - deck.append("Building loan matures - collect $150"); - - // self.shuffle_array(deck); - - deck - } - - // Count how many railroads the owner has - fn count_owner_railroads( - ref self: ContractState, owner: ContractAddress, game_id: u256, - ) -> u8 { - let mut count = 0; - let mut i = 1; - while i < 41_u32 { - let prop: Property = self.world_default().read_model((i, game_id)); - if prop.owner == owner && prop.property_type == PropertyType::RailRoad { - count += 1; - } - i += 1; - }; - count - } - - // Count how many utilities the owner has - fn count_owner_utilities( - ref self: ContractState, owner: ContractAddress, game_id: u256, - ) -> u8 { - let mut count = 0; - let mut i = 1; - while i < 41_u32 { - let prop: Property = self.world_default().read_model((i, game_id)); - if prop.owner == owner && prop.property_type == PropertyType::Utility { - count += 1; - } - i += 1; - }; - count - } - - - fn generate_chance_indices(ref self: ContractState) -> Array { - let mut indices: Array = array![]; - let cards = self.generate_chance_deck(); - let n = cards.len(); - let mut i = 0; - while i < n { - indices.append(i); - i += 1; - }; - indices - } fn handle_chance(ref self: ContractState, game_id: u256, random_index: u32) -> ByteArray { let mut world = self.world_default(); let mut game: Game = world.read_model(game_id); - let len = game.chance.len(); - if len == 0 { - game.chance = self.generate_chance_deck(); // returns Array + let mut len = game.chance.len(); + if len <= 1 { + game.chance = self.generate_chance_deck(); + len = game.chance.len(); world.write_model(@game); } - let draw_index = (random_index % (len)); - // Directly get the card ByteArray from game.chance (no further indexing needed) + let draw_index = random_index % len; + let card = game.chance[draw_index].clone(); - // Build a new deck without the drawn card + // Build new deck excluding drawn card let mut new_deck = array![]; let mut i = 0; while i < len { @@ -870,32 +793,28 @@ pub mod actions { } i += 1; }; - game.chance = new_deck.clone(); - + game.chance = new_deck; world.write_model(@game); card } - - fn handle_community_chest( ref self: ContractState, game_id: u256, random_index: u32, ) -> ByteArray { let mut world = self.world_default(); let mut game: Game = world.read_model(game_id); - let len = game.community.len(); - if len == 0 { - game.community = self.generate_community_chest_deck(); // Array + let mut len = game.community.len(); + if len <= 1 { + game.community = self.generate_community_chest_deck(); + len = game.community.len(); world.write_model(@game); } - let draw_index = (random_index % (len)); + let draw_index = random_index % len; - // Get the card directly from the community deck let card = game.community[draw_index].clone(); - // Build a new deck without the drawn card let mut new_deck = array![]; let mut i = 0; while i < len { @@ -905,51 +824,20 @@ pub mod actions { i += 1; }; game.community = new_deck; - world.write_model(@game); card } - - fn find_nearest(ref self: ContractState, player_pos: u8, utilities: Array) -> u8 { - let board_size: u8 = 40; - - let mut nearest_pos: u8 = *utilities[0]; - let mut smallest_distance = if *utilities[0] >= player_pos { - *utilities[0] - player_pos - } else { - board_size - (player_pos - *utilities[0]) - }; - - let len = utilities.len(); - let mut i = 1; - while i < len { - let utility_pos = *utilities[i]; - let distance = if utility_pos >= player_pos { - utility_pos - player_pos - } else { - board_size - (player_pos - utility_pos) - }; - - if distance < smallest_distance { - smallest_distance = distance; - nearest_pos = utility_pos; - } - i += 1; - }; - - nearest_pos - } - - fn process_chance_card( ref self: ContractState, mut game: Game, mut player: GamePlayer, card: ByteArray, ) -> (Game, GamePlayer) { // We'll decode by matching text. // NOTE: If you have enums or ids for cards, it's cleaner. With ByteArray, compare // strings. - + let mut world = self.world_default(); + let property = self.get_property(player.position, game.id); + assert(property.property_type == PropertyType::Chance, 'not on chance'); if card == "Advance to Go (Collect $200)" { player.position = 1; player.balance += 200; @@ -1014,32 +902,20 @@ pub mod actions { } else if card == "Building loan matures - collect $150" { player.balance += 150; } - + game = self.finish_turn(game); + world.write_model(@player); + world.write_model(@game); (game, player) } - fn get_properties_by_group( - ref self: ContractState, group_id: u8, game_id: u256, - ) -> Array { - let mut world = self.world_default(); - let mut group_properties: Array = array![]; - - let mut i = 0; // defaults to felt252 - while i < 41_u32 { - let prop: Property = world.read_model((i, game_id)); - if prop.group_id == group_id { - group_properties.append(prop); - } - i += 1; - }; - - group_properties - } - fn process_community_chest_card( ref self: ContractState, mut game: Game, mut player: GamePlayer, card: ByteArray, ) -> (Game, GamePlayer) { let mut world = self.world_default(); + let property = self.get_property(player.position, game.id); + assert( + property.property_type == PropertyType::CommunityChest, 'not on community chest', + ); if card == "Advance to Go (Collect $200)" { player.position = 1; player.balance += 200; @@ -1089,8 +965,170 @@ pub mod actions { player.balance += 100; } + game = self.finish_turn(game); + world.write_model(@player); + world.write_model(@game); (game, player) } + } + + #[generate_trait] + impl InternalImpl of InternalTrait { + /// Use the default namespace "dojo_starter". This function is handy since the ByteArray + /// can't be const. + fn world_default(self: @ContractState) -> dojo::world::WorldStorage { + self.world(@"blockopoly") + } + + fn generate_chance_deck(ref self: ContractState) -> Array { + let mut deck: Array = array![]; + + deck.append("Advance to Go (Collect $200)"); + deck.append("Advance to Illinois Avenue - If you pass Go, collect $200"); + deck.append("Advance to St. Charles Place - If you pass Go, collect $200"); + deck.append("Advance token to nearest Utility. Pay 10x dice."); + deck.append("Advance token to nearest Railroad. Pay 2x rent."); + deck.append("Bank pays you dividend of $50"); + deck.append("Get out of Jail Free"); + deck.append("Go Back 3 Spaces"); + deck.append("Go to Jail dirctly do not pass Go do not collect $200"); + deck.append("Make general repairs - $25 house, $100 hotel"); + deck.append("Pay poor tax of $15"); + deck.append("Take a trip to Reading Railroad"); + deck.append("Take a walk on the Boardwalk"); + deck.append("Speeding fine $200"); + deck.append("Building loan matures - collect $150"); + + // self.shuffle_array(deck); + + deck + } + + // Count how many railroads the owner has + fn count_owner_railroads( + ref self: ContractState, owner: ContractAddress, game_id: u256, + ) -> u8 { + let mut count = 0; + let mut i = 1; + while i < 41_u32 { + let prop: Property = self.world_default().read_model((i, game_id)); + if prop.owner == owner && prop.property_type == PropertyType::RailRoad { + count += 1; + } + i += 1; + }; + count + } + + // Count how many utilities the owner has + fn count_owner_utilities( + ref self: ContractState, owner: ContractAddress, game_id: u256, + ) -> u8 { + let mut count = 0; + let mut i = 1; + while i < 41_u32 { + let prop: Property = self.world_default().read_model((i, game_id)); + if prop.owner == owner && prop.property_type == PropertyType::Utility { + count += 1; + } + i += 1; + }; + count + } + + + fn generate_chance_indices(ref self: ContractState) -> Array { + let mut indices: Array = array![]; + let cards = self.generate_chance_deck(); + let n = cards.len(); + let mut i = 0; + while i < n { + indices.append(i); + i += 1; + }; + indices + } + + fn handle_chance(ref self: ContractState, game_id: u256, random_index: u32) -> ByteArray { + let mut world = self.world_default(); + let mut game: Game = world.read_model(game_id); + + let len = game.chance.len(); + if len == 0 { + game.chance = self.generate_chance_deck(); // returns Array + world.write_model(@game); + } + let draw_index = (random_index % (len)); + + // Directly get the card ByteArray from game.chance (no further indexing needed) + let card = game.chance[draw_index].clone(); + + // Build a new deck without the drawn card + let mut new_deck = array![]; + let mut i = 0; + while i < len { + if i != draw_index { + new_deck.append(game.chance[i].clone()); + } + i += 1; + }; + game.chance = new_deck.clone(); + + world.write_model(@game); + + card + } + + + fn find_nearest(ref self: ContractState, player_pos: u8, utilities: Array) -> u8 { + let board_size: u8 = 40; + + let mut nearest_pos: u8 = *utilities[0]; + let mut smallest_distance = if *utilities[0] >= player_pos { + *utilities[0] - player_pos + } else { + board_size - (player_pos - *utilities[0]) + }; + + let len = utilities.len(); + let mut i = 1; + while i < len { + let utility_pos = *utilities[i]; + let distance = if utility_pos >= player_pos { + utility_pos - player_pos + } else { + board_size - (player_pos - utility_pos) + }; + + if distance < smallest_distance { + smallest_distance = distance; + nearest_pos = utility_pos; + } + i += 1; + }; + + nearest_pos + } + + + fn get_properties_by_group( + ref self: ContractState, group_id: u8, game_id: u256, + ) -> Array { + let mut world = self.world_default(); + let mut group_properties: Array = array![]; + + let mut i = 0; // defaults to felt252 + while i < 41_u32 { + let prop: Property = world.read_model((i, game_id)); + if prop.group_id == group_id { + group_properties.append(prop); + } + i += 1; + }; + + group_properties + } + fn generate_community_chest_deck(ref self: ContractState) -> Array { let mut deck: Array = array![]; @@ -1947,62 +1985,87 @@ pub mod actions { let caller = get_caller_address(); let bank_address = get_contract_address(); - if property.owner == bank_address { - // Property is unowned - println!( - "This property '{}' is owned by the bank. It costs {}.", - property.name, - property.cost_of_property, - ); - } else if property.owner != caller { - // Property owned by someone else, calculate rent dynamically - let owner_railroads = self.count_owner_railroads(property.owner, property.game_id); - let owner_utilities = self.count_owner_utilities(property.owner, property.game_id); - - let rent_amount = property - .get_rent_amount(owner_railroads, owner_utilities, player.dice_rolled.into()); - - match property.property_type { - PropertyType::RailRoad => { - println!( - "This railroad '{}' is owned by {:?}. Player {:?} must pay rent: {}.", - property.name, - property.owner, - caller, - rent_amount, - ); - }, - PropertyType::Utility => { - println!( - "This utility '{}' is owned by {:?}. Player {:?} must pay rent: {}.", - property.name, - property.owner, - caller, - rent_amount, - ); - }, - PropertyType::Property => { + match property.property_type { + PropertyType::CommunityChest => { + println!( + "Player {:?} landed on Community Chest '{}'. Drawing a card...", + caller, + property.name, + ); + // you could call self.draw_community_chest_card() here + }, + PropertyType::Chance => { + println!( + "Player {:?} landed on Chance '{}'. Drawing a card...", + caller, + property.name, + ); + // you could call self.draw_chance_card() here + }, + _ => { + if property.owner == bank_address { println!( - "This property '{}' is owned by {:?}. Player {:?} must pay rent: {}.", + "This property '{}' is owned by the bank. It costs {}.", property.name, - property.owner, - caller, - rent_amount, + property.cost_of_property, ); - }, - _ => { + } else if property.owner != caller { + // Owned by someone else + let owner_railroads = self + .count_owner_railroads(property.owner, property.game_id); + let owner_utilities = self + .count_owner_utilities(property.owner, property.game_id); + + let rent_amount = property + .get_rent_amount( + owner_railroads, owner_utilities, player.dice_rolled.into(), + ); + + match property.property_type { + PropertyType::RailRoad => { + println!( + "This railroad '{}' is owned by {:?}. Player {:?} must pay rent: {}.", + property.name, + property.owner, + caller, + rent_amount, + ); + }, + PropertyType::Utility => { + println!( + "This utility '{}' is owned by {:?}. Player {:?} must pay rent: {}.", + property.name, + property.owner, + caller, + rent_amount, + ); + }, + PropertyType::Property => { + println!( + "This property '{}' is owned by {:?}. Player {:?} must pay rent: {}.", + property.name, + property.owner, + caller, + rent_amount, + ); + }, + _ => { + println!( + "This space '{}' is owned by {:?}. Player {:?} may owe rent: {}.", + property.name, + property.owner, + caller, + rent_amount, + ); + }, + } + } else { + // Player owns this property println!( - "This space '{}' is owned by {:?}. Player {:?} may owe rent: {}.", - property.name, - property.owner, - caller, - rent_amount, + "Player {:?} landed on their own property '{}'.", caller, property.name, ); - }, - } - } else { - // Property owned by caller - println!("Player {:?} landed on their own property '{}'.", caller, property.name); + } + }, } property diff --git a/src/tests/test_world.cairo b/src/tests/test_world.cairo index 4169030..b186664 100644 --- a/src/tests/test_world.cairo +++ b/src/tests/test_world.cairo @@ -1132,6 +1132,302 @@ mod tests { assert(aji.total_houses_owned == 8, 'house count error'); } + #[test] + fn test_community_chest() { + let caller_1 = contract_address_const::<'aji'>(); + let caller_2 = contract_address_const::<'collins'>(); + let caller_3 = contract_address_const::<'jerry'>(); + let caller_4 = contract_address_const::<'aliyu'>(); + let username = 'Ajidokwu'; + let username_1 = 'Collins'; + let username_2 = 'Jerry'; + let username_3 = 'Aliyu'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"actions").unwrap(); + let actions_system = IActionsDispatcher { contract_address }; + + testing::set_contract_address(caller_2); + actions_system.register_new_player(username_1); + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username); + + testing::set_contract_address(caller_3); + actions_system.register_new_player(username_2); + + testing::set_contract_address(caller_4); + actions_system.register_new_player(username_3); + + testing::set_contract_address(caller_1); + actions_system.create_new_game(GameType::PublicGame, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_2); + actions_system.join_game(PlayerSymbol::Dog, 1); + + testing::set_contract_address(caller_3); + actions_system.join_game(PlayerSymbol::Car, 1); + + testing::set_contract_address(caller_4); + actions_system.join_game(PlayerSymbol::Iron, 1); + + testing::set_contract_address(caller_1); + let started = actions_system.start_game(1); + assert(started, 'Game start fail'); + + testing::set_contract_address(caller_1); + actions_system.move_player(1, 4); + + let ppt = actions_system.get_property(5, 1); + let mut community = actions_system.handle_community_chest(1, 3); + println!("community chest 1 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 2: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 3: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 4: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 5: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 6: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 7: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 8: {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 9 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 10 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 11 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 12 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 13 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 14 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 15 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 16 : {}", community); + community = actions_system.handle_community_chest(1, 3); + println!("community chest 17 : {}", community); + } + + #[test] + fn test_community_chance() { + let caller_1 = contract_address_const::<'aji'>(); + let caller_2 = contract_address_const::<'collins'>(); + let caller_3 = contract_address_const::<'jerry'>(); + let caller_4 = contract_address_const::<'aliyu'>(); + let username = 'Ajidokwu'; + let username_1 = 'Collins'; + let username_2 = 'Jerry'; + let username_3 = 'Aliyu'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"actions").unwrap(); + let actions_system = IActionsDispatcher { contract_address }; + + testing::set_contract_address(caller_2); + actions_system.register_new_player(username_1); + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username); + + testing::set_contract_address(caller_3); + actions_system.register_new_player(username_2); + + testing::set_contract_address(caller_4); + actions_system.register_new_player(username_3); + + testing::set_contract_address(caller_1); + actions_system.create_new_game(GameType::PublicGame, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_2); + actions_system.join_game(PlayerSymbol::Dog, 1); + + testing::set_contract_address(caller_3); + actions_system.join_game(PlayerSymbol::Car, 1); + + testing::set_contract_address(caller_4); + actions_system.join_game(PlayerSymbol::Iron, 1); + + testing::set_contract_address(caller_1); + let started = actions_system.start_game(1); + assert(started, 'Game start fail'); + + testing::set_contract_address(caller_1); + actions_system.move_player(1, 4); + + let ppt = actions_system.get_property(5, 1); + + let mut chance = actions_system.handle_chance(1, 3); + println!("chance 1 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 2 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 3 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 4 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 5 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 6 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 7 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 8 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 9 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 10 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 11 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 12 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 13 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 14 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 15 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 16 : {}", chance); + chance = actions_system.handle_chance(1, 3); + println!("chance 17 : {}", chance); + } + #[test] + fn test_process_chance() { + let caller_1 = contract_address_const::<'aji'>(); + let caller_2 = contract_address_const::<'collins'>(); + let caller_3 = contract_address_const::<'jerry'>(); + let caller_4 = contract_address_const::<'aliyu'>(); + let username = 'Ajidokwu'; + let username_1 = 'Collins'; + let username_2 = 'Jerry'; + let username_3 = 'Aliyu'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"actions").unwrap(); + let actions_system = IActionsDispatcher { contract_address }; + + testing::set_contract_address(caller_2); + actions_system.register_new_player(username_1); + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username); + + testing::set_contract_address(caller_3); + actions_system.register_new_player(username_2); + + testing::set_contract_address(caller_4); + actions_system.register_new_player(username_3); + + testing::set_contract_address(caller_1); + actions_system.create_new_game(GameType::PublicGame, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_2); + actions_system.join_game(PlayerSymbol::Dog, 1); + + testing::set_contract_address(caller_3); + actions_system.join_game(PlayerSymbol::Car, 1); + + testing::set_contract_address(caller_4); + actions_system.join_game(PlayerSymbol::Iron, 1); + + testing::set_contract_address(caller_1); + let started = actions_system.start_game(1); + assert(started, 'Game start fail'); + + testing::set_contract_address(caller_1); + actions_system.move_player(1, 7); + + let mut g = actions_system.retrieve_game(1); + println!("array len b4 : {} ", g.chance.len()); + + let mut p = actions_system.retrieve_game_player(caller_1, 1); + + let mut chance = actions_system.handle_chance(1, 3); + println!("chance 1 : {}", chance); + let (game, ply) = actions_system.process_chance_card(g, p, chance); + + assert(ply.position == 12, 'position error'); + assert(ply.balance == 1430, 'bal error'); + } + #[test] + fn test_process_community_chest() { + let caller_1 = contract_address_const::<'aji'>(); + let caller_2 = contract_address_const::<'collins'>(); + let caller_3 = contract_address_const::<'jerry'>(); + let caller_4 = contract_address_const::<'aliyu'>(); + let username = 'Ajidokwu'; + let username_1 = 'Collins'; + let username_2 = 'Jerry'; + let username_3 = 'Aliyu'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"actions").unwrap(); + let actions_system = IActionsDispatcher { contract_address }; + + testing::set_contract_address(caller_2); + actions_system.register_new_player(username_1); + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username); + + testing::set_contract_address(caller_3); + actions_system.register_new_player(username_2); + + testing::set_contract_address(caller_4); + actions_system.register_new_player(username_3); + + testing::set_contract_address(caller_1); + actions_system.create_new_game(GameType::PublicGame, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_2); + actions_system.join_game(PlayerSymbol::Dog, 1); + + testing::set_contract_address(caller_3); + actions_system.join_game(PlayerSymbol::Car, 1); + + testing::set_contract_address(caller_4); + actions_system.join_game(PlayerSymbol::Iron, 1); + + testing::set_contract_address(caller_1); + let started = actions_system.start_game(1); + assert(started, 'Game start fail'); + + testing::set_contract_address(caller_1); + actions_system.move_player(1, 3); + + let mut g = actions_system.retrieve_game(1); + println!("array len b4 : {} ", g.chance.len()); + + let mut p = actions_system.retrieve_game_player(caller_1, 1); + + let mut community_chest = actions_system.handle_community_chest(1, 3); + println!("community_chest: {}", community_chest); + + let (_, ply) = actions_system.process_community_chest_card(g, p, community_chest); + + assert(ply.position == 3, 'position error'); + assert(ply.balance == 1550, 'bal error'); + } + #[test] fn test_play_game() { let caller_1 = contract_address_const::<'aji'>();