From 3d44da3163d25abafa8d34e284dcef08060c7a52 Mon Sep 17 00:00:00 2001 From: rishotics Date: Tue, 23 Apr 2024 02:09:27 +0530 Subject: [PATCH 1/3] add find_next_active_player --- lib/contracts/core/game.masm | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/lib/contracts/core/game.masm b/lib/contracts/core/game.masm index c6d4f90..ff6feb5 100644 --- a/lib/contracts/core/game.masm +++ b/lib/contracts/core/game.masm @@ -17,6 +17,8 @@ const.CURRENT_TURN_PLAYER_PUB_KEY_INDEX=63 # need to check it's storage initiall const.CURRENT_PLAYER_PUB_KEY_INDEX=62 # at 63 we stored pub key for current player (it will contain) const.HIGHEST_BET_SLOT_INDEX=64 # highest bet amount which player will try to match with call const.CURRENT_PHASE=65 # whole game is divided into 4 phases + +const.NEXT_ACTIVE_PLAYER_KEY_INDEX=67 # next active player key index # game events # TODO: fix some storage for the value corresponding to these events const.PLAYER_BETTED_AMOUNT=169 # check slot (169 - 100) @@ -223,6 +225,84 @@ export.play_raise # [] end + +export.find_next_active_player + + ##update the slot for next active players public + # iterate over the number of players starting from the index of current player + 1 + # for each player check is_fold = 0 or 1 + # if 0 then set this to slot NEXT_ACTIVE_PLAYER_KEY_INDEX + # if 1 move to next player + + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX drop drop drop + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX] + + push.10 add #assuming there are 9 values for each player + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + ## FIND THE NUMBER OF ROWS + push.NO_OF_PLAYERS_INDEX drop drop drop + exec.account.get_item drop drop drop + push.9 mul push.NEXT_ACTIVE_PLAYER_KEY_INDEX drop drop drop add + + lte + #[1/0, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + drop dup + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + + while.true + + + ## FIND THE NUMBER OF ROWS + push.NO_OF_PLAYERS_INDEX drop drop drop + exec.account.get_item drop drop drop + push.10 mul push.NEXT_ACTIVE_PLAYER_KEY_INDEX drop drop drop add + lte + #[1/0, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + mem_store.0 + if.mem_load.0 + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + push.1 sub + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10 - 1, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + exec.account.get_item drop drop drop # we should be in the is_fold of current player + #[1/0, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + mem_store.1 # store is_fold inside the mem_store + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + # now check if fold + if.mem_load.1 + push.10 add + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10 + 10] + + else + push.NEXT_ACTIVE_PLAYER_KEY_INDEX drop drop drop swap + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10, NEXT_ACTIVE_PLAYER_KEY_INDEX] + + push.10 sub + #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX, NEXT_ACTIVE_PLAYER_KEY_INDEX] + + exec.account.set_item + push.0 + end + + else + ## FIND THE NUMBER OF ROWS + push.NO_OF_PLAYERS_INDEX drop drop drop + exec.account.get_item drop drop drop + push.10 mul push.NEXT_ACTIVE_PLAYER_KEY_INDEX drop drop drop add + # [num_of_rows, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + sub + # [CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10 - num_of_rows] + end +end + # some basic account methods export.basic_wallet::receive_asset From 773b4c29f0af71f78e024e457faa5ae24b66a7af Mon Sep 17 00:00:00 2001 From: nlok5923 Date: Tue, 23 Apr 2024 14:09:41 +0530 Subject: [PATCH 2/3] added comments --- lib/contracts/core/game.masm | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/contracts/core/game.masm b/lib/contracts/core/game.masm index ff6feb5..9b519df 100644 --- a/lib/contracts/core/game.masm +++ b/lib/contracts/core/game.masm @@ -226,24 +226,33 @@ export.play_raise end -export.find_next_active_player +export.find_next_active_player # why are you exporting this ?? we need to use this internally right - ##update the slot for next active players public + # update the slot for next active players public # iterate over the number of players starting from the index of current player + 1 # for each player check is_fold = 0 or 1 # if 0 then set this to slot NEXT_ACTIVE_PLAYER_KEY_INDEX # if 1 move to next player push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX drop drop drop - #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX] + # => [CURRENT_TURN_PLAYER_PUB_KEY_INDEX] - push.10 add #assuming there are 9 values for each player - #[CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + push.10 add # assuming there are 9 stats values for each player + # => [CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] - ## FIND THE NUMBER OF ROWS push.NO_OF_PLAYERS_INDEX drop drop drop - exec.account.get_item drop drop drop - push.9 mul push.NEXT_ACTIVE_PLAYER_KEY_INDEX drop drop drop add + + exec.account.get_item drop drop drop + # x = no of players + # => [x, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] + + # why are we pushing 9 and then multiplying it with no of players ? + push.9 mul + + # => [9 * x, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] 9 * x would be fold index of last player why are we checking that ?? + push.NEXT_ACTIVE_PLAYER_KEY_INDEX drop drop drop + + add lte #[1/0, CURRENT_TURN_PLAYER_PUB_KEY_INDEX + 10] From 37fc73d0fc65780d2b1c6f69da03079c08cd8461 Mon Sep 17 00:00:00 2001 From: Rachit Chahar <202151123@iiitvadodara.ac.in> Date: Mon, 13 May 2024 20:29:14 +0530 Subject: [PATCH 3/3] feat: add unit test for proc check --- lib/contracts/core/game.masm | 37 +++++++++--- lib/contracts/notes/game/check.masm | 39 +++++++++--- lib/src/constants/mod.rs | 3 +- node/tests/integration/main.rs | 92 +++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 18 deletions(-) diff --git a/lib/contracts/core/game.masm b/lib/contracts/core/game.masm index 14d15c5..82af3b7 100644 --- a/lib/contracts/core/game.masm +++ b/lib/contracts/core/game.masm @@ -344,20 +344,41 @@ export.play_check push.PLAYER_CHECK_COUNTER exec.account::get_item # => [0, 0, 0, player_check_counter] drop drop drop - push.1 add - # => [player_check_counter + 1] + # => [player_check_counter] + + # check whether previous players have checked or not + dup push.1 add + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX exec.account::get_item + # => [0, 0, 0, current_turn_player_pub_key_index, player_check_counter + 1, player_check_counter] + drop drop drop + # => [current_turn_player_pub_key_index, player_check_counter + 1, player_check_counter] + push.CARDS_SLOTS sub + push.PLAYER_STATS_SLOTS div + # => [player no., player_check_counter + 1, player_check_counter] + eq + # => [0/1, player_check_counter] + + if.true + push.1 add + # => [player_check_counter + 1] + else + drop + # => [...] + end + padw drop push.PLAYER_CHECK_COUNTER exec.account::set_item dropw dropw + # => [...] # need to update the turn of the player - push.CURRENT_TURN_INDEX exec.account::get_item - # => [0, 0, 0, current_turn_index] + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX exec.account::get_item + # => [0, 0, 0, current_turn_player_pub_key_index] drop drop drop - # => [current_turn_index] + # => [current_turn_player_pub_key_index] push.PLAYER_STATS_SLOTS add - # => [current_turn_index + 13] + # => [current_turn_player_pub_key_index + 13] # => [next_turn_index] push.NO_OF_PLAYERS_INDEX exec.account::get_item @@ -402,8 +423,8 @@ export.play_check padw drop # => [0, 0, 0, next_turn_index] - push.CURRENT_TURN_INDEX # slot of current turn - # => [CURRENT_TURN_INDEX, 0, 0, 0, next_turn_index] + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX # slot of current turn + # => [CURRENT_TURN_PLAYER_PUB_KEY_INDEX, 0, 0, 0, next_turn_index] exec.account::set_item dropw dropw diff --git a/lib/contracts/notes/game/check.masm b/lib/contracts/notes/game/check.masm index 7667804..06ec337 100644 --- a/lib/contracts/notes/game/check.masm +++ b/lib/contracts/notes/game/check.masm @@ -3,7 +3,7 @@ use.miden::note use.miden::contracts::wallets::basic->wallet const.NO_OF_PLAYERS_INDEX=57 -const.CURRENT_TURN_INDEX=60 +const.CURRENT_TURN_PLAYER_PUB_KEY_INDEX=60 const.PLAYER_STATS_SLOTS=13 const.CARDS_SLOTS=52 const.PLAYER_CHECK_COUNTER=63 @@ -13,20 +13,41 @@ proc.play_check push.PLAYER_CHECK_COUNTER exec.account::get_item # => [0, 0, 0, player_check_counter] drop drop drop - push.1 add - # => [player_check_counter + 1] + # => [player_check_counter] + + # check whether previous players have checked or not + dup push.1 add + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX exec.account::get_item + # => [0, 0, 0, current_turn_player_pub_key_index, player_check_counter + 1, player_check_counter] + drop drop drop + # => [current_turn_player_pub_key_index, player_check_counter + 1, player_check_counter] + push.CARDS_SLOTS sub + push.PLAYER_STATS_SLOTS div + # => [player no., player_check_counter + 1, player_check_counter] + eq + # => [0/1, player_check_counter] + + if.true + push.1 add + # => [player_check_counter + 1] + else + drop + # => [...] + end + padw drop push.PLAYER_CHECK_COUNTER exec.account::set_item dropw dropw + # => [...] # need to update the turn of the player - push.CURRENT_TURN_INDEX exec.account::get_item - # => [0, 0, 0, current_turn_index] + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX exec.account::get_item + # => [0, 0, 0, current_turn_player_pub_key_index] drop drop drop - # => [current_turn_index] + # => [current_turn_player_pub_key_index] push.PLAYER_STATS_SLOTS add - # => [current_turn_index + 13] + # => [current_turn_player_pub_key_index + 13] # => [next_turn_index] push.NO_OF_PLAYERS_INDEX exec.account::get_item @@ -71,8 +92,8 @@ proc.play_check padw drop # => [0, 0, 0, next_turn_index] - push.CURRENT_TURN_INDEX # slot of current turn - # => [CURRENT_TURN_INDEX, 0, 0, 0, next_turn_index] + push.CURRENT_TURN_PLAYER_PUB_KEY_INDEX # slot of current turn + # => [CURRENT_TURN_PLAYER_PUB_KEY_INDEX, 0, 0, 0, next_turn_index] exec.account::set_item dropw dropw diff --git a/lib/src/constants/mod.rs b/lib/src/constants/mod.rs index 275ffe4..6b9f7b5 100644 --- a/lib/src/constants/mod.rs +++ b/lib/src/constants/mod.rs @@ -18,4 +18,5 @@ pub const PLAYER_INITIAL_BALANCE: u8 = 10; pub const HIGHEST_BET: u8 = SMALL_BLIND_AMOUNT; pub const PLAYER_BALANCE_SLOT: u8 = 68; pub const CURRENT_TURN_INDEX_SLOT: u8 = 60; -pub const PLAYER_STATS_SLOTS: u8 = 13; \ No newline at end of file +pub const PLAYER_STATS_SLOTS: u8 = 13; +pub const CHECK_COUNTER_SLOT: u8 = 63; \ No newline at end of file diff --git a/node/tests/integration/main.rs b/node/tests/integration/main.rs index 3c6d154..4ccf16a 100644 --- a/node/tests/integration/main.rs +++ b/node/tests/integration/main.rs @@ -7,6 +7,7 @@ use aze_lib::client::{ PlayRaiseTransactionData, PlayCallTransactionData, PlayFoldTransactionData, + PlayCheckTransactionData, }; use aze_lib::constants::{ BUY_IN_AMOUNT, @@ -18,6 +19,7 @@ use aze_lib::constants::{ PLAYER_INITIAL_BALANCE, PLAYER_BALANCE_SLOT, CURRENT_TURN_INDEX_SLOT, + CHECK_COUNTER_SLOT, }; use aze_lib::executor::execute_tx_and_sync; use aze_lib::utils::{ get_random_coin, load_config }; @@ -382,6 +384,75 @@ async fn test_play_fold() { assert_slot_status_fold(&client, target_account_id, game_slot_data).await; } +#[tokio::test] +async fn test_play_check() { + let mut client: AzeClient = create_test_client(); + + let (game_account, player_account_id, faucet_account_id, game_slot_data) = setup_accounts( + &mut client + ); + + let game_account_storage = game_account.storage(); + + let fungible_asset = FungibleAsset::new(faucet_account_id, BUY_IN_AMOUNT).unwrap(); + let sender_account_id = player_account_id; + let target_account_id = game_account.id(); + + fund_account(&mut client, sender_account_id, faucet_account_id).await; + + let playcheck_txn_data = PlayCheckTransactionData::new( + Asset::Fungible(fungible_asset), + sender_account_id, + target_account_id + ); + + let transaction_template = AzeTransactionTemplate::PlayCheck(playcheck_txn_data); + let txn_request = client.build_aze_play_check_tx_request(transaction_template).unwrap(); + execute_tx_and_sync(&mut client, txn_request.clone()).await; + + let note_id = txn_request.expected_output_notes()[0].id(); + let note = client.get_input_note(note_id).unwrap(); + + let tx_template = TransactionTemplate::ConsumeNotes(target_account_id, vec![note.id()]); + let tx_request = client.build_transaction_request(tx_template).unwrap(); + execute_tx_and_sync(&mut client, tx_request).await; + + println!("Executed and synced with node"); + assert_slot_status_check(&client, target_account_id, game_slot_data.clone(), 1 as u8).await; + + let (player2_account, _) = client + .new_game_account( + AzeAccountTemplate::PlayerAccount { + mutable_code: false, + storage_mode: AccountStorageMode::Local, + }, + None + ) + .unwrap(); + + fund_account(&mut client, player2_account.id(), faucet_account_id).await; + + let playcheck_txn_data = PlayCheckTransactionData::new( + Asset::Fungible(fungible_asset), + player2_account.id(), + target_account_id + ); + + let transaction_template = AzeTransactionTemplate::PlayCheck(playcheck_txn_data); + let txn_request = client.build_aze_play_check_tx_request(transaction_template).unwrap(); + execute_tx_and_sync(&mut client, txn_request.clone()).await; + + let note_id = txn_request.expected_output_notes()[0].id(); + let note = client.get_input_note(note_id).unwrap(); + + let tx_template = TransactionTemplate::ConsumeNotes(target_account_id, vec![note.id()]); + let tx_request = client.build_transaction_request(tx_template).unwrap(); + execute_tx_and_sync(&mut client, tx_request).await; + + println!("Executed and synced with node"); + assert_slot_status_check(&client, target_account_id, game_slot_data, 2 as u8).await; +} + async fn assert_account_status(client: &AzeClient, account_id: AccountId, index: usize) { let (account, _) = client.get_account(account_id).unwrap(); let card_suit = 1u8; @@ -561,6 +632,27 @@ async fn assert_slot_status_fold( ); } +async fn assert_slot_status_check( + client: &AzeClient, + account_id: AccountId, + slot_data: GameStorageSlotData, + player_number: u8 +) { + let (account, _) = client.get_account(account_id).unwrap(); + let game_account_storage = account.storage(); + + // assert check count + let check_count = game_account_storage.get_item(CHECK_COUNTER_SLOT); + assert_eq!(check_count, RpoDigest::new([Felt::from(player_number as u8), Felt::ZERO, Felt::ZERO, Felt::ZERO])); + + let next_turn_index = slot_data.current_turn_index() + 13 * player_number; + // check next turn index + assert_eq!( + game_account_storage.get_item(CURRENT_TURN_INDEX_SLOT), + RpoDigest::new([Felt::from(next_turn_index), Felt::ZERO, Felt::ZERO, Felt::ZERO]) + ); +} + async fn fund_account(client: &mut AzeClient, account_id: AccountId, faucet_account_id: AccountId) { let note = mint_note(client, account_id, faucet_account_id, NoteType::Public).await; consume_notes(client, account_id, &[note]).await;