A-level Computing/AQA/Paper 1/Skeleton program/2020

This is for the AQA A Level Computer Science Specification.

This is where suggestions can be made about what some of the questions might be and how we can solve them.

Please be respectful and do not vandalise the page, as this would affect students' preparation for exams! - Martin Perdicke
Please do not discuss questions on this page. Instead use the discussion page: Coming soon!

AQA Skeleton Program 2020 - Class Diagram

Section C PredictionsEdit

  • The 2020 paper 1 will contain 1 question in Section C: two parts, worth 1 and 2 marks respectively.
  • What is the function of super() in the definition of the LargeSettlement class? - Not relevant to all languages - Could question be reworded to make it more realistic? (Another option could be: "Explain how Settlement is used as a superclass in the program")
  • State one additional line of code which should be added after the Ben Thor Cuisine default company definition in the Simulation class' constructor in order to make it consistent with the ModifyCompany() function.
  • What relationship (composition, aggregation and inheritance) exists between each of the classes
  • What are the (i) exact chances of each of the events happening individually (ii) the chances of all of the events occurring simultaneously?

Section D PredictionsEdit

Programming Questions on Skeleton Program

  • The 2020 paper 1 will contain 4 questions: a 6 mark, an 8 mark question, a 11 mark question and one 12 mark question - these marks include the screen capture(s), so the likely marks for the coding will be 1-2 marks lower.
  • The 2019 paper 1 contained 4 questions: a 5 mark, an 8 mark question, a 9 mark question and one 13 mark question - these marks include the screen capture(s), so the marks for the coding will be 1-2 marks lower.
  • The 2018 paper 1 contained one 2 mark question, a 5 mark question, two 9 mark questions, and one 12 mark question - these marks include the screen capture(s).
  • The 2017 paper 1 contained a 5 mark question, three 6 mark questions, and one 12 mark question.

Current questions are speculation by contributors to this page. Answers are down for maintenance, we are sorry for the inconvenience.

  • Ensure all costs are displayed in the following format £X.XX (4 Marks)
  • Add a new Small Settlement class and an option to create a Small Settlement in the simulation launch menu (6 Marks)
  • Add a Close Outlet event which results in an outlet being removed from the simulation (11 Marks)
  • ExpandOutlet() add option for when the capacity is now zero
  • AlterCapacity(Change) correctly calculate the new DailyCosts when new capacity is limited to the max capacity
  • AddCompany(self) add check to see if CompanyName already exists in _Companies
  • RemoveCompany() add option to remove a company instead of removing each of its outlets individually (this is likely to come up, there is no option 5 in the menu so this seems logical)
  • Add a faster option to load in the default scenario
  • Close an outlet for a specified temporary number of days
  • Merge two companies together
  • Advanced a specified number of days
  • Display how many days have passed
  • Display net gain/loss for the companies
  • Display net and average weekly gains/losses for individual outlets
  • Ensure fuel costs can never become negative
  • Increase or decrease reputation of a company by a inputted value (or predefined values)
  • Modify the CalculateDeliveryCost() function so that the shortest path through all Outlets is used to minimise delivery costs (using Breadth-First graph traversal)
  • Add ability to create a new settlement and have outlets set up there
  • Validation on the initial entries for the program to run its menu
  • Validation on coordinates of Outlets, Households etc since two could randomly overlap on the x and y coordinates
  • Find, by using Djikstra's algorithm, the shortest path between a restaurant and the delivery locations. From there, calculate the total cost of delivery.
  • At day end, if any company has more than £20,000 as a balance, open another outlet at a random location and subtract £20,000 from their balance.
  • Only allow a new outlet to be created at a NEW location (i.e. one that doesn't already have an outlet of that company type)
  • At the end of the day, if a household eats out then its chance to eat out should change to another random number. However, if a household does not eat out then its probability to eat out should increase (e.g by 0.1) (4 Marks)
  • Create a random instance of a company or an outlet running a promotion, during which time its expenses go up but its reputation score also rises
  • Decrease company's balance when an outlet is closed
  • Add a class foodTruck which inherits from the class outlet and has a subroutine move()
  • Add validation for any user input to ensure something is entered
  • Add validation according to type such that inputs required to be numeric are numeric
  • Create an additional category of restaurant, with a new Company of that type created as part of the default companies
  • Close an outlet that runs at a loss for five consecutive days, adding a notification that this has happened to the events
  • Display details of a restaurant, which was either the most profitable, the most visited or the one with the highest reputation reading
  • Generate a random budget and store it as an attribute within each household object; a household that eats out will only eat out will only eat out with a company whose prices are within their budget
  • Incorporate weather into the simulation; it can rain at random, in which cases the probabilities of eating out are all halved, and the presence of rain is indicated within the events
  • Add a feature in which meals can be delivered, rather than customers visiting outlets; households who choose not to eat out might, according to random chance, order food to be delivered, although this costs the company extra in fuel according to the distance of delivery
  • The name chef outlets generally make a profit while other categories make a loss; write a subroutine to determine, for each type of company, how much an outlet should have charged per meal during the previous day in order to have operated at a profit

Calculate the delivery cost to deliver between 2 outletsEdit

Calculate the delivery cost where the user gives the company and the 2 outlets to calculate the delivery cost

Java:

for display menu

public void displayMenu() {
        Console.writeLine(System.lineSeparator() + "*********************************");
        Console.writeLine("**********    MENU     **********");
        Console.writeLine("*********************************");
        Console.writeLine("1. Display details of households");
        Console.writeLine("2. Display details of companies");
        Console.writeLine("3. Modify company");
        Console.writeLine("4. Add new company");
        Console.writeLine("5. remove company");
        Console.writeLine("6. Advance to next day");
        Console.writeLine("7. Remove company");
        Console.writeLine("8. Merge company");
        Console.writeLine("9. calculate delivery costs");
        Console.writeLine("Q. Quit");
        Console.write(System.lineSeparator() + "Enter your choice: ");
    }

for run method

public void run() {
        String choice = "";
        int index;
        while (!choice.equals("Q")) {
            displayMenu();
            choice = Console.readLine();
            if(choice.isEmpty()){
                Console.println("You have not entered an option. Check menu again. ");
                continue;
            }
            switch (choice) {
         
                case "1":
                    simulationSettlement.displayHouseholds();
                    break;
                case "2":
                    displayCompanies();
                    break;
                case "3":
                    for(int i = 0; i <companies.size(); i++){
                        System.out.println((i+1)+". "+companies.get(i).getName());
                    }
                    int companyindex;
                    do {
                        Console.write("Enter company index: ");
                        companyindex = Integer.parseInt(Console.readLine());
                        
                    } while (companyindex == -1);
                    
                    modifyCompany(companyindex-1);
                    break;
                case "4":
                    addCompany();
                    break;
                case "5":
                    removeCompany();
                    break;
                case "6":
                    processDayEnd();
                    break;
                case "7":
                    removeCompany();
                    break;
                case "8":
                    mergeCompany();
                    break;
                case "9":
                    Console.print("Which company: ");
                    String company = Console.readLine();
                    shortestDistance(company);
                    break;
                case "Q":
                    Console.writeLine("Simulation finished, press Enter to close.");
                    Console.readLine();
                    break;
            }
             
            
        }
    }

for calculating distance

public void shortestDistance(String Company){
        for(int i = 0; i<companies.size(); i++){
            if(companies.get(i).getName().equals(Company)){
                
                Console.println(companies.get(i).getDetails());
                Console.println("");
                Console.print("Enter number of first outlet: ");
                int firstOutlet = Integer.parseInt(Console.readLine());
                Console.print("Enter number of second outlet: ");
                int secondOutlet = Integer.parseInt(Console.readLine());
                int x1 = companies.get(i).outlets.get(firstOutlet-1).getX();
                int y1 =companies.get(i).outlets.get(firstOutlet-1).getY();
                int x2 = companies.get(i).outlets.get(secondOutlet-1).getX();
                int y2 = companies.get(i).outlets.get(secondOutlet-1).getY();
                long distance = Math.round(Math.pow(Math.pow((x2-x1), 2)+Math.pow((y2-y1), 2), 0.5) );
                
                
                    
                    float cost = distance * baseCostForDelivery;
                    System.out.println("The total delivery cost is "+cost+" and the total distance to be travelled is "+distance);
                    
                
            }
        }
    }


VB.NET:


C#:


Delphi/Pascal:


Python:


Validation of user input so user's option is not nullEdit

Check whether user's option is not null

Java:

include in run() method following code

public void run() {
        String choice = "";
        int index;
        while (!choice.equals("Q")) {
            displayMenu();
            choice = Console.readLine();
            if(choice.isEmpty()){
                Console.println("You have not entered an option. Check menu again. ");
                continue;
            }
            switch (choice) {
         
                case "1":
                    simulationSettlement.displayHouseholds();
                    break;
                case "2":
                    displayCompanies();
                    break;
                case "3":
                    for(int i = 0; i <companies.size(); i++){
                        System.out.println((i+1)+". "+companies.get(i).getName());
                    }
                    int companyindex;
                    do {
                        Console.write("Enter company index: ");
                        companyindex = Integer.parseInt(Console.readLine());
                        
                    } while (companyindex == -1);
                    
                    modifyCompany(companyindex-1);
                    break;
                case "4":
                    addCompany();
                    break;
                case "5":
                    removeCompany();
                    break;
                case "6":
                    processDayEnd();
                    break;
                case "7":
                    removeCompany();
                    break;
                case "8":
                    mergeCompany();
                case "Q":
                    Console.writeLine("Simulation finished, press Enter to close.");
                    Console.readLine();
                    break;
            }
             
            
        }
    }


VB.NET:


C#:


Delphi/Pascal:


Python:


Promotion of a companyEdit

Create a random instance of a company or an outlet running a promotion during which time its expenses go up but its reputation score also rises

Java:

for promotion method

public void promotion(){
        int outletOrCompany = rnd.nextInt(((1-0)+1)+0);
        if(outletOrCompany == 0){
            int compmax = companies.size()-1;
            int compmin = 0;
            int companyIndex = rnd.nextInt(((compmax-compmin)+1)+compmin);
            companies.get(companyIndex).dailyCosts += 1000;
            companies.get(companyIndex).reputationScore += 3;
            System.out.println("company "+companies.get(companyIndex).getName()+" is promoted");
        } else{
            System.out.print("Enter company to include promotion ");
            String company = Console.readLine();
            for(int i = 0; i<companies.size(); i++){
                if(companies.get(i).getName().equals(company)){
                    int outletmax = companies.get(i).outlets.size()-1;
                    int outletmin = 0;
                    int outletNo = rnd.nextInt(((outletmax-outletmin)+1)+outletmin);
                    companies.get(i).outlets.get(outletNo).dailyCosts += 1000;
                    companies.get(i).reputationScore += 3;
                    System.out.println("outlet "+outletNo+" is promoted");
                }
            }
            
        }
        
    }

for processdayEnd method

private void displayEventsAtDayEnd() {
        Console.writeLine(System.lineSeparator() + "***********************");
        Console.writeLine("*****   Events:   *****");
        Console.writeLine("***********************" + System.lineSeparator());
        float eventRanNo;
        eventRanNo = rnd.nextFloat();
        if (eventRanNo < 0.25f) {
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.25f) {
                processAddHouseholdsEvent();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.9f) {
                promotion();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.5f) {
                processCostOfFuelChangeEvent();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.5f) {
                processReputationChangeEvent();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo >= 0.5f) {
                processCostChangeEvent();
            }
        } else {
            Console.writeLine("No events.");
        }
    }


VB.NET:


C#:


Delphi/Pascal:


Python:


Delivery cost using Dijkstra's Algorithm. (likely 12 mark question in my opinion)Edit

Dijkstra's algorithm can only be used to find the shortest path between one node and another. In order to optimise delivery cost, we need to calculate the shortest path through all nodes. Djikstra's algorithm is not meant for this.
Find the shortest route to get from the first outlet to all the other outlets.

Java:


VB.NET:


C#:


Delphi/Pascal:

This is a generic Djikstra's algorithm I have written in Delphi. It needs to be adapted for use in the Food Magnate program.

Declare a Node class.

TNode = class
  public
    NodeIdentity, Original, Weight : integer;
    Visited : boolean;
    constructor Create(myNodeIdentity, myOriginal, myWeight : integer);
end;

const Area = Settlement.XSize * Settlement.YSize;
var HorizontalHeap, VerticalHeap : array of integer;

Construct the class

constructor TNode.Create(myNodeIdentity: Integer; myOriginal: Integer; myWeight: Integer);
begin
  NodeIdentity := MyNodeIdentity;
  Original := myOriginal;
  Weight := myWeight;
end;

Grab the next node from the list

function GetNodeFromIdentity(NodeIdentity : integer; ListOfNodes : TList) : TNode; overload;
var
  I : integer;
  Node : TNode;
begin
  result := nil;
  for I := 0 to (ListOfNodes.Count - 1) do
    begin
      Node := ListOfNodes[I];
      if Node.NodeIdentity = NodeIdentity then
        begin
          result := Node;
          break;
        end;
    end;
end;

Find the minimum weight to traverse between two nodes

function GetNodeOfMiniWeight(ListOfNodes: TList) : TNode; overload;
var
  I, minimum : Integer;
  Node : TNode;
begin
  result := nil;
  minimum := maxint;
  for I := 0 to ListOfNodes.Count - 1 do
    begin
      Node := ListOfNodes[I];
      if Node.Visited then continue;
      if Node.Weight < minimum then
        begin
          result := Node;
          Minimum := Node.Weight;
        end;
    end;
end;

Find the shortest path between the origin (restaurant) and the destination (house).

procedure ShortestPath(origin, destination : integer);
var
  NewWeight : integer;
  ListOfNodes : TList;
  CurrentNode, NextNode : TNode;
  ShortestPath : string;
