# Code

'***************************************************************************************
'Import FCL390
'Sample program to demonstate the use of arrays
'An array is a list of related data that can be added to, deleted from, modified and accessed to perform a task
'***************************************************************************************
TextWindow.Show()
'
'An array of numbers, we want to store odd raddom numbers
'
'The hard way without arrays
num1 = 1+2*Math.GetRandomNumber(100)
num2 = 1+2*Math.GetRandomNumber(100)
num3 = 1+2*Math.GetRandomNumber(100)
num4 = 1+2*Math.GetRandomNumber(100)
num5 = 1+2*Math.GetRandomNumber(100)
output = "Five random odd numbers stored the hard way"
comment()
TextWindow.WriteLine(num1)
TextWindow.WriteLine(num2)
TextWindow.WriteLine(num3)
TextWindow.WriteLine(num4)
TextWindow.WriteLine(num5)
next()
'The easy way with arrays
For i = 1 To 10
numi = 1+2*Math.GetRandomNumber(100)
EndFor
output = "Ten random odd numbers stored the easy way"
comment()
For i = 1 To 10
TextWindow.WriteLine(numi)
EndFor
next()
'
'The number of elements in an array may be changing or not known, we can see how many there are
'
TextWindow.Clear()
For i = 1 To 10+Math.GetRandomNumber(10)
vali = Math.GetRandomNumber(100)
EndFor
output = "We have stored "+Array.GetItemCount(val)+" random numbers between 1 and 100"
comment()
TextWindow.WriteLine("Index Value")
For i = 1 To Array.GetItemCount(val)
TextWindow.Write(i+"     ") ' we break the write into 2 statements to prevent it reporting i+vali
TextWindow.WriteLine(vali)
EndFor
next()
avg = 0
For i = 1 To Array.GetItemCount(val)
avg = avg+vali
EndFor
avg = 0.01*Math.Floor(100*avg/Array.GetItemCount(val)+0.5) ' rounded to nearest (hence the +0.5) 2 decimal places
TextWindow.WriteLine("Their average value is "+avg)
TextWindow.WriteLine("")
'
'We can see if the array contains a value or not

