A Monopoly-inspired board game built in C++ with full OOP principles, CLI/GUI support, and bot players — created as a course project for IF2010 Object-Oriented Programming.
![Program Interface][cover.png] Nimonspoli is a feature-complete digital board game inspired by Monopoly, implemented entirely in C++17. Players navigate a 40-tile board, buying properties, paying rent, participating in auctions, and managing wealth — all while competing to be the last player standing (or richest when time runs out).
The game supports both Console (CLI) and Graphical (GUI) modes, includes a Computer Player (Bot) opponent, a full Save/Load system, and a structured Transaction Logger. The codebase follows strict OOP design with layered architecture, abstract classes, generics, operator overloading, and comprehensive exception handling.
- 40-tile board with Streets, Railroads, Utilities, Tax tiles, Festival tiles, Jail, and special spaces
- 2–4 players (human or bot mix), turn-based with dice rolling (random or manual)
- Double roll mechanic — rolling doubles grants an extra turn; three consecutive doubles sends you to jail
- Property ownership — buy Streets, automatically claim Railroads and Utilities upon landing
- Rent system — dynamic rent based on property level, monopoly status, railroad count, or utility dice multiplier
- Building system — construct up to 4 houses then upgrade to a hotel per Street; requires full color group monopoly and even distribution
- Mortgage & Redeem — mortgage properties for instant cash, redeem to restore rent income
- Auction — triggered when a player declines or cannot afford a property, or when a bankrupt player's assets are liquidated
- Tax tiles — Pajak Penghasilan (flat or percentage of wealth) and Pajak Barang Mewah (flat)
- Festival tiles — doubles rent on a chosen property for 3 turns (stackable up to 8×)
- Jail mechanics — pay fine, use a "Get Out of Jail Free" card, or roll for doubles (max 3 attempts)
- Chance Cards (Kartu Kesempatan) — move to nearest station, go back 3 tiles, or go directly to jail
- Community Chest Cards (Kartu Dana Umum) — collect from / pay all players, pay doctor fees
- Special Skill Cards (Kartu Kemampuan Spesial) — hand-held tactical cards, max 3 per player:
MoveCard— advance a random number of tilesDiscountCard— random purchase discount for 1 turnShieldCard— immunity to rent and penalties for 1 turnTeleportCard— move to any tile on the boardLassoCard— pull a leading opponent back to your positionDemolitionCard— destroy one building on an opponent's property
- Skill cards are usable before rolling dice, once per turn; generic
CardDeck<T>handles all deck types
- When unable to pay, players can liquidate assets (sell properties/buildings to bank, mortgage) to cover debt
- If still insolvent: bankrupt to a player creditor transfers all assets; bankrupt to Bank auctions all properties
- Game continues until 1 player remains or the turn limit is reached
- Bankruptcy mode — last player remaining wins
- Max Turn mode — winner determined by: most cash → most properties → most cards → shared victory if still tied
- Full game state serialized to a structured
.txtfile - Captures: turn number, all player states, card hands, property states (festival multipliers, buildings), deck order, and full transaction log
- Load is available at startup only; Save is available at the start of a player's turn before any action
- Automatically records every significant event: dice rolls, purchases, rent payments, auctions, card usage, bankruptcies, saves/loads
- Viewable in-game with
CETAK_LOG [n](last n entries, or full log)
- Optional GUI mode powered by Raylib
- Visual board rendering with color-coded tiles, player tokens, building indicators, and a panel manager
- All gameplay mechanics fully operational in GUI mode
- Launch with
--guiflag or select at startup
BotPlayerinherits fromPlayerand overridesdecideAction()for autonomous play- Handles: dice rolling, property purchase decisions, auction bidding, building, mortgaging, and redemption
- Every bot action is announced clearly in output
Monopoly-Game/
├── config/ # Game configuration files
│ ├── property.txt # All 28 properties with prices and rent tables
│ ├── railroad.txt # Railroad rent by ownership count
│ ├── utility.txt # Utility rent multipliers
│ ├── tax.txt # PPH flat/percentage and PBM flat values
│ ├── aksi.txt # Action tile mappings
│ ├── special.txt # GO salary and jail fine
│ └── misc.txt # Max turn count and starting balance
│
├── include/ # Header files (mirrors src/ structure)
│ ├── board/ # Board class
│ ├── card/ # Card hierarchy: Card, SkillCard, ChanceCard, CommunityChestCard, DeckCard<T>
│ ├── config/ # Config data structs: PropertyData, MiscConfig, TaxConfig, etc.
│ ├── core/ # Game engine layer: GameEngine, TurnManager, AuctionManager,
│ │ # BankruptcyManager, Dice, TransactionLogger, SaveLoadManager
│ ├── exception/ # Custom exceptions: InsufficientFundsException, BankruptcyException,
│ │ # CardSlotFullException, SaveLoadException, etc.
│ ├── gui/ # GUI layer: GuiRenderer, GuiPanelManager, GuiAssetModule, etc.
│ ├── player/ # Player and BotPlayer
│ ├── property/ # Property hierarchy: Property, StreetProperty, RailroadProperty, UtilityProperty
│ ├── states/ # Serializable state structs: GameState, PlayerState, PropertyState, CardState, LogEntry
│ ├── tile/ # Tile hierarchy: Tile (abstract), PropertyTile, ActionTile
│ └── utils/ # ParseUtils, SerializeUtils
│
├── src/ # Implementation files (mirrors include/)
│ └── main.cpp # Entry point — mode selection (CLI / GUI)
│
├── test/ # Unit and integration tests
│ ├── test_config_validation.cpp
│ ├── test_save_load.cpp
│ └── gui/gui_simulation_driver.cpp
│
├── class-design/ # UML/PlantUML class diagrams (M1 submission)
│ ├── 01_overview_layer.puml
│ ├── 02_tile_hierarchy.puml
│ ├── 03_property_card.puml
│ ├── 04_player_game.puml
│ ├── 05_io_saveload.puml
│ └── 06_bonus_gui_com_dynamic.puml
│
├── data/ # Runtime save files go here
├── CMakeLists.txt # CMake build configuration (recommended)
├── makefile # Alternative Makefile build
└── .clang-format # Code style configuration
The project follows a strict 3-layer architecture:
| Layer | Components | Responsibility |
|---|---|---|
| UI Layer | CommandHandler, GuiRenderer, GuiPanelManager |
All input/output, display, CLI commands, GUI rendering |
| Game Logic Layer | GameEngine, TurnManager, AuctionManager, BankruptcyManager, Player, Board, all Cards and Tiles |
Game rules, state transitions, calculations |
| Data Access Layer | ConfigLoader, SaveLoadManager, StateParser, StateSerializer |
File reading/writing for config and save states |
- C++17 or later (
-std=c++17) - GCC or Clang on Linux/macOS (or WSL on Windows)
- CMake ≥ 3.16 (recommended), or GNU Make
- Raylib library
Install on Debian/Ubuntu:
sudo apt-get install libraylib-devBuild from source (if package unavailable):
git clone https://github.com/raysan5/raylib.git
cd raylib && mkdir build && cd build
cmake -DBUILD_SHARED_LIBS=ON ..
cmake --build . --target install
sudo ldconfigOn macOS:
brew install raylibIf Raylib is not found during build, the program automatically falls back to Console mode.
git clone <repository-url>
cd Monopoly-Gamecmake -S . -B cmake-build
cmake --build cmake-buildmake# CMake build
./cmake-build/game --console
# Makefile build
./bin/game --console
# Or just launch and select at the menu
./cmake-build/game./cmake-build/game --guimake runOnce the game starts, use these commands during your turn:
| Command | Description |
|---|---|
CETAK_PAPAN |
Print the game board |
LEMPAR_DADU |
Roll dice randomly |
ATUR_DADU X Y |
Set dice values manually |
CETAK_AKTA |
View a property's certificate |
CETAK_PROPERTI |
View your owned properties |
GADAI |
Mortgage a property |
TEBUS |
Redeem a mortgaged property |
BANGUN |
Build houses or upgrade to hotel |
GUNAKAN_KEMAMPUAN |
Use a Skill Card (before rolling) |
CETAK_LOG [n] |
Print last n log entries (or full log) |
SIMPAN <file> |
Save game state to file |
MUAT <file> |
Load game state from file (startup only) |
Automated commands (BELI, BAYAR_SEWA, LELANG, FESTIVAL, BANGKRUT, etc.) trigger automatically based on game events.
# List available test targets
cmake --build cmake-build --target help
# Build all tests
cmake --build cmake-build --target all_tests
# Build and run a specific test
cmake --build cmake-build --target test_save_load
./cmake-build/test_save_load
# Clean build artifacts
make cleanThis project is an academic assignment for IF2010 Object-Oriented Programming at Institut Teknologi Bandung (ITB). It is intended for educational use only and is not licensed for commercial distribution.
Tugas Besar 1 — IF2010 Pemrograman Berorientasi Objek
| Name | GitHub |
|---|---|
| Aufar Kusuma | @parkuskus |
| Kurt-Mikhael | @Kurt-Mikhael |
| Nicholas Wise | @nicholaswisee |
| Ray Owen | @Tensai-033 |
| Vincent R | @Vixrlie |