begin
  ListOfNodes := TList.Create;
  CurrentNode := TNode.Create(origin, MaxInt, 0);
  ListOfNodes.Add(CurrentNode);
  while not (CurrentNode.NodeIdentity = destination) do
    begin
      if (CurrentNode.NodeIdentity > Area) and not (CurrentNode.Original - CurrentNode.NodeIdentity = Area) then
        begin
          NewWeight := CurrentNode.Weight + HorizontalHeap[CurrentNode.NodeIdentity - Area];
          NextNode := GetNodeFromIdentity(CurrentNode.NodeIdentity - Area, ListOfNodes);
          if NextNode <> Nil then
            begin
              NextNode.Original := CurrentNode.NodeIdentity;
              NextNode.Weight := NewWeight;
            end;
        end
      else
        begin
          NextNode := TNode.Create(CurrentNode.NodeIdentity - Area, CurrentNode.NodeIdentity, NewWeight);
          ListOfNodes.Add(NextNode);
        end;
    end;

    if (CurrentNode.NodeIdentity < Area*Area-Area) and not (CurrentNode.Original - CurrentNode.NodeIdentity = Area) then
      begin
        NewWeight := CurrentNode.Weight + HorizontalHeap[CurrentNode.NodeIdentity];
        NextNode := GetNodeFromIdentity(CurrentNode.NodeIdentity + Area, ListOfNodes);
        if NextNode <> nil then
          begin
            if NextNode.Weight > NewWeight then
              begin
                NextNode := TNode.Create(CurrentNode.NodeIdentity + Area, CurrentNode.NodeIdentity, NewWeight);
                ListOfNodes.Add(NextNode);
              end;
          end;
      end;

    if not (CurrentNode.NodeIdentity mod Area = Area - 1) and not (CurrentNode.Original - CurrentNode.NodeIdentity - 1) then
      begin
        NewWeight := CurrentNode.Weight + VerticalHeap[CurrentNode.NodeIdentity];
        NextNode := GetNodeFromIdentity(CurrentNode.NodeIdentity + 1, ListOfNodes);
        if NextNode <> nil then
          begin
            if NextNode.Weight > NewWeight then
              begin
                NextNode := TNode.Create(CurrentNode.NodeIdentity + 1, CurrentNode.NodeIdentity, NewWeight);
                ListOfNodes.Add(NextNode);
              end;
          end;
      end;

    if not (CurrentNode.NodeIdentity mod Area = 0) and not (CurrentNode.Original - CurrentNode.NodeIdentity = -1) then
      begin
        NewWeight := CurrentNode.Weight + VerticalHeap[CurrentNode.NodeIdentity - 1];
        NextNode := GetNodeFromIdentity(CurrentNode.NodeIdentity - 1, ListOfNodes);
        if NextNode <> Nil then
          begin
            if NextNode.Weight > NewWeight then
              begin
                NextNode.Original := CurrentNode.NodeIdentity;
                NextNode.Weight := NewWeight;
              end;
          end
        else
          begin
            NextNode := TNode.Create(CurrentNode.NodeIdentity - 1, CurrentNode.NodeIdentity, NewWeight);
            ListOfNodes.Add(NextNode);
          end;
      CurrentNode.Visited := true;
      CurrentNode := GetNodeOfMiniWeight(ListOfNodes);
      end;

    ShortestPath := 'The shortest path from ' + inttostr(destination) + ' to ' + inttostr(Origin) + ' is ';
    while (CurrentNode.NodeIdentity <> origin) do
      begin
        ShortestPath := ShortestPath + inttostr(CurrentNode.NodeIdentity) + ', ';
        CurrentNode := GetNodeFromIdentity(CurrentNode.Original, ListOfNodes);
      end;
end;

This algorithm is by Chris | Peter Symonds College


Python:

Another Generic Dijkstras algorithm that needs to be adapted into the Skeleton Program.
Dependancies: Matplotlib, NetworkX. (This is only to show a graphical version of the weighted graph).
Datetime is a python3 inbuilt library so it doesn't need to be installed.

# Imports Below
import datetime
import networkx as nx
import matplotlib.pyplot as plt

# Variable Declarations Below
adjacencyList = list()
Graph = nx.Graph()

# Function Declarations Below
def initiateAdjacencyList(length):
    for i in range(length):
        adjacencyList.append([])

def addEdge(source, destination, weight): # Function for adding edges to a priority queue
        adjacencyList[source].append([destination, weight])
        adjacencyList[destination].append([source, weight])
        Graph.add_edge(source, destination, weight = weight)

def dijkstra(adjacencyList, source, destination): # Dijkstras algorithm function 
    parents = list()
    distances = list()
    tempQueue = list()
    startWeight = float('inf') # Initiates a float with the largest possible value
    shortestPath = list()
    vertexCount = len(adjacencyList) # Initiates the Vertex count as the number of edges on the graph

    for i in range(vertexCount):
        weight = startWeight
        if source == i:
            weight = 0
        distances.append(weight)
        parents.append(None)

    tempQueue.append((0, source))

    while tempQueue: # While the Queue has items in it
        v_tuple = tempQueue.pop()
        v = v_tuple[1]

        for Edge in adjacencyList[v]: # Loops through every edge in the List
            candidate_distance = distances[v] + Edge[1]
            if distances[Edge[0]] > candidate_distance:
                distances[Edge[0]] = candidate_distance
                parents[Edge[0]] = v
                tempQueue.append([distances[Edge[0]], Edge[0]])

    end = destination
    while end is not None:
        shortestPath.append(end)
        end = parents[end]

    shortestPath.reverse() # Reverses the list to show the first point visited first

    return shortestPath, distances[destination]

# Main Program Below
initiateAdjacencyList(10) # Initiate Graph with 10 points maximum

# Add edges onto the graph (Just an arbitrary layout, can be edited for testing)
addEdge(0, 1, 2)
addEdge(0, 2, 3)
addEdge(1, 2, 2)
addEdge(1, 5, 4)
addEdge(2, 3, 2)
addEdge(2, 4, 8)
addEdge(3, 4, 5)
addEdge(4, 5, 1)
addEdge(5, 4, 6)
addEdge(5, 6, 4)
addEdge(6, 0, 9)
addEdge(7, 6, 11)

# Find the shortest path between two points
startTime = datetime.datetime.now()
print('Points Visited: {} \nTotal Distance: {}'.format(*dijkstra(adjacencyList, 0, 6))) # Prints the point dijkstras went through as-well as the path length

pos = nx.shell_layout(Graph) # Sets the layout for the graph nodes on the plot
labels = nx.get_edge_attributes(Graph,'weight') # Plots the nodes on the graph

nx.draw(Graph, pos, with_labels = True) # Draws the graph
nx.draw_networkx_edge_labels(Graph, pos, edge_labels=labels) # Draws the weights on the graph

plt.show() # Shows the plot

#endTime = datetime.datetime.now() # End time doesn't work with matplotlib
#print(f'runtime {endTime.second - startTime.second}.{endTime.microsecond - startTime.second}s')
  • Written by Harry - Peter Symonds College


Change reputation with user's ratingEdit

Java:

  • change reputation method
private void changeReputation(){
        System.out.print("Which company: ");
        String compCR = Console.readLine();
        int indCR = getIndexOfCompany(compCR);
        System.out.print("How do you rate the company? - good or bad : ");
        String rate = Console.readLine();
        if(rate.equals("good")){
            companies.get(indCR).alterReputation(3);
        } else{
            companies.get(indCR).alterReputation(-3);
        }
    }
  • add this to display menu
public void displayMenu() {
        Console.writeLine(System.lineSeparator() + "*********************************");
        Console.writeLine("**********    MENU     **********");
        Console.writeLine("*********************************");
        Console.writeLine("1. Display details of households");
        Console.writeLine("2. Display details of companies");
        Console.writeLine("3. Modify company");
        Console.writeLine("4. Add new company");
        Console.writeLine("6. Advance to next day");
        Console.writeLine("7. Change Reputation");
        Console.writeLine("Q. Quit");
        Console.write(System.lineSeparator() + "Enter your choice: ");
    }
  • add this to run
public void run() {
        String choice = "";
        int index;
        while (!choice.equals("Q")) {
            displayMenu();
            choice = Console.readLine();
            switch (choice) {
                case "1":
                    simulationSettlement.displayHouseholds();
                    break;
                case "2":
                    displayCompanies();
                    break;
                case "3":
                    String companyName;
                    do {
                        Console.write("Enter company name: ");
                        companyName = Console.readLine();
                        index = getIndexOfCompany(companyName);
                    } while (index == -1);
                    modifyCompany(index);
                    break;
                case "4":
                    addCompany();
                    break;
                case "6":
                    processDayEnd();
                    break;
                case "7":
                    changeReputation();
                    break;
                case "Q":
                    Console.writeLine("Simulation finished, press Enter to close.");
                    Console.readLine();
                    break;
            }
        }
    }


VB.NET:


C#:


Delphi/Pascal:

Slight change to Simulation.Run(); Just to add call to ChangeReputation procedure();

procedure Simulation.Run();
var
  CompanyName : String;
  Choice : Char;
  Index : Integer;
begin
  Choice := ' ';
  while Choice <> 'Q' do
    begin
      DisplayMenu();
      readln(Choice);
      case (Choice) of
        '1': Self.SimulationSettlement.DisplayHouseholds();
        '2': DisplayCompanies();
        '3':
          begin
            repeat
              write('Enter company name: ');
              readln(CompanyName);
              Index := GetIndexOfCompany(CompanyName);
            until Index <> - 1;
            ModifyCompany(Index);
          end;
        '4': AddCompany();
        '5': ChangeReputation();
        '6': ProcessDayEnd();
        'Q':
          begin
            writeln('Simulation finished, press Enter to close.');
            readln;
          end;
      end;
    end;
end;

Alter Menu (corrected spelling - Chris)

procedure Simulation.DisplayMenu();
begin
  writeln;
  writeln('*********************************');
  writeln('**********    MENU     **********');
  writeln('*********************************');
  writeln('1. Display details of households');
  writeln('2. Display details of companies');
  writeln('3. Modify company');
  writeln('4. Add new company');
  writeln('5. Change Reputation');
  writeln('6. Advance to next day');
  writeln('Q. Quit');
  writeln;
  write('Enter your choice: ');
end;

Declare the procedures. Also requires procedure declarations inside simulation class.

procedure Simulation.DisplayCompanyNames();
var I : Integer;
begin
  for I := low(Self.Companies) to high(Self.Companies) do
    writeln('[' + IntToStr(I) + '] ' + Self.Companies[I].GetName);
end;

procedure Simulation.ChangeReputation();
var
ValidCompanyNum : Boolean;
CompanyNumberInput : String;
CompanyNumber : Integer;
CompanyChange : Company;
ValidChangeInt : Boolean;
ReputationChangeInput : String;
ReputationChange : Integer;
begin
  ValidCompanyNum := False;
  writeln('What company would you like to alter the reputation of?');
  repeat
    try
      DisplayCompanyNames();
      write('Select company number: ');
      Readln(CompanyNumberInput);
      CompanyNumber := StrToInt(CompanyNumberInput);
      CompanyChange := Self.Companies[CompanyNumber];
      if( (CompanyNumber >= low(Self.Companies))  and (high(Self.Companies) >= CompanyNumber) ) then
      ValidCompanyNum := True
      else raise Exception.Create('Invalid Company Number');
      except
      writeln('Error: Not real company number');
    end;

  until (ValidCompanyNum);
  ValidChangeInt := False;
  repeat
    try
      write('What would you like to change the reputation by?: ');
      Readln(ReputationChangeInput);
      ReputationChange := StrToInt(ReputationChangeInput);
      CompanyChange.AlterReputation(ReputationChange);
      ValidChangeInt := True;
    except
      writeln('Invalid Input Change!');

    end;

  until (ValidChangeInt);
  writeln('Reputation Changed Press Any Key To Continue');
  readln;

end;

This solution is by Alex Finch - Peter Symonds College


Python:


Power outage eventEdit

Java:

private void processPowerOutageEvent() {
        int numOfDays = rnd.nextInt(3) + 1;
        float amountToLose = rnd.nextFloat();
        Console.writeLine("There has been a powercut, which will last for " + numOfDays + " days, and each company has lost " + amountToLose);
        for (Company c : companies)
            c.balance -= amountToLose;
    }

    private void displayEventsAtDayEnd() {
        boolean hasEvent = false;
        Console.writeLine(System.lineSeparator() + "***********************");
        Console.writeLine("*****   Events:   *****");
        Console.writeLine("***********************" + System.lineSeparator());
        float eventRanNo;
        eventRanNo = rnd.nextFloat();
        if (!companies.isEmpty()) {
            if (eventRanNo < 0.25f) {
                eventRanNo = rnd.nextFloat();
                if (eventRanNo < 0.25f) {
                    processAddHouseholdsEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo < 0.5f) {
                    processCostOfFuelChangeEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo < 0.5f) {
                    processReputationChangeEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo >= 0.5f) {
                    processCostChangeEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo >= 0.25f) {
                    processPowerOutageEvent();
                    hasEvent = true;
                }
            }
            if (processGoBankruptEvent())
                hasEvent = true;
            if (!hasEvent) {
                Console.writeLine("No events.");
            }
        } else {
            Console.writeLine("No more companies. Simulation finished, press Enter to close.");
            Console.readLine();
            System.exit(0);
        }
    }
  • by Lucy W


C#:

Both of these in the simulation class, the display events at end of day is an updated version
private void ProcessPowerCutEvent() //  making an event for the company to loose power for a random amount of time
        {
            int count = 0;
            double numOfDays = Math.Round((rnd.NextDouble() * 10), 0);
            double amountToLose = rnd.NextDouble() *numOfDays * 1000;
            Console.WriteLine("There has been a powercut, which will last for " + numOfDays + " days, and each company has lost " + amountToLose);
            do
            {
                companies[count].ChangeBal(amountToLose);
                count++;
            } while (count < 3);
            dayCounter += (int)(numOfDays);
        }

        
