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

Sisyphus smiling/add condensed match creation txn #47

Merged
Merged
Show file tree
Hide file tree
Changes from 6 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
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: CI

on:
- push
- pull_request
pull_request:
branches: [main]
push:
branches: [main]

jobs:
build:
Expand Down
3 changes: 1 addition & 2 deletions scripts/rock_paper_scissors_game/get_matches_in_play.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
55 changes: 55 additions & 0 deletions test/rps_tests.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,50 @@ 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 & Submit Move --- */
//
// 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
let matchIDs = getMatchIDsInPlay(player.address)
Test.assertEqual(1, matchIDs.length)
let matchID = matchIDs[0]

/* --- Resolve the Match --- */
//
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
Expand Down Expand Up @@ -368,6 +412,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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
/// Collectio, also submitting the given move for the new match and calling for the automated player's move to be played.
sisyphusSmiling marked this conversation as resolved.
Show resolved Hide resolved
///
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)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down