diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..9549799 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,37 @@ +name: Bug Report +description: Report a bug +labels: [ "bug" ] +body: + - type: dropdown + id: service-name + attributes: + label: Which service is your bug related to? + multiple: true + options: + - Frontend + - Contracts + validations: + required: true + + - type: textarea + id: what-happened + attributes: + label: What happened + description: Describe the issue here. + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Trace + description: Please provide output of the error. + validations: + required: false + + - type: checkboxes + id: verified-not-exists + attributes: + label: Is there an existing issue for this? + options: + - label: I have searched the existing issues and verified no issue exits for this problem. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..0634204 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,21 @@ +name: Feature request +description: Suggest a feature +body: + - type: dropdown + id: service-name + attributes: + label: Which service is your feature related to? + multiple: true + options: + - Frontend + - Contracts + validations: + required: true + + - type: textarea + id: Suggestion + attributes: + label: Feature Request + description: Describe the feature(s) you would like to be added. + validations: + required: true \ No newline at end of file diff --git a/Scarb.lock b/Scarb.lock new file mode 100644 index 0000000..eb2e65b --- /dev/null +++ b/Scarb.lock @@ -0,0 +1,22 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "dojo" +version = "0.5.1" +source = "git+https://github.com/dojoengine/dojo?tag=v0.6.0-alpha.3#9b2bf3e465be5efeeb7f41032c15d35c46d90002" +dependencies = [ + "dojo_plugin", +] + +[[package]] +name = "dojo_plugin" +version = "0.3.11" +source = "git+https://github.com/dojoengine/dojo?tag=v0.3.11#1e651b5d4d3b79b14a7d8aa29a92062fcb9e6659" + +[[package]] +name = "zknight" +version = "0.0.0" +dependencies = [ + "dojo", +] diff --git a/Scarb.toml b/Scarb.toml index d84711f..805bf18 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,15 +1,14 @@ [package] -cairo-version = "2.2.0" +cairo-version = "2.4.0" name = "zknight" -version = "0.1.0" +version = "0.0.0" +edition = "2023_10" [cairo] sierra-replace-ids = true [dependencies] -starknet = ">=2.2.0" -alexandria_data_structures = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "46c8d8ab9e3bfb68b70a29b3246f809cd8bf70e4" } -dojo = { git = "https://github.com/dojoengine/dojo.git", tag = "v0.3.1" } +dojo = { git = "https://github.com/dojoengine/dojo", tag = "v0.6.0-alpha.3" } [[target.dojo]] @@ -17,13 +16,12 @@ dojo = { git = "https://github.com/dojoengine/dojo.git", tag = "v0.3.1" } initializer_class_hash = "0xbeef" [tool.dojo.env] +# Katana rpc_url = "http://localhost:5050/" -# Default account for katana with seed = 0 -account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" +account_address = "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03" private_key = "0x1800000000300000180000000000030000000000003006001800006600" -# world_address = "0x5797dca16591ca89ac11a7946e962185dfad886f029d91bb57339eeb94c57fa" -# Madara testnet -# rpc_url = "https://api.cartridge.gg/x/shinai/madara" -# account_address = "0x2" -# private_key = "0xc1cf1490de1352865301bb8705143f3ef938f97fdf892f1090dcb5ac7bcd1d" +# Dev +# rpc_url = "https://api.cartridge.gg/x/paved-dev/katana/" +# account_address = "0x68d2fe2d7b67ef40d9567f96fdc6925eb6c8a103ecde715a17c108afc3652e5" +# private_key = "0x69c450373bce35581f17586b7a4fdc9ad49ba30ea4340607df8f08864f36a8a" diff --git a/log.txt b/log.txt deleted file mode 100644 index 5e6db02..0000000 --- a/log.txt +++ /dev/null @@ -1,279 +0,0 @@ - Updating git repository https://github.com/keep-starknet-strange/alexandria - Updating git repository https://github.com/dojoengine/dojo - Updating git repository https://github.com/dojoengine/dojo -running 1 tests -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x7 - -[DEBUG]  (raw: 0x2 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x2 - -[DEBUG]  (raw: 0x5 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x6 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x3 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x7 - -[DEBUG]  (raw: 0x1 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x5 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x5 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x6 - -[DEBUG]  (raw: 0x1 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x4 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x6 - -[DEBUG] (raw: 0x0 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x3 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x5 - -[DEBUG] (raw: 0x0 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x3 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x4 - -[DEBUG] (raw: 0x0 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x3 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x3 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x1 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x3 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG] (raw: 0x0 - -[DEBUG]  (raw: 0x4 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG]  (raw: 0x1 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG] (raw: 0x0 - -[DEBUG]  (raw: 0x4 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG] (raw: 0x0 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] TURN (raw: 0x5455524e - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] BAR (raw: 0x424152 - -[DEBUG] (raw: 0x0 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -[DEBUG] BOW (raw: 0x424f57 - -[DEBUG] (raw: 0x0 - -[DEBUG]  (raw: 0x4 - -[DEBUG] (raw: 0x0 - -[DEBUG] WIZ (raw: 0x57495a - -[DEBUG] (raw: 0x0 - -[DEBUG]  (raw: 0x4 - -[DEBUG]  (raw: 0x2 - -test zknight::tests::spawn::test_spawn ... fail (gas usage est.: 705058734) -failures: - zknight::tests::spawn::test_spawn - panicked with [149087707159844663916361888893382174920923888182497288816189708034873648997 ('Target position is not in range'), 23583600924385842957889778338389964899652 ('ENTRYPOINT_FAILED'), ]. - -error: test result: FAILED. 0 passed; 1 failed; 0 ignored diff --git a/scripts/default_auth.sh b/scripts/default_auth.sh deleted file mode 100644 index 8982501..0000000 --- a/scripts/default_auth.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -euo pipefail -pushd $(dirname "$0")/.. - -export WORLD_ADDRESS="0x7d1f066a910bd86f532fa9ca66766722c20d47462fb99fb2fb0e1030262f9c5"; - -# enable system -> component authorizations -COMPONENTS=("Position" "Moves" ) - -for component in ${COMPONENTS[@]}; do - sozo auth writer $component spawn --world $WORLD_ADDRESS -done - -for component in ${COMPONENTS[@]}; do - sozo auth writer $component move --world $WORLD_ADDRESS -done - -echo "Default authorizations have been successfully set." \ No newline at end of file diff --git a/scripts/katana.sh b/scripts/katana.sh new file mode 100755 index 0000000..f0fc45a --- /dev/null +++ b/scripts/katana.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -euo pipefail +pushd $(dirname "$0")/.. + +export STARKNET_RPC_URL="http://localhost:5050"; + +export DOJO_WORLD_ADDRESS=$(cat ./target/dev/manifest.json | jq -r '.world.address') + +export PLAY_ADDRESS=$(cat ./target/dev/manifest.json | jq -r '.contracts[] | select(.name == "zknight::systems::play::play" ).address') + +echo "---------------------------------------------------------------------------" +echo world : $DOJO_WORLD_ADDRESS +echo " " +echo play : $PLAY_ADDRESS +echo "---------------------------------------------------------------------------" + +# enable system -> component authorizations +MODELS=("Game" "Map" "Tile" "Character") +ACTIONS=($PLAY_ADDRESS) + +command="sozo auth grant writer " +for model in "${MODELS[@]}"; do + for action in "${ACTIONS[@]}"; do + command+="$model,$action " + done +done +eval "$command" + +echo "Default authorizations have been successfully set." \ No newline at end of file diff --git a/src/constants.cairo b/src/constants.cairo index b3ef9ed..ee8100b 100644 --- a/src/constants.cairo +++ b/src/constants.cairo @@ -1,3 +1,11 @@ +// World + +fn WORLD() -> starknet::ContractAddress { + starknet::contract_address_const::< + 0x390c8aa16fc6c44658719d4d1d6c5d49e04d09119faec615c01790e5c9cbc9a + >() +} + const NAME: felt252 = 'NAME'; const PLAYER: felt252 = 'PLAYER'; const SIZE: u32 = 8; diff --git a/src/events.cairo b/src/events.cairo index 378e030..38305d5 100644 --- a/src/events.cairo +++ b/src/events.cairo @@ -1,6 +1,6 @@ use dojo::world::{Context, IWorldDispatcherTrait}; use serde::Serde; -use array::{ArrayTrait, SpanTrait}; +use core::array::{ArrayTrait, SpanTrait}; use starknet::ContractAddress; // helper function to emit events, eventually dojo will diff --git a/src/lib.cairo b/src/lib.cairo index c353058..82e5f2b 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,14 +1,14 @@ mod constants; -mod datastore; +mod store; -mod entities { +mod types { mod foe; mod barbarian; mod bowman; mod wizard; } -mod components { +mod models { mod game; mod map; mod tile; @@ -16,7 +16,8 @@ mod components { } mod systems { - mod player; + mod interfaces; + mod play; } #[cfg(test)] diff --git a/src/components/character.cairo b/src/models/character.cairo similarity index 76% rename from src/components/character.cairo rename to src/models/character.cairo index d203a41..477f663 100644 --- a/src/components/character.cairo +++ b/src/models/character.cairo @@ -1,7 +1,11 @@ -use array::SpanTrait; +// Core imports + +use core::array::SpanTrait; + +// Internal imports use zknight::constants::{KNIGHT_TYPE, BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE}; -use zknight::components::tile::Tile; +use zknight::models::tile::Tile; #[derive(Model, Copy, Drop, Serde)] struct Character { @@ -15,18 +19,7 @@ struct Character { hit: u8, } -trait CharacterTrait { - fn new(health: u8) -> Character; - fn get_knight_type() -> u8; - fn get_barbarian_type() -> u8; - fn get_bowman_type() -> u8; - fn get_wizard_type() -> u8; - fn is_dead(self: Character) -> bool; - fn set_index(ref self: Character, index: u32); - fn take_damage(ref self: Character, hitter: u8, damage: u8); - fn reset_damage(ref self: Character); -} - +#[generate_trait] impl CharacterImpl of CharacterTrait { fn new(health: u8) -> Character { Character { game_id: 0, _type: 0, health: health, index: 0, hitter: 0, hit: 0, } @@ -68,9 +61,14 @@ impl CharacterImpl of CharacterTrait { #[cfg(test)] mod tests { - use array::ArrayTrait; + // Core imports + + use core::debug::PrintTrait; + use core::array::ArrayTrait; + + // Local imports + use super::{Character, CharacterTrait}; - use debug::PrintTrait; #[test] #[available_gas(1_000_000)] diff --git a/src/components/game.cairo b/src/models/game.cairo similarity index 76% rename from src/components/game.cairo rename to src/models/game.cairo index dd74c23..cc46d7b 100644 --- a/src/components/game.cairo +++ b/src/models/game.cairo @@ -1,3 +1,5 @@ +// Starknet imports + use starknet::ContractAddress; #[derive(Model, Copy, Drop, Serde)] @@ -9,11 +11,7 @@ struct Game { seed: felt252, } -trait GameTrait { - fn new(player: felt252, game_id: u32, seed: felt252) -> Game; - fn set_over(ref self: Game, over: bool); -} - +#[generate_trait] impl GameImpl of GameTrait { fn new(player: felt252, game_id: u32, seed: felt252) -> Game { Game { player: player, game_id: game_id, over: false, seed: seed, } diff --git a/src/components/map.cairo b/src/models/map.cairo similarity index 85% rename from src/components/map.cairo rename to src/models/map.cairo index dd04315..51945f6 100644 --- a/src/components/map.cairo +++ b/src/models/map.cairo @@ -1,15 +1,18 @@ -use array::{ArrayTrait, SpanTrait}; -use traits::Into; -use dict::Felt252DictTrait; -use poseidon::poseidon_hash_span; +// Core imports -use alexandria_data_structures::array_ext::SpanTraitExt; +use core::array::{ArrayTrait, SpanTrait}; +use core::traits::Into; +use core::poseidon::poseidon_hash_span; -use zknight::components::tile::{Tile, TileTrait}; +// Internal imports + +use zknight::models::tile::{Tile, TileTrait}; use zknight::constants::{ NAME, SIZE, GROUND_TYPE, HOLE_TYPE, KNIGHT_TYPE, BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE }; +// Constants + const MULTIPLIER: u128 = 10000; #[derive(Model, Copy, Drop, Serde)] @@ -24,33 +27,17 @@ struct Map { name: felt252, } -// @notice Types #[derive(Serde, Copy, Drop, PartialEq)] enum Type { - Ground: (), - Hole: (), - Knight: (), - Barbarian: (), - Bowman: (), - Wizard: (), -} - -// Constants - -trait MapTrait { - fn new(game_id: u32, level: u32, name: felt252) -> Map; - fn compose(self: Map, x: u32, y: u32) -> u32; - fn decompose(self: Map, index: u32) -> (u32, u32); - fn generate(self: Map, seed: felt252) -> Span; - fn get_type(self: Map, raw_type: u8) -> Type; - fn get_raw_type(self: Map, _type: Type) -> u8; - fn increase_score(ref self: Map, score: u8); - fn decrease_score(ref self: Map, score: u8); - fn set_over(ref self: Map, over: bool); - fn increase_level(ref self: Map); - fn set_spawn(ref self: Map, spawn: bool); + Ground, + Hole, + Knight, + Barbarian, + Bowman, + Wizard, } +#[generate_trait] impl MapImpl of MapTrait { fn new(game_id: u32, level: u32, name: felt252) -> Map { Map { @@ -224,11 +211,11 @@ fn _uniform_random(seed: felt252, max: u128) -> u128 { #[cfg(test)] mod tests { - use array::{ArrayTrait, SpanTrait}; + use core::array::{ArrayTrait, SpanTrait}; use zknight::constants::SEED; - use zknight::components::tile::{Tile, TileTrait}; + use zknight::models::tile::{Tile, TileTrait}; use super::{Map, MapTrait, Type}; - use debug::PrintTrait; + use core::debug::PrintTrait; #[test] #[available_gas(10_000_000)] diff --git a/src/components/tile.cairo b/src/models/tile.cairo similarity index 85% rename from src/components/tile.cairo rename to src/models/tile.cairo index 745f14e..ea7150d 100644 --- a/src/components/tile.cairo +++ b/src/models/tile.cairo @@ -1,4 +1,4 @@ -use array::{SpanTrait, ArrayTrait}; +use core::array::{SpanTrait, ArrayTrait}; use zknight::constants::{ GROUND_TYPE, HOLE_TYPE, KNIGHT_TYPE, BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE, SIZE @@ -17,27 +17,7 @@ struct Tile { y: u32, } -trait TileTrait { - fn new(x: u32, y: u32) -> Tile; - fn is_ground(self: Tile) -> bool; - fn is_hole(self: Tile) -> bool; - fn is_knight(self: Tile) -> bool; - fn is_barbarian(self: Tile) -> bool; - fn is_bowman(self: Tile) -> bool; - fn is_wizard(self: Tile) -> bool; - fn is_character(self: Tile) -> bool; - fn is_zero(self: Tile) -> bool; - fn is_equal(self: Tile, b: Tile) -> bool; - fn is_close(self: Tile, b: Tile) -> bool; - fn distance(self: Tile, b: Tile) -> u32; - fn is_include(self: Tile, tiles: Span) -> bool; - fn set_ground_type(ref self: Tile); - fn set_knight_type(ref self: Tile); - fn set_barbarian_type(ref self: Tile); - fn set_bowman_type(ref self: Tile); - fn set_wizard_type(ref self: Tile); -} - +#[generate_trait] impl TileImpl of TileTrait { fn new(x: u32, y: u32) -> Tile { Tile { game_id: 0, level: 0, index: 0, _type: 0, x, y } @@ -137,11 +117,19 @@ impl TileImpl of TileTrait { #[cfg(test)] mod tests { - use array::{SpanTrait, ArrayTrait}; + // Core imports + + use core::debug::PrintTrait; + use core::array::{SpanTrait, ArrayTrait}; + + // Internal imports + use zknight::constants::SIZE; - use zknight::components::map::_compose; + use zknight::models::map::_compose; + + // Local imports + use super::{Tile, TileTrait}; - use debug::PrintTrait; #[test] #[available_gas(100_000)] diff --git a/src/datastore.cairo b/src/store.cairo similarity index 55% rename from src/datastore.cairo rename to src/store.cairo index 57f7d4f..7383ae7 100644 --- a/src/datastore.cairo +++ b/src/store.cairo @@ -1,4 +1,4 @@ -//! DataStore struct and component management methods. +//! Store struct and component management methods. // Dojo imports @@ -6,55 +6,47 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; // Components imports -use zknight::components::character::{Character, CharacterTrait}; -use zknight::components::game::{Game, GameTrait}; -use zknight::components::map::{Map, MapTrait}; -use zknight::components::tile::{Tile, TileTrait}; +use zknight::models::character::{Character, CharacterTrait}; +use zknight::models::game::{Game, GameTrait}; +use zknight::models::map::{Map, MapTrait}; +use zknight::models::tile::{Tile, TileTrait}; // Internal imports use zknight::constants; -/// DataStore struct. +/// Store struct. #[derive(Drop)] -struct DataStore { +struct Store { world: IWorldDispatcher } -/// Trait to initialize, get and set components from the DataStore. -trait DataStoreTrait { - fn new(world: IWorldDispatcher) -> DataStore; - fn game(ref self: DataStore, player: felt252) -> Game; - fn map(ref self: DataStore, game: Game) -> Map; - fn character(ref self: DataStore, game: Game, _type: u8) -> Character; - fn tile(ref self: DataStore, game: Game, map: Map, index: u32) -> Tile; - fn ground_neighbors(ref self: DataStore, game: Game, map: Map, tile: Tile) -> Span; - fn set_game(ref self: DataStore, game: Game); - fn set_map(ref self: DataStore, map: Map); - fn set_character(ref self: DataStore, character: Character); - fn set_tile(ref self: DataStore, tile: Tile); -} - -/// Implementation of the `DataStoreTrait` trait for the `DataStore` struct. -impl DataStoreImpl of DataStoreTrait { - fn new(world: IWorldDispatcher) -> DataStore { - DataStore { world: world } +/// Implementation of the `StoreTrait` trait for the `Store` struct. +#[generate_trait] +impl StoreImpl of StoreTrait { + #[inline(always)] + fn new(world: IWorldDispatcher) -> Store { + Store { world: world } } - fn game(ref self: DataStore, player: felt252) -> Game { + #[inline(always)] + fn game(ref self: Store, player: felt252) -> Game { get!(self.world, player, (Game)) } - fn map(ref self: DataStore, game: Game) -> Map { + #[inline(always)] + fn map(ref self: Store, game: Game) -> Map { get!(self.world, game.game_id, (Map)) } - fn character(ref self: DataStore, game: Game, _type: u8) -> Character { + #[inline(always)] + fn character(ref self: Store, game: Game, _type: u8) -> Character { let character_key = (game.game_id, _type); get!(self.world, character_key.into(), (Character)) } - fn tile(ref self: DataStore, game: Game, map: Map, index: u32) -> Tile { + #[inline(always)] + fn tile(ref self: Store, game: Game, map: Map, index: u32) -> Tile { let tile_key = (game.game_id, map.level, index); let mut tile: Tile = get!(self.world, tile_key.into(), (Tile)); // Could be unknown entity if GROUND_TYPE, then set coordinates @@ -66,7 +58,8 @@ impl DataStoreImpl of DataStoreTrait { tile } - fn ground_neighbors(ref self: DataStore, game: Game, map: Map, tile: Tile) -> Span { + #[inline(always)] + fn ground_neighbors(ref self: Store, game: Game, map: Map, tile: Tile) -> Span { let mut neighbors: Array = ArrayTrait::new(); // [Compute] Left neighbor @@ -108,19 +101,23 @@ impl DataStoreImpl of DataStoreTrait { neighbors.span() } - fn set_game(ref self: DataStore, game: Game) { + #[inline(always)] + fn set_game(ref self: Store, game: Game) { set!(self.world, (game)); } - fn set_map(ref self: DataStore, map: Map) { + #[inline(always)] + fn set_map(ref self: Store, map: Map) { set!(self.world, (map)); } - fn set_character(ref self: DataStore, character: Character) { + #[inline(always)] + fn set_character(ref self: Store, character: Character) { set!(self.world, (character)); } - fn set_tile(ref self: DataStore, tile: Tile) { + #[inline(always)] + fn set_tile(ref self: Store, tile: Tile) { set!(self.world, (tile)); } } diff --git a/src/systems/create.cairo b/src/systems/create.cairo deleted file mode 100644 index 227d299..0000000 --- a/src/systems/create.cairo +++ /dev/null @@ -1,108 +0,0 @@ -#[system] -mod Create { - use array::{ArrayTrait, SpanTrait}; - use traits::Into; - - use dojo::world::{Context, IWorld}; - - use zknight::components::game::{Game, GameTrait}; - use zknight::components::map::{Map, MapTrait, Type}; - use zknight::components::tile::{Tile}; - use zknight::components::character::Character; - - use zknight::constants::{KNIGHT_HEALTH, MOB_HEALTH}; - - fn execute(ctx: Context, player: felt252, seed: felt252, name: felt252) { - // [Command] Game entity - let game_id = ctx.world.uuid(); - let mut game = GameTrait::new(player, game_id, seed); - set!(ctx.world, (game)); - - // [Command] Map entity - let map = MapTrait::new(game_id, 1, name); - set!(ctx.world, (map)); - - // [Command] Characters and Tiles - let raw_types = map.generate(game.seed); - let mut index = 0; - let length = raw_types.len(); - loop { - if index == length { - break; - } - - let raw_type = *raw_types[index]; - let tile_type = map.get_type(raw_type); - let (x, y) = map.decompose(index); - let tile = Tile { game_id, level: map.level, x, y, index, _type: raw_type }; - - // [Command] Set Tile and Character entities - match tile_type { - Type::Ground(()) => { // - }, - Type::Hole(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - }, - Type::Knight(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Set Character entity - let knight = Character { - game_id: game_id, - _type: raw_type, - health: KNIGHT_HEALTH, - index, - hitter: 0, - hit: 0 - }; - set!(ctx.world, (knight)); - }, - Type::Barbarian(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Set Character entity - let barbarian = Character { - game_id: game_id, - _type: raw_type, - health: MOB_HEALTH, - index, - hitter: 0, - hit: 0 - }; - set!(ctx.world, (barbarian)); - }, - Type::Bowman(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Set Character entity - let bowman = Character { - game_id: game_id, - _type: raw_type, - health: MOB_HEALTH, - index, - hitter: 0, - hit: 0 - }; - set!(ctx.world, (bowman)); - }, - Type::Wizard(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Set Character entity - let wizard = Character { - game_id: game_id, - _type: raw_type, - health: MOB_HEALTH, - index, - hitter: 0, - hit: 0 - }; - set!(ctx.world, (wizard)); - }, - }; - - index += 1; - } - } -} diff --git a/src/systems/interfaces.cairo b/src/systems/interfaces.cairo new file mode 100644 index 0000000..9455fb0 --- /dev/null +++ b/src/systems/interfaces.cairo @@ -0,0 +1,18 @@ +// Dojo imports + +use dojo::world::IWorldDispatcher; + +// Interface definition + +#[starknet::interface] +trait IPlay { + fn create( + self: @TContractState, + world: IWorldDispatcher, + player: felt252, + seed: felt252, + name: felt252, + ); + fn play(self: @TContractState, world: IWorldDispatcher, player: felt252, x: u32, y: u32,); + fn spawn(self: @TContractState, world: IWorldDispatcher, player: felt252,); +} diff --git a/src/systems/play.cairo b/src/systems/play.cairo index f5398e1..be5b200 100644 --- a/src/systems/play.cairo +++ b/src/systems/play.cairo @@ -1,361 +1,558 @@ -#[system] -mod Play { - use array::{ArrayTrait, SpanTrait}; - use dict::Felt252DictTrait; - use traits::Into; - use nullable::NullableTrait; +#[starknet::contract] +mod play { + // Core imports - use dojo::world::{Context, IWorld}; + use core::array::{ArrayTrait, SpanTrait}; + use core::poseidon::poseidon_hash_span; + // Dojo imports + + use dojo::world; + use dojo::world::IWorldDispatcher; + use dojo::world::IWorldDispatcherTrait; + use dojo::world::IWorldProvider; + use dojo::world::IDojoResourceProvider; + + // Internal imports + + use zknight::models::character::{Character, CharacterTrait}; + use zknight::models::game::{Game, GameTrait}; + use zknight::models::map::{Map, MapTrait, Type}; + use zknight::models::tile::{Tile, TileTrait}; + use zknight::types::foe::{Foe, FoeTrait}; use zknight::constants::{ - GROUND_TYPE, KNIGHT_DAMAGE, BARBARIAN_DAMAGE, BOWMAN_DAMAGE, WIZARD_DAMAGE + GROUND_TYPE, KNIGHT_DAMAGE, BARBARIAN_DAMAGE, BOWMAN_DAMAGE, WIZARD_DAMAGE, KNIGHT_HEALTH, + MOB_HEALTH, WORLD, }; - use zknight::components::game::{Game, GameTrait}; - use zknight::components::map::{Map, MapTrait, Type}; - use zknight::components::tile::{Tile, TileTrait}; - use zknight::components::character::{Character, CharacterTrait}; - use zknight::entities::foe::{Foe, FoeTrait}; - - use debug::PrintTrait; - - fn execute(ctx: Context, player: felt252, x: u32, y: u32) { - // [Command] Game entity - let mut game: Game = get!(ctx.world, player, (Game)); - - // [Check] Game is not over - assert(!game.over, 'Game is over'); - - // [Command] Map entity - let mut map: Map = get!(ctx.world, game.game_id, (Map)); - - // [Command] Tile entities - let length = map.size * map.size; - let mut tiles: Felt252Dict> = Default::default(); - let mut index = 0; - loop { - if index == length { - break; - } - let tile_key = (game.game_id, map.level, index); - let mut tile = get!(ctx.world, tile_key.into(), (Tile)); - // Could be unknown entity if GROUND_TYPE, then set coordinates - if tile._type == GROUND_TYPE { - let (tile_x, tile_y) = map.decompose(index); - tile.x = tile_x; - tile.y = tile_y; - } - tiles.insert(index.into(), nullable_from_box(BoxTrait::new(tile))); - index += 1; - }; - - // [Command] Knight entity - let knight_key = (game.game_id, CharacterTrait::get_knight_type()); - let mut knight_char = get!(ctx.world, knight_key.into(), (Character)); - knight_char.reset_damage(); - let mut knight_tile = tiles.get(knight_char.index.into()).deref(); - - // [Command] Barbarian entity - let barbarian_key = (game.game_id, CharacterTrait::get_barbarian_type()); - let mut barbarian_char = get!(ctx.world, barbarian_key.into(), (Character)); - barbarian_char.reset_damage(); - let mut barbarian_tile = tiles.get(barbarian_char.index.into()).deref(); - - // [Command] Bowman entity - let bowman_key = (game.game_id, CharacterTrait::get_bowman_type()); - let mut bowman_char = get!(ctx.world, bowman_key.into(), (Character)); - bowman_char.reset_damage(); - let mut bowman_tile = tiles.get(bowman_char.index.into()).deref(); - - // [Command] Wizard entity - let wizard_key = (game.game_id, CharacterTrait::get_wizard_type()); - let mut wizard_char = get!(ctx.world, wizard_key.into(), (Character)); - wizard_char.reset_damage(); - let mut wizard_tile = tiles.get(wizard_char.index.into()).deref(); - - // [Check] Target position is in range, target is not a hole - let new_index = map.compose(x, y); - let mut new_tile = tiles.get(new_index.into()).deref(); - assert(knight_tile.is_close(new_tile), 'Target position is not in range'); - assert(!new_tile.is_hole(), 'Target position is a hole'); - - // [Effect] Pass if target is knight, Attack if the target is a foe, move otherwise - if new_tile.is_knight() { // Pass - } else if new_tile.is_barbarian() && barbarian_char.health > 0 { - // [Command] Update Character - barbarian_char.take_damage(knight_char._type, KNIGHT_DAMAGE); - set!(ctx.world, (barbarian_char)); - - // [Check] Foe death - if barbarian_char.health == 0 { - // [Command] Update Tile - new_tile.set_ground_type(); - set!(ctx.world, (new_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if new_tile.is_bowman() && bowman_char.health > 0 { - // [Command] Update Character - bowman_char.take_damage(knight_char._type, KNIGHT_DAMAGE); - set!(ctx.world, (bowman_char)); - - // [Check] Foe death - if bowman_char.health == 0 { - // [Command] Update Tile - new_tile.set_ground_type(); - set!(ctx.world, (new_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if new_tile.is_wizard() && wizard_char.health > 0 { - // [Command] Update Character - wizard_char.take_damage(knight_char._type, KNIGHT_DAMAGE); - set!(ctx.world, (wizard_char)); - - // [Check] Foe death - if wizard_char.health == 0 { - // [Command] Update Tile - new_tile.set_ground_type(); - set!(ctx.world, (new_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; - } else { - // [Effect] Move Knight, update the knight position in storage and hashmap - let tile = Tile { - game_id: game.game_id, - level: map.level, - index: new_index, - _type: knight_char._type, - x, - y - }; - tiles.insert(index.into(), nullable_from_box(BoxTrait::new(tile))); - // [Command] Update previous tile - knight_tile.set_ground_type(); - tiles.insert(knight_tile.index.into(), nullable_from_box(BoxTrait::new(knight_tile))); - set!(ctx.world, (knight_tile)); - // [Command] Update new tile - new_tile.set_knight_type(); - tiles.insert(new_tile.index.into(), nullable_from_box(BoxTrait::new(new_tile))); - set!(ctx.world, (tile)); - knight_tile = new_tile; // Update knight tile for the next instructions - // [Command] Update Character - knight_char.set_index(new_index); - set!(ctx.world, (knight_char)); + use zknight::store::{Store, StoreTrait}; + use zknight::systems::interfaces::IPlay; + + // Errors + + mod errors {} + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl DojoResourceProviderImpl of IDojoResourceProvider { + fn dojo_resource(self: @ContractState) -> felt252 { + 'play' } + } + + #[abi(embed_v0)] + impl WorldProviderImpl of IWorldProvider { + fn world(self: @ContractState) -> IWorldDispatcher { + IWorldDispatcher { contract_address: WORLD() } + } + } - // [Effect] Barbarian: Attack if possible, move otherwise - let barbarian: Foe = FoeTrait::new(barbarian_char.health, barbarian_char._type); - if barbarian.can_attack(barbarian_tile, knight_tile) && knight_char.health > 0 { - // [Effect] Hit each character in the line of sight - let hits = barbarian.get_hits(barbarian_tile, knight_tile, map.size); - let len = hits.len(); - let mut i = 0; + #[abi(embed_v0)] + impl Play of IPlay { + fn create( + self: @ContractState, + world: IWorldDispatcher, + player: felt252, + seed: felt252, + name: felt252, + ) { + // [Setup] Datastore + let mut store: Store = StoreTrait::new(world); + + // [Command] Game entity + let game_id = world.uuid(); + let mut game = GameTrait::new(player, game_id, seed); + store.set_game(game); + + // [Command] Map entity + let map = MapTrait::new(game_id, 1, name); + store.set_map(map); + + // [Command] Characters and Tiles + let raw_types = map.generate(game.seed); + let mut index = 0; + let length = raw_types.len(); loop { - if i == len { + if index == length { break; } - let hit_index = *hits.at(i); - let mut hit_tile = tiles.get(hit_index.into()).deref(); - if hit_tile.is_knight() { - // [Command] Update Character - knight_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); - set!(ctx.world, (knight_char)); - } else if hit_tile.is_bowman() && bowman_char.health > 0 { - // [Command] Update Character - bowman_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); - set!(ctx.world, (bowman_char)); - // [Check] Foe death - if bowman_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - set!(ctx.world, (hit_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if hit_tile.is_wizard() && wizard_char.health > 0 { - // [Command] Update Character - wizard_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); - set!(ctx.world, (wizard_char)); - // [Check] Foe death - if wizard_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - set!(ctx.world, (hit_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; + + let raw_type = *raw_types[index]; + let tile_type = map.get_type(raw_type); + let (x, y) = map.decompose(index); + let tile = Tile { game_id, level: map.level, x, y, index, _type: raw_type }; + + // [Command] Set Tile and Character entities + match tile_type { + Type::Ground(()) => { // + }, + Type::Hole(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + }, + Type::Knight(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Set Character entity + let knight = Character { + game_id: game_id, + _type: raw_type, + health: KNIGHT_HEALTH, + index, + hitter: 0, + hit: 0 + }; + store.set_character(knight); + }, + Type::Barbarian(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Set Character entity + let barbarian = Character { + game_id: game_id, + _type: raw_type, + health: MOB_HEALTH, + index, + hitter: 0, + hit: 0 + }; + store.set_character(barbarian); + }, + Type::Bowman(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Set Character entity + let bowman = Character { + game_id: game_id, + _type: raw_type, + health: MOB_HEALTH, + index, + hitter: 0, + hit: 0 + }; + store.set_character(bowman); + }, + Type::Wizard(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Set Character entity + let wizard = Character { + game_id: game_id, + _type: raw_type, + health: MOB_HEALTH, + index, + hitter: 0, + hit: 0 + }; + store.set_character(wizard); + }, }; - i += 1; - }; - } else if barbarian.can_move() && knight_char.health > 0 { - // [Effect] Move Barbarian, update the barbarian position in storage and hashmap - let new_index = barbarian.next(barbarian_tile, knight_tile, map.size, ref tiles); - let mut new_tile = tiles.get(new_index.into()).deref(); - // [Command] Update previous tile - barbarian_tile.set_ground_type(); - tiles - .insert( - barbarian_tile.index.into(), nullable_from_box(BoxTrait::new(barbarian_tile)) - ); - set!(ctx.world, (barbarian_tile)); - // [Command] Update new tile - new_tile.set_barbarian_type(); - tiles.insert(new_tile.index.into(), nullable_from_box(BoxTrait::new(new_tile))); - set!(ctx.world, (new_tile)); - barbarian_tile = new_tile; // Update knight tile for the next instructions - // [Command] Update Character - barbarian_char.set_index(new_index); - set!(ctx.world, (barbarian_char)); + + index += 1; + } } - // [Effect] Bowman: Attack if possible, move otherwise - let bowman: Foe = FoeTrait::new(bowman_char.health, bowman_char._type); - if bowman.can_attack(bowman_tile, knight_tile) && knight_char.health > 0 { - // [Effect] Hit each character in the line of sight, but stop at first hit - let hits = bowman.get_hits(bowman_tile, knight_tile, map.size); - let len = hits.len(); - let mut i = 0; - loop { - if i == len { - break; - } - let hit_index = *hits.at(i); - let mut hit_tile = tiles.get(hit_index.into()).deref(); - if hit_tile.is_knight() { - // [Command] Update Character - knight_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); - set!(ctx.world, (knight_char)); - // [Break] Hits stop at the first character - break; - } else if hit_tile.is_barbarian() && barbarian_char.health > 0 { - // [Command] Update Character - barbarian_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); - set!(ctx.world, (barbarian_char)); - // [Check] Foe death - if barbarian_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - set!(ctx.world, (hit_tile)); - // [Effect] Update the map score - map.increase_score(11); + fn play(self: @ContractState, world: IWorldDispatcher, player: felt252, x: u32, y: u32,) { + // [Setup] Datastore + let mut store: Store = StoreTrait::new(world); + + // [Command] Game entity + let mut game: Game = store.game(player); + + // [Check] Game is not over + assert(!game.over, 'Game is over'); + + // [Command] Map entity + let mut map: Map = store.map(game); + + // [Command] Knight entity + let mut knight_char = store.character(game, CharacterTrait::get_knight_type()); + knight_char.reset_damage(); + let mut knight_tile = store.tile(game, map, knight_char.index); + + // [Command] Barbarian entity + let mut barbarian_char = store.character(game, CharacterTrait::get_barbarian_type()); + barbarian_char.reset_damage(); + let mut barbarian_tile = store.tile(game, map, barbarian_char.index); + + // [Command] Bowman entity + let mut bowman_char = store.character(game, CharacterTrait::get_bowman_type()); + bowman_char.reset_damage(); + let mut bowman_tile = store.tile(game, map, bowman_char.index); + + // [Command] Wizard entity + let mut wizard_char = store.character(game, CharacterTrait::get_wizard_type()); + wizard_char.reset_damage(); + let mut wizard_tile = store.tile(game, map, wizard_char.index); + + // [Check] Target position is in range, target is not a hole + let new_index = map.compose(x, y); + let mut new_tile = store.tile(game, map, new_index); + assert(knight_tile.is_close(new_tile), 'Target position is not in range'); + assert(!new_tile.is_hole(), 'Target position is a hole'); + + // [Effect] Pass if target is knight, Attack if the target is a foe, move otherwise + if new_tile.is_knight() { // Pass + } else if new_tile.is_barbarian() && barbarian_char.health > 0 { + // [Command] Update Character + barbarian_char.take_damage(knight_char._type, KNIGHT_DAMAGE); + store.set_character(barbarian_char); + + // [Check] Foe death + if barbarian_char.health == 0 { + // [Command] Update Tile + new_tile.set_ground_type(); + store.set_tile(new_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + } else if new_tile.is_bowman() && bowman_char.health > 0 { + // [Command] Update Character + bowman_char.take_damage(knight_char._type, KNIGHT_DAMAGE); + store.set_character(bowman_char); + + // [Check] Foe death + if bowman_char.health == 0 { + // [Command] Update Tile + new_tile.set_ground_type(); + store.set_tile(new_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + } else if new_tile.is_wizard() && wizard_char.health > 0 { + // [Command] Update Character + wizard_char.take_damage(knight_char._type, KNIGHT_DAMAGE); + store.set_character(wizard_char); + + // [Check] Foe death + if wizard_char.health == 0 { + // [Command] Update Tile + new_tile.set_ground_type(); + store.set_tile(new_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + } else { + // [Effect] Move Knight, update the knight position in storage and hashmap + // [Command] Update previous tile + knight_tile.set_ground_type(); + store.set_tile(knight_tile); + // [Command] Update new tile + new_tile.set_knight_type(); + store.set_tile(new_tile); + knight_tile = new_tile; // Update knight tile for the next instructions + // [Command] Update Character + knight_char.set_index(new_index); + store.set_character(knight_char); + } + + // [Effect] Barbarian: Attack if possible, move otherwise + let barbarian: Foe = FoeTrait::new(barbarian_char.health, barbarian_char._type); + if barbarian.can_attack(barbarian_tile, knight_tile) && knight_char.health > 0 { + // [Effect] Hit each character in the line of sight + let hits = barbarian.get_hits(barbarian_tile, knight_tile, map.size); + let len = hits.len(); + let mut i = 0; + loop { + if i == len { + break; + } + let hit_index = *hits.at(i); + let mut hit_tile = store.tile(game, map, hit_index); + if hit_tile.is_knight() { + // [Command] Update Character + knight_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); + store.set_character(knight_char); + } else if hit_tile.is_bowman() && bowman_char.health > 0 { + // [Command] Update Character + bowman_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); + store.set_character(bowman_char); + // [Check] Foe death + if bowman_char.health == 0 { + // [Command] Update Tile + hit_tile.set_ground_type(); + store.set_tile(hit_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + } else if hit_tile.is_wizard() && wizard_char.health > 0 { + // [Command] Update Character + wizard_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); + store.set_character(wizard_char); + // [Check] Foe death + if wizard_char.health == 0 { + // [Command] Update Tile + hit_tile.set_ground_type(); + store.set_tile(hit_tile); + // [Effect] Update the map score + map.increase_score(11); + }; }; - // [Break] Hits stop at the first character - break; - } else if hit_tile.is_wizard() && wizard_char.health > 0 { - // [Command] Update Character - wizard_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); - set!(ctx.world, (wizard_char)); - // [Check] Foe death - if wizard_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - set!(ctx.world, (hit_tile)); - // [Effect] Update the map score - map.increase_score(11); + i += 1; + }; + } else if barbarian.can_move() && knight_char.health > 0 { + // [Effect] Move Barbarian, update the barbarian position in storage and hashmap + let mut neighbors = store.ground_neighbors(game, map, barbarian_tile); + let new_index = barbarian + .next(barbarian_tile, knight_tile, map.size, ref neighbors); + let mut new_tile = store.tile(game, map, new_index); + // [Command] Update previous tile + barbarian_tile.set_ground_type(); + store.set_tile(barbarian_tile); + // [Command] Update new tile + new_tile.set_barbarian_type(); + store.set_tile(new_tile); + barbarian_tile = new_tile; // Update tile for the next instructions + // [Command] Update Character + barbarian_char.set_index(new_index); + store.set_character(barbarian_char); + } + + // [Effect] Bowman: Attack if possible, move otherwise + let bowman: Foe = FoeTrait::new(bowman_char.health, bowman_char._type); + if bowman.can_attack(bowman_tile, knight_tile) && knight_char.health > 0 { + // [Effect] Hit each character in the line of sight, but stop at first hit + let hits = bowman.get_hits(bowman_tile, knight_tile, map.size); + let len = hits.len(); + let mut i = 0; + loop { + if i == len { + break; + } + let hit_index = *hits.at(i); + let mut hit_tile = store.tile(game, map, hit_index); + if hit_tile.is_knight() { + // [Command] Update Character + knight_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); + store.set_character(knight_char); + // [Break] Hits stop at the first character + break; + } else if hit_tile.is_barbarian() && barbarian_char.health > 0 { + // [Command] Update Character + barbarian_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); + store.set_character(barbarian_char); + // [Check] Foe death + if barbarian_char.health == 0 { + // [Command] Update Tile + hit_tile.set_ground_type(); + store.set_tile(hit_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + // [Break] Hits stop at the first character + break; + } else if hit_tile.is_wizard() && wizard_char.health > 0 { + // [Command] Update Character + wizard_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); + store.set_character(wizard_char); + // [Check] Foe death + if wizard_char.health == 0 { + // [Command] Update Tile + hit_tile.set_ground_type(); + store.set_tile(hit_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + // [Break] Hits stop at the first character + break; }; - // [Break] Hits stop at the first character - break; + i += 1; }; - i += 1; - }; - } else if bowman.can_move() && knight_char.health > 0 { - // [Effect] Move Bowman, update the bowman position in storage and hashmap - let new_index = bowman.next(bowman_tile, knight_tile, map.size, ref tiles); - let mut new_tile = tiles.get(new_index.into()).deref(); - // [Command] Update previous tile - bowman_tile.set_ground_type(); - tiles.insert(bowman_tile.index.into(), nullable_from_box(BoxTrait::new(bowman_tile))); - set!(ctx.world, (bowman_tile)); - // [Command] Update new tile - new_tile.set_bowman_type(); - tiles.insert(new_tile.index.into(), nullable_from_box(BoxTrait::new(new_tile))); - set!(ctx.world, (new_tile)); - bowman_tile = new_tile; // Update knight tile for the next instructions - // [Command] Update Character - bowman_char.set_index(new_index); - set!(ctx.world, (bowman_char)); + } else if bowman.can_move() && knight_char.health > 0 { + // [Effect] Move Bowman, update the bowman position in storage and hashmap + let mut neighbors = store.ground_neighbors(game, map, bowman_tile); + let new_index = bowman.next(bowman_tile, knight_tile, map.size, ref neighbors); + let mut new_tile = store.tile(game, map, new_index); + // [Command] Update previous tile + bowman_tile.set_ground_type(); + store.set_tile(bowman_tile); + // [Command] Update new tile + new_tile.set_bowman_type(); + store.set_tile(new_tile); + bowman_tile = new_tile; // Update tile for the next instructions + // [Command] Update Character + bowman_char.set_index(new_index); + store.set_character(bowman_char); + } + + // [Effect] Wizard: Attack if possible, move otherwise + let wizard: Foe = FoeTrait::new(wizard_char.health, wizard_char._type); + if wizard.can_attack(wizard_tile, knight_tile) && knight_char.health > 0 { + // [Effect] Hit each character in the line of sight + let hits = wizard.get_hits(wizard_tile, knight_tile, map.size); + let len = hits.len(); + let mut i = 0; + loop { + if i == len { + break; + } + let hit_index = *hits.at(i); + let mut hit_tile = store.tile(game, map, hit_index); + if hit_tile.is_knight() { + // [Command] Update Character + knight_char.take_damage(wizard_char._type, WIZARD_DAMAGE); + store.set_character(knight_char); + } else if hit_tile.is_barbarian() && barbarian_char.health > 0 { + // [Command] Update Character + barbarian_char.take_damage(wizard_char._type, WIZARD_DAMAGE); + store.set_character(barbarian_char); + // [Check] Foe death + if barbarian_char.health == 0 { + // [Command] Update Tile + hit_tile.set_ground_type(); + store.set_tile(hit_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + } else if hit_tile.is_bowman() && bowman_char.health > 0 { + // [Command] Update Character + bowman_char.take_damage(wizard_char._type, WIZARD_DAMAGE); + store.set_character(bowman_char); + // [Check] Foe death + if bowman_char.health == 0 { + // [Command] Update Tile + hit_tile.set_ground_type(); + store.set_tile(hit_tile); + // [Effect] Update the map score + map.increase_score(11); + }; + }; + i += 1; + }; + } else if wizard.can_move() && knight_char.health > 0 { + // [Effect] Move Wizard, update the wizard position in storage and hashmap + let mut neighbors = store.ground_neighbors(game, map, wizard_tile); + let new_index = wizard.next(wizard_tile, knight_tile, map.size, ref neighbors); + let mut new_tile = store.tile(game, map, new_index); + // [Command] Update previous tile + wizard_tile.set_ground_type(); + store.set_tile(wizard_tile); + // [Command] Update new tile + new_tile.set_wizard_type(); + store.set_tile(new_tile); + wizard_tile = new_tile; // Update tile for the next instructions + // [Command] Update Character + wizard_char.set_index(new_index); + store.set_character(wizard_char); + } + + // [Effect] Score and game evalutation + map.decrease_score(1); + if knight_char.health == 0 { + // [Command] Update Game + game.set_over(true); + store.set_game(game); + // [Command] Update Map + map.set_over(true); + store.set_map(map); + } else if barbarian_char.health == 0 + && bowman_char.health == 0 + && wizard_char.health == 0 { + // [Command] Update Map + map.increase_level(); + map.set_spawn(false); + store.set_map(map); + } else { + // [Command] Update Map + store.set_map(map); + } } - // [Effect] Wizard: Attack if possible, move otherwise - let wizard: Foe = FoeTrait::new(wizard_char.health, wizard_char._type); - if wizard.can_attack(wizard_tile, knight_tile) && knight_char.health > 0 { - // [Effect] Hit each character in the line of sight - let hits = wizard.get_hits(wizard_tile, knight_tile, map.size); - let len = hits.len(); - let mut i = 0; + fn spawn(self: @ContractState, world: IWorldDispatcher, player: felt252,) { + // [Setup] Datastore + let mut store: Store = StoreTrait::new(world); + + // [Command] Game entity + let game = store.game(player); + + // [Check] Map must not be spawned + let mut map = store.map(game); + assert(!map.spawn, 'Map must not be spawned'); + + // [Command] Map entity + map.spawn = true; + store.set_map(map); + + // [Command] Characters and Tiles + let seed = poseidon_hash_span(array![game.seed, map.level.into()].span()).into(); + let raw_types = map.generate(seed); + let mut index = 0; + let length = raw_types.len(); loop { - if i == len { + if index == length { break; } - let hit_index = *hits.at(i); - let mut hit_tile = tiles.get(hit_index.into()).deref(); - if hit_tile.is_knight() { - // [Command] Update Character - knight_char.take_damage(wizard_char._type, WIZARD_DAMAGE); - set!(ctx.world, (knight_char)); - } else if hit_tile.is_barbarian() && barbarian_char.health > 0 { - // [Command] Update Character - barbarian_char.take_damage(wizard_char._type, WIZARD_DAMAGE); - set!(ctx.world, (barbarian_char)); - // [Check] Foe death - if barbarian_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - set!(ctx.world, (hit_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if hit_tile.is_bowman() && bowman_char.health > 0 { - // [Command] Update Character - bowman_char.take_damage(wizard_char._type, WIZARD_DAMAGE); - set!(ctx.world, (bowman_char)); - // [Check] Foe death - if bowman_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - set!(ctx.world, (hit_tile)); - // [Effect] Update the map score - map.increase_score(11); - }; + + let raw_type = *raw_types[index]; + let tile_type = map.get_type(raw_type); + let (x, y) = map.decompose(index); + let tile = Tile { + game_id: game.game_id, level: map.level, x, y, index, _type: raw_type }; - i += 1; - }; - } else if wizard.can_move() && knight_char.health > 0 { - // [Effect] Move Wizard, update the wizard position in storage and hashmap - let new_index = wizard.next(wizard_tile, knight_tile, map.size, ref tiles); - let mut new_tile = tiles.get(new_index.into()).deref(); - // [Command] Update previous tile - wizard_tile.set_ground_type(); - tiles.insert(wizard_tile.index.into(), nullable_from_box(BoxTrait::new(wizard_tile))); - set!(ctx.world, (wizard_tile)); - // [Command] Update new tile - new_tile.set_wizard_type(); - tiles.insert(new_tile.index.into(), nullable_from_box(BoxTrait::new(new_tile))); - set!(ctx.world, (new_tile)); - wizard_tile = new_tile; // Update knight tile for the next instructions - // [Command] Update Character - wizard_char.set_index(new_index); - set!(ctx.world, (wizard_char)); - } - // [Effect] Score and game evalutation - map.decrease_score(1); - if knight_char.health == 0 { - // [Command] Update Game - game.set_over(true); - set!(ctx.world, (game)); - // [Command] Update Map - map.set_over(true); - set!(ctx.world, (map)); - } else if barbarian_char.health == 0 && bowman_char.health == 0 && wizard_char.health == 0 { - // [Command] Update Map - map.increase_level(); - map.set_spawn(false); - set!(ctx.world, (map)); - } else { - // [Command] Update Map - set!(ctx.world, (map)); + // [Command] Set Tile and Character entities + match tile_type { + Type::Ground(()) => { // + }, + Type::Hole(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + }, + Type::Knight(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Update Character entity + let mut character = store + .character(game, CharacterTrait::get_knight_type()); + character.index = index; + character.hitter = 0; + character.hit = 0; + store.set_character(character); + }, + Type::Barbarian(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Update Character entity + let mut character = store + .character(game, CharacterTrait::get_barbarian_type()); + character.health = MOB_HEALTH; + character.index = index; + character.hitter = 0; + character.hit = 0; + store.set_character(character); + }, + Type::Bowman(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Update Character entity + let mut character = store + .character(game, CharacterTrait::get_bowman_type()); + character.health = MOB_HEALTH; + character.index = index; + character.hitter = 0; + character.hit = 0; + store.set_character(character); + }, + Type::Wizard(()) => { + // [Command] Set Tile entity + store.set_tile(tile); + // [Command] Update Character entity + let mut character = store + .character(game, CharacterTrait::get_wizard_type()); + character.health = MOB_HEALTH; + character.index = index; + character.hitter = 0; + character.hit = 0; + store.set_character(character); + }, + }; + + index += 1; + } } } + + #[generate_trait] + impl Internal of InternalTrait {} } diff --git a/src/systems/player.cairo b/src/systems/player.cairo deleted file mode 100644 index f55c8bd..0000000 --- a/src/systems/player.cairo +++ /dev/null @@ -1,579 +0,0 @@ -// Dojo imports - -use dojo::world::IWorldDispatcher; - -// System trait - -#[starknet::interface] -trait IActions { - fn create( - self: @TContractState, - world: IWorldDispatcher, - player: felt252, - seed: felt252, - name: felt252, - ); - fn play(self: @TContractState, world: IWorldDispatcher, player: felt252, x: u32, y: u32,); - fn spawn(self: @TContractState, world: IWorldDispatcher, player: felt252,); -} - -// System implementation - -#[starknet::contract] -mod actions { - // Core imports - - use array::{ArrayTrait, SpanTrait}; - use poseidon::poseidon_hash_span; - - // Dojo imports - - use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; - - // Components imports - - use zknight::components::character::{Character, CharacterTrait}; - use zknight::components::game::{Game, GameTrait}; - use zknight::components::map::{Map, MapTrait, Type}; - use zknight::components::tile::{Tile, TileTrait}; - - // Entities imports - - use zknight::entities::foe::{Foe, FoeTrait}; - - // Internal imports - - use zknight::constants::{ - GROUND_TYPE, KNIGHT_DAMAGE, BARBARIAN_DAMAGE, BOWMAN_DAMAGE, WIZARD_DAMAGE, KNIGHT_HEALTH, - MOB_HEALTH - }; - use zknight::datastore::{DataStore, DataStoreTrait}; - - // Local imports - - use super::IActions; - - // Errors - - mod errors {} - - #[storage] - struct Storage {} - - #[external(v0)] - impl Actions of IActions { - fn create( - self: @ContractState, - world: IWorldDispatcher, - player: felt252, - seed: felt252, - name: felt252, - ) { - // [Setup] Datastore - let mut datastore: DataStore = DataStoreTrait::new(world); - - // [Command] Game entity - let game_id = world.uuid(); - let mut game = GameTrait::new(player, game_id, seed); - datastore.set_game(game); - - // [Command] Map entity - let map = MapTrait::new(game_id, 1, name); - datastore.set_map(map); - - // [Command] Characters and Tiles - let raw_types = map.generate(game.seed); - let mut index = 0; - let length = raw_types.len(); - loop { - if index == length { - break; - } - - let raw_type = *raw_types[index]; - let tile_type = map.get_type(raw_type); - let (x, y) = map.decompose(index); - let tile = Tile { game_id, level: map.level, x, y, index, _type: raw_type }; - - // [Command] Set Tile and Character entities - match tile_type { - Type::Ground(()) => { // - }, - Type::Hole(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - }, - Type::Knight(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Set Character entity - let knight = Character { - game_id: game_id, - _type: raw_type, - health: KNIGHT_HEALTH, - index, - hitter: 0, - hit: 0 - }; - datastore.set_character(knight); - }, - Type::Barbarian(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Set Character entity - let barbarian = Character { - game_id: game_id, - _type: raw_type, - health: MOB_HEALTH, - index, - hitter: 0, - hit: 0 - }; - datastore.set_character(barbarian); - }, - Type::Bowman(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Set Character entity - let bowman = Character { - game_id: game_id, - _type: raw_type, - health: MOB_HEALTH, - index, - hitter: 0, - hit: 0 - }; - datastore.set_character(bowman); - }, - Type::Wizard(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Set Character entity - let wizard = Character { - game_id: game_id, - _type: raw_type, - health: MOB_HEALTH, - index, - hitter: 0, - hit: 0 - }; - datastore.set_character(wizard); - }, - }; - - index += 1; - } - } - - fn play(self: @ContractState, world: IWorldDispatcher, player: felt252, x: u32, y: u32,) { - // [Setup] Datastore - let mut datastore: DataStore = DataStoreTrait::new(world); - - // [Command] Game entity - let mut game: Game = datastore.game(player); - - // [Check] Game is not over - assert(!game.over, 'Game is over'); - - // [Command] Map entity - let mut map: Map = datastore.map(game); - - // [Command] Knight entity - let mut knight_char = datastore.character(game, CharacterTrait::get_knight_type()); - knight_char.reset_damage(); - let mut knight_tile = datastore.tile(game, map, knight_char.index); - - // [Command] Barbarian entity - let mut barbarian_char = datastore - .character(game, CharacterTrait::get_barbarian_type()); - barbarian_char.reset_damage(); - let mut barbarian_tile = datastore.tile(game, map, barbarian_char.index); - - // [Command] Bowman entity - let mut bowman_char = datastore.character(game, CharacterTrait::get_bowman_type()); - bowman_char.reset_damage(); - let mut bowman_tile = datastore.tile(game, map, bowman_char.index); - - // [Command] Wizard entity - let mut wizard_char = datastore.character(game, CharacterTrait::get_wizard_type()); - wizard_char.reset_damage(); - let mut wizard_tile = datastore.tile(game, map, wizard_char.index); - - // [Check] Target position is in range, target is not a hole - let new_index = map.compose(x, y); - let mut new_tile = datastore.tile(game, map, new_index); - assert(knight_tile.is_close(new_tile), 'Target position is not in range'); - assert(!new_tile.is_hole(), 'Target position is a hole'); - - // [Effect] Pass if target is knight, Attack if the target is a foe, move otherwise - if new_tile.is_knight() { // Pass - } else if new_tile.is_barbarian() && barbarian_char.health > 0 { - // [Command] Update Character - barbarian_char.take_damage(knight_char._type, KNIGHT_DAMAGE); - datastore.set_character(barbarian_char); - - // [Check] Foe death - if barbarian_char.health == 0 { - // [Command] Update Tile - new_tile.set_ground_type(); - datastore.set_tile(new_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if new_tile.is_bowman() && bowman_char.health > 0 { - // [Command] Update Character - bowman_char.take_damage(knight_char._type, KNIGHT_DAMAGE); - datastore.set_character(bowman_char); - - // [Check] Foe death - if bowman_char.health == 0 { - // [Command] Update Tile - new_tile.set_ground_type(); - datastore.set_tile(new_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if new_tile.is_wizard() && wizard_char.health > 0 { - // [Command] Update Character - wizard_char.take_damage(knight_char._type, KNIGHT_DAMAGE); - datastore.set_character(wizard_char); - - // [Check] Foe death - if wizard_char.health == 0 { - // [Command] Update Tile - new_tile.set_ground_type(); - datastore.set_tile(new_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - } else { - // [Effect] Move Knight, update the knight position in storage and hashmap - let tile = Tile { - game_id: game.game_id, - level: map.level, - index: new_index, - _type: knight_char._type, - x, - y - }; - // [Command] Update previous tile - knight_tile.set_ground_type(); - datastore.set_tile(knight_tile); - // [Command] Update new tile - new_tile.set_knight_type(); - datastore.set_tile(new_tile); - knight_tile = new_tile; // Update knight tile for the next instructions - // [Command] Update Character - knight_char.set_index(new_index); - datastore.set_character(knight_char); - } - - // [Effect] Barbarian: Attack if possible, move otherwise - let barbarian: Foe = FoeTrait::new(barbarian_char.health, barbarian_char._type); - if barbarian.can_attack(barbarian_tile, knight_tile) && knight_char.health > 0 { - // [Effect] Hit each character in the line of sight - let hits = barbarian.get_hits(barbarian_tile, knight_tile, map.size); - let len = hits.len(); - let mut i = 0; - loop { - if i == len { - break; - } - let hit_index = *hits.at(i); - let mut hit_tile = datastore.tile(game, map, hit_index); - if hit_tile.is_knight() { - // [Command] Update Character - knight_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); - datastore.set_character(knight_char); - } else if hit_tile.is_bowman() && bowman_char.health > 0 { - // [Command] Update Character - bowman_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); - datastore.set_character(bowman_char); - // [Check] Foe death - if bowman_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - datastore.set_tile(hit_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if hit_tile.is_wizard() && wizard_char.health > 0 { - // [Command] Update Character - wizard_char.take_damage(barbarian_char._type, BARBARIAN_DAMAGE); - datastore.set_character(wizard_char); - // [Check] Foe death - if wizard_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - datastore.set_tile(hit_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - }; - i += 1; - }; - } else if barbarian.can_move() && knight_char.health > 0 { - // [Effect] Move Barbarian, update the barbarian position in storage and hashmap - let mut neighbors = datastore.ground_neighbors(game, map, barbarian_tile); - let new_index = barbarian - .next(barbarian_tile, knight_tile, map.size, ref neighbors); - let mut new_tile = datastore.tile(game, map, new_index); - // [Command] Update previous tile - barbarian_tile.set_ground_type(); - datastore.set_tile(barbarian_tile); - // [Command] Update new tile - new_tile.set_barbarian_type(); - datastore.set_tile(new_tile); - barbarian_tile = new_tile; // Update tile for the next instructions - // [Command] Update Character - barbarian_char.set_index(new_index); - datastore.set_character(barbarian_char); - } - - // [Effect] Bowman: Attack if possible, move otherwise - let bowman: Foe = FoeTrait::new(bowman_char.health, bowman_char._type); - if bowman.can_attack(bowman_tile, knight_tile) && knight_char.health > 0 { - // [Effect] Hit each character in the line of sight, but stop at first hit - let hits = bowman.get_hits(bowman_tile, knight_tile, map.size); - let len = hits.len(); - let mut i = 0; - loop { - if i == len { - break; - } - let hit_index = *hits.at(i); - let mut hit_tile = datastore.tile(game, map, hit_index); - if hit_tile.is_knight() { - // [Command] Update Character - knight_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); - datastore.set_character(knight_char); - // [Break] Hits stop at the first character - break; - } else if hit_tile.is_barbarian() && barbarian_char.health > 0 { - // [Command] Update Character - barbarian_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); - datastore.set_character(barbarian_char); - // [Check] Foe death - if barbarian_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - datastore.set_tile(hit_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - // [Break] Hits stop at the first character - break; - } else if hit_tile.is_wizard() && wizard_char.health > 0 { - // [Command] Update Character - wizard_char.take_damage(bowman_char._type, BOWMAN_DAMAGE); - datastore.set_character(wizard_char); - // [Check] Foe death - if wizard_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - datastore.set_tile(hit_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - // [Break] Hits stop at the first character - break; - }; - i += 1; - }; - } else if bowman.can_move() && knight_char.health > 0 { - // [Effect] Move Bowman, update the bowman position in storage and hashmap - let mut neighbors = datastore.ground_neighbors(game, map, bowman_tile); - let new_index = bowman.next(bowman_tile, knight_tile, map.size, ref neighbors); - let mut new_tile = datastore.tile(game, map, new_index); - // [Command] Update previous tile - bowman_tile.set_ground_type(); - datastore.set_tile(bowman_tile); - // [Command] Update new tile - new_tile.set_bowman_type(); - datastore.set_tile(new_tile); - bowman_tile = new_tile; // Update tile for the next instructions - // [Command] Update Character - bowman_char.set_index(new_index); - datastore.set_character(bowman_char); - } - - // [Effect] Wizard: Attack if possible, move otherwise - let wizard: Foe = FoeTrait::new(wizard_char.health, wizard_char._type); - if wizard.can_attack(wizard_tile, knight_tile) && knight_char.health > 0 { - // [Effect] Hit each character in the line of sight - let hits = wizard.get_hits(wizard_tile, knight_tile, map.size); - let len = hits.len(); - let mut i = 0; - loop { - if i == len { - break; - } - let hit_index = *hits.at(i); - let mut hit_tile = datastore.tile(game, map, hit_index); - if hit_tile.is_knight() { - // [Command] Update Character - knight_char.take_damage(wizard_char._type, WIZARD_DAMAGE); - datastore.set_character(knight_char); - } else if hit_tile.is_barbarian() && barbarian_char.health > 0 { - // [Command] Update Character - barbarian_char.take_damage(wizard_char._type, WIZARD_DAMAGE); - datastore.set_character(barbarian_char); - // [Check] Foe death - if barbarian_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - datastore.set_tile(hit_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - } else if hit_tile.is_bowman() && bowman_char.health > 0 { - // [Command] Update Character - bowman_char.take_damage(wizard_char._type, WIZARD_DAMAGE); - datastore.set_character(bowman_char); - // [Check] Foe death - if bowman_char.health == 0 { - // [Command] Update Tile - hit_tile.set_ground_type(); - datastore.set_tile(hit_tile); - // [Effect] Update the map score - map.increase_score(11); - }; - }; - i += 1; - }; - } else if wizard.can_move() && knight_char.health > 0 { - // [Effect] Move Wizard, update the wizard position in storage and hashmap - let mut neighbors = datastore.ground_neighbors(game, map, wizard_tile); - let new_index = wizard.next(wizard_tile, knight_tile, map.size, ref neighbors); - let mut new_tile = datastore.tile(game, map, new_index); - // [Command] Update previous tile - wizard_tile.set_ground_type(); - datastore.set_tile(wizard_tile); - // [Command] Update new tile - new_tile.set_wizard_type(); - datastore.set_tile(new_tile); - wizard_tile = new_tile; // Update tile for the next instructions - // [Command] Update Character - wizard_char.set_index(new_index); - datastore.set_character(wizard_char); - } - - // [Effect] Score and game evalutation - map.decrease_score(1); - if knight_char.health == 0 { - // [Command] Update Game - game.set_over(true); - datastore.set_game(game); - // [Command] Update Map - map.set_over(true); - datastore.set_map(map); - } else if barbarian_char.health == 0 - && bowman_char.health == 0 - && wizard_char.health == 0 { - // [Command] Update Map - map.increase_level(); - map.set_spawn(false); - datastore.set_map(map); - } else { - // [Command] Update Map - datastore.set_map(map); - } - } - - fn spawn(self: @ContractState, world: IWorldDispatcher, player: felt252,) { - // [Setup] Datastore - let mut datastore: DataStore = DataStoreTrait::new(world); - - // [Command] Game entity - let game = datastore.game(player); - - // [Check] Map must not be spawned - let mut map = datastore.map(game); - assert(!map.spawn, 'Map must not be spawned'); - - // [Command] Map entity - map.spawn = true; - datastore.set_map(map); - - // [Command] Characters and Tiles - let seed = poseidon_hash_span(array![game.seed, map.level.into()].span()).into(); - let raw_types = map.generate(seed); - let mut index = 0; - let length = raw_types.len(); - loop { - if index == length { - break; - } - - let raw_type = *raw_types[index]; - let tile_type = map.get_type(raw_type); - let (x, y) = map.decompose(index); - let tile = Tile { - game_id: game.game_id, level: map.level, x, y, index, _type: raw_type - }; - - // [Command] Set Tile and Character entities - match tile_type { - Type::Ground(()) => { // - }, - Type::Hole(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - }, - Type::Knight(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Update Character entity - let mut character = datastore - .character(game, CharacterTrait::get_knight_type()); - character.index = index; - character.hitter = 0; - character.hit = 0; - datastore.set_character(character); - }, - Type::Barbarian(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Update Character entity - let mut character = datastore - .character(game, CharacterTrait::get_barbarian_type()); - character.health = MOB_HEALTH; - character.index = index; - character.hitter = 0; - character.hit = 0; - datastore.set_character(character); - }, - Type::Bowman(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Update Character entity - let mut character = datastore - .character(game, CharacterTrait::get_bowman_type()); - character.health = MOB_HEALTH; - character.index = index; - character.hitter = 0; - character.hit = 0; - datastore.set_character(character); - }, - Type::Wizard(()) => { - // [Command] Set Tile entity - datastore.set_tile(tile); - // [Command] Update Character entity - let mut character = datastore - .character(game, CharacterTrait::get_wizard_type()); - character.health = MOB_HEALTH; - character.index = index; - character.hitter = 0; - character.hit = 0; - datastore.set_character(character); - }, - }; - - index += 1; - } - } - } - - #[generate_trait] - impl Internal of InternalTrait {} -} diff --git a/src/systems/spawn.cairo b/src/systems/spawn.cairo deleted file mode 100644 index 3f7b405..0000000 --- a/src/systems/spawn.cairo +++ /dev/null @@ -1,105 +0,0 @@ -#[system] -mod Spawn { - use array::{ArrayTrait, SpanTrait}; - use traits::Into; - use poseidon::poseidon_hash_span; - - use dojo::world::{Context, IWorld}; - - use zknight::components::game::{Game, GameTrait}; - use zknight::components::map::{Map, MapTrait, Type}; - use zknight::components::tile::{Tile}; - use zknight::components::character::{Character, CharacterTrait}; - - use zknight::constants::{KNIGHT_HEALTH, MOB_HEALTH}; - - fn execute(ctx: Context, player: felt252) { - // [Command] Game entity - let game = get!(ctx.world, player, (Game)); - - // [Check] Map must not be spawned - let mut map = get!(ctx.world, game.game_id, (Map)); - assert(!map.spawn, 'Map must not be spawned'); - - // [Command] Map entity - map.spawn = true; - set!(ctx.world, (map)); - - // [Command] Characters and Tiles - let seed = poseidon_hash_span(array![game.seed, map.level.into()].span()).into(); - let raw_types = map.generate(seed); - let mut index = 0; - let length = raw_types.len(); - loop { - if index == length { - break; - } - - let raw_type = *raw_types[index]; - let tile_type = map.get_type(raw_type); - let (x, y) = map.decompose(index); - let tile = Tile { - game_id: game.game_id, level: map.level, x, y, index, _type: raw_type - }; - - // [Command] Set Tile and Character entities - match tile_type { - Type::Ground(()) => { // - }, - Type::Hole(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - }, - Type::Knight(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Update Character entity - let key = (game.game_id, CharacterTrait::get_knight_type()); - let mut character = get!(ctx.world, key.into(), (Character)); - character.index = index; - character.hitter = 0; - character.hit = 0; - set!(ctx.world, (character)); - }, - Type::Barbarian(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Update Character entity - let key = (game.game_id, CharacterTrait::get_barbarian_type()); - let mut character = get!(ctx.world, key.into(), (Character)); - character.health = MOB_HEALTH; - character.index = index; - character.hitter = 0; - character.hit = 0; - set!(ctx.world, (character)); - }, - Type::Bowman(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Update Character entity - let key = (game.game_id, CharacterTrait::get_bowman_type()); - let mut character = get!(ctx.world, key.into(), (Character)); - character.health = MOB_HEALTH; - character.index = index; - character.hitter = 0; - character.hit = 0; - set!(ctx.world, (character)); - }, - Type::Wizard(()) => { - // [Command] Set Tile entity - set!(ctx.world, (tile)); - // [Command] Update Character entity - let key = (game.game_id, CharacterTrait::get_wizard_type()); - let mut character = get!(ctx.world, key.into(), (Character)); - character.health = MOB_HEALTH; - character.index = index; - character.hitter = 0; - character.hit = 0; - set!(ctx.world, (character)); - }, - }; - - index += 1; - } - } -} diff --git a/src/tests/create.cairo b/src/tests/create.cairo index 9b5c592..5cc3391 100644 --- a/src/tests/create.cairo +++ b/src/tests/create.cairo @@ -1,6 +1,6 @@ // Core imports -use debug::PrintTrait; +use core::debug::PrintTrait; // Dojo imports @@ -12,47 +12,46 @@ use zknight::constants::{ SEED, NAME, PLAYER, KNIGHT_HEALTH, MOB_HEALTH, GROUND_TYPE, HOLE_TYPE, KNIGHT_TYPE, BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE }; -use zknight::datastore::{DataStore, DataStoreTrait}; -use zknight::components::game::Game; -use zknight::components::map::{Map, MapTrait}; -use zknight::components::tile::{Tile, TileTrait}; -use zknight::components::character::{Character}; -use zknight::systems::player::IActionsDispatcherTrait; -use zknight::tests::setup::{setup, setup::Systems}; +use zknight::store::{Store, StoreTrait}; +use zknight::models::game::Game; +use zknight::models::map::{Map, MapTrait}; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::models::character::{Character}; +use zknight::tests::setup::{setup, setup::IPlayDispatcherTrait}; #[test] #[available_gas(1_000_000_000)] fn test_create() { // [Setup] - let (world, systems) = setup::spawn_game(); - let mut datastore = DataStoreTrait::new(world); + let (world, systems, _context) = setup::spawn_game(); + let mut store = StoreTrait::new(world); // [Create] - systems.player_actions.create(world, PLAYER, SEED, NAME); + systems.play.create(world, PLAYER, SEED, NAME); // [Assert] Game - let game = datastore.game(PLAYER); + let game = store.game(PLAYER); assert(game.game_id == 0, 'Wrong game id'); assert(game.seed == SEED, 'Wrong seed'); // [Assert] Map - let map = datastore.map(game); + let map = store.map(game); assert(map.level == 1, 'Wrong map id'); assert(map.score == 0, 'Wrong score'); assert(map.name == NAME, 'Wrong name'); // [Assert] Knight Character - let knight_char = datastore.character(game, KNIGHT_TYPE); + let knight_char = store.character(game, KNIGHT_TYPE); assert(knight_char.health == KNIGHT_HEALTH, 'Wrong knight health'); assert(knight_char.index == 7 + map.size * 2, 'Wrong knight index'); // [Assert] Barbarian Character - let barbarian_char = datastore.character(game, BARBARIAN_TYPE); + let barbarian_char = store.character(game, BARBARIAN_TYPE); assert(barbarian_char.health == MOB_HEALTH, 'Wrong barbarian health'); assert(barbarian_char.index == 6 + map.size * 2, 'Wrong barbarian index'); // [Assert] Bowman Character - let bowman_char = datastore.character(game, BOWMAN_TYPE); + let bowman_char = store.character(game, BOWMAN_TYPE); assert(bowman_char.health == MOB_HEALTH, 'Wrong bowman health'); assert(bowman_char.index == 2 + map.size * 4, 'Wrong bowman index'); } diff --git a/src/tests/play.cairo b/src/tests/play.cairo index da22d88..1960751 100644 --- a/src/tests/play.cairo +++ b/src/tests/play.cairo @@ -1,6 +1,6 @@ // Core imports -use debug::PrintTrait; +use core::debug::PrintTrait; // Dojo imports @@ -12,72 +12,71 @@ use zknight::constants::{ SEED, NAME, PLAYER, KNIGHT_HEALTH, MOB_HEALTH, GROUND_TYPE, HOLE_TYPE, KNIGHT_TYPE, BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE }; -use zknight::datastore::{DataStore, DataStoreTrait}; -use zknight::components::game::Game; -use zknight::components::map::{Map, MapTrait}; -use zknight::components::tile::{Tile, TileTrait}; -use zknight::components::character::{Character}; -use zknight::systems::player::IActionsDispatcherTrait; -use zknight::tests::setup::{setup, setup::Systems}; +use zknight::store::{Store, StoreTrait}; +use zknight::models::game::Game; +use zknight::models::map::{Map, MapTrait}; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::models::character::{Character}; +use zknight::tests::setup::{setup, setup::IPlayDispatcherTrait}; #[test] #[available_gas(1_000_000_000)] fn test_play_attack_move() { // [Setup] - let (world, systems) = setup::spawn_game(); - let mut datastore = DataStoreTrait::new(world); + let (world, systems, _context) = setup::spawn_game(); + let mut store = StoreTrait::new(world); // [Create] - systems.player_actions.create(world, PLAYER, SEED, NAME); - let game = datastore.game(PLAYER); - let map = datastore.map(game); + systems.play.create(world, PLAYER, SEED, NAME); + let game = store.game(PLAYER); + let map = store.map(game); // [Play] Attack let target_tile = TileTrait::new(6, 2); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Assert] Barbarian Character - let barbarian_char = datastore.character(game, BARBARIAN_TYPE); + let barbarian_char = store.character(game, BARBARIAN_TYPE); assert(barbarian_char.health == 0, 'Wrong barbarian health'); // [Assert] Barbarian Tile doesn't exist anymore - let barbarian_tile = datastore.tile(game, map, barbarian_char.index); + let barbarian_tile = store.tile(game, map, barbarian_char.index); assert(barbarian_tile._type == GROUND_TYPE, 'Wrong barbarian type'); // [Assert] Bowman Character - let bowman_char = datastore.character(game, BOWMAN_TYPE); + let bowman_char = store.character(game, BOWMAN_TYPE); assert(bowman_char.health == MOB_HEALTH, 'Wrong bowman health'); assert(bowman_char.index == 2 + map.size * 3, 'Wrong bowman index'); // [Play] Move let target_tile = TileTrait::new(6, 2); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Assert] Knight Character - let knight_char = datastore.character(game, KNIGHT_TYPE); + let knight_char = store.character(game, KNIGHT_TYPE); assert(knight_char.health == KNIGHT_HEALTH, 'Wrong knight health'); assert(knight_char.index == 6 + map.size * 2, 'Wrong knight index'); // [Assert] Knight Tile - let knight_tile = datastore.tile(game, map, knight_char.index); + let knight_tile = store.tile(game, map, knight_char.index); assert(knight_tile._type == KNIGHT_TYPE, 'Wrong new knight type'); assert(knight_tile.x == target_tile.x, 'Wrong new knight x'); assert(knight_tile.y == target_tile.y, 'Wrong new knight y'); // [Assert] Bowman Character - let bowman_char = datastore.character(game, BOWMAN_TYPE); + let bowman_char = store.character(game, BOWMAN_TYPE); assert(bowman_char.health == MOB_HEALTH, 'Wrong bowman health'); assert(bowman_char.index == 2 + map.size * 2, 'Wrong bowman index'); // [Assert] Bowman Tile - let bowman_tile = datastore.tile(game, map, bowman_char.index); + let bowman_tile = store.tile(game, map, bowman_char.index); assert(bowman_tile._type == BOWMAN_TYPE, 'Wrong bowman type'); assert(bowman_tile.x == 2, 'Wrong bowman x'); assert(bowman_tile.y == 2, 'Wrong bowman y'); // [Assert] Game - let map = datastore.map(game); + let map = store.map(game); assert(map.score == 9, 'Wrong score'); } @@ -86,25 +85,25 @@ fn test_play_attack_move() { #[available_gas(1_000_000_000)] fn test_play_pass() { // [Setup] - let (world, systems) = setup::spawn_game(); - let mut datastore = DataStoreTrait::new(world); + let (world, systems, _context) = setup::spawn_game(); + let mut store = StoreTrait::new(world); // [Create] - systems.player_actions.create(world, PLAYER, SEED, NAME); - let game = datastore.game(PLAYER); - let map = datastore.map(game); + systems.play.create(world, PLAYER, SEED, NAME); + let game = store.game(PLAYER); + let map = store.map(game); // [Assert] Knight Character - let knight_char = datastore.character(game, KNIGHT_TYPE); + let knight_char = store.character(game, KNIGHT_TYPE); assert(knight_char.health == KNIGHT_HEALTH, 'Wrong knight health'); assert(knight_char.index == 7 + map.size * 2, 'Wrong knight index'); // [Play] Pass let target_tile = TileTrait::new(7, 2); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Assert] Knight Character - let knight_char = datastore.character(game, KNIGHT_TYPE); + let knight_char = store.character(game, KNIGHT_TYPE); assert(knight_char.health == KNIGHT_HEALTH - 1, 'Wrong knight health'); assert(knight_char.index == 7 + map.size * 2, 'Wrong knight index'); } @@ -114,35 +113,35 @@ fn test_play_pass() { #[available_gas(1_000_000_000)] fn test_play_team_kill() { // [Setup] - let (world, systems) = setup::spawn_game(); - let mut datastore = DataStoreTrait::new(world); + let (world, systems, _context) = setup::spawn_game(); + let mut store = StoreTrait::new(world); // [Create] let seed = 1000; - systems.player_actions.create(world, PLAYER, seed, NAME); + systems.play.create(world, PLAYER, seed, NAME); // [Play] Move let target_tile = TileTrait::new(6, 3); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(5, 3); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(5, 4); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(5, 5); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Pass let target_tile = TileTrait::new(5, 5); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Assert] Barbarian Character - let game = datastore.game(PLAYER); - let barbarian_char = datastore.character(game, BARBARIAN_TYPE); + let game = store.game(PLAYER); + let barbarian_char = store.character(game, BARBARIAN_TYPE); assert(barbarian_char.health == 0, 'Wrong barbarian health'); // [Assert] Map - let map = datastore.map(game); + let map = store.map(game); assert(map.score == 10, 'Wrong score'); } diff --git a/src/tests/setup.cairo b/src/tests/setup.cairo index bfb9916..38bb2ff 100644 --- a/src/tests/setup.cairo +++ b/src/tests/setup.cairo @@ -6,34 +6,37 @@ mod setup { // Internal imports - use zknight::components::game::{game, Game}; - use zknight::components::map::{map, Map}; - use zknight::components::tile::{tile, Tile}; - use zknight::components::character::{character, Character}; - use zknight::systems::player::{actions as player_actions, IActionsDispatcher}; + use zknight::models::game::{game, Game}; + use zknight::models::map::{map, Map}; + use zknight::models::tile::{tile, Tile}; + use zknight::models::character::{character, Character}; + use zknight::systems::play::play; + use zknight::systems::interfaces::{IPlayDispatcher, IPlayDispatcherTrait}; #[derive(Drop)] struct Systems { - player_actions: IActionsDispatcher, + play: IPlayDispatcher, } - fn spawn_game() -> (IWorldDispatcher, Systems) { - // [Setup] Components - let mut components = ArrayTrait::new(); - components.append(game::TEST_CLASS_HASH); - components.append(map::TEST_CLASS_HASH); - components.append(character::TEST_CLASS_HASH); - let world = spawn_test_world(components); + #[derive(Drop)] + struct Context {} + + fn spawn_game() -> (IWorldDispatcher, Systems, Context) { + // [Setup] Models + let mut models: core::Array = core::ArrayTrait::new(); + models.append(game::TEST_CLASS_HASH); + models.append(map::TEST_CLASS_HASH); + models.append(character::TEST_CLASS_HASH); + let world = spawn_test_world(models); // [Setup] Systems - let player_actions_address = deploy_contract( - player_actions::TEST_CLASS_HASH, array![].span() - ); - let systems = Systems { - player_actions: IActionsDispatcher { contract_address: player_actions_address }, - }; + let play_address = deploy_contract(play::TEST_CLASS_HASH, array![].span()); + let systems = Systems { play: IPlayDispatcher { contract_address: play_address }, }; + + // [Setup] Context + let context = Context {}; // [Return] - (world, systems) + (world, systems, context) } } diff --git a/src/tests/spawn.cairo b/src/tests/spawn.cairo index 0556357..b5bdff7 100644 --- a/src/tests/spawn.cairo +++ b/src/tests/spawn.cairo @@ -1,6 +1,6 @@ // Core imports -use debug::PrintTrait; +use core::debug::PrintTrait; // Dojo imports @@ -12,85 +12,84 @@ use zknight::constants::{ SEED, NAME, PLAYER, KNIGHT_HEALTH, MOB_HEALTH, GROUND_TYPE, HOLE_TYPE, KNIGHT_TYPE, BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE }; -use zknight::datastore::{DataStore, DataStoreTrait}; -use zknight::components::game::Game; -use zknight::components::map::{Map, MapTrait}; -use zknight::components::tile::{Tile, TileTrait}; -use zknight::components::character::{Character}; -use zknight::systems::player::IActionsDispatcherTrait; -use zknight::tests::setup::{setup, setup::Systems}; +use zknight::store::{Store, StoreTrait}; +use zknight::models::game::Game; +use zknight::models::map::{Map, MapTrait}; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::models::character::{Character}; +use zknight::tests::setup::{setup, setup::IPlayDispatcherTrait}; #[test] #[available_gas(1_000_000_000)] fn test_spawn() { // [Setup] - let (world, systems) = setup::spawn_game(); - let mut datastore = DataStoreTrait::new(world); + let (world, systems, _context) = setup::spawn_game(); + let mut store = StoreTrait::new(world); // [Create] let seed = 1000; - systems.player_actions.create(world, PLAYER, seed, NAME); + systems.play.create(world, PLAYER, seed, NAME); // [Play] Move let target_tile = TileTrait::new(7, 2); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(7, 1); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(6, 1); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(6, 0); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(5, 0); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move let target_tile = TileTrait::new(4, 0); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Move - TK let target_tile = TileTrait::new(4, 1); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Attack let target_tile = TileTrait::new(4, 2); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Play] Attack let target_tile = TileTrait::new(4, 2); - systems.player_actions.play(world, PLAYER, target_tile.x, target_tile.y); + systems.play.play(world, PLAYER, target_tile.x, target_tile.y); // [Assert] Game - let game = datastore.game(PLAYER); + let game = store.game(PLAYER); assert(game.game_id == 0, 'Wrong game id'); assert(game.over == false, 'Wrong over status'); // [Assert] Barbarian Character - let barbarian_char = datastore.character(game, BARBARIAN_TYPE); + let barbarian_char = store.character(game, BARBARIAN_TYPE); assert(barbarian_char.health == 0, 'Wrong barbarian health'); // [Assert] Bowman Character - let bowman_char = datastore.character(game, BOWMAN_TYPE); + let bowman_char = store.character(game, BOWMAN_TYPE); assert(bowman_char.health == 0, 'Wrong bowman health'); // [Assert] Wizard Character - let wizard_char = datastore.character(game, WIZARD_TYPE); + let wizard_char = store.character(game, WIZARD_TYPE); assert(wizard_char.health == 0, 'Wrong wizard health'); // [Assert] Map - let map = datastore.map(game); + let map = store.map(game); assert(map.level == 2, 'Wrong map level'); assert(map.spawn == false, 'Wrong spawn'); assert(map.score == 30, 'Wrong score'); // [Spawn] - systems.player_actions.spawn(world, PLAYER); + systems.play.spawn(world, PLAYER); // [Assert] Map - let map = datastore.map(game); + let map = store.map(game); assert(map.spawn == true, 'Wrong spawn'); // [Assert] Barbarian Character - let barbarian_char = datastore.character(game, BARBARIAN_TYPE); + let barbarian_char = store.character(game, BARBARIAN_TYPE); assert(barbarian_char.health == MOB_HEALTH, 'Wrong barbarian health'); } diff --git a/src/entities/barbarian.cairo b/src/types/barbarian.cairo similarity index 88% rename from src/entities/barbarian.cairo rename to src/types/barbarian.cairo index ad13b7f..1f677b8 100644 --- a/src/entities/barbarian.cairo +++ b/src/types/barbarian.cairo @@ -1,7 +1,7 @@ // Internal imports -use zknight::components::tile::{Tile, TileTrait}; -use zknight::entities::foe::FoeTrait; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::types::foe::FoeTrait; #[derive(Copy, Drop)] struct Barbarian { @@ -57,9 +57,7 @@ impl BarbarianImpl of FoeTrait { result = new_tile; }; }, - Option::None => { - break; - }, + Option::None => { break; }, }; }; @@ -71,12 +69,12 @@ impl BarbarianImpl of FoeTrait { mod tests { // Core imports - use debug::PrintTrait; + use core::debug::PrintTrait; // Internal imports - use zknight::components::character::{Character, CharacterTrait}; - use zknight::components::tile::{Tile, TileTrait}; + use zknight::models::character::{Character, CharacterTrait}; + use zknight::models::tile::{Tile, TileTrait}; // Local imports diff --git a/src/entities/bowman.cairo b/src/types/bowman.cairo similarity index 95% rename from src/entities/bowman.cairo rename to src/types/bowman.cairo index 31a6456..f2f6859 100644 --- a/src/entities/bowman.cairo +++ b/src/types/bowman.cairo @@ -1,7 +1,7 @@ // Internal imports -use zknight::components::tile::{Tile, TileTrait}; -use zknight::entities::foe::FoeTrait; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::types::foe::FoeTrait; #[derive(Copy, Drop)] struct Bowman { @@ -133,9 +133,7 @@ impl BowmanImpl of FoeTrait { result = new_tile; }; }, - Option::None => { - break; - }, + Option::None => { break; }, }; }; @@ -145,14 +143,14 @@ impl BowmanImpl of FoeTrait { #[cfg(test)] mod tests { - use traits::Into; - use array::{ArrayTrait, SpanTrait}; - use dict::Felt252DictTrait; - use nullable::NullableTrait; - use zknight::components::character::{Character, CharacterTrait}; - use zknight::components::tile::{Tile, TileTrait}; + use core::traits::Into; + use core::array::{ArrayTrait, SpanTrait}; + use core::dict::Felt252DictTrait; + use core::nullable::NullableTrait; + use zknight::models::character::{Character, CharacterTrait}; + use zknight::models::tile::{Tile, TileTrait}; use super::{Bowman, FoeTrait}; - use debug::PrintTrait; + use core::debug::PrintTrait; const SIZE: u32 = 8; diff --git a/src/entities/foe.cairo b/src/types/foe.cairo similarity index 94% rename from src/entities/foe.cairo rename to src/types/foe.cairo index 7b131a7..89a0fc4 100644 --- a/src/entities/foe.cairo +++ b/src/types/foe.cairo @@ -1,10 +1,10 @@ // Internal imports use zknight::constants::{BARBARIAN_TYPE, BOWMAN_TYPE, WIZARD_TYPE}; -use zknight::components::tile::{Tile, TileTrait}; -use zknight::entities::barbarian::Barbarian; -use zknight::entities::bowman::Bowman; -use zknight::entities::wizard::Wizard; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::types::barbarian::Barbarian; +use zknight::types::bowman::Bowman; +use zknight::types::wizard::Wizard; #[derive(Copy, Drop)] struct Foe { diff --git a/src/entities/wizard.cairo b/src/types/wizard.cairo similarity index 96% rename from src/entities/wizard.cairo rename to src/types/wizard.cairo index 8e524d0..a8bea90 100644 --- a/src/entities/wizard.cairo +++ b/src/types/wizard.cairo @@ -1,7 +1,7 @@ // Internal imports -use zknight::components::tile::{Tile, TileTrait}; -use zknight::entities::foe::FoeTrait; +use zknight::models::tile::{Tile, TileTrait}; +use zknight::types::foe::FoeTrait; #[derive(Copy, Drop)] struct Wizard { @@ -130,9 +130,7 @@ impl WizardImpl of FoeTrait { result = new_tile; }; }, - Option::None => { - break; - }, + Option::None => { break; }, }; }; @@ -142,14 +140,14 @@ impl WizardImpl of FoeTrait { #[cfg(test)] mod tests { - use traits::Into; - use array::{ArrayTrait, SpanTrait}; - use dict::Felt252DictTrait; - use nullable::NullableTrait; - use zknight::components::character::{Character, CharacterTrait}; - use zknight::components::tile::{Tile, TileTrait}; + use core::traits::Into; + use core::array::{ArrayTrait, SpanTrait}; + use core::dict::Felt252DictTrait; + use core::nullable::NullableTrait; + use zknight::models::character::{Character, CharacterTrait}; + use zknight::models::tile::{Tile, TileTrait}; use super::{Wizard, FoeTrait}; - use debug::PrintTrait; + use core::debug::PrintTrait; const SIZE: u32 = 8;