Implementation of the game Kalah using Java and React, This application let the users create games and join other games and play the game on their own computers.
You can find the rules of the game on Wikipedia: https://en.wikipedia.org/wiki/Kalah.
For the backend, I choose a Java Monolithic application with clean architecture and tried to use Test driven development approach for implementing this project. I also implement an SQL database and for the development, I used the H2 database. UI communicating with the backend over REST, and because this is a turn-based game, I used WebSocket to notify all players in a game about changes on the board. Main entities for this project are Board, Pit to store information of board and pits. for simplifying the database I have one Board Entity, but it would be better to have different entities for game and board. The sowing logic is implemented using the GameRule interface. Every turn goes through a set of rules, and if a rule changes or a new rule is added to the game, you just need to edit these interface implementations or create a concrete class for that. The logic of pits arrangement is in board Entity because it knows the structure of the pits in a board.
For the front end, I used React.js and typescript and I also tried to use the TDD approach but due to time limits, I just implement tests for the board component. I used functional components and hooks like useState, useEffect, useCallback, useContext. I also implement some end-to-end tests with Cypress to test important parts of the game.
I used GitHub tasks for managing the tasks and I create different branches for every feature or bug. I also create PRs and merge branches with squashing.
The followings are the directories of this project:
-
design
For designing this application I tried to make it simple and clean. The class diagram of the project is available in the design folder, you can open it using https://draw.io website. -
kalah-server
is the backend of the application, main technology stack for this project are:- Spring Boot - The framework used
- Maven - Dependency management
- H2 Database - Used for database
- JUnit - Test framework
- Mockito - Tasty mocking framework for unit tests in Java
- Swagger - Used to generate API docs
- Spring Websocket - Used to build an interactive web application
-
kalah-ui
is the frontend of the application, main technology stack for this project are:- React library for building ui
- TypeScript Used typed syntax
- Axios http client for communicating with backend
- Cypress end to end testing
- styled-components used for CSS-in-JS styling
- react-stomp-hooks A react library to manage a application wide STOMP connection via SockJS or Websockets
_NOTE: requires java
Go to the project directory
cd kalah-server
Install dependencies using:
./mvnw install
Run the project using:
./mvnw spring-boot:run
Swagger:
http://localhost:8080/swagger-ui/index.html
Database:
http://localhost:8080/h2-console
_NOTE: requires node
Go to the project directory
cd kalah-ui
Install dependencies using:
npm install
Run the project using:
npm start
The project is running in:
http://localhost:3000
I did not implement security issues a lot, for detecting the current User, I pushed the username
header in requests and try to decode the current user from that token. If I had time I think it was better to implement User and jwt for authorization.
start game:
- Open https://localhost:3000
- Press login and try to log in with a username.
- After login you can see two parts,
My Boards
are the board created by this username, andAvailable Boards
are the boards that were created by other users and nobody joins them yet. you can create a new board by clicking theAdd Board
button.
- After selecting a game in
My Board
or joining a board inAvailable Boards
you go to the Board Page and can play the game.
- Each player sees their pits on the button of the board, the pits that can be sowed have hovered.
- If a player sows the pit, the board will automatically update for both players.
- Play until the application notifies you that the game is over.
- Enjoy!
_NOTE: requires docker, docker-compose
Build the project using:
docker-compose build
Create the required volume (change /Users/jalal/kalah-db
to your custom directory):
docker volume create --name kalah-db-data --opt type=none --opt device=/Users/jalal/kalah-db --opt o=bind --driver local
You can run the project using:
docker-compose up -d
You can stop the project using:
docker-compose down
There are some things that I learned during this sample project:
- Spring Websocket library
- Styled-components
- CSS transitions
- CQRS architecture
- react useContext
- JHipster
Because of time limits, I could not implement all of the features, but there are some things that if I had more time, I would do:
- I read about CQRS and I think it would be a good architecture for this game, By Using this we can have Undo command and replay for the game. looks amazing.
- Implement the project using application generators like JHipster.
- use ModelMapper for Generating DTOs
- use ESLint for coding styles
- JWT token support to make sure consistency.
- Secure web sockets so only the board players can access events.
- Register, Login, and forget your password.
- Make the checking of current user a spring request filter.
- improves the overall UI of the system.
- Make it better for mobile devices.
- i18n and locale.
- Add User entity.
- Keep events instead of current Entity, and try to generate board using events.
- Use flyway to manage database migrations.
- Change database drive and use MySQL in docker deployment.
- implement an AI agent for playing with users.