private void DisplayEventsAtDayEnd()
        {
            Console.WriteLine("\n***********************");
            Console.WriteLine("*****   Events:   *****");
            Console.WriteLine("***********************\n");
            double eventRanNo;
            eventRanNo = rnd.NextDouble();
            if (eventRanNo < 0.25)
            {
                eventRanNo = rnd.NextDouble();
                if (eventRanNo < 0.25)
                {
                    ProcessAddHouseholdsEvent();
                }
                eventRanNo = rnd.NextDouble();
                if (eventRanNo < 0.5)
                {
                    ProcessCostOfFuelChangeEvent();
                }
                eventRanNo = rnd.NextDouble();
                if (eventRanNo < 0.5)
                {
                    ProcessReputationChangeEvent();
                }
                eventRanNo = rnd.NextDouble();
                if (eventRanNo >= 0.5)
                {
                    ProcessCostChangeEvent();
                }
                if (eventRanNo >= 0.5)
                {
                    ProcessPowerCutEvent();
                }
            }
            else
            {
                Console.WriteLine("No events.");
            }
        }

This needs to go in the company class


public void ChangeBal(double amounttoloose) // changing the balance for a power cut event
        {
            balance -= amounttoloose;

        }

*By Michael Tomkinson


Delphi/Pascal:

This power outage event functions by creating a power outage for the entire 'world'. While the power outage is in progress, no companies will gain/ lose any money. At the end of the day the companies will all be reimbursed the earnings from that day. All other events will continue as normal. All new sub processes need to be declared in the class declarations.

// Two lines below changed in the Company.ProcessDayEnd subprocess. Puts the change in balance in a separate variable to be accessed later
Self.BalanceChange := ProfitLossFromOutlets - Self.DailyCosts - DeliveryCosts; // Calculates the change in balance that occurs for the day
Self.Balance := Self.Balance + Self.BalanceChange; // updates the current balance

procedure Simulation.ProcessPowerOutageEvent(); // Procedure added to handle the power outage event
var
  company : integer;
begin
  writeln('There has been a power cut and no companies have been running');

  for company := 0 to length(self.companies) - 1 do
  begin
    if companies[company].BalanceChange < 0 then
       writeln(companies[company].getName() + ' Prevented: ' + floatToStr(companies[company].BalanceChange) + ' worth of losses')
    else
       writeln(companies[company].getName() + ' Lost: ' + floatToStr(companies[company].BalanceChange) + ' worth of earnings');
    companies[company].Balance := companies[company].Balance - companies[company].BalanceChange
  end;
end;

procedure Simulation.DisplayEventsAtDayEnd(); // Procedure edited to add support for the new subprocess
var
  EventRanNo : Real;
begin
  inc(self.Day);
  writeln;
  writeln('***********************');
  writeln('*****   Events:   *****');
  writeln('***********************');
  writeln;
  EventRanNo := random();
  if EventRanNo < 0.25 then
    begin
      EventRanNo := random(1);
      if (EventRanNo < 0.25) then // Entry added for the chance to run power outage event, change the percentage to make the event run more/ less frequently
        ProcessPowerOutageEvent(); 
      if EventRanNo < 0.25 then
        ProcessAddHouseholdsEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessCostOfFuelChangeEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessReputationChangeEvent();
      EventRanNo := random();
      if EventRanNo >= 0.5 then
        ProcessCostChangeEvent();
    end
    else
      writeln('No events.');
    writeln('Day: ' + inttostr(self.Day));
end;
  • Written by Harry - Peter Symonds College

VB.NET:


Power cut event for a random company for a random amount of time in hours.

Add into Simulation class:

Public Sub ProcessPowerOutage()

        Randomize()
        Dim noOfDays As Integer = Int((Rnd() * 7) + 1)
        Dim moneyLost As Integer = Int((Rnd() * 1000) + 1)
        Dim totalLoss As Integer
        Dim CompanyNo As Integer = Int(Rnd() * Companies.Count)

        Console.WriteLine(Environment.NewLine & Companies(CompanyNo).GetName() & " is experiencing a powercut:")
        Console.WriteLine(Environment.NewLine & Companies(CompanyNo).GetName() & ". Balance: £" & Companies(CompanyNo).getBalance())

        For i = 1 To noOfDays
            Companies(CompanyNo).alterbalance(moneyLost)
            totalLoss += moneyLost
            Console.WriteLine(Environment.NewLine & "Hour: " & i)
            Console.WriteLine(Companies(CompanyNo).GetName() & " has lost £" & totalLoss & " in " & i & " hours.")
            Console.WriteLine(Companies(CompanyNo).GetName() & ". Balance: £" & Companies(CompanyNo).getBalance())
        Next

        Console.WriteLine(Environment.NewLine & Companies(CompanyNo).GetName() & " has lost £" & totalLoss & " in total." & Environment.NewLine)
    End Sub

Edited DisplayEventsAtDayEnd() subroutine:

Private Sub DisplayEventsAtDayEnd()
        Console.WriteLine(Environment.NewLine & "***********************")
        Console.WriteLine("*****   Events:   *****")
        Console.WriteLine("***********************" & Environment.NewLine)
        Dim EventRanNo As Single
        EventRanNo = Rnd()
        If EventRanNo < 0.25 Then
            EventRanNo = Rnd()
            If EventRanNo < 0.25 Then
                ProcessAddHouseholdsEvent()
            End If
            EventRanNo = Rnd()
            If EventRanNo < 0.5 Then
                ProcessCostOfFuelChangeEvent()
            End If
            EventRanNo = Rnd()
            If EventRanNo < 0.5 Then
                ProcessReputationChangeEvent()
            End If
            EventRanNo = Rnd()
            If EventRanNo >= 0.5 Then
                ProcessCostChangeEvent()
            End If
            EventRanNo = Rnd()
            If EventRanNo < 0.1 Then
                ProcessPowerOutage()
            End If
        Else
            Console.WriteLine("No events.")
        End If
    End Sub

In Company Class add:

Public Function GetBalance() As Single
        Return Balance
    End Function

Public Sub AlterBalance(ByVal Change As Single)
        Balance -= Change
    End Sub


'Hubert (Ousedale School) - 09/11/2019


End of world eventEdit

Python:

import sys

  def EndOfWorldEvent(self):
    RandNumber = random.random()
    if RandNumber < 0.1:
      RandNumber = random.random()
      if RandNumber < 0.1:
        print("An asteroid hit Earth! Bye Bye!!!")
        input()
        sys.exit()
      elif RandNumber > 0.1 and RandNumber < 0.3:
        print("Earth has died because of global warming! Bye Bye !!!")
        input()
        sys.exit()
      elif RandNumber > 0.3 and RandNumber < 0.5:
        print("The sun became a red giant! Bye Bye !!!")
        input()
        sys.exit()
      elif RandNumber > 0.5 and RandNumber < 0.7:
        print("A nuclear World War just finshed all life in Earth! Bye Bye !!!")
        input()
        sys.exit()


In the __DisplayEventsAtDayEnd method:

if EventRanNo < 0.1:
        self.EndOfWorldEvent()

Java:

Within the Simulation class, make a method processEndOfWorld():

private void processEndOfWorld() 
{
    Console.println("An asteroid has hit the earth. The world has ended.");
    System.exit(0);
}

Within the displayEventsAtDayEnd() method in the Simulation class, add:

if (eventRanNo <= 0.1f)
{
    processEndOfWorld();
}

Delphi/Pascal:

The custom end of world message for each chance is not necessary for this question (This may be different if it comes up in the exam), if you're running low on time it may be possible just to have one option and leave out the random choice. New Procedures should also be declared in class definitions

procedure Simulation.ProcessEndOfWorldEvent(); // Procedure added to handle End of World events
var
  randomNumber : Float;
begin
       randomNumber := Random();

       if randomNumber < 0.1 then
       begin
          write('An asteroid hit Earth! Bye Bye!!!'); //End of World text courtesy of the author of the Python Solutions
          readln;
          Halt;
       end
       else if (randomNumber > 0.1) and (randomNumber < 0.3) then
       begin
          write('Earth has died because of Global Warming! Bye Bye!!!');
          readln;
          Halt;
       end
       else if (randomNumber > 0.3) and (randomNumber < 0.5) then
       begin
           write('The sun became a red giant! Bye Bye !!!');
           readln;
           Halt;
       end
       else if (randomNumber > 0.5) and (randomNumber < 0.7) then
       begin
         write('A nuclear World War just finshed all life in Earth! Bye Bye !!!');
         readln;
         Halt;
       end
       else
       begin
         write('The Earth was destroyed in the midst of an alien invasion! Bye Bye !!!');
         readln;
         Halt;
       end;

end;

procedure Simulation.DisplayEventsAtDayEnd();
var
  EventRanNo : Real;
begin
  writeln;
  writeln('***********************');
  writeln('*****   Events:   *****');
  writeln('***********************');
  writeln;
  EventRanNo := random();
  if EventRanNo < 0.25 then
    begin
      EventRanNo := random();
      if EventRanNo < 0.25 then
        ProcessAddHouseholdsEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessCostOfFuelChangeEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessReputationChangeEvent();
      EventRanNo := random();
      if EventRanNo >= 0.5 then
        ProcessCostChangeEvent();
      if EventRanNo < 0.1 then // Event Added to trigger the End of world event
        ProcessEndOfWorldEvent();
    end
    else
      writeln('No events.');
end;
  • Written by Harry - Peter Symonds College

VB.net:

Make a method Dropworld() in the simulation class:

Sub Dropworld()
        console.writeline("Darkrai used black hole eclipse. A quadrillion quadrillion joules of energy was released in two seconds. The world is gone")
        console.readline()
        Stop
    End Sub

Within the DisplayEventsAtDayEnd() sub in the Simulation class, add:

If EventRanNo < 0.1 Then
                DropWorld()
            End If

Merge companiesEdit

Java:

/* in the Simulation class */
public void mergeCompanies() {
        System.out.println("\n******* Merge Companies *********\n");
        for(int i = 0; i < companies.size();i++ ){
            System.out.println((i+1) + "." + companies.get(i).getName());
        } System.out.println("");
        int com1, com2;
        do {
            System.out.print("Enter 1st Company: ");
            String comTemp1 = Console.readLine();
            try{
                com1 = Integer.parseInt(comTemp1)-1;
            } catch (NumberFormatException e) {
                com1 = -1;
            }
        } while (com1 < 0);
        Company company1 = companies.get(com1);
        companies.remove(com1);
        
        System.out.println("");
        for(int i = 0; i < companies.size();i++ ){
            Console.writeLine((i+1) + "." + companies.get(i).getName());
        } System.out.println("");
        do {
            System.out.print("Enter 2nd Company: ");
            String comTemp2 = Console.readLine();
            try{
                com2 = Integer.parseInt(comTemp2)-1;
            } catch (NumberFormatException e) {
                com2 = -1;
            }
        } while (com2 < 0);
        Company company2 = companies.get(com2);
        companies.remove(com2);
        System.out.print("Enter new Company name: ");
        String comName = Console.readLine();
        float comBal = company2.getBalance() + company1.getBalance();
        float comReputation = (company1.getReputationScore() > company2.getReputationScore())
                ?company1.getReputationScore()
                :company2.getReputationScore();
        float comAvgCost = (company1.getAvgCostPerMeal() + company2.getAvgCostPerMeal())/2;
        float comAvgPrice = (company2.getAvgPricePerMeal() + company2.getAvgPricePerMeal())/2;
        float comDaily = (company1.getDailyCosts() + company2.getDailyCosts())/2;
        float comFuel = (company1.getFuelCostPerUnit() + company2.getFuelCostPerUnit())/2;
        float comBase = (company1.getBaseCostOfDelivery()+company2.getBaseCostOfDelivery())/2;
        List<Outlet> comOutlets = company1.getOutlets();
        comOutlets.addAll(company2.getOutlets());
        Company newCom = new Company(comName, company1.getCategory(), comBal, comReputation, comAvgCost, comAvgPrice, comDaily, comFuel, comBase, comOutlets);
        companies.add(newCom);
    }
/* in the company class */
public Company(String name, String category, float balance, float reputationScore, float avgCostPerMeal, 
            float avgPricePerMeal, float dailyCosts, float fuelCostPerUnit, float baseCostOfDelivery, List<Outlet> outlets) {
        familyOutletCost = 1000;
        fastFoodOutletCost = 2000;
        namedChefOutletCost = 15000;
        familyFoodOutletCapacity = 150;
        fastFoodOutletCapacity = 200;        
        namedChefOutletCapacity = 50;
        this.name = name;
        this.category = category;
        this.balance = balance;
        this.reputationScore = reputationScore;
        this.avgCostPerMeal = avgCostPerMeal;
        this.avgPricePerMeal = avgPricePerMeal;
        this.dailyCosts = dailyCosts;
        this.fuelCostPerUnit = fuelCostPerUnit;
        this.baseCostOfDelivery = baseCostOfDelivery;
        this.outlets = outlets;
    }
    
    public float getBalance() { return balance; }
    public String getCategory() { return category;} 
    public float getAvgCostPerMeal() { return avgCostPerMeal; }
    public float getAvgPricePerMeal() {  return avgPricePerMeal; }
    public float getDailyCosts() { return dailyCosts; }
    public float getFuelCostPerUnit() { return fuelCostPerUnit; }
    public float getBaseCostOfDelivery() {return baseCostOfDelivery;}
    public List<Outlet> getOutlets() {return outlets;}

Go bankrupt eventEdit

Added event for companies to go bankrupt at -10,000

Python3:

class Company:
   def __init__(self, Name, Category, Balance, X, Y, FuelCostPerUnit, BaseCostOfDelivery):
       self._Outlets = []
       self._FamilyOutletCost = 1000
       self._NamedChefOutletCapacity = 50
       self._Name = Name
  # Added this function, which allows you to grab the balance into the "processdayend" function in the 
  # Simulation class.
   def GetBalance(self):
       return self._Balance
       

class Simulation:

   def __init__(self):
       self._Companies = []
       self._FuelCostPerUnit = 0.0098
       self._BaseCostforDelivery = 100
   
   # Added this code at the start of the processdayend function.
       def ProcessDayEnd(self):
       for Current in self._Companies:
           Balance = Current.GetBalance()
           Name = Current.GetName()
           Index = self.GetIndexOfCompany(Name)
           if Balance < -10000:
               del (self._Companies[Index])
               print("The company {} has gone into bankruptcy".format(Name))


Created by skesh

Java:

