Where theres a will theres array.

28 views
Skip to first unread message

carl

unread,
Jun 11, 2014, 1:08:05 PM6/11/14
to fign...@googlegroups.com
Hi,

I wondered if anyone here could help me with arrays,

My mini game that I am working on could do with some extra depth, one way of doing this would be to add worlds to visit as a new element.
So I could just write out 'n' amount of worlds, but I learn nothing new plus I know that arrays are many times more efficient, the best example would be a deck of cards I guess.

I could use the classic arrays example to set this up, but how can I get the array to discount one constant ( if this is the correct term) when it is used. So not letting the King being selected more than once. Plus how could I randomly generate a result from my array?

Regards,

Carl.


Mark Wills

unread,
Jun 11, 2014, 2:35:16 PM6/11/14
to fign...@googlegroups.com

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..

--
You received this message because you are subscribed to the Google Groups "FIGnition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fignition+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Julian Skidmore

unread,
Jun 11, 2014, 4:06:35 PM6/11/14
to FIGnition
Here's another FIGnition-y take on it:

When we start programming we learn about how variables work:

0 var x
0 var y

etc.

We refer to the variables by name. However at some point we find we have a need to calculate which particular variable we want, we'd like to able to put all the variables in cells on a spreadsheet and be able to refer to them by column and number, or more simply just the column.

So, let's imagine we have a number of boxes (containing numbers) in columns on a spreadsheet, on the row "WORLDS" it'd look like this:

Row\Col:       0       1               2         3          4
WORLDS  |  2    |  2670     | 151 | -9999  |  4     |

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


--
                             
                  The DIY 8-bit computer from nichemachines™

FIG - black on whiteMini.jpg
NmLogoMini.jpg

Julian Skidmore

unread,
Jun 11, 2014, 4:21:03 PM6/11/14
to FIGnition
FIGnition also provides a command for creating arrays of bytes, called (happily enough) bytes:

100 bytes buff

Would create a byte array called buff which has 100 cells all of which can take numbers between 0 to 255 (or characters).

So, if you had one of the planet names:

4 tradPlanets buff "!

Would copy planet #4 ("Jupiter") to buff. Typing:

buff ". ( the command quote-dot, not the same as dot-quote)

will display the buffer.

You can modify buffers, e.g:

create toMsg " to "

toMsg buff "+

Will add " to " to " Jupiter ", typing:

buff ".

will now display " Jupiter to "

And we could then do:

2 tradPlanets buff "+

buff ". then displays " Jupiter to Earth "

There are quite a few string handling commands in Forth, though they're fairly low-level. They're documented in a fairly formal way in the command manual:


See the section on Text Processing.

-cheers from Julz
NmLogoMini.jpg
FIG - black on whiteMini.jpg
Reply all
Reply to author
Forward
0 new messages