- Flowchart
- Prerelease commentary
- Key components
- Important snippets
- Advice
- Example tasks
- Credits
- Further reading
Prerelease files:
+────────────────────────────────────────────────────────────────────+
| |
| +------+ |
| | Main | |
| +---+--+ |
| | |
| +------v-----+ |
| | Simulation | |
| +------+-----+ |
| +-----------------+ | |
| | GetHowLongToRun +------------> |
| +-----------------+ | +----------+ |
| | +--+ ReadFile | |
| +--------v--------+ | +----------+ |
| | InitializeField <---+ |
| +--------+--------+ | +----------------+ |
| | +--+ CreateNewField | |
| | +----------------+ |
| +--------v--------+ |
| | SimulateOneYear <--------------------+ |
| +--------+--------+ | |
| | | |
| | | |
| +--------v-------+ | |
| +----> SimulateSpring | | |
| +-------------+ | +----------------+ | |
| | CountPlants +---+ |-------------+ | |
| +-------------+ | +-------v--------+ | | |
| +----> SimulateSummer | | | |
| +----------------+ | +---------+ | |
| |-----------------> Display | | |
| +-----------+ +-------v--------+ | +---------+ | |
| | SeedLands +--------> SimulateAutumn | | | |
| +-----------+ +----------------+ | | |
| |-------------+ | |
| +-------v--------+ | |
| | SimulateWinter | | |
| +-------+--------+ | |
| | | |
| +------------------------------+ |
| |
+────────────────────────────────────────────────────────────────────+
The program without comments can be found [here][pre-files-highlighted program].
System.IO allows access to files. Importaion occurs before the main module
begins. To use reasonable indentaion for the rest of the document the End Module
statement is also shown.
Imports System.IO
Module Module1
' [Rest of the code shown below]
End Module
Global constants will retain their value throughout the program. The first four are the characters that represent possible cell contents. The last two represent the size of the field.
Global constants are used because using literals can result in hard to read code. They result in numbers and symbols scattered around the program, and make maintanance harder because it's easy to forget what each symbol or number means. Global constants avoid these problems twofold: symbols change occurs in a single location and the value's representation is clear.
Const SOIL As Char = "."
Const SEED As Char = "S"
Const PLANT As Char = "P"
Const ROCKS As Char = "X"
Const FIELDLENGTH As Integer = 20
Const FIELDWIDTH As Integer = 35
The user can choose how long they want to run the simulation for. A prompt asks
the user to select a number between 0 and 5, but no validation is present.
The function returns years as an integer, and simulation()
has to decide what
to do with the year.
Function GetHowLongToRun() As Integer
Dim Years As Integer
Console.WriteLine("Welcome to the Plant Growing Simulation")
Console.WriteLine()
Console.WriteLine("You can step through the simulation a year at a time")
Console.WriteLine("or run the simulation for 0 to 5 years")
Console.WriteLine("How many years do you want the simulation to run?")
Console.Write("Enter a number between 0 and 5, or -1 for stepping mode: ")
Years = Console.ReadLine()
Return Years
End Function
If the user chooses not to load their field from a file in InitialiseField()
or if the file they select in ReadFile()
is not an accesible a new field is
generated. An array called Field
stores the field as chars. The array
contains many other arrays, making it two dimentsional. A visualisation of the
array's two dimensional nature follows:
[
[ ..P....... ]
[ .S...S.... ]
[ ....P..X.. ]
[ .P....S... ]
[ ...X...P.. ]
]
The earlier global constants determine the size of the array; the length
determines the number of second-level arrays (y-axis) and the width determines
the size of each second-level array (x-axis). Initially, every item in the
array has the value SOIL
. The central location is determined by floor
dividing the field size by two. The central location then determines the
initial seed location.
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = SOIL
Next
Next
Row = FIELDLENGTH \ 2
Column = FIELDWIDTH \ 2
Field(Row, Column) = SEED
Return Field
End Function
If the user wants to load an existing file this function asks them to enter the
file location, and attempts to read the file. If a file is not found or if the
file is not accesible a new file is generated using the CreateNewField()
sub.
The user is not informed if a new field is created. If a file is found it is
stored in an array called Field
, as explained earlier.
Function ReadFile() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim FileName As String
Dim FieldRow As String
Dim FileHandle As IO.StreamReader
Console.Write("Enter file name: ")
FileName = Console.ReadLine()
Try
FileHandle = New IO.StreamReader(FileName)
For Row = 0 To FIELDLENGTH - 1
FieldRow = FileHandle.ReadLine
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = FieldRow(Column)
Next
Next
FileHandle.Close()
Catch
Field = CreateNewField()
End Try
Return Field
End Function
A prompt asks the user if they want to load an already existing file. If they choose not to, a new field is generated.
Function InitialiseField() As Char(,)
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim Response As String
Console.Write("Do you want to load a file with seed positions? (Y/N): ")
Response = Console.ReadLine()
If Response = "Y" Then
Field = ReadFile()
Else
Field = CreateNewField()
End If
Return Field
End Function
Shows information about the current state of the simulation. The information shown is the:
- Current Season
- Current Year
- Field with row numbers
The PadLeft
adds spaces to the left part of the row number. This means the
string will always finish in the third column, like this:
8|
9|
10|
11|
Finishing in the third column allows up to 99 rows to be shown easily.
Sub Display(ByVal Field(,) As Char, ByVal Season As String, ByVal Year As Integer)
Dim Row As Integer
Dim Column As Integer
Console.WriteLine("Season: " & Season & " Year number: " & Year)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Console.Write(Field(Row, Column))
Next
Console.WriteLine("|" & Str(Row).PadLeft(3))
Next
Console.WriteLine()
End Sub
Works out the number of plants in the simulation. It iterates through each item
in the field uing a standard field iterator and checks if the item is a plant.
If the item is a plant it increments NumberOfPlants
. The number of plants is
then displayed. The if/then statement makes sure the grammar is correct.
Sub CountPlants(ByVal Field(,) As Char)
Dim Row As Integer
Dim Column As Integer
Dim NumberOfPlants As Integer
NumberOfPlants = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
NumberOfPlants += 1
End If
Next
Next
If NumberOfPlants = 1 Then
Console.WriteLine("There is 1 plant growing")
Else
Console.WriteLine("There are " & NumberOfPlants & " plants growing")
End If
End Sub
There are four seasons (#the more you know):
- Spring: Every seed grows into a plant. If frost occurs every third plant dies.
- Summer: If drought occurs every second plant dies.
- Autumn: All plants drop seeds into adjacent cells.
- Winter: All plants die.
In spring all seeds grown into plants. CountPlants()
the displays the number
of plants. A random number generator determines the occurance of frost. If
frost occurs every third plants dies. A display informs the user about the
frost, and CountPlants()
displays the number of plants again.
Function SimulateSpring(ByVal Field As Char(,)) As Char(,)
Dim Frost As Boolean
Dim PlantCount As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = SEED Then
Field(Row, Column) = PLANT
End If
Next
Next
CountPlants(Field)
If Int(Rnd() * 2) = 1 Then
Frost = True
Else
Frost = False
End If
If Frost Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 3 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a frost")
CountPlants(Field)
End If
Return Field
End Function
A random number generator determines the amount of rainfall. If the amount of
rainfall is low every second plant dies and a display shows the occurance of
the drought. CountPlants()
shows the number of plants. If a drought does not
occur the number of plants is not displayed because the field is not affected.
Function SimulateSummer(ByVal Field(,) As Char) As Char(,)
Dim RainFall As Integer
Dim PlantCount As Integer
RainFall = Int(Rnd() * 3)
If RainFall = 0 Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 2 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a severe drought")
CountPlants(Field)
End If
Return Field
End Function
Creates seeds. The function takes a location and checks if it is on the field. If the location is on the field a seed is placed on the corresponding location on the array.
Function SeedLands(ByVal Field(,) As Char, ByVal Row As Integer, ByVal Column As Integer) As Char(,)
If Row >= 0 And Row < FIELDLENGTH And Column >= 0 And Column < FIELDWIDTH Then
If Field(Row, Column) = SOIL Then
Field(Row, Column) = SEED
End If
End If
Return Field
End Function
A seed is dropped on every location around a plant. Each location is passed to
SeedLands()
, which checks if the location is on the field, and plants seeds
on on-field locations.
Function SimulateAutumn(ByVal Field(,) As Char) As Char(,)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If FieldRow, Column) = PLANT Then
Fiel = SeedLands(Field, Row - 1, Column - 1)
Fiel = SeedLands(Field, Row - 1, Column)
Fiel = SeedLands(Field, Row - 1, Column + 1)
Fiel = SeedLands(Field, Row, Column - 1)
Fiel = SeedLands(Field, Row, Column + 1)
Fiel = SeedLands(Field, Row + 1, Column - 1)
Fiel = SeedLands(Field, Row + 1, Column)
Fiel = SeedLands(Field, Row + 1, Column + 1)
End If
Next
Next
Return Field
End Function
Kills all plants.
Function SimulateWinter(ByVal Field As Char(,)) As Char(,)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
Field(Row, Column) = SOIL
End If
Next
Next
Return Field
End Function
The four season functions together simualte an entire year because a year has
four seasons. After each month the Display()
sub displays the state of the
simulation.
Sub SimulateOneYear(ByVal Field(,) As Char, ByVal Year As Integer)
Field = SimulateSpring(Field)
Display(Field, "spring", Year)
Field = SimulateSummer(Field)
Display(Field, "summer", Year)
Field = SimulateAutumn(Field)
Display(Field, "autumn", Year)
Field = SimulateWinter(Field)
Display(Field, "winter", Year)
End Sub
Main function of the simulation. A prompt asks the user to input how long to
run the simulation. The sub initializes the field if YearsToRun
is not 0.
Initialization occurs by asking the user if they want to generate a new field
or use an existing one. If the field they choose nonexistant or invalid a new
field is generated anyway. If the YearsToRun
is not -1
the simulation runs
however many times. The simulation enters stepping mode if YearsToRun
is
-1
. The simulation goes one year at a time until the user chooses to exit
using "x" or "X". The user informed when the simulation finished.
Sub Simulation()
Dim YearsToRun As Integer
Dim Continuing As Boolean
Dim Response As String
Dim Year As Integer
Dim Field(FIELDWIDTH, FIELDLENGTH) As Char
YearsToRun = GetHowLongToRun()
If YearsToRun <> 0 Then
Field = InitialiseField()
If YearsToRun >= 1 Then
For Year = 1 To YearsToRun
SimulateOneYear(Field, Year)
Next
Else
Continuing = True
Year = 0
While Continuing
Year += 1
SimulateOneYear(Field, Year)
Console.Write("Press Enter to run simulation for another Year, Input X to stop: ")
Response = Console.ReadLine()
If Response = "x" Or Response = "X" Then
Continuing = False
End If
End While
End If
Console.WriteLine("End of Simulation")
End If
Console.ReadLine()
End Sub
Main procedure. Reseeds random number generator to provide different numbers
each time and starts Simulation()
, which handles the simulations.
Sub Main()
Randomize()
Simulation()
End Sub
Name | Type | Description |
---|---|---|
SOIL |
Char | Stores the character to represent soil: ". " |
SEED |
Char | Stores the character to represent seeds: "S " |
PLANT |
Char | Stores the character to represent plants: "P " |
ROCKS |
Char | Stores the character to represent rocks: "X " |
FIELDLENGTH |
Integer | Stores length the of the field, which is 20 by default |
FIELDWIDTH |
Integer | Stores width the of the field, which is 35 by defualt |
I have not included location of decleration for these variables because the program may declare them in multiple routines.
Variable name | Type | Description |
---|---|---|
Column |
Integer | Used to hold a selected column, often within a field iterator |
Continuing |
Boolean | Indicates continuation within Simulation() |
Field(,) |
2-D Char array | Holds the field. Every entry is a seperate cell on the field |
FieldName |
String | Holds the name of the field when reading it in ReadFile |
FieldRow |
String | Stores each line read in from ReadFile |
Frost |
Boolean | Describes if a frost has occured |
NumberOfPlants |
Integer | Counts the number of plants on the field |
PlantCount |
Integer | Used in SimulateSummer() and SimulateWinter() to effect every n-th plant |
Rainfall |
Integer | Models ammount of rain in SimulateSummer() |
Response |
String | Holds user response to questions |
Row |
Integer | Used to hold a selected row, often within a field iterator |
Year |
Integer | Holds the year of simulation |
Years |
Integer | Holds the total number of years to run |
YearsToRun |
Integer | Holds the total number of years to run |
Name | Type | Description |
---|---|---|
CountPlants |
procedure | Counts and diplays the number of plants on the field |
CreateNewField |
function | Creates a new field, with only a seed at the center |
Display |
procedure | Displays the field along wiht key statistics |
GetHowLongToRun |
function | Asks the user for how long to run the simulation |
InitialiseField |
function | Generate new field or read from file |
Main |
function | Reseeds random number generator and calls other subs |
ReadFile |
function | Reads field from file |
SeedLands |
function | Plants seeds in given locations |
SimulateAutumn |
function | Simulates autumn |
SimulateOneYear |
procedure | Simulates a year by calling other simulators |
SimulateSpring |
function | Simulates spring |
SimulateSummer |
function | Simulates summer |
SimulateWinter |
function | Simulates winter |
Simulation |
procedure | Does everything |
Table giving important details about each function:
Name | Type | Recieves | Returns | Called from |
---|---|---|---|---|
CountPlants |
Procedure | Field(,) |
SimulateSpring , SimulateSummer |
|
CreateNewField |
Function | Field(,) |
Readfile , InitialiseField |
|
Display |
Procedure | Field(,) , Season , Year |
SimulateOneYear |
|
GetHowLongToRun |
Function | Years |
Simulation |
|
InitialiseField |
Function | Field(,) |
Simulations |
|
Main |
Function | N/A | ||
ReadFile |
Function | Field(,) |
InitialiseField |
|
SeedLands |
Function | Field , Row , Column |
Field(,) |
SimulateAutumn |
SimulateAutumn |
Function | Field(,) |
Field(,) |
SimulateOneYear |
SimulateOneYear |
Procedure | Field(,) , Year |
Simulation |
|
SimulateSpring |
Function | Field(,) |
Field(,) |
SimulateOneYear |
SimulateSummer |
Function | Field(,) |
Field(,) |
SimulateOneYear |
SimulateWinter |
Function | Field(,) |
Field(,) |
SimulateOneYear |
Simulation |
Procedure | Main |
Thisi s a collection of code snippets that may help during the exam.
This iterates through every cell in the field. The standard field iterator iterates through every cell by using the literal 0 and the size constants.
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
' Some code
Next
Next
Reusing the code allows a row iterator to iterate through rows:
Row = 17
For Column = 0 To FIELDWIDTH - 1
' Some code, may include Field(Row, Column)
Next
A column iterator can be made in the same way:
Column = 17
For Row = 0 To FIELDLENGTH - 1
' Some code, may include Field(Row, Column)
Next
This goes through every cell around an origin cell.
For CheckRow = Row - 1 To Row + 1
For CheckRow = Column - 1 To Column + 1
' [Some code]
Next
Next
Note that this will iterate through the origin cell. To avoid this compare the location with the origin location, and do the code inside if they do not match.
For CheckRow = Row - 1 To Row + 1
For CheckRow = Column - 1 To Column + 1
If Field(Row, Column) <> Field(CheckRow, CheckRow) Then
' [Some code]
End If
Next
Next
Using these methods avoids having chunks of code like SimulateAutumn()
:
Function SimulateAutumn(ByVal Field(,) As Char) As Char(,)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
Field = SeedLands(Field, Row - 1, Column - 1)
Field = SeedLands(Field, Row - 1, Column)
Field = SeedLands(Field, Row - 1, Column + 1)
Field = SeedLands(Field, Row, Column - 1)
Field = SeedLands(Field, Row, Column + 1)
Field = SeedLands(Field, Row + 1, Column - 1)
Field = SeedLands(Field, Row + 1, Column)
Field = SeedLands(Field, Row + 1, Column + 1)
End If
Next
Next
Return Field
End Function
This iterator can also go through cells two cells near the origin:
For CheckRow = Row - 2 To Row + 2
For CheckRow = Column - 2 To Column + 2
' [Some code]
Next
Next
Always use field bounds validator to avoid outOfBounds
errors.
I stole this snippet from SeedLands()
:
If Row >= 0 And Row < FIELDLENGTH And Column >= 0 And Column < FIELDWIDTH Then
' [Code goes here]
End If
This can simplified to eease unserstanding:
Dim ConditionRow as Boolean = Row >= 0 And Row < FIELDLENGTH
Dim ConditionColumn as Boolean = Column >= 0 And Column < FIELDWIDTH
If ConditionRow And ConditionColumn Then
' [Code goes here]
End If
The windows command line is black by default. This may make it difficult to read command line content after printing the EAD. Making the command line's background white reduces the problem.
-
Add a simple
Console.Readline
to the source code to prevent the terminal window from closing. -
Open a terminal window using
f5
. -
Right click on the title bar. The title bar is the top part of the window:
+----------------------------------------------------+ | This section is the title bar _X | +----------------------------------------------------+ | | | This is the window's content. | | | | | | | | | | | | | | | +----------------------------------------------------+
-
From the menu that now appears select
properties
. A new window should appear. Select the last tab, calledcolors
. Change the background colour to white and the text colour to black.
Useselect case statements rather than if/then statements. This results in much
cleaner code. Declare th statement using Select Case [variableBeingCompared]
.
Compare the following if/then statement:
If UserEnteredNumber = "one" Then
ActualNumber = 1
Else If UserEnteredNumber = "two" Then
ActualNumber = 2
Else If UserEnteredNumber = "three" Then
ActualNumber = 3
Else If UserEnteredNumber = "four" Then
ActualNumber = 4
Else If UserEnteredNumber = "five" Then
ActualNumber = 5
Else If UserEnteredNumber = "six" Then
ActualNumber = 6
Else If UserEnteredNumber = "ten" Then
ActualNumber = 10
Else
ActualNumber = 0
With this case/select statement equivilant:
Case Select UserEnteredNumber
Case "one"
ActualNumber = 1
Case "two"
ActualNumber = 2
Case "three"
ActualNumber = 3
Case "four"
ActualNumber = 4
Case "five"
ActualNumber = 5
Case "six"
ActualNumber = 6
Case Else
ActualNumber = 0
End Select
The case select statement is easier to read, and would be easier to maintain in the exam.
Visual basic uses the UpperCamelCase (PascalCase) convetion. This involves joining strings of words into compound words, where each word starts with a capital letter.
This convention exists as comilers and interperators may consider spaces as seperators between tokens. Early languages including Lisp and COBOL allowed dashes (-) between words of identifiers (kebab-case). However, this was not acceptable in mathematical languages like FORTRAN where the hyphen is the subtraction symbol. The problems were exagerated by punchcards often supporting only capital letters and no symbols. In the late 1960s ASCII became more common, and terminals made writing code easier and more flexible. This allowed programmers to use uppercase and lowercase letters together. It also introduced the underscorce character (_). Some languages like C (and now C-influenced languages like Perl and Python) chose to seperate words using snake_case because the underscores look like whitespace, and this made code easier to read. Other programmers chose to use camelCase or UpperCamelCase, as they did not want what could be confused for whitespace in their variable names. Constants are often identified by their all-caps nature. Here are some examples of the same code in different languages with different conventions:
Python with snake_case.
def find_identifier_from_list(text_argument):
# Example of snake_case in python:
the_important_list = [1, 2, 3, 4, 5]
print(text_argument)
identifier_we_want = input("What identifier do you want to look for?")
if identifier_we_want in the_important_list:
identifier_in_list = True
else:
identifier_in_list = False
return identifier_in_list
VisualBasic with PascalCase.
Function FindIdentifierFromList(ByVal TextArgument As String)
' Example of UpperCamelCase in visualBasic:
Dim TheImportantList As Integer = [1, 2, 3, 4, 5] ' TODO: make this work.
Dim IdentifierWeWant As String
Dim IdentifierInList As Boolean
Console.Writeline(TextArgument)
Console.Writeline("What identifier do you want to look for?")
IdentifierWeWant = Console.Readline()
If TheImportantList.Contains(IdentifierWeWant) Then
IdentifierInList = True
Else
IdentifierInList = False
End If
Return IdentifierInList
End Function
JavaScript with camelCase.
// Example of camelCase in JavaScript:
function findIdentifierFromList(textArgument) {
var theImportantList = [1, 2, 3, 4, 5];
console.log(textArgument);
console.log("What identifier do you want to look for?");
var identifierWeWant = readline();
if (theImportantList.indexOf(identifierWeWant) >= 0) {
identifierInList = true;
} else {
identifierInList = false;
};
return identifierInList;
}
Lisp with kebab-case (this is not the greatest example but lisp is a functional language).
(member (read-string "What identifier do you want to look for?") '(1 2 3 4 5))
Choosing which variable naming scheme to use is largely down to convention. Following a language's convention is important as it allows multiple developers to work on the same code with minimal friction. In the exam all variables, subs and functions should be in UpperCamelCase because the code was orignally written with in UpperCamelCase.
Incrementing a variable involves increasing its value by 1. It ma be used in a counter, for example to count the number of coccurances of a thing. There are two ways to increment a value.
The proper way looks as follows:
Dim NumberOfIterations As Integer
For i = 1 to 10
NumberOfIterations += 1
Next
The wrong way looks like this:
Dim NumberOfIterations As Integer
For i = 1 to 10
NumberOfIterations = NumberOfIterations + 1
Next
Using the proper incrementing method allows easier maintainance and makes
debugging easier. Decrementation works in the same way using the -=
operator.
These are my solutions to questions that may appear in the exams. They may not be perfect.
These tasks concern question 8 (6 marks) and question 9 (3 marks).
This will randomly generate rocks when creating the field. It functions by generating a random number for each cell. The number is then multiplied by 15 and converted into an integer (effectively rounding it). The value can be modified to increase or reduce the chance of rocks. If the rounded value is a 0 the function places a rock, otherwise it places soil.
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim ChanceOfRock As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
ChanceOfRock = Int(Rnd() * 15)
If ChanceOfRock = 0 Then
Field(Row, Column) = ROCKS
Else
Field(Row, Column) = SOIL
End If
Next
Next
Row = FIELDLENGTH \ 2
Column = FIELDWIDTH \ 2
Field(Row, Column) = SEED
Return Field
End Function
An alterantive method is to generate the field first, then iterate through each cell sperateley (but y dou?).
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim ChanceOfRock As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = SOIL
Next
Next
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
ChanceOfRock = Int(Rnd() * 15)
If ChanceOfRock = 0 Then
Field(Row, Column) = ROCKS
End If
Next
Next
Row = FIELDLENGTH \ 2
Column = FIELDWIDTH \ 2
Field(Row, Column) = SEED
Return Field
End Function
The exception handler already handles missing files. Adding code to the exception handler allows displaying a message when errors occur.
Function ReadFile() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim FileName As String
Dim FieldRow As String
Dim FileHandle As IO.StreamReader
Console.Write("Enter file name: ")
FileName = Console.ReadLine()
Try
FileHandle = New IO.StreamReader(FileName)
For Row = 0 To FIELDLENGTH - 1
FieldRow = FileHandle.ReadLine
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = FieldRow(Column)
Next
Next
FileHandle.Close()
Catch
Console.WriteLine("File not found, generating new field.")
Field = CreateNewField()
End Try
Return Field
End Function
For summer, we can ask the user about the amount of rainfall.
Function SimulateSummer(ByVal Field(,) As Char) As Char(,)
Dim RainFall As Integer
Dim PlantCount As Integer
Console.Writeline("How much rainfall has there been?")
RainFall = Console.Readline
If RainFall = 0 Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 2 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a severe drought")
CountPlants(Field)
End If
Return Field
End Function
We can also directly ask about disaster occurance and save the response as a boolean.
Function SimulateSummer(ByVal Field(,) As Char) As Char(,)
Dim Drought As Boolean
Dim PlantCount As Integer
Console.Writeline("Has there been a drought?")
Drought = Console.Readline
If Drought = True Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 2 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a severe drought")
CountPlants(Field)
End If
Return Field
End Function
Frost is done in a similar way:
Function SimulateSpring(ByVal Field As Char(,)) As Char(,)
Dim Frost As Boolean
Dim PlantCount As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = SEED Then
Field(Row, Column) = PLANT
End If
Next
Next
Console.writeline("Has there been frost?")
Frost = Console.Readline
If Frost Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 3 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a frost")
CountPlants(Field)
End If
Return Field
End Function
The number of years should be between -1 and 5 with appropriate error message.
A Do...Loop
ends when Years
is a valid number of years. The do loop will
display its contents at least once. The message is displayed if the number of
years is not valid. The if statement will display a message if the number of
years entered is not valid.
Function GetHowLongToRun() As Integer
Dim Years As Integer
Console.WriteLine("Welcome to the Plant Growing Simulation")
Console.WriteLine()
Console.WriteLine("You can step through the simulation a year
at a time")
Console.WriteLine("or run the simulation for 0 to 5 years")
Do
Console.WriteLine("How many years do you want the simulation to run?")
Console.Write("Enter a number between 0 and 5, or -1 for stepping mode: ")
Years = Console.ReadLine()
If 0 > Years Or Years > 5 Then
Console.WriteLine("Please enter a number between -1 and 5")
End If
Loop Until -1 <= Years And Years <= 5
Return Years
End Function
A simplified version can only validate the number of years being bellow 6:
Function GetHowLongToRun() As Integer
Dim Years As Integer
Console.WriteLine("Welcome to the Plant Growing Simulation")
Console.WriteLine()
Console.WriteLine("You can step through the simulation a year at a time")
Console.WriteLine("or run the simulation for 0 to 5 years")
Do
Console.WriteLine("How many years do you want the simulation to run?")
Console.Write("Enter a number between 0 and 5, or -1 for stepping mode: ")
Years = Console.ReadLine()
If 0 > Years Or Years > 5 Then
Console.WriteLine("Please enter a number between -1 and 5")
End If
Loop Until Years <= 5
Return Years
End Function
Since global constants control the field size changing their values on decleration will affect all instances. The constants retain their value throughout the program since the constants have a global scope.
Const FIELDLENGTH As Integer = 3
Const FIELDWIDTH As Integer = 1337
This example prompts the user to enter the row and column to plant the seed on. A plants is the planted on the field location corresponding to the input.
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = SOIL
Next
Next
Console.WriteLine("Please enter row to plants seed on")
Row = Console.ReadLine
Console.WriteLine("Please enter column to plant seed on")
Column = Console.ReadLine
Field(Row, Column) = SEED
Return Field
End Function
The following examples adapts the above code to validate the input. The loop terminates once the input row and column are valid.
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = SOIL
Next
Next
Do
Console.WriteLine("Please enter row to plants seed on")
Row = Console.ReadLine
Console.WriteLine("Please enter column to plant seed on")
Column = Console.ReadLine
If 0 > Years Or Years > 5 Then
Console.WriteLine("Please enter a number between -1 and 5")
End If
Loop Until 0 <= Row <= FIELDLENGTH And 0 <= Column <= FIELDWIDTH
Field(Row, Column) = SEED
Return Field
End Function
This example will ask the user to choose if they want to choose the start location.
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim SeedLocationChoice As String
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = SOIL
Next
Next
Console.Write("Would you like to choose your initial seed location? (Y/N)")
SeedLocationChoice = Console.ReadLine
If SeedLocationChoice = "Y" Then
Do
Console.WriteLine("Please enter row to plants seed on")
Row = Console.ReadLine
Console.WriteLine("Please enter column to plant seed on")
Column = Console.ReadLine
Loop Until 0 <= Row <= FIELDLENGTH And 0 <= Column <= FIELDWIDTH
Else
Row = FIELDLENGTH \ 2
Column = FIELDWIDTH \ 2
End If
Field(Row, Column) = SEED
Return Field
End Function
The only modification in this case is FileName = Console.ReadLine() + ".txt"
.
This will append .txt
to the end of the end of the entered file name.
Function ReadFile() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim FileName As String
Dim FieldRow As String
Dim FileHandle As IO.StreamReader
Console.Write("Enter file name: ")
FileName = Console.ReadLine() + ".txt"
Try
FileHandle = New IO.StreamReader(FileName)
For Row = 0 To FIELDLENGTH - 1
FieldRow = FileHandle.ReadLine
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = FieldRow(Column)
Next
Next
FileHandle.Close()
Catch
Console.WriteLine("That's not a valid file")
Field = CreateNewField()
End Try
RunLengthString(Field)
Return Field
End Function
Modifying the message for the user will simplif their lives.
Function ReadFile() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim FileName As String
Dim FieldRow As String
Dim FileHandle As IO.StreamReader
Console.Write("Enter file name (without .txt): ")
FileName = Console.ReadLine() + ".txt"
Try
FileHandle = New IO.StreamReader(FileName)
For Row = 0 To FIELDLENGTH - 1
FieldRow = FileHandle.ReadLine
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = FieldRow(Column)
Next
Next
FileHandle.Close()
Catch
Console.WriteLine("That's not a valid file")
Field = CreateNewField()
End Try
RunLengthString(Field)
Return Field
End Function
InitialiseField()
will reject lowercase y
s. The easiest way to avoid this
is to turn the input into all caps using the .ToUpper
method.
Function InitialiseField() As Char(,)
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim Response As String
Console.Write("Do you want to load a file with seed positions? (Y/N): ")
Response = Console.ReadLine().ToUpper()
If Response = "Y" Then
Field = ReadFile()
Else
Field = CreateNewField()
End If
Return Field
End Function
The if then statement can also be modified to compare Response
to both the
uppercase and lowercase y
.
Function InitialiseField() As Char(,)
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim Response As String
Console.Write("Do you want to load a file with seed positions? (Y/N): ")
Response = Console.ReadLine()
If Response = "Y" Or Response = "y" Then
Field = ReadFile()
Else
Field = CreateNewField()
End If
Return Field
End Function
The same techniques can be used for CreateNewField()
aswell.
Function CreateNewField() As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim Field(FIELDLENGTH, FIELDWIDTH) As Char
Dim SeedLocationChoice As String
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Field(Row, Column) = SOIL
Next
Next
Console.Write("Would you like to choose your initial seed location? (Y/N)")
SeedLocationChoice = Console.ReadLine.ToUpper()
If SeedLocationChoice = "Y" Then
Do
Console.WriteLine("Please enter row to plants seed on")
Row = Console.ReadLine
Console.WriteLine("Please enter column to plant seed on")
Column = Console.ReadLine
Loop Until 0 <= Row <= FIELDLENGTH And 0 <= Column <= FIELDWIDTH
Else
Row = FIELDLENGTH \ 2
Column = FIELDWIDTH \ 2
End If
Field(Row, Column) = SEED
Return Field
End Function
Some summers are good. If RainFall
is high the plants will be able to drop
more seeds. I reused SimulateAutumn()
as it already does this. Every seed
then grows into a plant.
Function SimulateSummer(ByVal Field(,) As Char) As Char(,)
Dim RainFall As Integer
Dim PlantCount As Integer
RainFall = Int(Rnd() * 3)
If RainFall = 0 Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 2 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a severe drought")
CountPlants(Field)
ElseIf RainFall = 2 Then
Field = SimulateAutumn(Field)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = SEED Then
Field(Row, Column) = PLANT
End If
Next
Next
Console.WriteLine("There has been a successful summer")
End If
Return Field
End Function
Using this mod alongside the overpopulation simulation mod reuslts in all plants dying. Like capitalists, the plants will grow until they can't sustain themselves, and then they all die.
One way to avoid these problems is to limit opourtunity for most plants, and only allow the priveleged plants to grow.
Function SimulateSummer(ByVal Field(,) As Char) As Char(,)
Dim RainFall As Integer
Dim PlantCount As Integer
RainFall = Int(Rnd() * 3)
If RainFall = 0 Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 2 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a severe drought")
CountPlants(Field)
ElseIf RainFall = 2 Then
PlantCount = 0
Field = SimulateAutumn(Field)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = SEED Then
PlantCount += 1
If PlantCount Mod 4 = 0 Then
Field(Row, Column) = PLANT
End If
End If
Next
Next
Console.WriteLine("There has been a successful summer")
End If
Return Field
End Function
If the RainFall is 2, the program informs the user there has been a flood.
Every 4th plant turns back in to soil. By expanding the if/then statement we
can check if Rainfall
is 2. The code within the block is mostly the same as
the first code block. The modulo operation on PlantCount
uses 4 instead of 2
to kill every fourth plant instead of second, and the message for the user
informs them about a flood rather than a drought.
Function SimulateSummer(ByVal Field(,) As Char) As Char(,)
Dim RainFall As Integer
Dim PlantCount As Integer
RainFall = Int(Rnd() * 3)
If RainFall = 0 Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 2 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a severe drought")
CountPlants(Field)
ElseIf RainFall = 2 Then
PlantCount = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
PlantCount += 1
If PlantCount Mod 4 = 0 Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Console.WriteLine("There has been a flood")
CountPlants(Field)
End If
Return Field
End Function
These tasks concern question 10 (11 marks) and question 11 (13 marks).
It will start by asking the user for what row they want to encode. The variable
currentCharacter
is then given the value of the first item in the row. A do
loop that will terminate when the last column is reached is used to iterate
through each cell. An if/then statement will check if the current cell is the
same as the currentCharacter
, and wiill iterate numberOfCharacter
if true.
The column is then also iterated by one. If the character is different The
previous number of the previous sequence of chacters is displayed alongside the
character. The numberOfCharacter
is reset to 0, and the currentCharacter
is
set to whichever character is now the subject. Call this sub is called when the
user loads the field from a text file.
Sub RunLengthString(ByVal Field(,) As Char)
Dim row As Integer
Dim column As Integer = 0
Dim currentCharacter As String
Dim numberOfCharacter As Integer = 0
Console.WriteLine("Which row would you like to encode?")
row = Console.ReadLine
currentCharacter = Field(row, column)
Do
If Field(row, column) = currentCharacter Then
numberOfCharacter += 1
column += 1
Else
Console.Write(currentCharacter & numberOfCharacter)
numberOfCharacter = 0
currentCharacter = Field(row, column)
End If
Loop Until column = FIELDWIDTH - 1
Console.Write(currentCharacter & numberOfCharacter)
Console.WriteLine()
End Sub
The first 6 lines initialize variables. A standard field iterator iterates
through every cell on the field. A select case statement check each cell's
type, and iterates a counter for that type. The number of each value is then
displayed. Call this sub at the end of the Display()
using
DisplayStatistics(Field)
.
Sub DisplayStatistics(ByVal Field(,) As Char)
Dim Row As Integer
Dim Column As Integer
Dim NumberOfRocks As Integer = 0
Dim NumberOfPlants As Integer = 0
Dim NumberOfSoil As Integer = 0
Dim NumberOfSeeds As Integer = 0
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Select Case Field(Row, Column)
Case ROCKS
NumberOfRocks += 1
Case PLANT
NumberOfPlants += 1
Case SEED
NumberOfSeeds += 1
Case SOIL
NumberOfSeeds += 1
End Select
Next
Next
Console.WriteLine("Statistics:")
Console.WriteLine(" Number of plants: " & NumberOfPlants)
Console.WriteLine(" Number of rocks: " & NumberOfRocks)
Console.WriteLine(" Number of soils: " & NumberOfSoil)
Console.WriteLine(" Number of seeds: " & NumberOfSeeds)
Console.WriteLine()
End Sub
The bird will then eat all the seed in a user-selected row. The program prompts
the user to select a row for the bird to eat. A row iterator then iterates
through all user-selected rows. All seeds are then turned into soil.
NumberOfSeedsEaten
iterates every time the bird eats a seed. Call this
function after SimulateWinter
but before Display
in SimulateOneYear
.
Function BirdFeeds(ByVal Field As Char(,)) As Char(,)
Dim row As Integer
Dim NumberOfSeedsEaten As Integer = 0
Console.WriteLine("Which row does the bird eat?")
row = Console.ReadLine
For Column = 0 To FIELDWIDTH - 1
If Field(row, Column) = SEED Then
Field(row, Column) = SOIL
NumberOfSeedsEaten += 1
End If
Next
Console.WriteLine(" Number of seeds eaten: " & NumberOfSeedsEaten)
Return Field
End Function
This will turn every cell around the origin to soil unless there is rock. The
program prompts the user to enter the origin of the forest fire. An adjacency
iterator then iterates through two cells around the origin cell. field bounds
validator makes sure it is on the field. If the location is on the field and on
the field it is brutally killed. Call this after the SimulateSummer
call in
SimulateOneYear
.
Function ForestFire(ByVal Field(,) As Char) As Char(,)
Dim Row As Integer
Dim Column As Integer
Console.WriteLine("What Row does the forest fire originate at?")
Row = Console.ReadLine
Console.WriteLine("What Column does the forest fire originate at?")
Column = Console.ReadLine
For CheckRow = Row - 2 To Row + 2
For CheckColumn = Column - 2 To Column + 2
If CheckRow >= 0 And CheckRow < FIELDLENGTH And CheckColumn >= 0 And CheckColumn < FIELDWIDTH Then
If Field(Row, Column) = PLANT Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Return Field
End Function
This modificaion will count the number of plants killed:
Function ForestFire(ByVal Field(,) As Char) As Char(,)
Dim Row As Integer
Dim Column As Integer
Dim NumberOfPlants As Integer
Console.WriteLine("What Row does the forest fire originate at?")
Row = Console.ReadLine
Console.WriteLine("What Column does the forest fire originate at?")
Column = Console.ReadLine
For CheckRow = Row - 2 To Row + 2
For CheckColumn = Column - 2 To Column + 2
If CheckRow >= 0 And CheckRow < FIELDLENGTH And CheckColumn >= 0 And CheckColumn < FIELDWIDTH Then
If Field(Row, Column) = PLANT Then
Field(Row, Column) = SOIL
NumberOfPlants += 1
End If
End If
Next
Next
Console.Writeline("A forest fire killed " & NumberOfPlants & " plants.")
Return Field
End Function
Growth for the sake of growth is the ideology of a cancer cell - Edward Abbey
In the blistering heat of the late summer resources being to run low. Plants with more than 4 neighbours cannot fight off starvation, and crowds begin to die off in mass starvation.
A seperate function called OverPopulation
will takes Field
in the standard
way. A variable called NumberOfSurroundingPlants
will hold the number of
plants surrounding each plant in the array. Every cell matches a cell in
Field
. I've used an extra array because killing plants as they are counted
will favour the bottom left.
A standard field iterator is then used to iterate through each cell. If any
cell is a plant an adjacency iterator is then introduce to loop through the
cells around the plant. A field bounds validator will validate the location. If
the location is on the field a an if/then statement checks whether the location
is a plant, and iterates NumberOfSurroundingPlants
if it is.
Once the loop terminates the program compares each value from
NumberOfSurroundingPlants
with MaximumNumberOfSurroundingPlants + 1
(the + 1
takes the origin cell into account). If the number of surrounding plants
goes over the limit the plant dies.
Call this function at the end of SimulateSummer
function using Field = OverPopulation(Field)
.
Function OverPopulation(ByVal Field(,) As Char) As Char(,)
Dim NumberOfSurroundingPlants(FIELDLENGTH, FIELDWIDTH) As Integer
Dim MaximumNumberOfSurroundingPlants As Integer = 4
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
For CheckRow = Row - 1 To Row + 1
For CheckColumn = Column - 1 To Column + 1
If CheckRow >= 0 And Row < FIELDLENGTH And CheckColumn >= 0 And Column < FIELDWIDTH Then
If Field(CheckRow, CheckColumn) = PLANT Then
NumberOfSurroundingPlants(Row, Column) += 1
End If
End If
Next
Next
End If
Next
Next
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If NumberOfSurroundingPlants(Row, Column) > MaximumNumberOfSurroundingPlants + 1 Then
Field(Row, Column) = SOIL
End If
Next
Next
Return Field
End Function
If the validity was not important, you could kill plants during the standard iterator's function. Plants closer to the top-left postion (0, 0) would be more likely to die.
Function OverPopulation(ByVal Field(,) As Char) As Char(,)
Dim NumberOfSurroundingPlants As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
NumberOfSurroundingPlants = 0
For CheckRow = Row - 1 To Row + 1
For CheckColumn = Column - 1 To Column + 1
If CheckRow >= 0 And Row < FIELDLENGTH And CheckColumn >= 0 And Column < FIELDWIDTH Then
If Field(CheckRow, CheckColumn) = PLANT Then
NumberOfSurroundingPlants += 1
End If
End If
Next
Next
If NumberOfSurroundingPlants > 5 Then
Field(Row, Column) = SOIL
End If
Next
Next
Return Field
End Function
A simple modification will count the number of plants killed and display that.
Function OverPopulation(ByVal Field(,) As Char) As Char(,)
Dim NumberOfSurroundingPlants(FIELDLENGTH, FIELDWIDTH) As Integer
Dim NumberOfPlantCasualties As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
For CheckRow = Row - 1 To Row + 1
For CheckColumn = Column - 1 To Column + 1
If CheckRow >= 0 And Row < FIELDLENGTH And CheckColumn >= 0 And Column < FIELDWIDTH Then
If Field(CheckRow, CheckColumn) = PLANT Then
NumberOfSurroundingPlants(Row, Column) += 1
End If
End If
Next
Next
End If
Next
Next
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If NumberOfSurroundingPlants(Row, Column) > 5 Then
Field(Row, Column) = SOIL
NumberOfPlantCasualties += 1
End If
Next
Next
Console.WriteLine("This year " & NumberOfPlantCasualties & " plants died due to overpopulation")
Return Field
End Function
The two final if/then statements can be also joined to one line. I did not do this above because it results in a very long line which may wrap badly (as a rule program lines should not be longer than 80 characters. If they are reduce the amount of indentation or split a single line into multiple lines).
Function OverPopulation(ByVal Field(,) As Char) As Char(,)
Dim NumberOfSurroundingPlants(FIELDLENGTH, FIELDWIDTH) As Integer
Dim MaximumNumberOfSurroundingPlants As Integer = 4
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
For CheckRow = Row - 1 To Row + 1
For CheckColumn = Column - 1 To Column + 1
If CheckRow >= 0 And Row < FIELDLENGTH And CheckColumn >= 0 And Column < FIELDWIDTH And Field(CheckRow, CheckColumn) = PLANT Then
NumberOfSurroundingPlants(Row, Column) += 1
End If
Next
Next
End If
Next
Next
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If NumberOfSurroundingPlants(Row, Column) > MaximumNumberOfSurroundingPlants + 1 Then
Field(Row, Column) = SOIL
End If
Next
Next
Return Field
End Function
Moss can be created to populate rocks. First a new constant for the moss is created. The constant will hold the character representing the moss.
Const SOIL As Char = "."
Const SEED As Char = "S"
Const PLANT As Char = "P"
Const ROCKS As Char = "X"
Const MOSS As Char = "M"
Const FIELDLENGTH As Integer = 20
Const FIELDWIDTH As Integer = 35
A new sub is then created. It will use a standard field iterator to check if any cell is a rock or moss. A random number generator determines the moisture. Moss cannot survive in dry conditions. If the moisture is high enough, the cell rock will have moss grow on it. If the mositure is too low the moss will die. Most of the time the rock is not affected, and the previous conditions will pass along.
Function SimulateMoss(ByVal Field As Char(,)) As Char(,)
Dim Moisture As Integer
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = ROCKS Or Field(Row, Column) = MOSS Then
Moisture = Int(Rnd() * 6)
If Moisture = 5 Or Moisture = 4 Then
Field(Row, Column) = MOSS
ElseIf Moisture = 1 Then
Field(Row, Column) = ROCKS
End If
End If
Next
Next
Return Field
End Function
You can call this every year by placing a call at the end of Display()
:
Sub Display(ByVal Field(,) As Char, ByVal Season As String, ByVal Year As Integer)
Dim Row As Integer
Dim Column As Integer
Console.WriteLine("Season: " & Season & " Year number: " & Year)
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
Console.Write(Field(Row, Column))
Next
Console.WriteLine("|" & Str(Row).PadLeft(3))
Next
Console.WriteLine()
Field = SimulateMoss(Field)
End Sub
To simulate moss after only one season modify SimulateOneYear()
to call
SimulateMoss
. This example uses winter.
Field = SimulateSpring(Field)
Display(Field, "spring", Year)
Field = SimulateSummer(Field)
Display(Field, "summer", Year)
Field = SimulateAutumn(Field)
Display(Field, "autumn", Year)
Field = SimulateWinter(Field)
Field = SimulateMoss(Field)
Display(Field, "winter", Year)
This modification will prevent plant death if the plant is around moss. A
variable called AroundMoss
describes if the plant is around moss or not. It
is initially reset to false for every cell. An adjacency iterator is used to
check if a plant is around moss or not. If any of the cells around it are moss
AroundMoss
s set to true. After the adjacency iterator checks every adjacent
cell and if/then statement checks the state of AroundMoss
and kills the plant
if it is false.
Function SimulateWinter(ByVal Field As Char(,)) As Char(,)
Dim AroundMoss As Boolean
For Row = 0 To FIELDLENGTH - 1
For Column = 0 To FIELDWIDTH - 1
If Field(Row, Column) = PLANT Then
AroundMoss = False
For CheckRow = Row - 1 To Row + 1
For CheckColumn = Column - 1 To Column + 1
If CheckRow >= 0 And CheckRow < FIELDLENGTH And CheckColumn >= 0 And CheckColumn < FIELDWIDTH Then
If Field(CheckRow, CheckColumn) = MOSS Then
AroundMoss = True
End If
End If
Next
Next
If Not AroundMoss Then
Field(Row, Column) = SOIL
End If
End If
Next
Next
Return Field
End Function
Skeleton Program for the AQA A1 Summer 2017 examination
this code should be used in conjunction with the Preliminary Material
written by the AQA AS1 Programmer Team
developed in the VB.Net 2008 environment
Stage : Pre
Version Number : 1.0
Original Author : N Barnes
Edited by : S Langfield
Date of edit : 15 January 2017
Thanks to Dr. Smith for teaching me the ways of Visual Basic.
Lists of useful stuff, sorted by how much I like each site.
Programming is slighly important for a programming exam.
- Project Euler, has maths problems that should be solved using programs.
- Hackerrank, sets challenges to solve.
- Exercism, sets excercises through the command line.
- Learn Visual Basic in Y minutes, example code meant to teach the entire language.
- Top Visual Basic github repositories, show how code is used in real life.
- Visual Basic Essentials.
- Microsoft's Visual Basic guide.
- Beginning Visual Basic 2008.
- Visual Basic 2005 for dummies.
- Visual Basic 2005 express for dummies.
- Codewars, programming challenges.
- Free code camp, frontend and backend development course for professional programmers.
- Codecademy, sets tasks and shows how to solve them.
These are the OCR-supplied files.
Other things.
- Comp Franklin videos, has many computer science videos.
- Gentoomen library, contains a ton of information on all topics.
- Mono project, because visual studio is windows-only.
- Awesome lists
- Github free E-Books
Notes for 2017 AS-Level Computer Science Skeleton program (VB) by Awes Mubarak is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.