'
output = "Enter a number to see if it is in the array"
comment()
If (Array.ContainsValue(val,num) = "True") Then
TextWindow.WriteLine(num+" is in the array")
Else
TextWindow.WriteLine(num+" is not in the array")
EndIf
next()
'
'We can delete entries in the array - delete the even numbers here
'
count = Array.GetItemCount(val) ' We set this variable first because we are change the number of elements in the array inside the loop
For i = 1 To count
If (Math.Remainder(vali,2) = 0) Then
vali = ""
EndIf
EndFor
output = "There are "+Array.GetItemCount(val)+" odd numbers left in the array"
comment()
TextWindow.WriteLine("")
'
'We have deleted the even numbers but the indexes of the remaining odd numbers have not changed
'
output = "The array now has empty deleted indexes"
comment()
TextWindow.WriteLine("Index Value")
For i = 1 To count
TextWindow.Write(i+"     ")
If (Array.ContainsIndex(val,i)) Then
TextWindow.WriteLine(vali)
Else
TextWindow.WriteLine("Deleted")
EndIf
EndFor
next()
'
'We need to reorder the array to change the array indexes to be sequetial
'This is not obvious, so be careful deleting array values, without remembering that the indexes are unchanged
'If the indices are just numbers, the use the code below
'
i = 1 'Index of unshuffled (original) array
j = 1 'New index values for shuffled up array
While (j <= Array.GetItemCount(val))
If (Array.ContainsIndex(val,i) = "True") Then
valj = vali
If (i <> j) Then
vali = ""
EndIf
j = j+1
EndIf
i = i+1
EndWhile
output = "The full odd number array after re-ordering indexes sequentially"
comment()
TextWindow.WriteLine("Index Value")
For i = 1 To Array.GetItemCount(val)
TextWindow.Write(i+"     ")
TextWindow.WriteLine(vali)
EndFor
next()
'
'Arrays indexed by strings
'These have the advantage that we don't have to worry about indexing when we add and delete values,
'but we cannot use inedexed loops (For i =1 To...) to access them
'
TextWindow.Clear()
age"Fred" = 21
age"Mary" = 28
age"David" = 36
output = "Unindexed string arrays are easy to use, but less powerful"
comment()
TextWindow.WriteLine("Mary is "+age"Mary"+" years old")
TextWindow.WriteLine("Fred is "+age"Fred"+" years old")
TextWindow.WriteLine("David is "+age"David"+" years old")
next()
'Multi-dimesional string arrays with indexing (more powerful but awkward to delete and maintain sequetial indexing)
'Name
contact1"name" = "Fred"
contact2"name" = "Mary"
contact3"name" = "David"
contact4"name" = "Sam"
contact5"name" = "Helen"
'Age
contact1"age" = 21
contact2"age" = 28
contact3"age" = 36
contact4"age" = 42
contact5"age" = 18
'City
contact1"city" = "Paris"
contact2"city" = "Prague"
contact3"city" = "New York"
contact4"city" = "Mombia"
contact5"city" = "Johannesburg"
'We store the data in the array contact (like a database)
'And access the data using the index
output = "String arrays with some index are easier to use"
comment()
For i = 1 To Array.GetItemCount(contact)
TextWindow.WriteLine(contacti"name"+" is "+contacti"age"+" years old and lives in "+contacti"city")
EndFor
next()
newindex = Array.GetItemCount(contact)+1
contactnewindex"name" = "Rolf"
contactnewindex"age" = 73
contactnewindex"city" = "Melbourne"
newindex = Array.GetItemCount(contact)+1
contactnewindex"name" = "Bruce"
contactnewindex"age" = 51
contactnewindex"city" = "Hong Kong"
comment()
For i = 1 To Array.GetItemCount(contact)
TextWindow.WriteLine(contacti"name"+" is "+contacti"age"+" years old and lives in "+contacti"city")
EndFor
next()
'Delete some entries
count = Array.GetItemCount(contact) 'we use count here because we are deleteing more than 1 entry and Array.GetItemCount(contact) is changing inside the loop
For i = 1 To count
If (contacti"name" = "Mary" Or contacti"name" = "Bruce") Then
contacti = ""
EndIf
EndFor
'shuffle indexes to run from 1 to number of entries in array (sequential indexing)
i = 1
j = 1
While (j <= Array.GetItemCount(contact))
If (Array.ContainsIndex(contact,i) = "True") Then
contactj = contacti
If (i <> j) Then
contacti = ""
EndIf
j = j+1
EndIf
i = i+1
EndWhile
output = "Delete Mary and Bruce"
comment()
For i = 1 To Array.GetItemCount(contact)
TextWindow.WriteLine(contacti"name"+" is "+contacti"age"+" years old and lives in "+contacti"city")
EndFor
next()
'
'Sort by name alphabetically
'
var = "name"
sortString()
output = "Sorted by name alphabetically"
comment()
For i = 1 To Array.GetItemCount(contact)
TextWindow.WriteLine(contacti"name"+" is "+contacti"age"+" years old and lives in "+contacti"city")
EndFor
next()
'
'Sort by city alphabetically
'
var = "city"
sortString()
output = "Sorted by city alphabetically"
comment()
For i = 1 To Array.GetItemCount(contact)
TextWindow.WriteLine(contacti"name"+" is "+contacti"age"+" years old and lives in "+contacti"city")
EndFor
next()
'
'Sort by age
'
var = "age"
sortNumber()
output = "Sorted by age"
comment()
For i = 1 To Array.GetItemCount(contact)
TextWindow.WriteLine(contacti"name"+" is "+contacti"age"+" years old and lives in "+contacti"city")
EndFor
next()
'
'Back to something simpler : 2D number arrays
'An array of squares in a graphics window - 'Pairs'
'
TextWindow.Hide()
GraphicsWindow.BackgroundColor = "LightBlue"
nrow = 2*2 'must be even number of boxes - it is PAIRS
ncol = 2*2
size = 50
For i = 1 To nrow
For j = 1 To ncol
Xboxij = 1.5*size*i
Yboxij = 1.5*size*j
Cboxij = -1 ' unset colour just now
foundij = 0 'flag for found pairs
EndFor
EndFor
'Set pairs of boxes (cards) with the same random colour
For i1 = 1 To nrow
For j1 = 1 To ncol
If (Cboxi1j1 < 0) Then
'i1,j1 isel not set so set it
Cboxi1j1 = GraphicsWindow.GetRandomColor()
'find another random box i2,j2 not already set
i2 = Math.GetRandomNumber(nrow)
j2 = Math.GetRandomNumber(ncol)
While (Cboxi2j2 >= 0)
i2 = Math.GetRandomNumber(nrow)
j2 = Math.GetRandomNumber(ncol)
EndWhile
Cboxi2j2 = Cboxi1j1
EndIf
EndFor
EndFor
'
'Change colour of selected box (delete and recreate it)
'See graphics demo for mouse event control
'
GraphicsWindow.MouseDown = OnMouseDown
Sub OnMouseDown
mx = GraphicsWindow.MouseX
my = GraphicsWindow.MouseY
clicked = 1
EndSub

