Introduction

The Food Magnate Simulation models how profitable different types of restaurant chain would be within a simulated settlement.

The structure of the simulation, conceptually, is as follows:

The program contains the following objects:

Let's look at the attributes for each class in detail…

Class: Simulation

The Main subroutine creates the program's single Simulation object and calls its Run subroutine.  From that point onwards, it is the Simulation object that is responsible for creating and managing all other objects.  Its attributes are as follows:

Class: Company

A company can be either a fast-food company, a family company or a named chef company.  This means that all outlets belonging to a company will also be of that type; a company cannot have, for example, some fast-food outlets and some family outlets.  The Company class's attributes are as follows:

Class: Outlet

An Outlet object is stored within a data structure in a Company object, modelling the fact that an outlet is owned by a single company.  Outlets are also associated with the settlement, since each outlet has a location within that settlement, and households, if they choose to visit a company's outlet, will always visit the closest one. 

The Outlet class's attributes are as follows:

Class: Settlement

The simulation contains a single settlement, and each household and outlet has a location within that settlement.  The settlement is easy to visualise in terms of a grid, but it is not stored as a two-dimensional array.  The reason for this is twofold.  Firstly, most elements within a settlement array would be empty.  The default settings create a settlement with one million possible locations, but only 250 households and 12 company outlets.  Secondly, a settlement contains objects of different types – namely households and outlets.  Instead, each outlet and each household stores its own X and Y coordinates, which must be within the bounds of the settlement. 

The Settlement class's attributes are as follows:

The LargeSettlement class inherits from Settlement, and allows the user to add to (but not subtract from) the values of StartNoOfHouseholds, XSize and YSize.

Class: Household

To all intents and purposes, this class models a consumer, since the whole household either eats out or does not.  There is scope here for modelling households of different sizes, or households in which some members (but not all) go out to eat, or even households where different individuals eat out at different outlets at the same time.  The Household class's attributes are as follows:

Overview

When the program begins:

  1. A new Simulation object is constructed
  2. That Simulation object constructs a new object of type Settlement or LargeSettlement (which inherits from Settlement), depending on user input. The Settlement constructor calls the constructor of Household
  3. That Simulation object, as part of being constructed, also constructs new Company objects, which are either the three default companies hard-coded into the Skeleton Program or user-defined, depending on user input
  4. The AddCompany subroutine is called if user-defined companies are selected, allowing the user to enter specific details of each company
  5. The Company constructor will make at least one call to the Outlet constructor, since each company must have at least one outlet
  6. The Simulation object's Run subroutine is called (see next hierarchy diagram)

Main Menu

'Modify Company' menu, shown when the user selects option 3 from the main menu and enters a valid company name


When the Run subroutine is called:

  1. The user is presented with a menu as a result of a call to DisplayMenu
  2. If the user selects option 1, a call is made to DisplayHouseholds, which lists details of all households in the settlement via a call to DisplayHouseholds in the Settlement class, which in turn calls GetDetails in each instance of the Household class
  3. If the user selects option 2, details of all companies are displayed via a call to DisplayCompanies, which calls the GetDetails subroutine in each Company The GetDetails subroutine in the Company class calls a GetDetails subroutine for each outlet, meaning that selecting option 2 from the menu results in details of all companies, and their outlets, being displayed.
  4. If the user selects option 3, to modify a company, they are prompted for a company name, which is then passed to GetIndexOfCompany in order to get the index of that company. The subsequent call to ModifyCompany presents the user with a second menu containing three options.  They can open a new outlet (OpenOutlet()), close an outlet (CloseOutlet()) or expand an existing outlet (ExpandOutlet()).
  5. If the user selects option 4, a new company can be created via a call to AddCompany. This prompts the user for details of the new company's name, type and starting balance.  The new company will have a single outlet in a random location within the settlement.
  6. There is no option 5, which makes it quite likely that adding an option 5 will be part of the exam
  7. If the user selects option 6, a call is made to ProcessDayEnd in the Simulation. Note that an identically named subroutine exists in the Company class, so be sure not to confuse the two.  This is the most involved subroutine in the program and is addressed in the next hierarchy diagram.

When each day ends:

  1. The call to NewDay (in the Company class) calls NewDay (a subroutine in each Outlet class) to reset the number of visits to zero
  2. The reputation score of each company is accessed and added to an ArrayList, with each float value therein storing a running total of all reputation scores so far (i.e. the first value stored is for the first company, the second value stored is the sum of the reputation scores for the first two companies, the third value stored is the sum of the reputation scores for the first three companies, and so on)
  3. The call to GetNumberOfHouseholds is to facilitate a loop through all households in a settlement
  4. The call to FindOutIfHouseholdEatsOut, for each Household object, returns a Boolean, which is more likely to be true for households with a higher probability of eating out. If it is true, a company is selected at random, using the ArrayList from step 15, with companies holding a higher reputation score more likely to be chosen.
  5. For the company that is chosen, the nearest outlet to the household eating out is visited. The distances to all outlets belonging to the chosen company are examined, and distances are calculated in the following way:
    • Distances are calculated by assuming movement is only possible north, south, east or west. This means that the distance from the house to outlet A is 4, while the distance from the house to outlet B is 3.
    • In the event that two outlets are of an equal distance from a house, the outlet examined first (i.e. the outlet appearing earlier in the Outlets list) will be the one visited.
  6. The call to DisplayCompaniesAtDayEnd calls the ProcessDayEnd subroutine in the Company This subroutine calculates changes to the company's balance, which is affected by visits to each outlet per day, the price at which meals are bought and sold, and the distance between outlets for the same company, for which the delivery of ingredients incurs a cost based on the price of fuel (distances are calculated as above).  The old balance and the new balance are then displayed, along with other details of the company and its outlets.
  7. The call to DisplayEventsAtDayEnd generates either a random probability of additional households in the settlement, a change of fuel cost for a company chosen at random, a change of reputation for a company chosen at random or a change of daily costs for a company chosen at random