Imagine a small array of numbers in memory like this:
2 4 6 8 10
The easiest way to stop yourself from selecting the same number twice is to change it to another value after you have selected it. The simplest way would be to negate it. So if you select the third number in the array, you push 6 to the stack, then you negate the 6 in the array, giving you:
2 4 -6 8 10
Now, in your selection logic you simply have a rule that checks the value and if it is negative then you know you have used it already.
In terms of randomly filling an array and selecting from it is quite easy in Forth.
The following will work in most Forths but it may need some tweaking for Fignition:
First, let's create an array that can hold 10 values:
CREATE ARRAY 10 CELLS ALLOT
So now we have a word called array that when executed returns the address of the beginning of the list. It's currently un-initialised.
Now let's fill it with random data:
: FILL-ARRAY ( -- )
10 0 DO
10 RND ( random number from 0 to 9)
ARRAY I CELLS + ( address of Ith cell in array)
! ( write the value to the array)
LOOP ;
Now let's write a word to select values from the array.
: SELECT ( index -- n flag)
CELLS ARRAY + ( address to read from)
DUP >R ( save a copy for later)
@ ( read from the array)
DUP 0> IF ( value is positive)
TRUE ( push flag)
OVER ( copy of value from the array
NEGATE ( negate it)
R> ( get address that we saved)
! ( write negative back to array)
ELSE
( value is negative. Already used)
False ( push flag)
R> DROP ( discard value saved on return stack)
THEN ;
That should do it. Untested as I'm on a train and this is all via my mobile! Post if you have questions. Hope this helps. Julz can put this in a Fignition context.
Mark
So, when calling SELECT you must put the index (The position in the array that you want to read from) on the stack first. SELECT will return the value fro..
In programming, a row of cells is called a 1 dimensional array. FIGnition provides a command for creating one dimensional arrays of numbers and it's called arr . We can create an array with 5 cells as follows:
5 arr worlds
And we could then initialize them with:
: initWorlds
2 0 worlds ! ( stores '2' in column 0 of row worlds)
2670 1 worlds ! ( stores '2670' in column 1 of row worlds)
151 2 worlds ! ( stores '151' in column 2 of row worlds)
-9999 3 worlds ! ( stores '-9999' in column 3 of row worlds)
4 4 worlds ! ( stores '4' in column 4 of row worlds)
;
With variables we access the contents using variableName @ and we store values by doing value variableName !
With cells in an array we always need to provide the column number. We access them with:
columnNumber arrayName @
And store values with:
value columnNumber arrayName !
That's what is happening in initWorlds. Internally what happens is that when you execute columnNumber arrayName, the arrayName uses its starting address and then adds 2*columnNumber to get to the address of the cell. Hence at that point, it's calculated the address of a cell, just like varName returns the address of a cell.
We can also create an array AND initialize at the same time:
0 arr worldsMk2
2 , 2670 , 151 , -9999 , 4 ,
This combines both 5 arr Worlds and initWorlds (providing you don't change any of the cells in worldsMk2).
With either technique you could display all the values with:
: .worldVals
5 0 do
." Col= " i .
." Value=" i worlds . cr
loop
;
In your case it looks like you're trying to create an array of strings. This is one way to do it in FIGnition Forth:
here " pluto "
here " neptune "
here " uranus "
here " saturn "
here " jupiter "
here " mars "
here " earth "
here " venus "
here " mercury "
0 arr tradPlanets
, , , , , , , , ,
FIGnition has some built-in support for strings, so " sometext" compiles the string " sometext" into program memory at here (which moves on every time code or data is allocated). So, the list of here " pluto " etc generates a list of addresses of strings on the stack and then all the commas at the end compile those addresses into an array called tradPlanets.
You can display the planet names:
: .planets
9 0 do
i tradPlanets ".
loop
;
Will display the planet names in order.
Does any of this help?
-cheers from Julz