// create isBankrupt() method in Company class
public boolean isBankrupt() {
	return balance <= -10000;
}
// create method for going bankrupt in Simulation
private boolean processGoBankruptEvent() {
        boolean goneBankrupt = false;
        for (int i = 0; i < companies.size(); i++) {
            if (companies.get(i).isBankrupt()) {
                System.out.println(companies.get(i).getName() + " has gone bankrupt and is closing.");
                companies.remove(i);
                i--;
                goneBankrupt = true;
            }
        }
        return goneBankrupt;
    }
// edit method in Simulation
private void displayEventsAtDayEnd() {
        boolean hasEvent = false;
        Console.writeLine(System.lineSeparator() + "***********************");
        Console.writeLine("*****   Events:   *****");
        Console.writeLine("***********************" + System.lineSeparator());
        float eventRanNo;
        eventRanNo = rnd.nextFloat();
        if (!companies.isEmpty()) {
            if (eventRanNo < 0.25f) {
                eventRanNo = rnd.nextFloat();
                if (eventRanNo < 0.25f) {
                    processAddHouseholdsEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo < 0.5f) {
                    processCostOfFuelChangeEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo < 0.5f) {
                    processReputationChangeEvent();
                    hasEvent = true;
                }
                eventRanNo = rnd.nextFloat();
                if (eventRanNo >= 0.5f) {
                    processCostChangeEvent();
                    hasEvent = true;
                }
            }
            if (processGoBankruptEvent())
                hasEvent = true;
            if (!hasEvent) {
                Console.writeLine("No events.");
            }
        } else {
            Console.writeLine("No more companies. Simulation finished, press Enter to close.");
            Console.readLine();
            System.exit(0);
        }
    }
  • by Lucy W

Delphi/Pascal:

function Company.BankruptEvent() : Boolean; // Function added to process if a company is going to go bankrupt
var
  bankruptThreshold : integer;

begin
  bankruptThreshold := -10000; // Variable allows the user to change the threshold for when a company goes bankrupt
    if self.Balance < bankruptThreshold then
       BankruptEvent := True
    else
      BankruptEvent := False
end;

procedure Simulation.RemoveCompany(index : integer); // Following Code edited from Alex Finch's remove company solution
var CompanyNumber, I : integer;

begin
  CompanyNumber := index;

if(CompanyNumber = high(Self.Companies)) then SetLength(Self.Companies, high(Self.Companies))
else
begin
  for I := CompanyNumber to high(Self.Companies)-1 do
  begin
    Self.Companies[I] := Self.Companies[I+1];
  end;
  setLength(Self.Companies, high(Self.Companies));
end;

end;  

procedure Simulation.DisplayEventsAtDayEnd(); // Small change to the events section allowing the program to display if a company has closed
var
  EventRanNo : Real;
  index : integer;
  companyIsBankrupt : boolean;
begin
  writeln;
  writeln('***********************');
  writeln('*****   Events:   *****');
  writeln('***********************');
  writeln;
  EventRanNo := random();
  if EventRanNo < 0.25 then
    begin
      EventRanNo := random();
      if EventRanNo < 0.25 then
        ProcessAddHouseholdsEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessCostOfFuelChangeEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessReputationChangeEvent();
      EventRanNo := random();
      if EventRanNo >= 0.5 then
        ProcessCostChangeEvent();
    end
    else
      writeln('No events.');

    for index := low(self.companies) to high(self.companies) do;
        companyIsBankrupt := Companies[index].BankruptEvent();
        if companyIsBankrupt = True then
          begin
           writeln(self.Companies[index].GetName() + ' has closed down due to bankrupcy');
           self.RemoveCompany(index);
          end;
end;
  • Written by Harry - Peter Symonds College

C#:

i have done this slightly differently, i have made it so that after 7 days of being in debt then the company will be forced closed

class Company

   {
       private static Random rnd = new Random();
       protected string name, category;
       protected double balance, reputationScore, avgCostPerMeal, avgPricePerMeal, dailyCosts, familyOutletCost, fastFoodOutletCost, namedChefOutletCost, fuelCostPerUnit, baseCostOfDelivery;
       protected List<Outlet> outlets = new List<Outlet>();
       protected int familyFoodOutletCapacity, fastFoodOutletCapacity, namedChefOutletCapacity;
       protected bool isindebt;                                                                         // mmaking a bool to store if the company is in debt
       protected int daysindebt;
 


“LINE 390 to 420”

public bool GetIfInDebt() // function of if the company is in debt

       {
           if (balance < 0)
           {
               daysindebt++; // increments how many days the company has been in debt for
               if (daysindebt == 7)
               {
                   CompanyForcedClose();
                   return true;
               }
               return true;
           }
           else
           {
               daysindebt = 0;
               return false;
           }
       }
       public void CompanyForcedClose()                           // procedure for a company to close when in debt for more than a week. could be changed to close outlets down at first.
       {
           if (isindebt == true && daysindebt ==7)   
           {
               while (outlets.Count > 0) // calls the other subroutines while there are more than one outlet
               {
                   CloseOutlet(0);
               }             
           }
       }

Process day end subroutine updated

public string ProcessDayEnd()

       {
           string details = "";
           double profitLossFromOutlets = 0;
           double profitLossFromThisOutlet = 0;
           double deliveryCosts;
           if (outlets.Count > 1)
           {
               deliveryCosts = baseCostOfDelivery + CalculateDeliveryCost();
           }
           else
           {
               deliveryCosts = baseCostOfDelivery;
           }
           details += "Daily costs for company: " + dailyCosts.ToString() + "\nCost for delivering produce to outlets: " + deliveryCosts.ToString() + "\n";
           for (int current = 0; current < outlets.Count; current++)
           {
               profitLossFromThisOutlet = outlets[current].CalculateDailyProfitLoss(avgCostPerMeal, avgPricePerMeal);
               details += "Outlet " + (current + 1) + " profit/loss: " + profitLossFromThisOutlet.ToString() + "\n";
               profitLossFromOutlets += profitLossFromThisOutlet;
           }
           details += "Previous balance for company: " + balance.ToString() + "\n";
           balance += profitLossFromOutlets - dailyCosts - deliveryCosts;
           details += "New balance for company: " + balance.ToString();
           isindebt = GetIfInDebt();
           // calling the subroutines that i have made  
           
           
           return details;
       }


Get details subroutine

public string GetDetails()

       {
           string details = "";
           details += "Name: " + name + "\nType of business: " + category + "\n";
           details += "Current balance: " + balance.ToString() + "\nAverage cost per meal: " + avgCostPerMeal.ToString() + "\n";
           details += "Average price per meal: " + avgPricePerMeal.ToString() + "\nDaily costs: " + dailyCosts.ToString() + "\n";
           details += "Delivery costs: " + CalculateDeliveryCost().ToString() + "\nReputation: " + reputationScore.ToString() + "\n";
           details += "Number of outlets: " + outlets.Count.ToString() + "\nOutlets\n";
           details += "\nIs the company in debt? " + isindebt.ToString() + "\n";                                                                                     // puts whether the company is in debt in the details
         
           if (isindebt == true)                                                                                                                          // displays how many days in debt if the company is in debt 
           {
               details += "\n Days the company has been in debt for " + daysindebt.ToString() + " days \n\n";
           }
            
           for (int current = 1; current < outlets.Count + 1; current++)
           {
               details += current + ". " + outlets[current - 1].GetDetails() + "\n";
           }
           return details;
       }

This needs to be in the simulation class.

public void DeleteCompany(int index) // new subroutine to delete a company which has had all its outlets closed

       {
           int outlets = companies[index].GetNumberOfOutlets();
           if (outlets == 0)
           {
             
                   Console.WriteLine("That company has now closed down as it has no outlets.");
                   companies.RemoveAt(index);
                                               
           }
       }

and it is called in process day end which is shown here

public void ProcessDayEnd()
       {
           int index = 0;
           
           do                                              // calls the other subroutine while the company count is changing
           {
               DeleteCompany(index);
               index++;
           } while (index < companies.Count);
           double totalReputation = 0;
           List<double> reputations = new List<double>();
           int companyRNo, current, loopMax, x = 0, y = 0;
           foreach (var c in companies)
           {
               c.NewDay();
               totalReputation += c.GetReputationScore();
               reputations.Add(totalReputation);
           }
           loopMax = simulationSettlement.GetNumberOfHouseholds() - 1;
           for (int counter = 0; counter < loopMax + 1; counter++)
           {
               if (simulationSettlement.FindOutIfHouseholdEatsOut(counter, ref x, ref y))
               {
                   companyRNo = rnd.Next(1, Convert.ToInt32(totalReputation) + 1);
                   current = 0;
                   while (current < reputations.Count)
                   {
                       if (companyRNo < reputations[current])
                       {
                           companies[current].AddVisitToNearestOutlet(x, y);
                           break;
                       }
                       current++;
                   }
               }
           }
           DisplayCompaniesAtDayEnd();
           DisplayEventsAtDayEnd();
           dayCounter++;                                                                //incrementing the days
         
       }
  • By Michael Tomkinson*


Remove CompanyEdit

C#:

make a new method called RemoveCompany.
public void removeCompany()
        {
            Console.Write("Enter company name: ");
            string name = Console.ReadLine();
            bool found = false;
            for(int i = 0; i < companies.Count; i++)
            {
                Console.WriteLine(companies[i]);
                if(companies[i].GetName() == name)
                {
                    companies.RemoveAt(i);
                    Console.WriteLine("Company removed");
                    found = true;
                }
            }
            if (!found)
            {
                Console.WriteLine("Company not found.");
            }
        }

modify the Run method to add a new case for option 5

public void Run()
        {
            string choice = "";
            int index;
            while (choice != "Q")
            {
                DisplayMenu();
                choice = Console.ReadLine();
                switch (choice)
                {
                    case "1":
                        simulationSettlement.DisplayHouseholds();
                        break;
                    case "2":
                        DisplayCompanies();
                        break;
                    case "3":
                        string companyName;
                        index = -1;
                        while (index == -1)
                        {
                            Console.Write("Enter company name: ");
                            companyName = Console.ReadLine();
                            index = GetIndexOfCompany(companyName);
                        }
                        ModifyCompany(index);
                        break;
                    case "4":
                        AddCompany();
                        break;
                    case "5":
                        removeCompany();
                        break;
                    case "6":
                        ProcessDayEnd();
                        break;
                    case "Q":
                        Console.WriteLine("Simulation finished, press Enter to close.");
                        Console.ReadLine();
                        break;
                }
            }
        }

lastly, modify the DisplayMenu method to write the option to the console.

public void DisplayMenu()
        {
            Console.WriteLine("\n*********************************");
            Console.WriteLine("**********    MENU     **********");
            Console.WriteLine("*********************************");
            Console.WriteLine("1. Display details of households");
            Console.WriteLine("2. Display details of companies");
            Console.WriteLine("3. Modify company");
            Console.WriteLine("4. Add new company");
            Console.WriteLine("5. Remove a company");
            Console.WriteLine("6. Advance to next day");
            Console.WriteLine("Q. Quit");
            Console.Write("\n Enter your choice: ");
        }


Delphi/Pascal:

Slight change to Simulation.Run(); Just to add call to RemoveCompany(); procedure.

procedure Simulation.Run();
var
  CompanyName : String;
  Choice : Char;
  Index : Integer;
begin
  Choice := ' ';
  while Choice <> 'Q' do
    begin
      DisplayMenu();
      readln(Choice);
      case (Choice) of
        '1': Self.SimulationSettlement.DisplayHouseholds();
        '2': DisplayCompanies();
        '3':
          begin
            repeat
              write('Enter company name: ');
              readln(CompanyName);
              Index := GetIndexOfCompany(CompanyName);
            until Index <> - 1;
            ModifyCompany(Index);
          end;
        '4': AddCompany();
        '5': RemoveCompany();
        '6': ProcessDayEnd();
        'Q':
          begin
            writeln('Simulation finished, press Enter to close.');
            readln;
          end;
      end;
    end;
end;

Slight change to menu to show new option

procedure Simulation.DisplayMenu();
begin
  writeln;
  writeln('*********************************');
  writeln('**********    MENU     **********');
  writeln('*********************************');
  writeln('1. Display details of households');
  writeln('2. Display details of companies');
  writeln('3. Modify company');
  writeln('4. Add new company');
  writeln('5. Remove Company');
  writeln('6. Advance to next day');
  writeln('Q. Quit');
  writeln;
  write('Enter your choice: ');
end;

Add Simulation.RemoveCompany(); procedure. Also ensure you declare this within the simulation class deceleration.

procedure Simulation.RemoveCompany();
var
ValidCompanyNum : Boolean;
CompanyNumberInput : String;
CompanyNumber : Integer;
CompanyChange : Company;
ValidChangeInt : Boolean;
ReputationChangeInput : String;
ReputationChange : Integer;
I : Integer;
begin
  ValidCompanyNum := False;
  writeln('What company would you like to remove?');
  repeat
    try
      DisplayCompanyNames();
      write('Select company number: ');
      Readln(CompanyNumberInput);
      CompanyNumber := StrToInt(CompanyNumberInput);
      CompanyChange := Self.Companies[CompanyNumber];
      if( (CompanyNumber >= low(Self.Companies))  and (high(Self.Companies) >= CompanyNumber) ) then
      begin
        ValidCompanyNum := True;
        //Code to Remove from an Array
        if(CompanyNumber = high(Self.Companies)) then SetLength(Self.Companies, high(Self.Companies))
        else
        begin
          for I := CompanyNumber to high(Self.Companies)-1 do
          begin
            Self.Companies[I] := Self.Companies[I+1];
          end;
          setLength(Self.Companies, high(Self.Companies));
        end;
      end
      else raise Exception.Create('Invalid Company Number');
      except
      writeln('Error: Not real company number');
    end;

  until ValidCompanyNum;
  writeln('Company Removed! Press any key to continue');
  readln;

end;

This solution is by Alex Finch - Peter Symonds College

Java BUT ACTUALLY GOOD:

Shows list of companies to be removed

public void removeCompany(){
        for(int i = 0; i < companies.size();i++ ){
            Console.writeLine((i+1) + "." + companies.get(i).getName());
        }
        Console.writeLine("Choose company to be removed: ");
        int removeCompany = (Integer.parseInt(Console.readLine())-1);
        companies.remove(removeCompany);
        run();
    }

public void run() {
        String choice = "";
        int index;
        while (!choice.equals("Q")) {
            displayMenu();
            choice = Console.readLine();
            switch (choice) {
                case "1":
                    simulationSettlement.displayHouseholds();
                    break;
                case "2":
                    displayCompanies();
                    break;
                case "3":
                    String companyName;
                    do {
                        Console.write("Enter company name: ");
                        companyName = Console.readLine();
                        index = getIndexOfCompany(companyName);
                    } while (index == -1);
                    modifyCompany(index);
                    break;
                case "4":
                    addCompany();
                    break;
                case "6":
                    processDayEnd();
                    break;
                case "7":
                    removeCompany();
                case "Q":
                    Console.writeLine("Simulation finished, press Enter to close.");
                    Console.readLine();
                    break;
            }
        }
    }

Obviously add the option for 7 in the menu so they know to press it. Solution by Owain Bestley

Java:

'method in java to remove a company from given user input

public void removeCompany(){
        System.out.print("Which company: ");
        String rem = Console.readLine();
        int ind = getIndexOfCompany(rem);
        companies.remove(ind);
        
        }

'displaying menu option to remove a company in java

public void displayMenu() {
        Console.writeLine(System.lineSeparator() + "*********************************");
        Console.writeLine("**********    MENU     **********");
        Console.writeLine("*********************************");
        Console.writeLine("1. Display details of households");
        Console.writeLine("2. Display details of companies");
        Console.writeLine("3. Modify company");
        Console.writeLine("4. Add new company");
        Console.writeLine("6. Advance to next day");
        Console.writeLine("7. Remove company");
        Console.writeLine("Q. Quit");
        Console.write(System.lineSeparator() + "Enter your choice: ");
    }

'adding remove company under run()

public void run() {
        String choice = "";
        int index;
        while (!choice.equals("Q")) {
            displayMenu();
            choice = Console.readLine();
            switch (choice) {
                case "1":
                    simulationSettlement.displayHouseholds();
                    break;
                case "2":
                    displayCompanies();
                    break;
                case "3":
                    String companyName;
                    do {
                        Console.write("Enter company name: ");
                        companyName = Console.readLine();
                        index = getIndexOfCompany(companyName);
                    } while (index == -1);
                    modifyCompany(index);
                    break;
                case "4":
                    addCompany();
                    break;
                case "6":
                    processDayEnd();
                    break;
                case "7":
                    removeCompany();
                    break;
                case "Q":
                    Console.writeLine("Simulation finished, press Enter to close.");
                    Console.readLine();
                    break;
            }
        }
    }

Python:

'Changes to add a new option for remove company in Run Subroutine

  def Run(self):
    Choice = ""
    while Choice != "Q":
      self.DisplayMenu()
      Choice = input()
      if Choice == "1":
        self._SimulationSettlement.DisplayHouseholds()
      elif Choice == "2":
        self.DisplayCompanies()
      elif Choice == "3":
        Index = -1
        while Index == -1:
          CompanyName = input("Enter company name: ")
          Index = self.GetIndexOfCompany(CompanyName)
        self.ModifyCompany(Index)
      elif Choice == "4":
        self.AddCompany()
      elif Choice == "5":
        CompanyName = input("what company would you like to delete: ")
        del(self._Companies[self.GetIndexOfCompany(CompanyName)])
      elif Choice == "6":
        self.ProcessDayEnd()
      elif Choice == "Q":
        print("Simulation finished, press Enter to close.")
        input()

* Sir Graham Balfour

Alternative Solution:

# Submitted by Jake Talling
  def removeCompany(self):
    for i in range(len(self._Companies)):
      print((i+1), self._Companies[i]._Name)
    print("Please select which company to remove: (ID)")
    try:
      removeC = int(input())
    except:
      print("Input invalid. Returning to menu")
      return
    del(self._Companies[removeC])

        
  def Run(self):
    Choice = ""
    while Choice != "Q":
      self.DisplayMenu()
      Choice = input()
      if Choice == "1":
        self._SimulationSettlement.DisplayHouseholds()
      elif Choice == "2":
        self.DisplayCompanies()
      elif Choice == "3":
        Index = -1
        while Index == -1:
          CompanyName = input("Enter company name: ")
          Index = self.GetIndexOfCompany(CompanyName)
        self.ModifyCompany(Index)
      elif Choice == "4":
        self.AddCompany()
      elif Choice == "5":
        self.removeCompany()
      elif Choice == "6":
        self.ProcessDayEnd()
      elif Choice == "Q":
        print("Simulation finished, press Enter to close.")
        input()

VB.NET:

'Changes to add a new option for remove company in Run Subroutine

    Public Sub Run(ByVal Days As Integer)
        Dim Choice As String = ""
        Dim Index As Integer
        While Choice <> "Q"
            DisplayMenu(Days)
            Choice = Console.ReadLine()
            Select Case Choice
                Case "1"
                    SimulationSettlement.DisplayHouseholds()
                Case "2"
                    DisplayCompanies()
                Case "3"
                    Dim CompanyName As String
                    Do
                        Console.Write("Enter company name: ")
                        CompanyName = Console.ReadLine()
                        Index = GetIndexOfCompany(CompanyName)
                    Loop Until Index <> -1
                    ModifyCompany(Index)
                Case "4"
                    AddCompany()

                'Add Fith option in Subroutine run
                Case "5"
                    RemoveCompany()
                Case "6"
                    Dim HowMany As Integer

                    Console.WriteLine("How many days would you like to advance? ")
                    HowMany = Console.ReadLine()

                    Days = Days + HowMany

                    ProcessDayEnd(HowMany)
                Case "Q"
                    Console.WriteLine("Simulation finished, press Enter to close.")
                    Console.ReadLine()
            End Select
        End While
    End Sub

    'New Remove Company Subroutine in simulation class

    Public Sub RemoveCompany()

        Dim CompanyToRemove As String
        Dim Index As String

        Console.WriteLine("Enter the name of the company you would like to remove: ")
        CompanyToRemove = Console.ReadLine()

        Try

            Index = GetIndexOfCompany(CompanyToRemove)
            Companies.RemoveAt(Index)

            Console.WriteLine()
            Console.WriteLine(CompanyToRemove & " removed!")
            Console.WriteLine()

        Catch

            Console.WriteLine()
            Console.WriteLine("Company: " & CompanyToRemove & " doesn't exist")
            Console.WriteLine()

        End Try

    End Sub

'Code created by Folkestone Grammar School for Girls Student - 20/09/2019

Run for many daysEdit

Add an option to run simulation for many days (>1)

C#:

This is the subroutine for the menu. in this i have also validated the menu choice.

public void Run()

       {
           string choice = "";
           int index;
           while (choice != "Q")
           {
               DisplayMenu();
               do {                                                                                                 // validation for the menu choice
                   choice = Console.ReadLine();
                   switch (choice)
                   {
                       case "1":
                           simulationSettlement.DisplayHouseholds();
                           break;
                       case "2":
                           DisplayCompanies();
                           break;
                       case "3":
                           string companyName;
                           index = -1;
                           while (index == -1)
                           {
                               Console.Write("Enter company name: ");
                               companyName = Console.ReadLine();
                               index = GetIndexOfCompany(companyName);
                           }
                           ModifyCompany(index);
                           break;
                       case "4":
                           AddCompany();
                           break;
                       
                           RemoveCompany();
                           break;
                       case "6":
                           ProcessDayEnd();
                           break;
                       case "7":
                           AdvanceMultipleDays(); // added a new case that will advance many days
                           break;
                       case "Q":
                           Console.WriteLine("Simulation finished, press Enter to close.");
                           Console.ReadLine();
                           break;
                   }
                   if((int.Parse(choice) > 0 && int.Parse(choice) < 8) || choice != "Q")                             // repeats untill this = true
                   {
                       Console.WriteLine("Pleas Re Enter a valid choice");
                   }
               } while ((int.Parse(choice) > 0 && int.Parse(choice) < 8) || choice != "Q");
       } }
   }