'Draw intial view of coloured squares (pairs), show for 5 sec, then turn to blank side
For i = 1 To nrow
For j = 1 To ncol
GraphicsWindow.BrushColor = Cboxij
Shapes.Move(Sboxij,Xboxij,Yboxij)
EndFor
EndFor
Program.Delay(5000)

back = "White"
GraphicsWindow.BrushColor = back
For i = 1 To nrow
For j = 1 To ncol
Shapes.Remove(Sboxij)
Shapes.Move(Sboxij,Xboxij,Yboxij)
EndFor
EndFor

clicked = 0
nclicked = 0
nfound = 0
While (nfound < nrow*ncol)
If (clicked = 1) Then
For i = 1 To nrow
For j = 1 To ncol
'Only consider unfound boxes
If (mx >= Xboxij And mx <= Xboxij+size And my >= Yboxij And my <= Yboxij+size) Then
If (foundij = 0 And nclicked < 2) Then
Sound.PlayClickAndWait()
'Turn over a card to the coloured side and note its location in isel,jsel
Shapes.Remove(Sboxij)
GraphicsWindow.BrushColor = Cboxij
Shapes.Move(Sboxij,Xboxij,Yboxij)
nclicked = nclicked+1
iselnclicked = i
jselnclicked = j
Else
'Don't click an already found pair
Sound.PlayBellRingAndWait()
EndIf
EndIf
EndFor
EndFor
'Two turned over - leave them showing if they are the same, otherwise wait 2 sec and turn then back over
If (nclicked = 2) Then
If (Cbox[isel][jsel] <> Cbox[isel][jsel]) Then
Program.Delay(2000)
For k = 1 To 2
i = isel[k]
j = jsel[k]
Shapes.Remove(Sbox[i][j])
GraphicsWindow.BrushColor = back
Shapes.Move(Sbox[i][j],Xbox[i][j],Ybox[i][j])
EndFor
Else
For k = 1 To 2
i = iselk
j = jselk
foundij = 1
EndFor
nfound = nfound+2
EndIf
nclicked = 0
EndIf
clicked = 0
EndIf
EndWhile
Program.Delay(2000)
'
'Finish up
'
GraphicsWindow.Clear()
GraphicsWindow.BackgroundColor = "Black"
gw = GraphicsWindow.Width
gh = GraphicsWindow.Height
GraphicsWindow.FontSize = 80
While (clicked = 0)
For i = 1 To 100 ' Do 100 of these for every update of the black text to speed it up
GraphicsWindow.SetPixel(Math.GetRandomNumber(gw),Math.GetRandomNumber(gh),GraphicsWindow.GetRandomColor())
EndFor
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawBoundText(20,20,gw-20,"All Done with ARRAYS.  Click to EXIT.")
EndWhile

Program.End()
'
'Utility to output a comment
'
Sub comment
TextWindow.ForegroundColor = "Yellow"
TextWindow.WriteLine(output)
TextWindow.ForegroundColor = "White"
EndSub
'
'Utility subroutine to move on in the TextWindow
'
Sub next
TextWindow.ForegroundColor = "Red"
TextWindow.WriteLine("")
TextWindow.ForegroundColor = "White"
EndSub
'
'Sort contacts array alphabetically
'
Sub sortString
For i = 1 To Array.GetItemCount(contact)-1
For j = i+1 To Array.GetItemCount(contact)
iVar = contactivar
jVar = contactjvar
iValue = 0
jValue = 0
char = 0
While (iValue = jValue)
char = char+1
iValue = Text.GetCharacterCode(Text.GetSubText(iVar,char,1))
jValue = Text.GetCharacterCode(Text.GetSubText(jVar,char,1))
EndWhile
If (jValue < iValue) Then
store = contacti
contacti = contactj
contactj = store
EndIf
EndFor
EndFor
EndSub
'
'Sort contacts array by number
'
Sub sortNumber
For i = 1 To Array.GetItemCount(contact)-1
For j = i+1 To Array.GetItemCount(contact)
iVar = contactivar
jVar = contactjvar
If (jVar < iVar) Then
store = contacti
contacti = contactj
contactj = store
EndIf
EndFor
EndFor
EndSub