🚀 Introducing Block Paper Scissors: a simple on-chain mobile game where players go head-to-head to earn a dynamic on-chain NFT.
Block Paper Scissors is a simple-but-clever on-chain game designed for web and mobile that brings the classic game of Rock, Paper, Scissors on chain. This project is not just a game; it's a key primitive and entry point into the worlds of on-chain gaming and digital collectibles.
At its core, Block Paper Scissors is a head-to-head game where two players compete in the timeless game of rock-paper-scissors. However, unlike the traditional game, victories in Block Paper Scissors are not just for bragging rights. Each win contributes to the player's collection of dynamic NFTs (ERC-1155s).
The game employs a simple zero-knowledge commit-reveal mechanic to ensure fairness in each match. Players commit their choices (block, paper, or scissors) in an encrypted format, which are then revealed simultaneously to determine the winner. This mechanic not only adds an element of suspense but also prevents cheating, ensuring a fair and enjoyable gaming experience.
One of the most fun features of Block Paper Scissors is the evolution of its NFTs. As players win matches, their NFTs evolve to display their most recent winning 'throw', along with a history of past victories, creating an ever-changing digital asset that grows with the player's success in the game.
The user experience is streamlined and accessible. Players access the game through a web-based decentralized app where they can create an account or log in, choose a display name, and start playing immediately. The game interface is intuitive, with players starting or joining matches using a match code. The game's design ensures that even those new to blockchain technology can jump in without a steep learning curve.
In summary, Block Paper Scissors is an engaging, fair, and potentially rewarding experiment that points an interesting way forward for continued work.
README.md registerPlayer(displayName: string): Registers a new player with a unique display name and mints an NFT for their game stats. Use this function for new player onboarding.
initiateMatch(): Starts a new game match and returns its unique ID. Call this when a player wants to start a new match.
joinMatch(matchId: uint256): Allows a second player to join an existing match. Use this for allowing players to join ongoing matches.
commitMove(matchId: uint256, hashedMove: bytes32): Players commit their move in a hashed form. Implement when players make their move, ensuring the move remains secret.
revealMove(matchId: uint256, playerMove: enum Move, secret: bytes32): Players reveal their move, verifying against the commit hash. Use a timer to prompt players to reveal their move within N blocks.
Utility Functions for Frontend getPlayerData(playerAddress: address): Returns Player struct (displayName: string, totalWins: uint256, nftId: uint256). Display player information and statistics.
getMatchData(matchId: uint256): Returns GameMatch struct. Show details of a match including player participation and status.
getNFTMetadata(nftId: uint256): Returns NFTMetadata struct. Display NFT-related statistics like wins per move type.
isPlayerRegistered(playerAddress: address): Returns Boolean. Verify if a user is already registered.
getTotalMatches(): Returns Total number of matches (uint256). Display statistics like total matches played on the platform.
isPlayerInMatch(matchId: uint256, playerAddress: address): Returns Boolean. Determine if a specific player is in a particular match.
isMatchResolved(matchId: uint256): Returns Boolean. Check if a match has been resolved.