This is the subroutine for advancing many days

public void AdvanceMultipleDays()     // new subroutine to advance many days
       {
           Console.WriteLine("How many days would you like to advance?");
           int AdvancingDays = int.Parse(Console.ReadLine());
           for (int i = 0; i < AdvancingDays ; i++)
           {
               ProcessDayEnd();
           }
       }
  • By Michael Tomkinson

Delphi/Pascal:

procedure Simulation.advanceDays(daysToAdvance : integer); // Added new subprocess for advancing multiple days
var index : integer;
begin
  for index := 1 to daysToAdvance do // Loops the following code the number of times given by the user
  ProcessDayEnd(); // Calls the ProcessDayEnd subprocess
  writeln;
  writeln('Advanced Simulation ' + IntToStr(daysToAdvance) + ' Days');
end;

procedure Simulation.Run();
var
  CompanyName : String;
  Choice : Char;
  Index, daysToAdvance : Integer;
begin
  Choice := ' ';
  while Choice <> 'Q' do
    begin
      DisplayMenu();
      readln(Choice);
      case (Choice) of
        '1': Self.SimulationSettlement.DisplayHouseholds();
        '2': DisplayCompanies();
        '3':
          begin
            repeat
              write('Enter company name: ');
              readln(CompanyName);
              Index := GetIndexOfCompany(CompanyName);
            until Index <> - 1;
            ModifyCompany(Index);
          end;
        '4': AddCompany();
        '6': ProcessDayEnd();
        'Q':
          begin
            writeln('Simulation finished, press Enter to close.');
            readln;
          end;
        '7' : // Added new entry for advancing multiple days
          begin
            write('Please enter the number of days to advance: ');
            try // Validation for user input
               readln(daysToAdvance);
               advanceDays(daysToAdvance);
            except on E : Exception do
               writeln('Input is invalid');
            end;
          end;
      end;
    end;
end;
  • Written by Harry - Peter Symonds

Java:

System.out.print("Enter the number of days you want to advance: ");
int days = Integer.parseInt(Console.readLine());
for (int i = 0; i < days; i++) {
processDayEnd();
}
  • by Benny

Python:

  def Run(self):
    Choice = ""
    while Choice != "Q":
      self.DisplayMenu()
      Choice = input()
      if Choice == "1":
        self._SimulationSettlement.DisplayHouseholds()
      elif Choice == "2":
        self.DisplayCompanies()
      elif Choice == "3":
        Index = -1
        while Index == -1:
          CompanyName = input("Enter company name: ")
          Index = self.GetIndexOfCompany(CompanyName)
        self.ModifyCompany(Index)
      elif Choice == "4":
        self.AddCompany()
      elif Choice == "6":
        self.ProcessDayEnd()
      elif Choice == "7":
        self.MultipleDayEnd()
      elif Choice == "Q":
        print("Simulation finished, press Enter to close.")
        input()


def DisplayMenu(self):
    print("\n*********************************")
    print("**********    MENU     **********")
    print("*********************************")
    print("1. Display details of households")
    print("2. Display details of companies")
    print("3. Modify company")
    print("4. Add new company")
    print("6. Advance to next day")
    print("7. Advance a set number of days")
    print("Q. Quit")
    print("\nEnter your choice: ", end = "")
def MultipleDayEnd(self):
    try:
      numberOfDays = int(input("How many days would you like to advance?"))
      for i in range(numberOfDays +1):
        self.ProcessDayEnd()
    except:
      print("Integer not accepted")

VB.NET:

'Add option 7 in Run() Subroutine in Simulation class

Public Sub Run()
        Dim Choice As String = ""
        Dim Index As Integer
        While Choice <> "Q"
            DisplayMenu()
            Choice = Console.ReadLine()
            Select Case Choice
                Case "1"
                    SimulationSettlement.DisplayHouseholds()
                Case "2"
                    DisplayCompanies()
                Case "3"
                    Dim CompanyName As String
                    Do
                        Console.Write("Enter company name: ")
                        CompanyName = Console.ReadLine()
                        Index = GetIndexOfCompany(CompanyName)
                    Loop Until Index <> -1
                    ModifyCompany(Index)
                Case "4"
                    AddCompany()
                Case "6"
                    ProcessDayEnd()

'Option 7 added
                Case "7"
                    ProcessMultipleDays()
                Case "Q"
                    Console.WriteLine("Simulation finished, press Enter to close.")
                    Console.ReadLine()
            End Select
        End While
    End Sub


'Add ProcessMultipleDays() Subroutine to Simulation Class

Public Sub ProcessMultipleDays()

        Dim noOfDays As Integer

        Try
            Console.Write("How many days do you want to advance? ")
            noOfDays = Console.ReadLine

            For i = 1 To noOfDays
                ProcessDayEnd()
            Next

        Catch ex As Exception
            Console.WriteLine("")
            Console.WriteLine("Invalid Input")
            Console.WriteLine("")
        End Try

    End Sub

'Hubert (Ousedale School) - 13/11/2019

Day CounterEdit

Display a counter of how many days have passed

C#:

make a new int varible in the simulation class and initlise it in constructor.

class Simulation
{
  private static Random rnd = new Random();
  '''private int dayCounter;'''
  protected Settlement simulationSettlement;
  protected int noOfCompanies;
  protected double fuelCostPerUnit, baseCostForDelivery;
  protected List<Company> companies = new List<Company>();

  public Simulation()
  {
    fuelCostPerUnit = 0.0098;
    baseCostForDelivery = 100;
    '''dayCounter = 1;'''
  }
}

modify the ProcessDayEnd method to increment the counter

