Project Objectives – by building this project you will:
  • Record a sports match on-chain with structs, an enum and a mapping.
  • Implement round-based scoring and winner rules with if/else logic.
  • Build a readable status message with string.concat.
Synopsis

Managing a badminton tournament involves player registration, match scheduling, live scoring, results and standings. Score records are often disputed, so storing them on a blockchain gives a tamper-proof match history that anyone can check.

This project focuses on the core of such a system: a single match between two players. The deploying account is the Match Referee, who registers both players, starts the match and records each point. The contract applies the rules – a game is won at 21 points, the player who wins two games wins the match, and a third game decides a 1–1 tie – and publishes the match status and winner.

Features of a Complete Tournament System (Scope)
  • Player registration and profiles
  • Tournament set-up and match scheduling
  • Live score tracking
  • Results and standings
  • Notifications
  • Analytics and reporting
  • Referee / officiating tools
  • Security and access control
  • Scoring-system integration

The smart contract in this project implements the referee tools, live scoring and result parts; the other features belong to the surrounding web application and database.

Contract Architecture
PartDetails
BlockFiles.solStructs PlayerBlock { playerAddress, playerName, PlayerCountry } and MatchBlock (two player addresses and points for each player in rounds 1–3)
Tournament.solContract BadmintonTournament; imports contracts/BlockFiles.sol
enum & mappingenum players { PLAYER1, PLAYER2 }; mapping(uint => PlayerBlock) public playerList
statematchReferee, MatchBlock public matchBlockObj, roundNumber, matchStatus, player-initialised flags
modifierscheckMatchReferee, checkPlayersInit (both players registered), checkRoundStatus (round 1–3 in progress)
functionsInitFirstPlayer, InitSecondPlayer, InitMatch, stepPlayer1, stepPlayer2 (add a point), gotoNextRound, private checkForNextRound, checkWinner, checkFinalWinner, and checkMatchStatus() (view)
How It Works
1. PlayersReferee registers Player 1 and Player 2
2. StartInitMatch → round 1, status “Running”
3. ScorestepPlayer1/2 add points; 21 points ends a round
4. WinnerTwo rounds won (or round 3 won) → “Match Over : Name (WINNER)”

After the match ends, roundNumber is set to 9, so checkRoundStatus rejects any further points.

Key Requirements (Concepts Used)
  • Structs imported from a separate file and an enum for player slots (Chapters 11, 13).
  • Mapping of player slots to player records (Chapter 12).
  • Decision making for rounds and winners (Chapter 7).
  • Private functions and a view function (Chapter 15).
  • Modifiers for referee-only actions and valid rounds (Chapter 22).
  • String building with string.concat (Chapter 9).
How to Run in Remix
  1. Create contracts/BlockFiles.sol and contracts/Tournament.sol; compile and deploy BadmintonTournament from the first account (referee).
  2. Call InitFirstPlayer and InitSecondPlayer with an address, name and country, then InitMatch.
  3. Call stepPlayer1/stepPlayer2 to add points; read matchBlockObj and roundNumber as the game progresses.
  4. Call checkMatchStatus() to read the result.
Limitations and Extension Exercises
Observation in the teaching versionImprovement to try
A game ends at exactly 21 points; official badminton also requires a 2-point lead (up to a 30-point cap).Implement the deuce rule.
Only one match can be stored.Use mapping(uint => MatchBlock) with match IDs to build a tournament.
Every point is a transaction, which costs gas.Record scores off-chain and store only the final, signed result on-chain.
The referee is the only trusted scorer.Require confirmation from both players or a second official.
No events are emitted.Emit PointScored and MatchWon events for a live scoreboard (Chapter 20).
Key Takeaways
  • Structs, an enum and a mapping represent players and a match; modifiers restrict scoring to the referee.
  • if/else logic in private functions implements the game rules and winner detection.
  • On-chain scoring gives a tamper-proof history but costs gas for every update.
Video : Project 5 : Smart Contract for Badminton Tournament System
Resource Files
Question / Answer (15 questions)

Answer : To record a match between two players on the blockchain – registration, points in each round and the final winner – so that the result is tamper-proof and publicly verifiable.

Answer : The account that deploys the contract. Only the referee can register players, start the match, add points and move to the next round.

Answer : PlayerBlock (playerAddress, playerName, PlayerCountry) and MatchBlock (both player addresses and each player’s points in rounds 1, 2 and 3).

Answer : enum players { PLAYER1, PLAYER2 } gives readable names to the two player slots; converted with uint(...), they act as keys of the playerList mapping.

Answer : That both players have been registered (isplayer1Init and isplayer2Init are true) before the match can start.

Answer : It creates the MatchBlock with both players’ addresses and all points set to zero, sets roundNumber to 1 and sets matchStatus to “Running”.

Answer : When a player’s points in the current round reach 21, checkForNextRound increases roundNumber and calls checkWinner; the referee can also call gotoNextRound.

Answer : If the same player reaches 21 points in rounds 1 and 2, that player wins. Otherwise round 3 is played, and the first player to reach 21 in round 3 wins.

Answer : With string.concat("Match Over : ", pname, " (WINNER)"), which joins strings (Solidity 0.8.12+).

Answer : checkRoundStatus only allows rounds 1–3, so setting 9 blocks any further scoring after the match is over.

Answer : They are internal steps of the scoring logic and should run only when called by the contract’s own functions, not directly by users.

Answer : The deuce rule: officially, at 20–20 a player must lead by two points to win the game (with a 30-point cap). The contract ends a game at exactly 21 points.

Answer : Each point is a transaction that costs gas and takes time; for real matches it may be better to record scores off-chain and store only signed final results.

Answer : Store many matches in a mapping keyed by match ID, add brackets or standings, and emit events for each point and result.

Answer : It is a view function that returns the matchStatus string – “Running” during play or “Match Over : Name (WINNER)” at the end – without costing gas when called off-chain.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Who can add points in the BadmintonTournament contract?

Show Answer

Correct Answer : C. Only the Match Referee
stepPlayer1/2 use checkMatchReferee.

Q2. A game (round) ends in the contract when a player reaches:

Show Answer

Correct Answer : B. 21 points
checkForNextRound tests points == 21.

Q3. Which function joins strings to build the winner message?

Show Answer

Correct Answer : A. string.concat
string.concat joins the strings.

Q4. What prevents scoring after the match is over?

Show Answer

Correct Answer : D. roundNumber set to 9 with checkRoundStatus
checkRoundStatus allows only rounds 1–3.

Q5. Player slots PLAYER1 and PLAYER2 are defined using:

Show Answer

Correct Answer : A. An enum
enum players { PLAYER1, PLAYER2 }.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Types (value types, reference types, mappings, operators, conversions). Solidity Documentation. https://docs.soliditylang.org/en/latest/types.html
  2. Solidity Team. (n.d.). Expressions and Control Structures (if/else, loops, checked arithmetic, error handling, try/catch). Solidity Documentation. https://docs.soliditylang.org/en/latest/control-structures.html
  3. Solidity Team. (n.d.). Contracts (creating contracts, visibility and getters, function modifiers, constant and immutable, functions, events, custom errors, inheritance, abstract contracts, interfaces, libraries). Solidity Documentation. https://docs.soliditylang.org/en/latest/contracts.html
  4. Remix Project. (n.d.). Remix IDE Documentation. https://remix-ide.readthedocs.io/en/latest/
  5. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.