Web implementation of the Gomoku board game
A web implementation of Gomoku (Five in a Row) built as an academic project for a web development course. The goal was a fully functional multiplayer game playable online, with persistent stats and rankings.
Stack
| Layer | Technology | Why |
|---|---|---|
| Backend | Spring Boot + Kotlin/Java | Course requirement |
| Database | PostgreSQL | Course requirement |
| Frontend | TypeScript | Course requirement |
| Deployment | Docker | Backend containerization |
Features
| Feature | Description |
|---|---|
| Online Multiplayer | Real-time matches against other players |
| Game History | View past games, win/loss record, and performance stats |
| Leaderboards | Global ranking to compare performance across all players |
| Favourites | Bookmark specific games for later review |
Architecture
Backend is a Spring Boot application exposing RESTful APIs for user management, game state, and leaderboards. Game state is managed via the PostgreSQL database. Move validation is performed server-side to ensure game integrity. Authentication is custom built for the sake of learning, with password hashing and session management.
The frontend is a React application that interacts with the backend via REST for authentication, game management, and leaderboards. Polling is used for real-time updates on game state, which is a simpler approach given the academic scope and constraints of the project. With a 1s interval, the game state is updated frequently enough for a responsive experience without overwhelming the server with requests but wouldn’t be ideal for a production-quality game.
Challenges
Game State Management - representing the board state in a relational schema was challenging because moves are sequential and positional, and querying for win conditions across rows, columns, and diagonals required careful schema design and query logic.
Academic Constraints - the time constraints as well as the requirement to use specific technologies (Spring Boot, PostgreSQL, TypeScript) limited the architectural choices and led to some tradeoffs in terms of real-time updates and scalability. For example, using polling for real-time updates was a simpler solution given the constraints, but it is not ideal for a production-quality game.
What I’d Do Differently
Drop polling for real-time updates. If I were to build this again without the academic constraints, I would implement WebSocket-based real-time communication for game state updates instead of polling. A WebSocket connection would allow for instant updates to the game state without the overhead and latency of polling as well as reducing unnecessary requests when the game state is static. This would provide a smoother and more responsive user experience, especially during active gameplay.
Implement a more robust game state management system. The current implementation relies on a simple database schema to track the board state and move history, which can become unwieldy as the game progresses. A more sophisticated approach would be storing the game state in a NoSQL database that could efficiently store the whole board state as a single document, allowing for easier retrieval and updates, similar to the real-time chat project, where Cassandra could be dropped in favor of MongoDB for handling high throughput updates.