public void ProcessDayEnd()
        {
            double totalReputation = 0;
            List<double> reputations = new List<double>();
            int companyRNo, current, loopMax, x = 0, y = 0;
            foreach (var c in companies)
            {
                c.NewDay();
                totalReputation += c.GetReputationScore();
                reputations.Add(totalReputation);
            }
            loopMax = simulationSettlement.GetNumberOfHouseholds() - 1;
            for (int counter = 0; counter < loopMax + 1; counter++)
            {
                if (simulationSettlement.FindOutIfHouseholdEatsOut(counter, ref x, ref y))
                {
                    companyRNo = rnd.Next(1, Convert.ToInt32(totalReputation) + 1);
                    current = 0;
                    while (current < reputations.Count)
                    {
                        if (companyRNo < reputations[current])
                        {
                            companies[current].AddVisitToNearestOutlet(x, y);
                            break;
                        }
                        current++;
                    }
                }
            }
            DisplayCompaniesAtDayEnd();
            DisplayEventsAtDayEnd();
            '''dayCounter++;''' 
        }


modify the menu to display the day number

public void DisplayMenu()
        {
            Console.WriteLine("\n*********************************");
            Console.WriteLine("**********    MENU     **********");
            Console.WriteLine("*********************************");
            '''Console.WriteLine($"Day: {dayCounter}");'''
            Console.WriteLine("*********************************");
            Console.WriteLine("1. Display details of households");
            Console.WriteLine("2. Display details of companies");
            Console.WriteLine("3. Modify company");
            Console.WriteLine("4. Add new company");
            Console.WriteLine("5. Advance multiple days");
            Console.WriteLine("6. Advance to next day");
            Console.WriteLine("Q. Quit");

Delphi/Pascal:

type
  Simulation = class
    protected
      Day : Integer; // Added new class variable 'Day' to simulation class

procedure Simulation.DisplayEventsAtDayEnd();
var
  EventRanNo : Real;
begin
  inc(self.Day); // Increment day before displaying the events
  writeln;
  writeln('***********************');
  writeln('*****   Events:   *****');
  writeln('***********************');
  writeln;
  EventRanNo := random();
  if EventRanNo < 0.25 then
    begin
      EventRanNo := random();
      if EventRanNo < 0.25 then
        ProcessAddHouseholdsEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessCostOfFuelChangeEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessReputationChangeEvent();
      EventRanNo := random();
      if EventRanNo >= 0.5 then
        ProcessCostChangeEvent();
    end
    else
      writeln('No events.');
    writeln('Day: ' + inttostr(self.Day)); // show the current day at the bottom of the Events section
end;
  • Written by Harry - Peter Symonds College

Java:

add integer days to Simulation class and set it to zero

class Simulation {
    protected Settlement simulationSettlement;
    protected int noOfCompanies;
    protected float fuelCostPerUnit, baseCostForDelivery;
    protected List<Company> companies = new ArrayList();
    private static Random rnd = new Random();
    public int days = 0;

............................}

'under Simulation class, add following methods: '1. to increment days

public void DayCounter(){
        days += 1;
    }

2. to output no of days passed

public void NoOfDays(){
        if(days != 1){
        System.out.println(days +" days have passed");
        } else{
            System.out.println(days +" day has passed");
        }
    }

'add this to run() method as well in right order and correct use of methods

public void run() {
        String choice = "";
        int index;
        
        while (!choice.equals("Q")) {
            displayMenu();
            choice = Console.readLine();
            DayCounter();
            switch (choice) {
                case "1":
                    simulationSettlement.displayHouseholds();
                    break;
                case "2":
                    displayCompanies();
                    break;
                case "3":
                    String companyName;
                    do {
                        Console.write("Enter company name: ");
                        companyName = Console.readLine();
                        index = getIndexOfCompany(companyName);
                    } while (index == -1);
                    modifyCompany(index);
                    break;
                case "4":
                    addCompany();
                    break;
                case "6":
                    processDayEnd();
                    break;
                case "7":
                    removeCompany();
                    break;
                case "Q":
                    Console.writeLine("Simulation finished, press Enter to close.");
                    Console.readLine();
                    break;
             
            }
            NoOfDays();
            
            
        }
    }

Python:

class Simulation:
  def __init__(self):
    self._DayCount = 0
    self._Companies = []
    self._FuelCostPerUnit = 0.0098
    self._BaseCostforDelivery = 100

 def ProcessDayEnd(self):
    TotalReputation = 0.0
    Reputations = []
    for C in self._Companies:
      C.NewDay()
      TotalReputation += C.GetReputationScore()
      Reputations.append(TotalReputation)
    LoopMax = self._SimulationSettlement.GetNumberOfHouseholds() - 1
    for Counter in range (0, LoopMax + 1):
      EatsOut, X, Y = self._SimulationSettlement.FindOutifHouseholdEatsOut(Counter)
      if EatsOut:
        CompanyRNo = random.randint(1, int(TotalReputation))
        Current = 0
        while Current < len(Reputations):
          if CompanyRNo < Reputations[Current]:
            self._Companies[Current].AddVisitToNearestOutlet(X, Y)
            break
          Current += 1
    self.__DisplayCompaniesAtDayEnd()
    self.__DisplayEventsAtDayEnd()
    self._DayCount += 1
    print("day:", self._DayCount)

- Sir Graham Balfour

VB.NET:

Public Sub Run()

'Add new variable that will be the counter of days
        Dim daysCount As Integer = 0
        Dim Choice As String = ""
        Dim Index As Integer
        While Choice <> "Q"
            DisplayMenu()
            Choice = Console.ReadLine()
            Select Case Choice
                Case "1"
                    SimulationSettlement.DisplayHouseholds()
                Case "2"
                    DisplayCompanies()
                Case "3"
                    Dim CompanyName As String
                    Do
                        Console.Write("Enter company name: ")
                        CompanyName = Console.ReadLine()
                        Index = GetIndexOfCompany(CompanyName)
                    Loop Until Index <> -1
                    ModifyCompany(Index)
                Case "4"
                    AddCompany()
                Case "5"
                    RemoveCompany()
                Case "6"
                    ProcessDayEnd()
'Every time we advance 1 day, the counter increments by 1.
                    daysCount += 1
                    Console.WriteLine("Day: " & daysCount)
                Case "Q"
                    Console.WriteLine("Simulation finished, press Enter to close.")
                    Console.ReadLine()
            End Select
        End While
    End Sub

'Hubert (Ousedale School) - 13/11/2019

Display Costs (£x.xx)Edit

Display the costs in the format £x.xx, as opposed to just an integer value.

C#:

public static string getPoundsFormat(double toChange)
        {
            string changed = "";
            changed = toChange.ToString("C", CultureInfo.CurrentCulture);
            return changed;
        } //doubt this will be a question since you'd have to change a lot of lines

Delphi/Pascal:

Please note: RoundValue was chosen as the name for this function as round() is a taken keyword in Pascal, when copying code don't change the function name to round or it will break other areas of this program.

function RoundValue(Value : float) : String; // New Function added to round numbers and return a string
var noDecimalPlaces : integer;
begin
         noDecimalPlaces := 2; // Variable to define how many decimal places the resulting string should be
         RoundValue := FloatToStrF(Value, ffFixed, 8, noDecimalPlaces);
end;

To Apply this to the program, simply replace all applicable FloatToStr() functions with this RoundValue() one.

  • Written by Harry - Peter Symonds College

Java:

'for given currency format, add in each class:

public DecimalFormat df = new DecimalFormat("£.00");

'to display any of the costs in £x.xx, eg:

df.format(dailyCosts)

Python:

def Round(money):
  money = "£" + str('{:.2f}'.format(money))
  return money

  def GetDetails(self):
    Details = "Coordinates: (" + str(self._XCoord) + ", " + str(self._YCoord) + ")     Capacity: " + str(self._Capacity) + "      Maximum Capacity: "
    Details += str(self._MaxCapacity) + "      Daily Costs: " + Round(self._DailyCosts) + "      Visits today: " + str(self._VisitsToday)
    return Details

  def GetDetails(self):
    Details = ""
    Details += "Name: " + self._Name + "\nType of business: " + self._Category + "\n"
    Details += "Current balance: " + Round(self._Balance) + "\nAverage cost per meal: " + Round(self._AvgCostPerMeal) + "\n"
    Details += "Average price per meal: " + Round(self._AvgPricePerMeal) + "\nDaily costs: " + Round(self._DailyCosts) + "\n"
    Details += "Delivery costs: " + Round(self.CalculateDeliveryCost()) + "\nReputation: " + str(self._ReputationScore) + "\n\n"
    Details += "Number of outlets: " + str(len(self._Outlets)) + "\nOutlets\n"
    for Current in range (1, len(self._Outlets) + 1):
      Details += str(Current) + ". " + self._Outlets[Current - 1].GetDetails() + "\n"
    return Details

VB.NET:

'Note: This would have to be done throughout the entire program for all variables or a subroutine could be created this is just an example, Line 267
FormatCurrency(CalculateDeliveryCost.ToString, 2)

Check if company name is takenEdit

AddCompany(self) add a check to see if CompanyName already exists in _Companies

C#:

Delphi/Pascal:

procedure Simulation.AddCompany();
var
  Balance, X, Y : Integer;
  CompanyName, TypeOfCompany : String;
  NewCompany, ExistingCompany : Company;
  NameAvailable : Boolean;
begin
  write('Enter a name for the company: ');
  readln(CompanyName);

  if length(self.Companies) <> 0 then
    begin
      for ExistingCompany in self.Companies do
        begin
          if CompanyName = ExistingCompany.GetName then
            begin
              writeln('Name Taken');
              NameAvailable := False;
              self.AddCompany(); //Recursive call.
            end
          else
            begin
              NameAvailable := True;
            end;
        end;
    end
  else
    begin
      NameAvailable := True; //Name is available if no other companies exist.
    end;

  if NameAvailable then
    begin
      write('Enter the starting balance for the company: ');
      readln(Balance);
      repeat
        write('Enter 1 for a fast food company, 2 for a family company or 3 for a named chef company: ');
        readln(TypeOfCompany);
      until ((TypeOfCompany = '1') or (TypeOfCompany = '2') or (TypeOfCompany = '3'));
      if TypeOfCompany = '1' then
        TypeOfCompany := 'fast food'
      else if TypeOfCompany = '2' then
        TypeOfCompany := 'family'
      else
        TypeOfCompany := 'named chef';
      Self.SimulationSettlement.GetRandomLocation(X, Y);
      NewCompany := Company.New(CompanyName, TypeOfCompany, Balance, X, Y, FuelCostPerUnit, Self.BaseCostForDelivery);
      SetLength(Self.Companies, length(Self.Companies) + 1);
      Self.Companies[High(Self.Companies)] := NewCompany;
    end;
end;

By Lawrence Dennison-Hall | Peter Symonds College

Java:

This is just an edit to the addCompany() function in the Simulation Class.

 public void addCompany() {
        int balance, x, y;
        String companyName, typeOfCompany;
        Console.write("Enter a name for the company: ");
        companyName = Console.readLine();
        String existingNames;
        for(int i = 0; i < companies.size();i++ ){
            existingNames = companies.get(i).getName();
            while(companyName.equals(existingNames)){
                Console.print("Company name taken, please enter another name: ");
                companyName = Console.readLine();
            }
        }

Created by the one and only Jorge Bishop

Python:

  def AddCompany(self):
    NameCheck = True
    while NameCheck == True:
      CompanyName = input("Enter a name for the company: ")
      NameCheck = False
      for name in self._Companies:
        checking=name.GetName()
        if checking==CompanyName:
          print('company name taken')
          NameCheck = True
    Balance = int(input("Enter the starting balance for the company: "))
    TypeOfCompany = ""
    while not(TypeOfCompany == "1" or TypeOfCompany == "2" or TypeOfCompany == "3"):
      TypeOfCompany = input("Enter 1 for a fast food company, 2 for a family company or 3 for a named chef company: ")
    if TypeOfCompany == "1":
      TypeOfCompany = "fast food"
    elif TypeOfCompany == "2":
      TypeOfCompany = "family"
    else:
      TypeOfCompany = "named chef"
    X, Y = self._SimulationSettlement.GetRandomLocation()
    NewCompany = Company(CompanyName, TypeOfCompany, Balance, X, Y, self._FuelCostPerUnit, self._BaseCostforDelivery)
    self._Companies.append(NewCompany)

VB.NET:

Public Sub AddCompany()
        'Use this variable as a condition for your while loop to stop you from continuing with a name already in use
        Dim checkName As Boolean = True
        Dim Balance, X, Y As Integer
        Dim CompanyName, TypeOfCompany As String
        'Use the name variable as a holder for the name you're checking your chosen name against in the ArrayList
        Dim name As String
        'Add in a while loop to check through the ArrayList of company names to check if the chosen name has already been used.
        While checkName = True
            Console.Write("Enter a name for the company: ")
            CompanyName = Console.ReadLine()
            checkName = False
            For i = 0 To Me.Companies.Count - 1
                name = Me.Companies(i).GetName()
                If CompanyName = name Then
                    Console.WriteLine("Company name is already in use")
                    checkName = True
                End If
            Next
        End While

        Console.Write("Enter the starting balance for the company: ")
        Balance = Console.ReadLine()
        Do
            Console.Write("Enter 1 for a fast food company, 2 for a family company or 3 for a named chef company: ")
            TypeOfCompany = Console.ReadLine()
        Loop Until TypeOfCompany = "1" Or TypeOfCompany = "2" Or TypeOfCompany = "3"
        If TypeOfCompany = "1" Then
            TypeOfCompany = "fast food"
        ElseIf TypeOfCompany = "2" Then
            TypeOfCompany = "family"
        Else
            TypeOfCompany = "named chef"
        End If
        SimulationSettlement.GetRandomLocation(X, Y)
        Dim NewCompany As New Company(CompanyName, TypeOfCompany, Balance, X, Y, FuelCostPerUnit, BaseCostForDelivery)
        Companies.Add(NewCompany)
    End Sub

TM ~ Ouse

Fuel cost always positiveEdit

Ensure fuel costs can never become negative

Points of Interest:

The fuel costs go negative because:
DeliveryCosts = Distance * FuelCostPerUnit
So when FuelCostPerUnit becomes negative, the fuel cost will very quickly break.
Just make sure FuelCostPerUnit does not go negative.

C#:

 
in the company class makes sure it is always positive
 public void AlterFuelCostPerUnit(double change)
        {
            fuelCostPerUnit += change;
            if (fuelCostPerUnit < 0) // checks if below zero 
            {
                fuelCostPerUnit -= fuelCostPerUnit; // if below zero then makes the negative positive
            }
        }

*By Michael Tomkinson

Delphi/Pascal:

procedure Company.AlterFuelCostPerUnit(Change : Real);
begin
  Self.FuelCostPerUnit := Self.FuelCostPerUnit + Change;
  if Self.FuelCostPerUnit < 0 then
    Self.FuelCostPerUnit := 0; //Sets fuel costs to 0 if they fall below 0.
end;

By Lawrence Dennison-Hall | Peter Symonds College

Java:

Python:

def __ProcessCostOfFuelChangeEvent(self):
    FuelCostChange = random.randint(1, 9) / 10.0
    UpOrDown = random.randint(0, 1)
    CompanyNo = random.randint(0, len(self._Companies) - 1)
    if UpOrDown == 1:
      if self._Companies[CompanyNo]._FuelCostPerUnit<FuelCostChange:
        UpOrDown=0
    if UpOrDown == 0:
      print("The cost of fuel has gone up by " + str(FuelCostChange) + " for " + self._Companies[CompanyNo].GetName())
    else:
      print("The cost of fuel has gone down by " + str(FuelCostChange) + " for " + self._Companies[CompanyNo].GetName())
      FuelCostChange *= -1
    self._Companies[CompanyNo].AlterFuelCostPerUnit(FuelCostChange)

VB.NET:

'Add a new public function to the company class to get access to the current value of FuelCostPerUnit
    Public Function GetFuelCostPerUnit() As Integer
        Return FuelCostPerUnit
    End Function

'Edit the ProcessCostOfFuelChangeEvent() Sub in the Simulation Class
    Private Sub ProcessCostOfFuelChangeEvent()
        Dim FuelCostChange As Single = (Int(Rnd() * 9) + 1) / 10
        Dim UpOrDown As Integer = Int(Rnd() * 2)
        Dim CompanyNo As Integer = Int(Rnd() * Companies.Count)
        'Add in a separate if statement to change the value of the upordown to 0 if the current fuelcost change is going to result in a negative fuelcostchange
        If UpOrDown = 1 Then
            If Me.Companies(CompanyNo).GetFuelCostPerUnit() < FuelCostChange Then
                UpOrDown = 0
            End If
        End If

        If UpOrDown = 0 Then
            Console.WriteLine("The cost of fuel has gone up by " & FuelCostChange.ToString() & " for " & Companies(CompanyNo).GetName())
        Else
            Console.WriteLine("The cost of fuel has gone down by " & FuelCostChange.ToString() & " for " & Companies(CompanyNo).GetName())
            FuelCostChange *= -1
        End If
        Companies(CompanyNo).AlterFuelCostPerUnit(FuelCostChange)
    End Sub

TM ~ Ouse

Small settlementEdit

Add small settlement class and provide an option in the launch menu

C#:

Delphi/Pascal:

Small settlement class:

type
  SmallSettlement = class(Settlement)
    public
      constructor New(ReducedXSize : Integer; ReducedYSize : Integer; ReducedHouseholds : Integer); overload;
  end;

Small settlement constructor:

constructor SmallSettlement.New(ReducedXSize : Integer; ReducedYSize : Integer; ReducedHouseholds : Integer);
var
  Count : Integer;
begin
  Self.New();
  Self.XSize := Self.XSize - ReducedXSize;
  Self.YSize := Self.YSize - ReducedYSize;
  Self.StartNoOfHouseholds := Self.StartNoOfHouseholds - ReducedHouseholds;
  for Count := 1 to Self.StartNoOfHouseholds do
    Self.AddHousehold();
end;

Updated menu options (Simulation constructor)

constructor Simulation.New();
var
  Choice : String;
  ExtraX, ExtraY, ExtraHouseholds, ReducedX, ReducedY, ReducedHouseholds, Count : Integer;
  Company1, Company2, Company3 : Company;
begin
  Self.FuelCostPerUnit := 0.0098;
  Self.BaseCostForDelivery := 100;
  write('Enter L for a large settlement OR S for a small settlement, anything else for a normal size settlement: ');
  readln(Choice);
  if Choice = 'L' then
    begin
      write('Enter additional amount to add to X size of settlement: ');
      readln(ExtraX);
      write('Enter additional amount to add to Y size of settlement: ');
      readln(ExtraY);
      write('Enter additional number of households to add to settlement: ');
      readln(ExtraHouseholds);
      Self.SimulationSettlement := LargeSettlement.New(ExtraX, ExtraY, ExtraHouseholds);
    end
  else if Choice = 'S' then
    begin
      write('Enter reduced amount to add to X size of settlement: ');
      readln(ReducedX);
      write('Enter reduced amount to add to Y size of settlement: ');
      readln(ReducedY);
      write('Enter reduced number of households to add to settlement: ');
      readln(ReducedHouseholds);
      Self.SimulationSettlement := SmallSettlement.New(ReducedX, ReducedY, ReducedHouseholds);
    end
  else
    Self.SimulationSettlement := Settlement.New();
  write('Enter D for default companies, anything else to add your own start companies: ');
  readln(Choice);
  if Choice = 'D' then
    begin
      Self.NoOfCompanies := 3;
      SetLength(Self.Companies, Self.NoOfCompanies);
      Company1 := Company.New('AQA Burgers', 'fast food', 100000, 200, 203, Self.FuelCostPerUnit, Self.BaseCostForDelivery);
      Self.Companies[0] := Company1;
      Self.Companies[0].OpenOutlet(300, 987);
      Self.Companies[0].OpenOutlet(500, 500);
      Self.Companies[0].OpenOutlet(305, 303);
      Self.Companies[0].OpenOutlet(874, 456);
      Self.Companies[0].OpenOutlet(23, 408);
      Self.Companies[0].OpenOutlet(412, 318);
      Company2 := Company.New('Ben Thor Cuisine', 'named chef', 100400, 390, 800, Self.FuelCostPerUnit, Self.BaseCostForDelivery);
      Self.Companies[1] := Company2;
      Company3 := Company.New('Paltry Poultry', 'fast food', 25000, 800, 390, Self.FuelCostPerUnit, Self.BaseCostForDelivery);
      Self.Companies[2] := Company3;
      Self.Companies[2].OpenOutlet(400, 390);
      Self.Companies[2].OpenOutlet(820, 370);
      Self.Companies[2].OpenOutlet(800, 600);
    end
  else
    begin
      write('Enter number of companies that exist at the start of simulation: ');
      readln(Self.NoOfCompanies);
      for Count := 1 to Self.NoOfCompanies do
        AddCompany();
    end;
end;

By Lawrence Dennison-Hall | Peter Symonds College

Java:

By changing the Settlement class to 0 instead of just taking away an integer we can avoid having any issues where we may get a negative integer. We can also now create a custom sized Settlement.

public Settlement() {
        xSize = 0;
        ySize = 0;
        startNoOfHouseholds = 0;
        createHouseholds();
    }

class DefaultSettlement extends Settlement{
    public DefaultSettlement() {
        xSize = 1000;
        ySize = 1000;
        startNoOfHouseholds = 250;
        createHouseholds();
    }
}

class LargeSettlement extends DefaultSettlement {
    public LargeSettlement(int extraxSize, int extraySize, int extraHouseholds) {
        super();
        super.xSize += extraxSize;
        super.ySize += extraySize;
        super.startNoOfHouseholds += extraHouseholds;
        for (int count = 1; count <= extraHouseholds; count++) {
            addHousehold();
        }
    }
}

class SmallSettlement extends Settlement {
    public SmallSettlement(int XSize, int YSize, int Households) {
        super();
        super.xSize = XSize;
        super.ySize = YSize;
        super.startNoOfHouseholds = Households;
        for (int count = 1; count <= Households; count++) {
            addHousehold();
        
    }
}

You also have to alter the simulation class to accomodate for the change, calling the default simulation class instead of just simulation.

 public Simulation() {
        fuelCostPerUnit = 0.0098f;
        baseCostForDelivery = 100;
        String choice;
        Console.write("Enter L for a large settlement, S for a small settlement and anything else for a normal size settlement: ");
        choice = Console.readLine();
        if (choice.toUpperCase().equals("L")) {
            int extrax, extray, extraHouseholds;
            Console.write("Enter additional amount to add to x size of settlement: ");
            extrax = Integer.parseInt(Console.readLine());
            Console.write("Enter additional amount to add to y size of settlement: ");
            extray = Integer.parseInt(Console.readLine());
            Console.write("Enter additional number of households to add to settlement: ");
            extraHouseholds = Integer.parseInt(Console.readLine());
            simulationSettlement = new LargeSettlement(extrax, extray, extraHouseholds);
        }
        else if(choice.toUpperCase().equals("S")){
            int sizeX, sizeY, noHouseholds;
            Console.write("Enter  x size of settlement: ");
            sizeX = Integer.parseInt(Console.readLine());
            Console.write("Enter y size of settlement: ");
            sizeY = Integer.parseInt(Console.readLine());
            Console.write("Enter number of households in settlement: ");
            noHouseholds = Integer.parseInt(Console.readLine());
            simulationSettlement = new SmallSettlement(sizeX,sizeY,noHouseholds);
        }
        else {
            simulationSettlement = new DefaultSettlement();            
        }

Solution made by Owain Bestley (Listen to Hachiko)

Python:

class SmallSettlement(Settlement):
  def __init__(self, LowerXSize, LowerYSize, LowerHouseholds):
    self._XSize = 1000 - LowerXSize
    self._YSize = 1000 - LowerYSize
    self._StartNoOfHouseholds = 250 -  LowerHouseholds
    self._Households = []
    for Count in range (1, self._StartNoOfHouseholds + 1):
      self.AddHousehold()


class Simulation:
  def __init__(self):
    self._DayCount = 0
    self._Companies = []
    self._FuelCostPerUnit = 0.0098
    self._BaseCostforDelivery = 100
    Choice = input("Enter L for a large settlement, S for a small settlement,  anything else for a normal size settlement: ")
    if Choice == "L":
      ExtraX = int(input("Enter additional amount to add to X size of settlement: "))
      ExtraY = int(input("Enter additional amount to add to Y size of settlement: "))
      ExtraHouseholds = int(input("Enter additional number of households to add to settlement: "))
      self._SimulationSettlement = LargeSettlement(ExtraX, ExtraY, ExtraHouseholds)
      ###
    elif Choice == "S":
      LowerX = 1001
      LowerY = 1001
      LowerHouseholds = 251
      while LowerX >= 1000 or LowerY >= 1000 or LowerHouseholds >= 250:
        print("X and Y reductions cannot equal to or more than 1000 and Household reduction cannot be equal to or more than 250")
        LowerX = int(input("Enter the amount of X size you want to reduce the settlement by: "))
        LowerY = int(input("Enter the amount of y size you want to reduce the settlement by: "))
        LowerHouseholds = int(input("Enter the amount of households you want to reduce in the settlement: "))
      self._SimulationSettlement = SmallSettlement(LowerX, LowerY, LowerHouseholds)
      ###
    else:
      self._SimulationSettlement = Settlement()            
    Choice = input("Enter D for default companies, anything else to add your own start companies: ")
    if Choice == "D":
      self._NoOfCompanies = 3
      Company1 = Company("AQA Burgers", "fast food", 100000, 200, 203, self._FuelCostPerUnit, self._BaseCostforDelivery)
      self._Companies.append(Company1)
      self._Companies[0].OpenOutlet(300, 987)
      self._Companies[0].OpenOutlet(500, 500)
      self._Companies[0].OpenOutlet(305, 303)
      self._Companies[0].OpenOutlet(874, 456)
      self._Companies[0].OpenOutlet(23, 408)
      self._Companies[0].OpenOutlet(412, 318)
      Company2 = Company("Ben Thor Cuisine", "named chef", 100400, 390, 800, self._FuelCostPerUnit, self._BaseCostforDelivery)
      self._Companies.append(Company2)
      Company3 = Company("Paltry Poultry", "fast food", 25000, 800, 390, self._FuelCostPerUnit, self._BaseCostforDelivery)
      self._Companies.append(Company3)
      self._Companies[2].OpenOutlet(400, 390)
      self._Companies[2].OpenOutlet(820, 370)
      self._Companies[2].OpenOutlet(800, 600)
    else:
      self._NoOfCompanies = int(input("Enter number of companies that exist at start of simulation: "))
      for Count in range (1, self._NoOfCompanies + 1):
        self.AddCompany()

VB.NET:

'Add in a new class called SmallSettllement that inherits its values from settlement
Class SmallSettlement
    Inherits Settlement

    Public Sub New(ByVal ReduceXBy As Integer, ByVal ReduceYBy As Integer, ByVal ReduceHousingBy As Integer)
        Me.XSize = 1000 - ReduceXBy
        Me.YSize = 1000 - ReduceYBy
        Me.StartNoOfHouseholds = 250 - ReduceHousingBy
        For count = 1 To (StartNoOfHouseholds + 1)
            Me.AddHousehold()
        Next

    End Sub
End Class

Public Sub New()
        FuelCostPerUnit = 0.0098
        BaseCostForDelivery = 100
        Dim Choice As String
        'Add in a choice for a small settlement on the choice display in the public sub new of simulation
        Console.Write("Enter L for a large settlement, S for a small settlement & anything else for a normal size settlement: ")
        Choice = Console.ReadLine()
        If Choice = "L" Then
            Dim ExtraX, ExtraY, ExtraHouseholds As Integer
            Console.Write("Enter additional amount to add to X size of settlement: ")
            ExtraX = Console.ReadLine()
            Console.Write("Enter additional amount to add to Y size of settlement: ")
            ExtraY = Console.ReadLine()
            Console.Write("Enter additional number of households to add to settlement: ")
            ExtraHouseholds = Console.ReadLine()
            SimulationSettlement = New LargeSettlement(ExtraX, ExtraY, ExtraHouseholds)
            'Add in an elseif for the choice of a small settlement in the public sub new of simulation.
        ElseIf Choice = "S" Then
            Dim reducexby As Integer = 1001
            Dim reduceyby As Integer = 1001
            Dim reducehousingby As Integer = 251
            While reducexby >= 1000 Or reduceyby >= 1000 Or reducehousingby >= 250
                Console.WriteLine("X & Y cannot be reduced by more than 999 and Housing cannot be reduced by more than 249.")
                Console.WriteLine("Please enter how much you would like to reduce the X size by: ")
                reducexby = Console.ReadLine()
                Console.WriteLine("Please enter how much you would like to reduce the Y size by: ")
                reduceyby = Console.ReadLine()
                Console.WriteLine("Please enter how much you would like to reduce the number of houses by: ")
                reducehousingby = Console.ReadLine()
            End While
            SimulationSettlement = New SmallSettlement(reducexby, reduceyby, reducehousingby)
            '
        Else
            SimulationSettlement = New Settlement()
        End If

TM ~ Ouse

Doesn't accept integers with ExtraX/YEdit

Question description

C#:

Delphi/Pascal:

Java:

Python:

VB.NET:

Add a Close Outlet eventEdit

Adds a random event function which removes an outlet from a company

C#:

Delphi/Pascal:

New functions and procedures added need to be declared in class definitions.

procedure Simulation.RemoveCompany(CompanyNumber : integer); // Following code adapted from Alex Finch's Remove Company program (Added here to remove companies that have no outlets)
var i : integer;
begin
if(CompanyNumber = high(Self.Companies)) then
                 SetLength(Self.Companies, high(Self.Companies))
else
    begin
         for i := CompanyNumber to high(Self.Companies)-1 do
                  Self.Companies[i] := Self.Companies[i+1];
         setLength(Self.Companies, high(Self.Companies));
    end;
end;

procedure Simulation.ProcessCloseOutletEvent(); // Procedure added to handle closing an outlet
var
  CompanyNumber, NumberOfOutlets : integer;
  CompanyName : String;

begin
  CompanyNumber := trunc(Random() * length(Self.Companies)); // Pick a random company
  CompanyName := self.companies[CompanyNumber].getName(); // Get that companies name
  NumberOfOutlets := self.companies[CompanyNumber].getNumberOfOutlets(); // Get the number of outlets that company has
  self.companies[CompanyNumber].CloseOutlet(Random(NumberOfOutlets)); // Close a random outlet from that company

  if NumberOfOutlets -1 = 0 then // the built in CloseOutlet() function returns whether the company should close or not, however I think this way is easier
  begin
     writeln(CompanyName + ' has closed their last outlet and has closed down');
     RemoveCompany(CompanyNumber)
  end
  else
      writeln(CompanyName + ' has closed one of their outlets, they have ' + IntToStr(NumberOfOutlets -1) + ' outlet(s) left');
end;

procedure Simulation.DisplayEventsAtDayEnd(); // Procedure edited to add in the chance to close an outlet
var
  EventRanNo : Real;
begin
  writeln;
  writeln('***********************');
  writeln('*****   Events:   *****');
  writeln('***********************');
  writeln;
  EventRanNo := random();
  if EventRanNo < 0.25 then
    begin
      EventRanNo := random();
      if EventRanNo < 0.25 then // Close outlet procedure added to this event, could be added to any events
        begin
             ProcessAddHouseholdsEvent();
             ProcessCloseOutletEvent(); // Calls procedure to close an outlet of a company
        end;
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessCostOfFuelChangeEvent();
      EventRanNo := random();
      if EventRanNo < 0.5 then
        ProcessReputationChangeEvent();
      EventRanNo := random();
      if EventRanNo >= 0.5 then
        ProcessCostChangeEvent();
    end
    else
      writeln('No events.');
end;
  • Written by Harry - Peter Symonds College

Java:

  • Under Simulation class add following method
public void closeOutletEvent(){
        int indexCOE = rnd.nextInt((companies.size()-1)+1) +1;
        int outletIndexCOE = rnd.nextInt((companies.get(indexCOE).getNumberOfOutlets()-1)+1) +1;
        for(int i = 0; i<=companies.size();i++){
            if(i == indexCOE){
                boolean closeCompany = companies.get(indexCOE).closeOutlet(outletIndexCOE-1);
                    if (closeCompany) {
                        Console.writeLine("That company has now closed down as it has no outlets.");
                        companies.remove(indexCOE);
                    }
            }
        }
        System.out.println("An outlet has been closed");
    }
  • also under displayEventsAtDayEnd() method, add some of the extra lines of code below:
private void displayEventsAtDayEnd() {
        Console.writeLine(System.lineSeparator() + "***********************");
        Console.writeLine("*****   Events:   *****");
        Console.writeLine("***********************" + System.lineSeparator());
        float eventRanNo;
        eventRanNo = rnd.nextFloat();
        if (eventRanNo<100f){
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.5f) {
                closeOutletEvent();
            }
        }
        if (eventRanNo < 0.25f) {
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.25f) {
                processAddHouseholdsEvent();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.5f) {
                processCostOfFuelChangeEvent();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo < 0.5f) {
                processReputationChangeEvent();
            }
            eventRanNo = rnd.nextFloat();
            if (eventRanNo >= 0.5f) {
                processCostChangeEvent();
            }
            
        } else {
            Console.writeLine("No events.");
        }
    }

Python:

def __ProcessCloseOutletEvent(self):
  indx = random.randrange(0,len(self._Companies))
  randomCompany = self._Companies[indx]

  print(str(randomCompany._Name+" has closed an outlet"))
  randomCompany.CloseOutlet(random.randrange(0,randomCompany.GetNumberOfOutlets()))
  remove = randomCompany.GetNumberOfOutlets()
  print(remove)
  if remove <= 0:
    print(randomCompany._Name+" has closed down due to not having any more outlets open")
    del(self._Companies[indx])
  else:
    pass

VB.NET:

Add a faster option to load in the default scenarioEdit

Add a faster option to load in the default scenario

C#:

Delphi/Pascal:

procedure Simulation.initiateDefaultCompanies(); // New procedure added to initiate the default companies and ensure no repeated code
var Company1, Company2, Company3 : Company;
begin
  Self.NoOfCompanies := 3;
  SetLength(Self.Companies, Self.NoOfCompanies);
  Company1 := Company.New('AQA Burgers', 'fast food', 100000, 200, 203, Self.FuelCostPerUnit, Self.BaseCostForDelivery);
  Self.Companies[0] := Company1;
  Self.Companies[0].OpenOutlet(300, 987);
  Self.Companies[0].OpenOutlet(500, 500);
  Self.Companies[0].OpenOutlet(305, 303);
  Self.Companies[0].OpenOutlet(874, 456);
  Self.Companies[0].OpenOutlet(23, 408);
  Self.Companies[0].OpenOutlet(412, 318);
  Company2 := Company.New('Ben Thor Cuisine', 'named chef', 100400, 390, 800, Self.FuelCostPerUnit, Self.BaseCostForDelivery);
  Self.Companies[1] := Company2;
  Company3 := Company.New('Paltry Poultry', 'fast food', 25000, 800, 390, Self.FuelCostPerUnit, Self.BaseCostForDelivery);
  Self.Companies[2] := Company3;
  Self.Companies[2].OpenOutlet(400, 390);
  Self.Companies[2].OpenOutlet(820, 370);
  Self.Companies[2].OpenOutlet(800, 600);
end;

constructor Simulation.New();
var
  Choice : String;
  ExtraX, ExtraY, ExtraHouseholds, Count : Integer;

begin
  Self.FuelCostPerUnit := 0.0098;
  Self.BaseCostForDelivery := 100;
  write('Enter D for default scenario, anything else for a custom settlement: ');
  readln(Choice);
  if Choice = 'D' then
    begin
      writeln('Default Simulation initiated');

      Self.SimulationSettlement := Settlement.New(); // Creates a normal size settlement
      initiateDefaultCompanies(); // Initiates default companies

      Exit; // Exits out of the procedure to ensure that none of the other options are asked
    end;

  write('Enter L for a large settlement, anything else for a normal size settlement: ');
  readln(Choice);
  if Choice = 'L' then
    begin
      write('Enter additional amount to add to X size of settlement: ');
      readln(ExtraX);
      write('Enter additional amount to add to Y size of settlement: ');
      readln(ExtraY);
      write('Enter additional number of households to add to settlement: ');
      readln(ExtraHouseholds);
      Self.SimulationSettlement := LargeSettlement.New(ExtraX, ExtraY, ExtraHouseholds);
    end
  else
    Self.SimulationSettlement := Settlement.New();
  write('Enter D for default companies, anything else to add your own start companies: ');
  readln(Choice);
  if Choice = 'D' then
    begin
      initiateDefaultCompanies(); // Initiates the default companies
    end
  else
    begin
      write('Enter number of companies that exist at the start of simulation: ');
      readln(Self.NoOfCompanies);
      for Count := 1 to Self.NoOfCompanies do
        AddCompany();
    end;
end;
  • Written by Harry - Peter Symonds College

Java:

public Simulation() {
        fuelCostPerUnit = 0.0098f;
        baseCostForDelivery = 100;
        String choice;
        Console.write("Enter L for a large settlement, anything else for a normal size settlement: ");
        choice = Console.readLine();
        if (choice.equals("L")) {
            int extrax, extray, extraHouseholds;
            Console.write("Enter additional amount to add to x size of settlement: ");
            extrax = Integer.parseInt(Console.readLine());
            Console.write("Enter additional amount to add to y size of settlement: ");
            extray = Integer.parseInt(Console.readLine());
            Console.write("Enter additional number of households to add to settlement: ");
            extraHouseholds = Integer.parseInt(Console.readLine());
            simulationSettlement = new LargeSettlement(extrax, extray, extraHouseholds);
        } else {
            simulationSettlement = new Settlement();            
        }
        Console.write("Enter D for default companies, anything else to add your own start companies: ");
        choice = Console.readLine();
        if (choice.equals("D")) {
            System.out.print("Do you want to load faster or slower? - faster or slower");
            String speedOption = Console.readLine();
            if(speedOption.equals("faster")){
                LoadFasterInDefaultScenario();
            } else{
                noOfCompanies = 3;
            Company company1 = new Company("AQA Burgers", "fast food", 100000, 200, 203, fuelCostPerUnit, baseCostForDelivery);
            companies.add(company1);
            companies.get(0).openOutlet(300, 987);
            companies.get(0).openOutlet(500, 500);
            companies.get(0).openOutlet(305, 303);
            companies.get(0).openOutlet(874, 456);
            companies.get(0).openOutlet(23, 408);
            companies.get(0).openOutlet(412, 318);
            Company company2 = new Company("Ben Thor Cuisine", "named chef", 100400, 390, 800, fuelCostPerUnit, baseCostForDelivery);
            companies.add(company2);
            Company company3 = new Company("Paltry Poultry", "fast food", 25000, 800, 390, fuelCostPerUnit, baseCostForDelivery);
            companies.add(company3);
            companies.get(2).openOutlet(400, 390);
            companies.get(2).openOutlet(820, 370);
            companies.get(2).openOutlet(800, 600);
            }
            
        } else {
            Console.write("Enter number of companies that exist at start of simulation: ");
            noOfCompanies = Integer.parseInt(Console.readLine());
            for (int count = 1; count <= noOfCompanies; count++) {
                addCompany();
            }
        }
    }

public void LoadFasterInDefaultScenario(){
        noOfCompanies = 3;
            Company company1 = new Company("AQA Burgers", "fast food", 100000, 200, 203, fuelCostPerUnit, baseCostForDelivery);
            companies.add(company1);
            companies.get(0).openOutlet(300, 987);
            companies.get(0).openOutlet(500, 500);
            companies.get(0).openOutlet(305, 303);
            companies.get(0).openOutlet(874, 456);
            companies.get(0).openOutlet(23, 408);
            companies.get(0).openOutlet(412, 318);
            Company company2 = new Company("Ben Thor Cuisine", "named chef", 100400, 390, 800, fuelCostPerUnit, baseCostForDelivery);
            companies.add(company2);
            Company company3 = new Company("Paltry Poultry", "fast food", 25000, 800, 390, fuelCostPerUnit, baseCostForDelivery);
            companies.add(company3);
            companies.get(2).openOutlet(400, 390);
            companies.get(2).openOutlet(820, 370);
            companies.get(2).openOutlet(800, 600);
}

Python:

 Choice = input("Enter D for default scenarios, anything else for your own scenario.")
        Choice = Choice.upper()
        if Choice == "D":
            self._SimulationSettlement = Settlement()
            self._NoOfCompanies = 3
            Company1 = Company("AQA Burgers", "fast food", 100000, 200, 203, self._FuelCostPerUnit,
                               self._BaseCostforDelivery)
            self._Companies.append(Company1)
            self._Companies[0].OpenOutlet(300, 987)
            self._Companies[0].OpenOutlet(500, 500)
            self._Companies[0].OpenOutlet(305, 303)
            self._Companies[0].OpenOutlet(874, 456)
            self._Companies[0].OpenOutlet(23, 408)
            self._Companies[0].OpenOutlet(412, 318)
            Company2 = Company("Ben Thor Cuisine", "named chef", 100400, 390, 800, self._FuelCostPerUnit,
                               self._BaseCostforDelivery)
            self._Companies.append(Company2)
            Company3 = Company("Paltry Poultry", "fast food", 25000, 800, 390, self._FuelCostPerUnit,
                               self._BaseCostforDelivery)
            self._Companies.append(Company3)
            self._Companies[2].OpenOutlet(400, 390)
            self._Companies[2].OpenOutlet(820, 370)
            self._Companies[2].OpenOutlet(800, 600)
        else:
            Choice = input("Enter L for a large settlement, anything else for a normal size settlement: ")
            Choice = Choice.upper()
            if Choice == "L":
                while True:

                    ExtraX = input("Enter additional amount to add to X size of settlement: ")
                    ExtraY = input("Enter additional amount to add to Y size of settlement: ")
                    ExtraHouseholds = input("Enter additional number of households to add to settlement: ")
                    try:
                        ExtraX = int(ExtraX)
                        ExtraY = int(ExtraY)
                        ExtraHouseholds = int(ExtraHouseholds)
                        break
                    except ValueError:
                        print("Those are not a number try again")
                        continue

VB.NET: