From 5d39cc5b1de3dcdb3c574c9c1b598fc317e9ea7a Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:11:24 -0500 Subject: [PATCH 1/7] add consolidated match setup & move submission txn for singleplayer --- test/rps_tests.cdc | 56 +++++++++++++++++++ ...ew_singleplayer_match_and_submit_moves.cdc | 47 ++++++++++++++++ .../submit_both_singleplayer_moves.cdc | 17 ++---- .../reset_win_loss_data.cdc | 24 ++++++++ 4 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc create mode 100644 transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc diff --git a/test/rps_tests.cdc b/test/rps_tests.cdc index 89f5441..0ed0f97 100644 --- a/test/rps_tests.cdc +++ b/test/rps_tests.cdc @@ -110,6 +110,51 @@ pub fun testCompleteSinglePlayerMatch() { Test.assertEqual(rock, history[playerID]!) } +pub fun testCompleteSinglePlayerMatchCreatingAndSubmittingMoves() { + /* --- Onboard Player --- */ + // + // Configure player's account with game resources + // **NOTE:** in the example app, we'd onboard players via walletless onboarding. We're not doing that here because + // we can't sign test transactions without a Test.Account object + let player = blockchain.createAccount() + selfCustodyOnboarding(player) + + // Ensure all resources & Capabilities configured as expected + assertCollectionConfigured(player.address, collection: gamePieceNFT) + assertGamePlayerConfigured(player.address) + assertTicketTokenConfigured(player.address) + + // Query minted NFT.id + let nftIDs = getCollectionIDs(player.address, collection: gamePieceNFT) + Test.assertEqual(1, nftIDs.length) + let nftID = nftIDs[0] + + // Query GamePlayer.id + let playerID = getGamePlayerID(player.address) + + /* --- Create Single-Player Match --- */ + // + // Sign up for match + setupNewSingleplayerMatchAndSubmitMoves(player, nftID: nftID, matchTimeLimit: matchTimeLimit, move: rock) + + // Get the ID of the match just created + let matchIDs = getMatchIDsInPlay(player.address) + Test.assertEqual(1, matchIDs.length) + let matchID = matchIDs[0] + + /* --- Play the Match --- */ + // + // submitBothSinglePlayerMoves(player, matchID: matchID, move: rock) + resolveMatch(player, matchID: matchID) + + /* --- Verify Match Results --- */ + // + let history = getMatchHistoryAsRawValues(matchID: matchID) + ?? panic("Should have returned valid history, but got nil!") + assert(history.containsKey(playerID)) + Test.assertEqual(rock, history[playerID]!) +} + pub fun testCompleteMultiPlayerMatch() { // **NOTE:** in the example app, we'd onboard players via walletless onboarding. We're not doing that here because @@ -368,6 +413,17 @@ pub fun setupNewSingleplayerMatch(_ acct: Test.Account, nftID: UInt64, matchTime Test.assert(success) } +pub fun setupNewSingleplayerMatchAndSubmitMoves(_ acct: Test.Account, nftID: UInt64, matchTimeLimit: UInt, move: UInt8) { + let success = txExecutor( + "rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc", + [acct], + [nftID, matchTimeLimit, move], + nil, + nil + ) + Test.assert(success) +} + pub fun setupNewMultiplayerMatch(_ acct: Test.Account, nftID: UInt64, playerTwoAddr: Address, matchTimeLimit: UInt) { let success = txExecutor( "rock_paper_scissors_game/game_player/setup_new_multiplayer_match.cdc", diff --git a/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc b/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc new file mode 100644 index 0000000..b457e9e --- /dev/null +++ b/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc @@ -0,0 +1,47 @@ +import "NonFungibleToken" +import "GamePieceNFT" +import "RockPaperScissorsGame" + +/// Transaction that creates a new Match in single player mode and +/// escrows the specified NFT from the signing account's Collection +/// +transaction(submittingNFTID: UInt64, matchTimeLimitInMinutes: UInt, move: UInt8) { + + let gamePlayerRef: &RockPaperScissorsGame.GamePlayer + let newMatchID: UInt64 + + prepare(acct: AuthAccount) { + // Get a reference to the GamePlayer resource in the signing account's storage + self.gamePlayerRef = acct.borrow<&RockPaperScissorsGame.GamePlayer>( + from: RockPaperScissorsGame.GamePlayerStoragePath + ) ?? panic("Could not borrow GamePlayer reference!") + + let receiverCap = acct.getCapability<&{NonFungibleToken.Receiver}>( + GamePieceNFT.CollectionPublicPath + ) + + // Get a reference to the account's Provider + let providerRef = acct.borrow<&{NonFungibleToken.Provider}>(from: GamePieceNFT.CollectionStoragePath) + ?? panic("Could not borrow reference to account's Provider") + // Withdraw the desired NFT + let submittingNFT <-providerRef.withdraw(withdrawID: submittingNFTID) as! @GamePieceNFT.NFT + + // Create a match with the given timeLimit in minutes + self.newMatchID = self.gamePlayerRef.createMatch( + multiPlayer: false, + matchTimeLimit: UFix64(matchTimeLimitInMinutes) * UFix64(60000), + nft: <-submittingNFT, + receiverCap: receiverCap + ) + } + + execute { + // Construct a legible move from the raw input value + let moveAsEnum = RockPaperScissorsGame.Moves(rawValue: move) + ?? panic("Given move does not map to a legal RockPaperScissorsGame.Moves value!") + // Submit moves for the game + self.gamePlayerRef.submitMoveToMatch(matchID: self.newMatchID, move: moveAsEnum) + RockPaperScissorsGame.submitAutomatedPlayerMove(matchID: self.newMatchID) + } +} + \ No newline at end of file diff --git a/transactions/rock_paper_scissors_game/game_player/submit_both_singleplayer_moves.cdc b/transactions/rock_paper_scissors_game/game_player/submit_both_singleplayer_moves.cdc index 7c3e5e4..79c32b0 100644 --- a/transactions/rock_paper_scissors_game/game_player/submit_both_singleplayer_moves.cdc +++ b/transactions/rock_paper_scissors_game/game_player/submit_both_singleplayer_moves.cdc @@ -9,24 +9,19 @@ import "RockPaperScissorsGame" transaction(matchID: UInt64, move: UInt8) { let gamePlayerRef: &RockPaperScissorsGame.GamePlayer - let moveAsEnum: RockPaperScissorsGame.Moves prepare(acct: AuthAccount) { // Get the GamePlayer reference from the signing account's storage - self.gamePlayerRef = acct - .borrow<&RockPaperScissorsGame.GamePlayer>( - from: RockPaperScissorsGame.GamePlayerStoragePath - ) ?? panic("Could not borrow GamePlayer reference!") - // Construct a legible move from the raw input value - self.moveAsEnum = RockPaperScissorsGame - .Moves( - rawValue: move - ) ?? panic("Given move does not map to a legal RockPaperScissorsGame.Moves value!") + self.gamePlayerRef = acct.borrow<&RockPaperScissorsGame.GamePlayer>(from: RockPaperScissorsGame.GamePlayerStoragePath) + ?? panic("Could not borrow GamePlayer reference!") } execute { + // Construct a legible move from the raw input value + let moveAsEnum = RockPaperScissorsGame.Moves(rawValue: move) + ?? panic("Given move does not map to a legal RockPaperScissorsGame.Moves value!") // Submit moves for the game - self.gamePlayerRef.submitMoveToMatch(matchID: matchID, move: self.moveAsEnum) + self.gamePlayerRef.submitMoveToMatch(matchID: matchID, move: moveAsEnum) RockPaperScissorsGame.submitAutomatedPlayerMove(matchID: matchID) } } diff --git a/transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc b/transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc new file mode 100644 index 0000000..bb80a1f --- /dev/null +++ b/transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc @@ -0,0 +1,24 @@ +import GamePieceNFT from "../../../contracts/GamePieceNFT.cdc" +import GamingMetadataViews from "../../../contracts/GamingMetadataViews.cdc" +import RockPaperScissorsGame from "../../../contracts/RockPaperScissorsGame.cdc" + +/// This transaction resets the win/loss record for the NFT with the specified id +/// +transaction(nftID: UInt64) { + + prepare(account: AuthAccount) { + // Borrow ResolverCollection reference + let collectionRef = account + .borrow<&{GamePieceNFT.GamePieceNFTCollectionPublic}>( + from: GamePieceNFT.CollectionStoragePath + ) ?? panic("Could not borrow a reference to the collection at path: ".concat(GamePieceNFT.CollectionStoragePath.toString())) + + // Get the NFT reference if it exists in the reference collection + if let nftRef = collectionRef.borrowGamePieceNFT(id: nftID) { + // Get the RPSAssignedMoves attachment if exists & reset + if let winLossRef = nftRef[RockPaperScissorsGame.RPSWinLossRetriever] { + winLossRef.resetWinLossData() + } + } + } +} From a6e9039e5a47c9fbe7ab0c2f9145c2a7cfa06c27 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:13:55 -0500 Subject: [PATCH 2/7] fix dev setup txn --- scripts/rock_paper_scissors_game/get_matches_in_play.cdc | 3 +-- .../dev_setup/setup_filter_and_factory_manager.cdc | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/rock_paper_scissors_game/get_matches_in_play.cdc b/scripts/rock_paper_scissors_game/get_matches_in_play.cdc index f364ea0..57e8115 100644 --- a/scripts/rock_paper_scissors_game/get_matches_in_play.cdc +++ b/scripts/rock_paper_scissors_game/get_matches_in_play.cdc @@ -7,8 +7,7 @@ pub fun main(address: Address): [UInt64] { let account = getAccount(address) - let gamePlayerRef = account - .getCapability(RockPaperScissorsGame.GamePlayerPublicPath) + let gamePlayerRef = account.getCapability(RockPaperScissorsGame.GamePlayerPublicPath) .borrow<&{RockPaperScissorsGame.GamePlayerPublic}>() ?? panic("Could not borrow capability from public collection at specified path") diff --git a/transactions/hybrid_custody/dev_setup/setup_filter_and_factory_manager.cdc b/transactions/hybrid_custody/dev_setup/setup_filter_and_factory_manager.cdc index 7ac108c..923633f 100644 --- a/transactions/hybrid_custody/dev_setup/setup_filter_and_factory_manager.cdc +++ b/transactions/hybrid_custody/dev_setup/setup_filter_and_factory_manager.cdc @@ -62,7 +62,7 @@ transaction(nftContractAddress: Address, nftContractName: String, ftContractAddr acct.save(<-f, to: CapabilityFactory.StoragePath) } - if !acct.getCapability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>(CapabilityFactory.PrivatePath).check() { + if !acct.getCapability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>(CapabilityFactory.PublicPath).check() { acct.unlink(CapabilityFactory.PublicPath) acct.link<&CapabilityFactory.Manager{CapabilityFactory.Getter}>(CapabilityFactory.PublicPath, target: CapabilityFactory.StoragePath) } From d517b128a0a64498605e2f0471e074b53cbb034d Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:18:19 -0500 Subject: [PATCH 3/7] update tests --- test/rps_tests.cdc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/rps_tests.cdc b/test/rps_tests.cdc index 0ed0f97..2a46c46 100644 --- a/test/rps_tests.cdc +++ b/test/rps_tests.cdc @@ -132,9 +132,9 @@ pub fun testCompleteSinglePlayerMatchCreatingAndSubmittingMoves() { // Query GamePlayer.id let playerID = getGamePlayerID(player.address) - /* --- Create Single-Player Match --- */ + /* --- Create Single-Player Match & Submit Move --- */ // - // Sign up for match + // Creates a match, also subitting move for the new match for both players setupNewSingleplayerMatchAndSubmitMoves(player, nftID: nftID, matchTimeLimit: matchTimeLimit, move: rock) // Get the ID of the match just created @@ -142,9 +142,8 @@ pub fun testCompleteSinglePlayerMatchCreatingAndSubmittingMoves() { Test.assertEqual(1, matchIDs.length) let matchID = matchIDs[0] - /* --- Play the Match --- */ + /* --- Resolve the Match --- */ // - // submitBothSinglePlayerMoves(player, matchID: matchID, move: rock) resolveMatch(player, matchID: matchID) /* --- Verify Match Results --- */ From 0b46764ce49d40f171b29fc8ba9eb45951a136a4 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:19:25 -0500 Subject: [PATCH 4/7] rm outdated txn --- .../reset_win_loss_data.cdc | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc diff --git a/transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc b/transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc deleted file mode 100644 index bb80a1f..0000000 --- a/transactions/rock_paper_scissors_game/rps_win_loss_retriever/reset_win_loss_data.cdc +++ /dev/null @@ -1,24 +0,0 @@ -import GamePieceNFT from "../../../contracts/GamePieceNFT.cdc" -import GamingMetadataViews from "../../../contracts/GamingMetadataViews.cdc" -import RockPaperScissorsGame from "../../../contracts/RockPaperScissorsGame.cdc" - -/// This transaction resets the win/loss record for the NFT with the specified id -/// -transaction(nftID: UInt64) { - - prepare(account: AuthAccount) { - // Borrow ResolverCollection reference - let collectionRef = account - .borrow<&{GamePieceNFT.GamePieceNFTCollectionPublic}>( - from: GamePieceNFT.CollectionStoragePath - ) ?? panic("Could not borrow a reference to the collection at path: ".concat(GamePieceNFT.CollectionStoragePath.toString())) - - // Get the NFT reference if it exists in the reference collection - if let nftRef = collectionRef.borrowGamePieceNFT(id: nftID) { - // Get the RPSAssignedMoves attachment if exists & reset - if let winLossRef = nftRef[RockPaperScissorsGame.RPSWinLossRetriever] { - winLossRef.resetWinLossData() - } - } - } -} From 48766fa999af8aa2128537769d52963d74395a4a Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:20:50 -0500 Subject: [PATCH 5/7] update txn comment --- .../setup_new_singleplayer_match_and_submit_moves.cdc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc b/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc index b457e9e..add64a1 100644 --- a/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc +++ b/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc @@ -2,8 +2,8 @@ import "NonFungibleToken" import "GamePieceNFT" import "RockPaperScissorsGame" -/// Transaction that creates a new Match in single player mode and -/// escrows the specified NFT from the signing account's Collection +/// Transaction that creates a new Match in single player mode and escrows the specified NFT from the signing account's +/// Collectio, also submitting the given move for the new match and calling for the automated player's move to be played. /// transaction(submittingNFTID: UInt64, matchTimeLimitInMinutes: UInt, move: UInt8) { From 7ac63776d075dfadd88e9379c180c48cbe05f08e Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:22:31 -0500 Subject: [PATCH 6/7] update github ci action --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c6ba6c..fb46e57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,10 @@ name: CI on: - - push - - pull_request + pull_request: + branches: [main] + push: + branches: [main] jobs: build: From de6f27d01000d8b9e63cd17ff452d1f4a8edd434 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:50:33 -0500 Subject: [PATCH 7/7] Update transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc Co-authored-by: Joshua Hannan --- .../setup_new_singleplayer_match_and_submit_moves.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc b/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc index add64a1..a8ac205 100644 --- a/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc +++ b/transactions/rock_paper_scissors_game/game_player/setup_new_singleplayer_match_and_submit_moves.cdc @@ -3,7 +3,7 @@ import "GamePieceNFT" import "RockPaperScissorsGame" /// Transaction that creates a new Match in single player mode and escrows the specified NFT from the signing account's -/// Collectio, also submitting the given move for the new match and calling for the automated player's move to be played. +/// Collection, also submitting the given move for the new match and calling for the automated player's move to be played. /// transaction(submittingNFTID: UInt64, matchTimeLimitInMinutes: UInt, move: UInt8) {