Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(contracts): move location spawn into create game #83

Merged
merged 1 commit into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/components/location.cairo
Original file line number Diff line number Diff line change
@@ -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<LocationId, u8> {
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,
}
}
}
13 changes: 12 additions & 1 deletion src/constants.cairo
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
const BALANCE_UPPER_BOUND: felt252 = 0x10000000000000000;
const SCALING_FACTOR: u128 = 10000;
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
4 changes: 2 additions & 2 deletions src/events.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
125 changes: 47 additions & 78 deletions src/systems/create.cairo
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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());
Expand Down
6 changes: 4 additions & 2 deletions src/systems/join.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -30,7 +32,7 @@ mod join_game {
}, Cash {
amount: 100 * SCALING_FACTOR // $100
}, Location {
id: 0_u32
id: LocationId::None(()).into()
}
)
);
Expand Down
2 changes: 1 addition & 1 deletion src/systems/travel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down
47 changes: 6 additions & 41 deletions src/tests/create.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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');
Expand Down Expand Up @@ -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::<felt252>::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::<felt252>::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::<Risks>::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
Expand Down
20 changes: 10 additions & 10 deletions src/tests/travel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ 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::<felt252>::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());

let mut res = world.entity('Location'.into(), (game_id, player_id).into(), 0, 0);
assert(res.len() > 0, 'no player location');

let location = serde::Serde::<Location>::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::<felt252>::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());

let mut res = world.entity('Location'.into(), (game_id, player_id).into(), 0, 0);
assert(res.len() > 0, 'no player location');

let location = serde::Serde::<Location>::deserialize(ref res).expect('deserialization failed');
assert(location.id.into() == location_two, 'incorrect travel');
assert(location.id == LocationId::Queens(()).into(), 'incorrect travel');
}