Skip to content

Commit

Permalink
Merge pull request #84 from Benjtalkshow/join-game-function
Browse files Browse the repository at this point in the history
Implement join game function
  • Loading branch information
0xibs authored Oct 17, 2024
2 parents 164cab7 + ad0adb5 commit 009b340
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@
"name": "game_mode",
"type": "starkludo::models::game::GameMode"
},
{
"name": "game_status",
"type": "starkludo::models::game::GameStatus"
},
{
"name": "player_green",
"type": "core::felt252"
Expand Down Expand Up @@ -400,6 +404,30 @@
],
"outputs": [],
"state_mutability": "external"
},
{
"type": "function",
"name": "join_game",
"inputs": [
{
"name": "game_id",
"type": "core::integer::u64"
},
{
"name": "player_color",
"type": "core::felt252"
},
{
"name": "username",
"type": "core::felt252"
}
],
"outputs": [
{
"type": "starkludo::models::game::Game"
}
],
"state_mutability": "external"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
kind = "DojoContract"
class_hash = "0x4cecefc87acb36b188cec659cfde8d7cbfafaf8684297f7d66cadd573cbfec5"
original_class_hash = "0x4cecefc87acb36b188cec659cfde8d7cbfafaf8684297f7d66cadd573cbfec5"
class_hash = "0x4822d5336e093bd5060f977312516677c87cda7cc86ebac5941cf148054a2bf"
original_class_hash = "0x4822d5336e093bd5060f977312516677c87cda7cc86ebac5941cf148054a2bf"
base_class_hash = "0x0"
abi = "manifests/dev/base/abis/contracts/starkludo-GameActions-72b46dc4.json"
reads = []
Expand Down
47 changes: 44 additions & 3 deletions onchain/src/systems/game_actions.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use starkludo::models::{game::{Game, GameTrait, GameMode}, player::{Player}};
use starkludo::models::{game::{Game, GameTrait, GameMode, GameStatus}, player::{Player}};
use starknet::{ContractAddress, get_block_timestamp};
use core::poseidon::PoseidonTrait;
use core::hash::HashStateTrait;


#[dojo::interface]
trait IGameActions {
fn create(
Expand All @@ -18,14 +19,18 @@ trait IGameActions {
fn restart(ref world: IWorldDispatcher, game_id: u64);
fn terminate_game(ref world: IWorldDispatcher, game_id: u64);
fn invite_player(ref world: IWorldDispatcher, game_id: u64, player_username: felt252);
fn join_game(
ref world: IWorldDispatcher, game_id: u64, player_username: felt252, player_color: felt252
);
}


#[dojo::contract]
mod GameActions {
// use Zero;
// use core::num::traits::Zero;
use core::array::ArrayTrait;
use super::{IGameActions, Game, GameTrait, GameMode, Player};
use super::{IGameActions, Game, GameTrait, GameMode, Player, GameStatus};
use starknet::{ContractAddress, get_caller_address, get_block_timestamp};

#[abi(embed_v0)]
Expand All @@ -38,7 +43,7 @@ mod GameActions {
player_yellow: felt252,
player_blue: felt252,
player_red: felt252,
number_of_players: u8
number_of_players: u8,
) -> Game {
// Get the current block timestamp
let id = get_block_timestamp();
Expand Down Expand Up @@ -156,6 +161,42 @@ mod GameActions {
// Update the game state in the world
set!(world, (game));
}


fn join_game( ref world: IWorldDispatcher, game_id: u64, player_username: felt252, player_color: felt252 ) {
let mut game: Game = get!(world, game_id, (Game));

assert(game.game_status == GameStatus::Waiting, 'Game is not pending');

let mut player: Player = get!(world, player_username, (Player));
assert(player.owner != 0.try_into().unwrap(), 'Player does not exist');
let players = array![
game.player_green, game.player_yellow, game.player_blue, game.player_red
];
let players_span = players.span();
let mut i = 0;
while i < 4 {
assert(players_span[i] != @player_username, 'Player already in game');
i += i;
};
match player_color {
0 => game.player_green = player_username,
1 => game.player_yellow = player_username,
2 => game.player_blue = player_username,
3 => game.player_red = player_username,
_ => panic!("Invalid player color")
}

// Update game status if all players have joined
if game.player_green != 0
&& game.player_yellow != 0
&& game.player_blue != 0
&& game.player_red != 0 {
game.game_status = GameStatus::Ongoing;
}

set!(world, (game));
}
}
}

Expand Down
40 changes: 40 additions & 0 deletions onchain/src/tests/test_game.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,45 @@ mod tests {
// // Assert that the player was invited. if false then player was not invited
// assert(is_player_invited, Errors::INVALID_PLAYER);
}


#[test]
#[ignore]
fn test_join_game() {
let caller = contract_address_const::<'Benjamin'>();
let player_red = 'player_red';
let player_blue = 'player_blue';
let player_yellow = 'player_yellow';
let player_green = 'player_green';
let number_of_players = 4;
let game_mode: GameMode = GameMode::MultiPlayer;
testing::set_account_contract_address(caller);
testing::set_contract_address(caller);

let (game, game_actions, world, _) = create_and_setup_game(
game_mode, number_of_players, player_red, player_blue, player_yellow, player_green
);

let game_id: u64 = game.id;
let new_player = 'player_red';
let player_color: felt252 = 0;

// Check game status before joining
let game_before_join = get!(world, game_id, Game);
assert_eq!(
game_before_join.game_status,
GameStatus::Waiting,
"Game should be in Waiting status before joining"
);

// Attempt to join the game
game_actions.join_game(game_id, new_player, player_color);

// Verify the game state after joining
let updated_game = get!(world, game_id, Game);
assert_eq!(
updated_game.player_green, new_player.into(), "Player should have joined the game"
);
}
}

0 comments on commit 009b340

Please sign in to comment.