forked from keep-starknet-strange/tsubasa
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement the attack logic keep-starknet-strange#26
I have implemented the beginning of the contract as well as the attack logic tests but the implementation of the attack requires the modification of the component file as well as the implementation of the card deck system in order to verify the lenght of the players' hand.
- Loading branch information
Showing
7 changed files
with
198 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,74 @@ | ||
#[system] | ||
mod attack_system { | ||
use dojo::world::Context; | ||
use traits::Into; | ||
use option::Option; | ||
use tsubasa::components::{Game, Energy, Card}; | ||
use tsubasa::components::Roles; | ||
use tsubasa::events::{EndTurn}; | ||
use array::ArrayTrait; | ||
use debug::PrintTrait; | ||
|
||
fn execute(ctx: Context, player: u8) {} | ||
fn execute(ctx: Context, game_id: felt252, token_id_player1: u256, token_id_player2: u256) { | ||
let game = get!(ctx.world, game_id, Game); | ||
let card_player1 = get!(ctx.world, token_id_player1, Card); | ||
let card_player2 = get!(ctx.world, token_id_player2, Card); | ||
|
||
set!( | ||
ctx.world, Card { | ||
token_id: token_id_player1, | ||
dribble: card_player1.dribble, | ||
current_dribble: card_player1.current_dribble, | ||
defense: card_player1.defense, | ||
current_defense: card_player1.current_defense, | ||
cost: card_player1.cost, | ||
role: card_player1.role, | ||
is_captain: card_player1.is_captain, | ||
} | ||
); | ||
|
||
//We set a value as boolean replacement to match the Roles | ||
let mut value = 0; | ||
match card_player1.role { | ||
Roles::Goalkeeper => 'Goalkeeper'.print(), | ||
Roles::Defender => 'Defender'.print(), | ||
Roles::Midfielder => 'Midfielder'.print(), | ||
Roles::Attacker => value = 1, | ||
} | ||
|
||
if value == 1 { | ||
//If the card_player1 can dribble the current card_player2 | ||
if card_player1.dribble > card_player2.defense { | ||
set!( | ||
ctx.world, Card { | ||
token_id: token_id_player1, | ||
dribble: card_player1.dribble, | ||
current_dribble: card_player1.current_dribble, | ||
defense: card_player1.defense, | ||
current_defense: card_player1.current_defense - card_player2.dribble, | ||
cost: card_player1.cost, | ||
role: card_player1.role, | ||
is_captain: card_player1.is_captain | ||
} | ||
); | ||
// TO-DO : Add an remove card_player2 function | ||
} else { | ||
//If the Attacker didn't pass the card_player2 => end of the turn | ||
let game = get!(ctx.world, game_id, Game); | ||
|
||
set!( | ||
ctx.world, Game { | ||
game_id, | ||
player1: game.player1, | ||
player2: game.player2, | ||
player1_score: game.player1_score, | ||
player2_score: game.player2_score, | ||
turn: game.turn + 1, | ||
outcome: game.outcome | ||
} | ||
); | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#[system] | ||
mod create_card_system { | ||
use traits::Into; | ||
use dojo::world::Context; | ||
use starknet::ContractAddress; | ||
use tsubasa::events::{GameCreated}; | ||
use tsubasa::components::{Game, Energy, Card}; | ||
use option::Option; | ||
use array::{ArrayTrait}; | ||
use tsubasa::components::Roles; | ||
|
||
|
||
fn execute(ctx: Context, token_id: u256, role: felt252) { | ||
let mut value = Roles::Attacker; | ||
match role { | ||
0 => value = Roles::Attacker, | ||
_ => value = Roles::Midfielder, | ||
} | ||
|
||
set!( | ||
ctx.world, Card { | ||
token_id: token_id, | ||
dribble: 11, | ||
current_dribble: 0, | ||
defense: 10, | ||
current_defense: 0, | ||
cost: 0, | ||
role: value, | ||
is_captain: false | ||
} | ||
); | ||
//emit!(ctx.world, GameCreated { game_id, player1, player2 }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
mod attack; | ||
mod create_game; | ||
mod create_card; | ||
mod end_turn; | ||
mod place_card; | ||
mod utils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,72 @@ | ||
use core::traits::{Into, Default}; | ||
use array::ArrayTrait; | ||
use traits::{Into, Default}; | ||
use option::{Option, OptionTrait}; | ||
use serde::Serde; | ||
use array::ArrayTrait; | ||
|
||
use dojo::world::IWorldDispatcherTrait; | ||
|
||
use tsubasa::systems::place_card_system; | ||
use tsubasa::systems::attack_system; | ||
use tsubasa::components::{Game, Energy, Card}; | ||
use tsubasa::components::Roles; | ||
use tsubasa::systems::{ | ||
create_game_system, attack_system, end_turn_system, place_card_system, create_card_system, | ||
}; | ||
|
||
use tsubasa::tests::utils::spawn_world; | ||
|
||
|
||
#[test] | ||
#[available_gas(30000000)] | ||
fn test_attack() { | ||
let caller = starknet::contract_address_const::<0x0>(); | ||
fn test_attack_turn() { | ||
let player1 = starknet::contract_address_const::<0x1>(); | ||
let player2 = starknet::contract_address_const::<0x2>(); | ||
|
||
// use player1 address | ||
starknet::testing::set_contract_address(player1); | ||
|
||
let world = spawn_world(); | ||
|
||
let mut place_card_calldata: Array = Default::default(); | ||
0_u256.serialize(ref place_card_calldata); | ||
//Create Game Part | ||
let mut create_game_calldata: Array<felt252> = ArrayTrait::new(); | ||
create_game_calldata.append(player2.into()); | ||
|
||
world.execute('create_game_system', create_game_calldata); | ||
let expected_game_id = pedersen(player1.into(), player2.into()); | ||
let game_id = pedersen(player1.into(), player2.into()); | ||
let game = get!(world, expected_game_id, Game); | ||
|
||
assert(game.game_id == expected_game_id, 'invalid game_id'); | ||
assert(game.player1 == player1, 'invalid player 1'); | ||
assert(game.player2 == player2, 'invalid player 2'); | ||
assert(game.player1_score == 0, 'invalid player 1 score'); | ||
assert(game.player2_score == 0, 'invalid player 2 score'); | ||
assert(game.outcome.is_none(), 'invalid outcome'); | ||
|
||
// let place_card_calldata = array![0, 0]; // u256 { low: 0, high: 0 } | ||
let mut place_card_calldata: Array<felt252> = ArrayTrait::new(); | ||
place_card_calldata.append(0); | ||
place_card_calldata.append(0); | ||
world.execute('place_card_system', place_card_calldata); | ||
|
||
let attack_calldata = array![0]; | ||
//Create Card For test prupose | ||
let mut create_card_calldata: Array<felt252> = ArrayTrait::new(); | ||
create_card_calldata.append(1); | ||
create_card_calldata.append(0); | ||
world.execute('create_card_system', create_card_calldata); | ||
|
||
let mut create_card_calldata_player2: Array<felt252> = ArrayTrait::new(); | ||
create_card_calldata_player2.append(2); | ||
create_card_calldata_player2.append(0); | ||
world.execute('create_card_system', create_card_calldata_player2); | ||
|
||
//Attack logic test part | ||
let mut attack_calldata: Array<felt252> = ArrayTrait::new(); | ||
attack_calldata.append(game.game_id); | ||
attack_calldata.append(1); | ||
attack_calldata.append(2); | ||
world.execute('attack_system', attack_calldata); | ||
|
||
let card_player1 = get!(world, 1, Card); | ||
let card_player2 = get!(world, 2, Card); | ||
let expected_remaining_defense = card_player1.dribble - card_player2.defense; | ||
assert(card_player1.defense != expected_remaining_defense, 'invalid Attack logic execution'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use core::traits::{Into, Default}; | ||
use array::ArrayTrait; | ||
use serde::Serde; | ||
use option::{Option, OptionTrait}; | ||
|
||
use dojo::world::IWorldDispatcherTrait; | ||
|
||
use tsubasa::components::{Game, Energy, Card}; | ||
use tsubasa::tests::utils::spawn_world; | ||
use tsubasa::systems::create_card_system; | ||
|
||
#[test] | ||
#[available_gas(30000000)] | ||
fn test_create_card() { | ||
let player1 = starknet::contract_address_const::<0x1>(); | ||
let player2 = starknet::contract_address_const::<0x2>(); | ||
|
||
let world = spawn_world(); | ||
|
||
//Create Card For test prupose | ||
let mut create_card_calldata: Array<felt252> = ArrayTrait::new(); | ||
create_card_calldata.append(1); | ||
create_card_calldata.append(4); | ||
world.execute('create_card_system', create_card_calldata); | ||
|
||
let mut create_card_calldata_player2: Array<felt252> = ArrayTrait::new(); | ||
create_card_calldata_player2.append(2); | ||
create_card_calldata_player2.append(4); | ||
world.execute('create_card_system', create_card_calldata_player2); | ||
|
||
let card_player1 = get!(world, 1, Card); | ||
let card_player2 = get!(world, 1, Card); | ||
|
||
assert(card_player1.dribble > card_player2.defense, 'invalid Attack logic execution'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +0,0 @@ | ||
use traits::{Into, Default}; | ||
use option::{Option, OptionTrait}; | ||
use serde::Serde; | ||
use array::ArrayTrait; | ||
|
||
use dojo::world::IWorldDispatcherTrait; | ||
|
||
use tsubasa::components::{Game, Energy}; | ||
use tsubasa::systems::{create_game_system, attack_system, end_turn_system, place_card_system}; | ||
|
||
use tsubasa::tests::utils::spawn_world; | ||
|
||
#[test] | ||
#[available_gas(30000000)] | ||
fn test_end_turn() { | ||
let player1 = starknet::contract_address_const::<0x1>(); | ||
let player2 = starknet::contract_address_const::<0x2>(); | ||
|
||
// use player1 address | ||
starknet::testing::set_contract_address(player1); | ||
|
||
let world = spawn_world(); | ||
|
||
let game_id = pedersen(player1.into(), player2.into()); | ||
|
||
// let create_game_calldata: Array<felt252> = array![player2.into()]; | ||
let mut create_game_calldata: Array<felt252> = ArrayTrait::new(); | ||
create_game_calldata.append(player2.into()); | ||
world.execute('create_game_system', create_game_calldata); | ||
|
||
// let place_card_calldata = array![0, 0]; // u256 { low: 0, high: 0 } | ||
let mut place_card_calldata: Array<felt252> = ArrayTrait::new(); | ||
place_card_calldata.append(0); | ||
place_card_calldata.append(0); | ||
world.execute('place_card_system', place_card_calldata); | ||
|
||
// let attack_calldata = array![0]; | ||
let mut attack_calldata: Array<felt252> = ArrayTrait::new(); | ||
attack_calldata.append(0); | ||
world.execute('attack_system', attack_calldata); | ||
|
||
// let end_turn_calldata = array![game_id]; | ||
let mut end_turn_calldata: Array<felt252> = ArrayTrait::new(); | ||
end_turn_calldata.append(game_id); | ||
world.execute('end_turn_system', end_turn_calldata); | ||
|
||
let game = get!(world, game_id, Game); | ||
|
||
let expected_game = Game { | ||
game_id, | ||
player1, | ||
player2, | ||
player1_score: 0, | ||
player2_score: 0, | ||
turn: 1, | ||
outcome: Option::None | ||
}; | ||
|
||
assert(game.game_id == expected_game.game_id, 'invalid game_id'); | ||
assert(game.player1_score == expected_game.player1_score, 'Wrong player1 score'); | ||
assert(game.player2_score == expected_game.player2_score, 'Wrong player2 score'); | ||
assert(game.turn == expected_game.turn, 'Wrong turn value'); | ||
// Check that option is None | ||
assert(game.outcome.is_none(), 'Wrong outcome value'); | ||
|
||
let expected_energy = Energy { game_id, player: player1, remaining: 2 }; | ||
let player_energy = get!(world, (expected_energy.game_id, expected_energy.player), Energy); | ||
// Check that player energy is correclty incremented at the end of each turn. | ||
assert(player_energy.remaining == expected_energy.remaining, 'Wrong player energy value'); | ||
} | ||