From 7d472814707422c593d051b51891c13dde2b2b14 Mon Sep 17 00:00:00 2001 From: Gerson <71728860+Gerson2102@users.noreply.github.com> Date: Wed, 27 Nov 2024 01:20:19 -0600 Subject: [PATCH] Adding the model and system tournament blueprint (#96) * Adding the model and system tournament blueprint * Deleting test file from PR * Adding test file for tournament functions * Adding new implementations and deleting test file of tournament system --- src/lib.cairo | 2 + src/models/tournament.cairo | 70 ++++++++++++++++++++++++++++ src/systems/tournament.cairo | 89 ++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 src/models/tournament.cairo create mode 100644 src/systems/tournament.cairo diff --git a/src/lib.cairo b/src/lib.cairo index 2944835..c574db2 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -5,6 +5,7 @@ mod systems { mod spawn; mod world_setup; mod bag; + mod tournament; } mod models { @@ -26,6 +27,7 @@ mod models { mod achievement_rarity; mod achievement_type; mod achievements; + mod tournament; } mod tests { diff --git a/src/models/tournament.cairo b/src/models/tournament.cairo new file mode 100644 index 0000000..c31bfd9 --- /dev/null +++ b/src/models/tournament.cairo @@ -0,0 +1,70 @@ +use super::player::Player; + +#[derive(Serde, Copy, Drop, Introspect, PartialEq, Debug)] +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, + pub prize_pool: u32, +} + + +#[cfg(test)] +mod tests { + use bytebeasts::{ + models::{tournament::Tournament, tournament::TournamentStatus, player::Player} + }; + + + #[test] + fn test_tournament_initialization() { + 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); + + let tournament = Tournament { + tournament_id: 1, + name: 'gersonwashere', + status: TournamentStatus::Pending, + entry_fee: 1, + max_participants: 2, + current_participants: players, + prize_pool: 1, + }; + + assert_eq!(tournament.tournament_id, 1, "Tournament ID should be 1"); + assert_eq!(tournament.name, 'gersonwashere', "Tournament name should be gersonwashere"); + assert_eq!( + tournament.status, TournamentStatus::Pending, "Tournament status should be pending" + ); + assert_eq!(tournament.entry_fee, 1, "Tournament entry fee should be 1"); + assert_eq!(tournament.max_participants, 2, "Tournament max participants should be 2"); + assert_eq!( + tournament.current_participants.len(), 1, "Tournament current participants should be 1" + ); + assert_eq!(tournament.prize_pool, 1, "Tournament prize pool should be 1"); + } +} + diff --git a/src/systems/tournament.cairo b/src/systems/tournament.cairo new file mode 100644 index 0000000..6c94b8a --- /dev/null +++ b/src/systems/tournament.cairo @@ -0,0 +1,89 @@ +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, + prize_pool: u32 + ); + fn register_player(ref world: IWorldDispatcher, tournament_id: u32, new_player: Player); + fn start_tournament(ref world: IWorldDispatcher, tournament_id: u32); + // fn complete_tournament(ref world: IWorldDispatcher, tournament_id: u32, player_id: u32); + fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament; +} + + +#[dojo::contract] +mod tournament_system { + use super::ITournamentAction; + use bytebeasts::{ + models::{player::Player, tournament::Tournament, tournament::TournamentStatus}, + }; + + #[abi(embed_v0)] + impl TournamentActionImpl of ITournamentAction { + fn create_tournament( + ref world: IWorldDispatcher, + tournament_id: u32, + name: felt252, + status: TournamentStatus, + entry_fee: u32, + max_participants: u32, + current_participants: Array, + 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)) + } + + fn register_player(ref world: IWorldDispatcher, tournament_id: u32, new_player: Player) { + let mut tournament = get!(world, tournament_id, (Tournament)); + + assert!(tournament.status == TournamentStatus::Pending, "Tournament not open for registration"); + + assert!( + tournament.current_participants.len() < tournament.max_participants.try_into().unwrap(), + "Tournament is full" + ); + + tournament.current_participants.append(new_player); + + set!(world, (tournament)); + } + + fn start_tournament(ref world: IWorldDispatcher, tournament_id: u32) { + let mut tournament = get!(world, tournament_id, (Tournament)); + + assert!(tournament.status == TournamentStatus::Pending, "Tournament not pending"); + + assert!( + tournament.current_participants.len() >= 2, + "Not enough participants to start" + ); + + tournament.status = TournamentStatus::Ongoing; + + set!(world, (tournament)); + } + + fn get_tournament(world: @IWorldDispatcher, tournament_id: u32) -> Tournament { + let tournament_from_world = get!(world, tournament_id, (Tournament)); + tournament_from_world + } + } +}