Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Adding the model and system tournament blueprint #96

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod systems {
mod spawn;
mod world_setup;
mod bag;
mod tournament;
}

mod models {
Expand All @@ -26,9 +27,11 @@ mod models {
mod achievement_rarity;
mod achievement_type;
mod achievements;
mod tournament;
}

mod tests {
mod test_battle;
mod test_bag;
mod test_tournament;
}
23 changes: 23 additions & 0 deletions src/models/tournament.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use super::player::Player;

#[derive(Serde, Copy, Drop, Introspect, PartialEq)]
pub enum TournamentStatus {
Pending,
Ongoing,
Completed,
}


#[derive(Drop, Serde)]
#[dojo::model]
pub struct Tournament {
#[key]
pub tournament_id: u32,
pub name: felt252,
pub status: TournamentStatus,
pub entry_fee: u32,
pub max_participants: u32,
pub current_participants: Array<Player>,
pub prize_pool: u32,
Comment on lines +18 to +21

This comment was marked as spam.

}

59 changes: 59 additions & 0 deletions src/systems/tournament.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use bytebeasts::{models::{player::Player, tournament::Tournament, tournament::TournamentStatus},};

#[dojo::interface]
trait ITournamentAction {
fn create_tournament(
ref world: IWorldDispatcher,
tournament_id: u32,
name: felt252,
status: TournamentStatus,
entry_fee: u32,
max_participants: u32,
current_participants: Array<Player>,
prize_pool: u32
);
// fn register_player(ref world: IWorldDispatcher, tournament_id: u32, player_id: u32);
// fn start_tournament(ref world: IWorldDispatcher, tournament_id: u32, player_id: u32);
// fn complete_torunament(ref world: IWorldDispatcher, tournament_id: u32, player_id: u32);

This comment was marked as spam.

fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament;

This comment was marked as spam.

}


#[dojo::contract]
mod tournament_system {
use super::ITournamentAction;
use bytebeasts::{
models::{player::Player, tournament::Tournament, tournament::TournamentStatus},
};

#[abi(embed_v0)]
impl TournamentActionImpl of ITournamentAction<ContractState> {
fn create_tournament(
ref world: IWorldDispatcher,
tournament_id: u32,
name: felt252,
status: TournamentStatus,
entry_fee: u32,
max_participants: u32,
current_participants: Array<Player>,
prize_pool: u32
) {
let tournament = Tournament {
tournament_id: tournament_id,
name: name,
status: status,
entry_fee: entry_fee,
max_participants: max_participants,
current_participants: current_participants,
prize_pool: prize_pool
};
set!(world, (tournament))
}
Comment on lines +32 to +52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add validation for tournament ID uniqueness.

The create_tournament method should verify that the tournament_id doesn't already exist to prevent overwriting existing tournaments.

Add this validation before creating the tournament:

         prize_pool: u32
     ) {
+        let existing = get!(world, tournament_id, (Tournament));
+        assert!(existing.tournament_id == 0, "Tournament ID already exists");
         let tournament = Tournament {

Committable suggestion skipped: line range outside the PR's diff.


fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament {

This comment was marked as spam.

let tournament_from_world = get!(world, tournament_id, (Tournament));
tournament_from_world
}
Comment on lines +84 to +87
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for non-existent tournament.

The get_tournament method should handle the case when the tournament doesn't exist.

Add error handling:

     fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament {
         let tournament_from_world = get!(world, tournament_id, (Tournament));
+        assert!(tournament_from_world.tournament_id != 0, "Tournament not found");
         tournament_from_world
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament {
let tournament_from_world = get!(world, tournament_id, (Tournament));
tournament_from_world
}
fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament {
let tournament_from_world = get!(world, tournament_id, (Tournament));
assert!(tournament_from_world.tournament_id != 0, "Tournament not found");
tournament_from_world
}

}
}
61 changes: 61 additions & 0 deletions src/tests/test_tournament.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#[cfg(test)]
mod tests {
use starknet::ContractAddress;

use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use dojo::utils::test::{spawn_test_world, deploy_contract};

use bytebeasts::{
systems::{
tournament::{
tournament_system, ITournamentActionDispatcher, ITournamentActionDispatcherTrait
}
},
};

use bytebeasts::{
models::tournament::{{Tournament, tournament}}, models::tournament::TournamentStatus,
models::player::{{Player, player}},
};


// Helper function
// This function create the world and define the required models
#[test]
fn setup_world() -> (IWorldDispatcher, ITournamentActionDispatcher) {
let mut models = array![tournament::TEST_CLASS_HASH];

let world = spawn_test_world("bytebeasts", models);

let contract_address = world
.deploy_contract('salt', tournament_system::TEST_CLASS_HASH.try_into().unwrap());

let tournament_system = ITournamentActionDispatcher { contract_address };

world.grant_writer(dojo::utils::bytearray_hash(@"bytebeasts"), contract_address);

(world, tournament_system)
}

#[test]
fn test_create_tournament() {
let (_, tournament_system) = setup_world();
let mut players = ArrayTrait::new();

let player_ash = Player {
player_id: 1,
player_name: 'Ash',
beast_1: 1, // Beast 1 assigned
beast_2: 0, // No beast assigned
beast_3: 0, // No beast assigned
beast_4: 0, // No beast assigned
potions: 1
};
players.append(player_ash);

tournament_system
.create_tournament(1, 'tournament', TournamentStatus::Pending, 1, 2, players, 1);
let tournament = tournament_system.get_tournament(1);
assert!(tournament.name == 'tournament', "The tournament name is wrong!");
}
}