Hey there folks, Matt here, greetings ...
This time maybe a bit longer thread, and I'd like to thank anyone in advance who takes time to read and spent some time for typing a reply.
For a long time I always wanted to implement the well known cardboard game of Monopoly in Java, based on an original one I have laying around here (oh boy, this really helps, as you can find almost any information - except the chance and community cards - seems like there nowhere listed anywhere on teh internetz - same for "official" rules). I've tried to start some times in the past - but never got more than a few lines down.
As for the new year - I now want to finaly get it done.
So, I looked up Monopoly at Wikipedia - wich referenced to the page about cardboard games - and starting here there's a really neat bit I really like and wich I'd like to base my game on:
A board game is a tabletop game that involves counters or pieces moved or placed on a pre-marked surface or "board", according to a set of rules.
As I'm really into this whole object orientend thing and like abstraction - I want to start as follows:
I know the "game" I like to implement is a board game - based on a cicrcle wich is played by 2+ players on a round-by-round style with possible interactions - according to some specific rules. So I start with the basis - the board. Looking at the board we can note down some important specs:
- the board is a square with overall 40 fields - layed out as 4 corner tiles - one in each corner - and placed 9 tiles in between on each side
- there some different types of fields: buyable properties (wich divide into properties with houses and those without (the two supply facilities and the 4 railroad stations)) and special actions (community chest, chance, taxes, corners (go, jail, free parking, go-to-jail))
- it is played with 2 - 8 players (each player has a unique toke)
- for the buyable properties with spaces for buildings apply some rules for those buildings (how, when, how many)
- the overall ruleset about the game itself
So to get started, I came up with this abstract description of the board wich now needs to be implemented in a Java class. As said - I really like abstraction - so in the board-class I would ignore the facts about different types of fields - the board just have fields. Also, for the board-class it doesn't matter in wich order the fields are or that they form a circle - that's up for the graphical classes and the logic-class responseable for player movement. This leads me to the question: as there is no logical relationship between the board and the fields in terms of Java-classes wich has to know each other - is it useful at all to implement a relationship here?
Maybe I can find an awnser when I try to think about: What kind of information the fields hold and do I access them? The fields themselves only have to know its type, and, if there buyable, if they're bought by a player, also, if they have room for houses, how many are on them.
On the other hand - does a field have to know if it's owned by a player - or is it better if players know what properties they own? I would try to awnser it this way: Each round a player has to roll the dice - wich let them land on a field. To decide what happens when a player lands on a field it needs to know its state and all what's needed for it.
So let me start on another side: I will have a "session"-class - the main object wich represents the overall gaming session itself - just like if you get together with some friends to play round of Monopoly. So this class knows the overall state of the game and of all pieces it is made of, i.e. wich player is currently the active one, in wich state a player is (so it can be checked what actions a player can do at any time) and wich actions a player can do on a field he stands on. So, one could think about: First step a player has to do is to roll the dice. This is only true with the exception of one field: the jail. Wich leads to this flow-chart:
1) check on wich field the player is currently on
- 1a) if the player is currently not on the field "jail" skip the following and proceed at step 1b
-- 1aa) the player is just on the "just visit" part of the "jail"-field - skip the following and proceed at step 1b
-- 1ab) check if the player has at least one of the two available "get out of jail"-cards
--- 1aba) the player doesn't have any card - skip the following and proceed at step 1ac
--- 1abba) the player have at least one of the cards and decide to use one - so he will get out for free - proceed at step 1b
--- 1abbb) the player have at least one of the cards, but decide to don't use one - player have to pay
-- 1ac) player has to roll the dice
--- 1aca) if the player rolls doublets (both dice show same number) the player gets out of jail for free and moves the amount of fields the player rolled > step 2
--- 1acb) the player doesn't hit a doublets
---- 1acba) if it's the first or second try nothing else happens - the player can still decide to trade - otherwise turn ends and next player get to move
---- 1acbb) if it's the thrid try, the player didn't used a card and didn't hit a doublets - the player gets out of jail buy paying a fee and moves the amount of fields > step 2
- 1b) if the player is on any other field than "jail" - according to rules the first thing a player has to do is roll the dice and advance the amount of fields
2) check type of field
- 2a) its a corner field
-- 2aa) go - if custom rule is enabeld - player gets double of round fee - otherwise just normal amount > turn ends
-- 2ab) jail - just visit - nothing happens - turn ends
-- 2ac) free parking - action depends on active rule - nothing, fixed amount, taxes, custom rule
-- 2ad) go to jail - player is move back to jail, flag "player in jail" is triggered and turn ends without able to trade
- 2b) taxes - player has to pay taxes - depend on rule if payed to bank or to free parking
- 2c) chance / community chest - action noted on card
- 2d) buyable property
-- 2da) owned by player - player can decide to manage buildings
-- 2db) owned by another player - player has to pay
--- 2dba) special case: if a player doesn't have enough net-worth money (including selling houses and taking mortgages) he may is allowed to trade or ask bank for money - but this is uncommon - usually a player is out and declared bankrouptcy
-- 2dc) not owned at all
--- 2dca) player can decide to buy - if he has enough money to do so
--- 2dcb) player decide to not to buy - or doesn't have money to do so - property is sold by auction (as of official rules: a not owned property has to be sold by auction - although player can agree upon to simple "nothing happens -> next player" - wich, according to google, seems common)
3) after above steps done the active player can decide to start a trade with another player (except for "go to fail" - then turn ends directly) - it's common that a player can manage buildings - although official rules say a player may only manage buildings if it stays on a field of the color group
4) all actions a player is allowed to do - and anything that has to be done mandatory is done - the current turn ends and the next player gets the dice
Looks kind of confusing - and it may contain errors - but this is simply how monopoly round plays. Based on these actions wich has to an can happen at each turn - the session object needs to now the players - and somehow has to connect on wich field the player is on - to decide what to do and to wich field a player moves next after rolling the dice. As on the gui-classes the tokens has to somehow get rendered - there needs to be a connection to tell wich player is on it. Drawing require information about status - so it needs to be kept in sync with the session. I'm not yet sure about how I will implement it.
Also - as I want to implement this project as MVP - it will be based on events. So may following flow helps to awnser last question: A player is selected as active - starts by rolling the dice - wich in its turn triggers the next events (checking field, moving, actions) and finally updates the new game status. So this would be:
- Session.checkField() -> jail-logic
- Session.fieldAction() -> cards, buy, buildings
- Session.update() -> sends out current new status to all player and instances to sync all objects
I would think its maybe a good idea to implement to field-updates - first in the movePlayer() - and second at last call on session-update. So the fields know wich players are on them - the players also know on wich fields they are - wich needs to be kept in sync - and thier internal status (owned, if so by wich player, buildings). I'm still a bit worried about the facilities as the logic has to check when a player lands on one of them if the other is owned at all and if so if its the same or an other player.
So, as I now already needed over 1 hour to right this post - I will think about some sample implementations and how to link the different pieces.
So long ...