Monopoly

The classic property trading board game

- C# tagšŸ•¹ļøšŸ«windows tag

Description

Monopoly is a classic property trading board game that comes in many versions and varieties. My application puts the game on screen as a Windows Form application. It was written in C# for a first-year university assignment. The game uses the standard rules, except property auctioning.

Features

Screenshots

click to enlarge

Starting state Gameplay Controls Property Tooltip Bankrupt dialog Selling dialog

Code Highlights

I created many classes for this application, but have highlighted two of them below. For this assignment, the access modifiers for attributes and methods was not important. As I knew the app was only for demonstration, I set all access to ā€˜publicā€™ in order to speed up development. For a release version of the software, Iā€™d have used ā€˜privateā€™ and ā€˜protectedā€™ modifiers with setters and getters to properly encapsulate the data.

Player Class

The Player class is used primarily to store data, but the setToken() method allowed me to conveniently update on-screen images when a player changes their token, leaves the game, or enters/exits Jail. Storing token values in Properties.Settings meant that I could also load a players last token during initialisation of a new game.

public class Player
        {
            public string Tag; //p1,p2,p3, or p4
            public int TokenIndex; //use 0 for not playing
            ...
            public PictureBox PicBox;
            public PictureBox PreviewBox;
            public PictureBox ParentBox;
            public int inJail;//default = 0. otherwise 1-3 to count turns.

            public void setToken(int index)
            {
                this.TokenIndex = index; //use token 0 for not playing
                switch (this.Tag)
                {
                    case "p1":
                        Properties.Settings.Default.P1Token = index;
                        break;
                    case "p2":
                        Properties.Settings.Default.P2Token = index;
                        break;
                    case "p3":
                        Properties.Settings.Default.P3Token = index;
                        break;
                    case "p4":
                        Properties.Settings.Default.P4Token = index;
                        break;
                    default: break;
                }
                Properties.Settings.Default.Save();
                if (PicBox != null && PreviewBox!=null)
                {
                    if (index == 0)
                    {
                        PicBox.Visible = false;
                        PreviewBox.Visible = false;
                    }
                    else
                    {
                        PicBox.Visible = true;
                        PreviewBox.Visible = true;
                        //foreground image to be used for 'in-jail bars'.
                        PicBox.BackgroundImage = themeImage("token_" + index.ToString());
                        PicBox.Image = themeImage(inJail > 0 ? "jail_bars" : "transparent");
                        PreviewBox.BackgroundImage = themeImage("token_" + index.ToString());
                        PreviewBox.Image = themeImage(inJail > 0 ? "jail_bars" : "transparent");
                    }
                }
            }

        }

PropertySet Class

A complete set of properties allows players to add houses or charge more rent. The PropertySet class contains an isComplete() method for checking if houses can be added to a set and the playerActive() method to return how many properties count towards rent, which is used for station and utility spaces.

public class PropertySet
        {
            public Color Color;
            public string Type;
            //The Property class contains information about the name, price, owner, mortgage status, rent and position of a square on the board.
            public Property[] Properties;

            // number of Properties in this set owned by specified player and 'active' (not mortgaged)
            public int playerActive(Player pl=null)
            {
                Property[] setProperties = Properties;
                int count = 0;
                string tag = pl==null?"":pl.Tag;
                for (int i = 0; i < setProperties.Length; ++i)
                {
                    Property curr = setProperties[i];
                    //if the current property in this set is unmortgaged and owned by the player passed as a parameter
                    if (curr.Owner!=null && curr.Owner.Tag == tag && curr.isMortgaged == false)
                    {
                        //add one to their active count
                        ++count;
                    }
                }
                return count;
            }

            public bool isComplete()
            {
                //every set is assumed to be completed until proven otherwise
                bool isComplete = true;
                Property[] setProperties = Properties;
                //for every property in this set
                for (int i = 0; i < setProperties.Length; ++i)
                {
                    //the first property in each set is ignored since there is nothing to compare it to.
                    //this ensures an error does not occur for single property sets like Free Parking, Jail and Go.
                    if (i > 0)
                    {
                        Property curr = setProperties[i];
                        Property prev = setProperties[i - 1];
                        //if this property is mortgaged or has a different owner to the previous one
                        if (curr.isMortgaged || curr.Owner == null || prev.Owner == null || curr.Owner.Tag != prev.Owner.Tag)
                        {
                            //the set is not complete
                            isComplete = false;
                            //break out of for loop, since we don't need to check any more properties.
                            break;
                        }
                    }
                }
                return isComplete;
            }
        }