A networked, multiplayer trivia game built in Python using raw TCP sockets, inspired by Kahoot. Multiple players connect to a central server and compete to answer trivia questions in real time. The server tracks scores, enforces per-question time limits, and broadcasts a live leaderboard between rounds.
This was built as a networking assignment for INFO1112 (Operating Systems and Network Platforms) at the University of Sydney.
- Client-server architecture over TCP with a custom JSON message protocol
- Newline-delimited message framing for reliable delivery over a stream socket
- Concurrent player handling on the server using
select()for I/O multiplexing - Graceful handling of mid-game disconnections (disconnected players remain on the leaderboard)
- Three client modes: manual input, auto-solve, and AI-powered (via Ollama)
- Auto-solve mode achieves 100% accuracy across all question types
- Time-limited answer windows enforced using
multiprocessingon the client
The server supports four question types, configurable via a JSON config file:
- Mathematics - Evaluates arithmetic expressions using the Shunting Yard algorithm (infix to Reverse Polish Notation)
- Roman Numerals - Converts roman numerals to their decimal equivalent
- Usable IP Addresses of a Subnet - Calculates the number of usable host addresses in a given CIDR subnet
- Network and Broadcast Address of a Subnet - Determines the network and broadcast addresses of a CIDR subnet using bitwise operations
.
├── server.py # TCP server: manages players, questions, scoring, and game flow
├── client.py # TCP client: connects to server and answers questions
├── questions.py # Question generation logic (randomised)
- Python 3.10 or higher
requestslibrary (for AI mode only)
Install dependencies:
pip install requestsFor AI mode, Ollama must be running locally with a model pulled (e.g. ollama pull mistral).
Both the server and client are configured via JSON files.
{
"port": 7777,
"players": 2,
"question_types": [
"Mathematics",
"Roman Numerals",
"Usable IP Addresses of a Subnet",
"Network and Broadcast Address of a Subnet"
],
"question_formats": {
"Mathematics": "What is {}?",
"Roman Numerals": "What is the decimal value of the roman numeral {}?",
"Usable IP Addresses of a Subnet": "How many usable addresses are there in the subnet {}?",
"Network and Broadcast Address of a Subnet": "What are the network and broadcast addresses of the subnet {}?"
},
"question_seconds": 10,
"question_interval_seconds": 5,
"ready_info": "Game starts in {question_interval_seconds} seconds!",
"question_word": "Question",
"correct_answer": "Correct!",
"incorrect_answer": "Wrong answer.",
"points_noun_singular": "point",
"points_noun_plural": "points",
"final_standings_heading": "Final standings:",
"one_winner": "{} wins!",
"multiple_winners": "It's a tie between {}!"
}{
"username": "player1",
"client_mode": "you"
}For AI mode:
{
"username": "robot",
"client_mode": "ai",
"ollama_config": {
"ollama_host": "localhost",
"ollama_port": 11434,
"ollama_model": "mistral:latest"
}
}1. Start the server:
python server.py --config server_config.jsonThe server waits until the configured number of players have joined before starting.
2. Start a client (in a separate terminal for each player):
python client.py --config client_config.json3. Connect to the server:
Once the client starts, type:
CONNECT localhost:7777
4. Play:
Once all players have connected, the server sends a ready message and the game begins. Each question appears with a time limit. Type your answer and press Enter.
| Mode | Description |
|---|---|
you |
Answer questions manually via standard input |
auto |
Answers automatically using code (100% accuracy on all question types) |
ai |
Sends questions to a local LLM via the Ollama API and submits its response |
| Command | Description |
|---|---|
CONNECT <host>:<port> |
Connect to a server |
DISCONNECT |
Disconnect from the current server |
EXIT |
Quit the client |
All messages between client and server are JSON objects encoded in UTF-8, terminated by a newline character (\n). The server sends: READY, QUESTION, RESULT, LEADERBOARD, and FINISHED. The client sends: HI, ANSWER, and BYE.
Example question message from the server:
{
"message_type": "QUESTION",
"question_type": "Mathematics",
"trivia_question": "Question 1 (Mathematics):\nWhat is 3 + 7?",
"short_question": "3 + 7",
"time_limit": 10
}Example answer from the client:
{
"message_type": "ANSWER",
"answer": "10"
}