From 5d3c5f0b003f6dda3023ddd315f53206112f9db4 Mon Sep 17 00:00:00 2001 From: broody Date: Wed, 5 Jul 2023 20:53:47 -0700 Subject: [PATCH] chore(contracts): move location spawn into create game --- src/components/location.cairo | 26 ++++++- src/constants.cairo | 13 +++- src/events.cairo | 4 +- src/systems/create.cairo | 125 ++++++++++++-------------------- src/systems/join.cairo | 6 +- src/systems/travel.cairo | 2 +- src/tests/create.cairo | 47 ++---------- src/tests/travel.cairo | 20 ++--- web/src/pages/[game]/travel.tsx | 3 + 9 files changed, 110 insertions(+), 136 deletions(-) diff --git a/src/components/location.cairo b/src/components/location.cairo index e22dd90d..50c9bd9c 100644 --- a/src/components/location.cairo +++ b/src/components/location.cairo @@ -1,5 +1,29 @@ #[derive(Component, Copy, Drop, Serde)] struct Location { - id: u32, + id: u8, } +#[derive(Serde, Copy, Drop)] +enum LocationId { + None: (), + Bronx: (), + Queens: (), + Brooklyn: (), + JerseyCity: (), + CentralPark: (), + ConeyIsland: (), +} + +impl LocationIdIntoU8 of Into { + fn into(self: LocationId) -> u8 { + match self { + LocationId::None(()) => 0, + LocationId::Bronx(()) => 1, + LocationId::Queens(()) => 2, + LocationId::Brooklyn(()) => 3, + LocationId::JerseyCity(()) => 4, + LocationId::CentralPark(()) => 5, + LocationId::ConeyIsland(()) => 6, + } + } +} diff --git a/src/constants.cairo b/src/constants.cairo index da4e8c98..01eb9f88 100644 --- a/src/constants.cairo +++ b/src/constants.cairo @@ -1,2 +1,13 @@ const BALANCE_UPPER_BOUND: felt252 = 0x10000000000000000; -const SCALING_FACTOR: u128 = 10000; \ No newline at end of file +const SCALING_FACTOR: u128 = 10000; + +const MAX_LOCATIONS: u8 = 6; +const MAX_PRODUCTS: u8 = 6; + +const TRAVEL_RISK: u8 = 30; +const HURT_RISK: u8 = 30; +const MUGGED_RISK: u8 = 30; +const ARRESTED_RISK: u8 = 10; + +const MARKET_QUANTITY: usize = 1000; +const MARKET_CASH: u128 = 1000000; // 100USD diff --git a/src/events.cairo b/src/events.cairo index 24638a2d..1e4985ca 100644 --- a/src/events.cairo +++ b/src/events.cairo @@ -53,8 +53,8 @@ struct Sold { struct Traveled { game_id: u32, player_id: felt252, - from_location_id: u32, - to_location_id: u32, + from_location_id: u8, + to_location_id: u8, } #[derive(Drop, Serde)] diff --git a/src/systems/create.cairo b/src/systems/create.cairo index 2411eb94..86b2ddea 100644 --- a/src/systems/create.cairo +++ b/src/systems/create.cairo @@ -1,74 +1,3 @@ -#[system] -mod create_location { - use traits::Into; - use box::BoxTrait; - use array::ArrayTrait; - use debug::PrintTrait; - - use dojo::world::Context; - - use rollyourown::events::{emit, LocationCreated}; - use rollyourown::components::risks::Risks; - use rollyourown::components::game::Game; - use rollyourown::components::location::Location; - use rollyourown::components::market::Market; - use rollyourown::components::drug::Drug; - use rollyourown::constants::SCALING_FACTOR; - - const MAX_PRODUCTS: u32 = 6; - - fn execute( - ctx: Context, - game_id: u32, - travel_risk: u8, - hurt_risk: u8, - mugged_risk: u8, - arrested_risk: u8 - ) -> u32 { - let block_info = starknet::get_block_info().unbox(); - let player_id: felt252 = ctx.origin.into(); - - let game_sk: Query = game_id.into(); - let game = get !(ctx.world, game_sk, Game); - assert(game.creator == player_id, 'only creator'); - assert(game.start_time >= block_info.block_timestamp, 'already started'); - - let location_id = ctx.world.uuid(); - set !( - ctx.world, - (game_id, location_id).into(), - ( - Location { - id: location_id - }, Risks { - travel: travel_risk, - hurt: hurt_risk, - mugged: mugged_risk, - arrested: arrested_risk, - } - ) - ); - - let mut i: u32 = 0; - loop { - if i >= MAX_PRODUCTS { - break (); - } - let quantity = 1000; - let cash = 100 * SCALING_FACTOR; - set !(ctx.world, (game_id, location_id, i).into(), (Market { cash, quantity })); - i += 1; - } - - let mut values = array::ArrayTrait::new(); - serde::Serde::serialize(@LocationCreated { game_id, location_id }, ref values); - emit(ctx, 'LocationCreated', values.span()); - - location_id - } -} - - #[system] mod create_game { use array::ArrayTrait; @@ -80,8 +9,14 @@ mod create_game { use rollyourown::components::game::Game; use rollyourown::components::player::Cash; use rollyourown::components::player::Stats; - use rollyourown::components::location::Location; - use rollyourown::constants::SCALING_FACTOR; + use rollyourown::components::risks::Risks; + use rollyourown::components::market::Market; + use rollyourown::components::drug::Drug; + use rollyourown::components::location::{Location, LocationId}; + use rollyourown::constants::{ + SCALING_FACTOR, MAX_LOCATIONS, MAX_PRODUCTS, TRAVEL_RISK, HURT_RISK, MUGGED_RISK, + ARRESTED_RISK, MARKET_CASH, MARKET_QUANTITY + }; fn execute( ctx: Context, start_time: u64, max_players: usize, max_turns: usize @@ -115,19 +50,53 @@ mod create_game { }, Cash { amount: 100 * SCALING_FACTOR // $100 }, Location { - id: 0_u32 + id: LocationId::None(()).into() } ) ); - // location entities + // TODO: spawn locations with risk profiles balanced + // with market pricing + let mut location_index: u8 = 1; + loop { + if location_index >= MAX_LOCATIONS { + break (); + } + set !( + ctx.world, + (game_id, location_index).into(), + ( + Location { + id: location_index + }, Risks { + travel: TRAVEL_RISK, + hurt: HURT_RISK, + mugged: MUGGED_RISK, + arrested: ARRESTED_RISK + } + ) + ) + + let mut drug_index: u8 = 0; + loop { + if drug_index >= MAX_PRODUCTS { + break (); + } + set !( + ctx.world, + (game_id, location_index, drug_index).into(), + (Market { cash: MARKET_CASH, quantity: MARKET_QUANTITY }) + ); + drug_index += 1; + } + + location_index += 1; + } let mut values = array::ArrayTrait::new(); serde::Serde::serialize( - @GameCreated { - game_id, creator: player_id, start_time, max_players, max_turns - }, + @GameCreated { game_id, creator: player_id, start_time, max_players, max_turns }, ref values ); emit(ctx, 'GameCreated', values.span()); diff --git a/src/systems/join.cairo b/src/systems/join.cairo index b33a37f0..81b0e137 100644 --- a/src/systems/join.cairo +++ b/src/systems/join.cairo @@ -7,7 +7,9 @@ mod join_game { use dojo::world::Context; use rollyourown::events::{emit, PlayerJoined}; - use rollyourown::components::{game::Game, player::{Cash, Stats}, location::Location}; + use rollyourown::components::game::Game; + use rollyourown::components::player::{Cash, Stats}; + use rollyourown::components::location::{Location, LocationId}; use rollyourown::constants::SCALING_FACTOR; fn execute(ctx: Context, game_id: u32) -> felt252 { @@ -30,7 +32,7 @@ mod join_game { }, Cash { amount: 100 * SCALING_FACTOR // $100 }, Location { - id: 0_u32 + id: LocationId::None(()).into() } ) ); diff --git a/src/systems/travel.cairo b/src/systems/travel.cairo index 061ab9cb..3f57388d 100644 --- a/src/systems/travel.cairo +++ b/src/systems/travel.cairo @@ -15,7 +15,7 @@ mod travel { // 2. Determine if a random travel event occurs and apply it if necessary. // 3. Update the players location to the next_location_id. // 4. Update the new locations supply based on random events. - fn execute(ctx: Context, game_id: u32, next_location_id: u32) -> bool { + fn execute(ctx: Context, game_id: u32, next_location_id: u8) -> bool { let game = get !(ctx.world, game_id.into(), Game); assert(game.tick(), 'game cannot progress'); diff --git a/src/tests/create.cairo b/src/tests/create.cairo index 5430744b..ff676ee7 100644 --- a/src/tests/create.cairo +++ b/src/tests/create.cairo @@ -27,7 +27,7 @@ use rollyourown::components::risks::{risks, Risks}; use rollyourown::systems::travel::travel; use rollyourown::systems::trade::{buy, sell}; use rollyourown::systems::join::join_game; -use rollyourown::systems::create::{create_game, create_location}; +use rollyourown::systems::create::create_game; use rollyourown::constants::SCALING_FACTOR; const START_TIME: u64 = 0; @@ -38,7 +38,7 @@ const HURT_RISK: u8 = 9; const MUGGED_RISK: u8 = 7; const ARRESTED_RISK: u8 = 6; -fn spawn_game() -> (ContractAddress, felt252, felt252) { +fn spawn_game() -> (ContractAddress, u32, felt252) { let mut components = array::ArrayTrait::new(); components.append(game::TEST_CLASS_HASH); components.append(stats::TEST_CLASS_HASH); @@ -50,7 +50,6 @@ fn spawn_game() -> (ContractAddress, felt252, felt252) { let mut systems = array::ArrayTrait::new(); systems.append(create_game::TEST_CLASS_HASH); - systems.append(create_location::TEST_CLASS_HASH); systems.append(join_game::TEST_CLASS_HASH); systems.append(travel::TEST_CLASS_HASH); systems.append(buy::TEST_CLASS_HASH); @@ -65,7 +64,7 @@ fn spawn_game() -> (ContractAddress, felt252, felt252) { let mut res = world.execute('create_game'.into(), spawn_game_calldata.span()); assert(res.len() > 0, 'did not spawn'); - let (game_id, player_id) = serde::Serde::<(felt252, felt252)>::deserialize(ref res) + let (game_id, player_id) = serde::Serde::<(u32, felt252)>::deserialize(ref res) .expect('spawn deserialization failed'); let mut res = world.entity('Game'.into(), game_id.into(), 0, 0); assert(res.len() > 0, 'game not found'); @@ -108,55 +107,21 @@ fn spawn_player(world_address: ContractAddress, game_id: felt252) -> felt252 { player_id } -fn spawn_location(world_address: ContractAddress, game_id: felt252) -> felt252 { - let world = IWorldDispatcher { contract_address: world_address }; - - let mut spawn_location_calldata = array::ArrayTrait::::new(); - spawn_location_calldata.append(game_id); - spawn_location_calldata.append(TRAVEL_RISK.into()); - spawn_location_calldata.append(HURT_RISK.into()); - spawn_location_calldata.append(MUGGED_RISK.into()); - spawn_location_calldata.append(ARRESTED_RISK.into()); - - let mut res = world.execute('create_location'.into(), spawn_location_calldata.span()); - assert(res.len() > 0, 'did not spawn'); - - let location_id = serde::Serde::::deserialize(ref res) - .expect('spawn deserialization failed'); - let mut res = world.entity('Risks'.into(), (game_id, location_id).into(), 0, 0); - assert(res.len() > 0, 'loc not found'); - - let risks = serde::Serde::::deserialize(ref res).expect('loc deserialization failed'); - assert(risks.travel == TRAVEL_RISK, 'travel risk mismatch'); - assert(risks.hurt == HURT_RISK, 'hurt risk mismatch'); - assert(risks.mugged == MUGGED_RISK, 'mugged risk mismatch'); - assert(risks.arrested == ARRESTED_RISK, 'arrested risk mismatch'); - - location_id -} #[test] #[available_gas(100000000)] -fn test_spawn_locations() { +fn test_create_game() { let (world_address, game_id, _) = spawn_game(); - let location_one = spawn_location(world_address, game_id); - let location_two = spawn_location(world_address, game_id); let res = IWorldDispatcher { contract_address: world_address - }.entity('Location'.into(), (game_id, location_one).into(), 0, 0); + }.entity('Location'.into(), (game_id, 0).into(), 0, 0); assert(res.len() > 0, 'no location 1'); let res = IWorldDispatcher { contract_address: world_address - }.entity('Location'.into(), (game_id, location_two).into(), 0, 0); + }.entity('Location'.into(), (game_id, 1).into(), 0, 0); assert(res.len() > 0, 'no location 2'); -} - -#[test] -#[available_gas(100000000)] -fn test_spawn_player() { - let (world_address, game_id, _) = spawn_game(); //creator auto joins let (players, _) = IWorldDispatcher { contract_address: world_address diff --git a/src/tests/travel.cairo b/src/tests/travel.cairo index bb37e50e..1762b3ac 100644 --- a/src/tests/travel.cairo +++ b/src/tests/travel.cairo @@ -11,20 +11,19 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use dojo::test_utils::spawn_test_world; -use rollyourown::components::location::{location, Location}; -use rollyourown::tests::create::{spawn_game, spawn_location, spawn_player}; +use rollyourown::components::location::{location, Location, LocationId}; +use rollyourown::tests::create::{spawn_game, spawn_player}; #[test] #[available_gas(110000000)] fn test_travel() { let (world_address, game_id, player_id) = spawn_game(); // creator auto joins - let location_one = spawn_location(world_address, game_id); - let location_two = spawn_location(world_address, game_id); let world = IWorldDispatcher { contract_address: world_address }; + let bronx_id: u8 = LocationId::Bronx(()).into(); let mut travel_calldata = array::ArrayTrait::::new(); - travel_calldata.append(game_id); - travel_calldata.append(location_one); + travel_calldata.append(game_id.into()); + travel_calldata.append(bronx_id.into()); world.execute('travel'.into(), travel_calldata.span()); @@ -32,11 +31,12 @@ fn test_travel() { assert(res.len() > 0, 'no player location'); let location = serde::Serde::::deserialize(ref res).expect('deserialization failed'); - assert(location.id.into() == location_one, 'incorrect travel'); + assert(location.id == LocationId::Bronx(()).into(), 'incorrect travel'); + let queens_id: u8 = LocationId::Queens(()).into(); let mut travel_calldata = array::ArrayTrait::::new(); - travel_calldata.append(game_id); - travel_calldata.append(location_two); + travel_calldata.append(game_id.into()); + travel_calldata.append(queens_id.into()); world.execute('travel'.into(), travel_calldata.span()); @@ -44,5 +44,5 @@ fn test_travel() { assert(res.len() > 0, 'no player location'); let location = serde::Serde::::deserialize(ref res).expect('deserialization failed'); - assert(location.id.into() == location_two, 'incorrect travel'); + assert(location.id == LocationId::Queens(()).into(), 'incorrect travel'); } diff --git a/web/src/pages/[game]/travel.tsx b/web/src/pages/[game]/travel.tsx index fa26b976..88f71ff2 100644 --- a/web/src/pages/[game]/travel.tsx +++ b/web/src/pages/[game]/travel.tsx @@ -19,11 +19,13 @@ import { Map } from "@/components/map"; import { Locations, travelTo } from "@/hooks/state"; import { motion } from "framer-motion"; import { LocationProps, useUiStore, getLocationByName } from "@/hooks/ui"; +import { useRyoWorld } from "@/hooks/useRyoWorld"; export default function Travel() { const router = useRouter(); const [target, setTarget] = useState(Locations.Central); const { locations } = useUiStore.getState(); + const { travel } = useRyoWorld(); const [locationSlug, setLocationSlug] = useState(""); @@ -134,6 +136,7 @@ export default function Travel() { w={["full", "auto"]} onClick={() => { travelTo(target); + router.push(`/0x123/location/${locationSlug}`); }} >{`Travel to ${target}`}