- Context
- Objective
- Application Preview
- Tech Stack
- Design
- How to Run
- Tests
- Development Approach
- Possible Improvements
This project is an Android code kata developed as part of a technical interview process. The goal is not to build a complex game or a polished UI, but to demonstrate software craftsmanship, code quality, and reasoning through a simple and well-known problem.
The objective of this kata is to implement a Tic Tac Toe game while focusing on:
- clear domain modeling
- separation of responsibilities
- test-driven development
- readable and maintainable code
The game rules themselves are intentionally simple in order to keep the focus on design and code quality.
- Kotlin
- Jetpack Compose
- Android ViewModel
- JUnit (unit tests)
The application is structured around a small, explicit domain model. The game logic is independent from Android and UI concerns, which allows it to be tested in isolation.
The main concepts are:
- a game aggregate responsible for orchestrating state changes
- an immutable board representing the current game state
- a rules evaluator responsible for determining the game status
Note:
PlantUML diagrams are rendered via the public PlantUML server.
Due to GitHub caching, diagrams may occasionally appear outdated in the markdown preview.
The .puml source files are the reference and always reflect the latest design.
The following class diagram illustrates the core domain model and relationships:
The following sequence diagram shows the main interaction flow when a player makes a move:
- Open the project in Android Studio (or IntelliJ with Android support)
- Sync Gradle
- Run the
Run appconfiguration on an emulator or a physical device
Shared run configurations are provided with the project for convenience.
From the project root:
./gradlew installDebugAn emulator or physical device must be running.
The project contains two types of tests:
All Gradle commands below are expected to be run from the project root.
These tests cover:
- the domain game logic
- the ViewModel and UI state
Run with:
./gradlew testDebugUnitTestThese tests cover:
- UI interactions
- user flows
- error handling
Run with:
./gradlew connectedDebugAndroidTestAn emulator or physical device must be running.
Both unit and instrumented tests can be run together with:
./gradlew testDebugUnitTest connectedDebugAndroidTestAn emulator or physical device must be running.
Shared run configurations are provided with the project:
Run appUnit tests (JVM)Android tests (instrumented)
These configurations can be used directly from Android Studio or IntelliJ to run the application or the different test suites.
This repository history reflects the incremental steps taken during development. Each change was committed with the intent to keep the evolution of the solution readable, rather than squashing commits into a single final state.
The following ideas were intentionally left out of the kata scope, but could be explored further:
- Persist the current game state locally (e.g. to survive process death)
- Add game history and move replay
- Support named players instead of fixed X / O
- Store and display game statistics or a leaderboard
- Allow configurable board sizes
- Add an optional AI opponent
