PDA

View Full Version : ARRAY SHUFFLE??



marcuslee
05-09-2008, 13:45
I found what I thought was going to be a neat little function, but I can't get it to work like I thought it should be working.

Here's something I put together to test ARRAY SHUFFLE:




USES "console"

DIM myarray( 12 ) AS INTEGER
DIM x AS INTEGER

myarray( 1 ) = 1
myarray( 2 ) = 2
myarray( 3 ) = 3
myarray( 4 ) = 4
myarray( 5 ) = 5
myarray( 6 ) = 6
myarray( 7 ) = 7
myarray( 8 ) = 8
myarray( 9 ) = 9

ARRAY SHUFFLE myarray( 1 ) FOR 1

FOR x = 1 TO 9
CONSOLE_WRITE myarray( x )
NEXT



When I run this, the shuffle command keeps assigning one or more of the elements as zero. Is there something I'm doing wrong?

Mark :(

Michael Hartlef
05-09-2008, 13:50
You have an array with 12 indices. But only assigned a value for 9 indices. So when you shuffle, some will get the value of index 10, 11 and 12.

Michael Hartlef
05-09-2008, 13:51
Raise the for loop to 12 and you will see what I mean:


' Empty GUI script created on 09-05-2008 13:48:02 by (ThinAIR)
USES "console"

DIM myarray( 12 ) AS INTEGER
DIM x AS INTEGER

myarray( 1 ) = 1
myarray( 2 ) = 2
myarray( 3 ) = 3
myarray( 4 ) = 4
myarray( 5 ) = 5
myarray( 6 ) = 6
myarray( 7 ) = 7
myarray( 8 ) = 8
myarray( 9 ) = 9

ARRAY SHUFFLE myarray( 1 ) FOR 1

FOR x = 1 TO 12
CONSOLE_WRITEline myarray( x )
NEXT

console_waitkey

Petr Schreiber
05-09-2008, 14:01
Few tips :)

When assigning to array, you can specify multiple items on one line via following 2 ways:


' -- Classic way
ARRAY ASSIGN myarray() = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

' -- Start filling from index 1 to 12
myarray(1) = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12


Sample to print all items of array to console, using short form of console commands:


USES "console"

DIM myarray( 12 ) AS INTEGER

' -- Start filling from index 1 to 12
myarray(1) = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

' -- Shuffle once
ARRAY SHUFFLE myarray() FOR 1

' -- Print line of array items joined by space
PRINTL JOIN$( myArray, " " )

WAITKEY


Bye,
Petr

marcuslee
06-09-2008, 01:31
You have an array with 12 indices. But only assigned a value for 9 indices. So when you shuffle, some will get the value of index 10, 11 and 12.


DUH! :-[ :D :o

Thank you.

Mark

marcuslee
06-09-2008, 01:37
Few tips :)

When assigning to array, you can specify multiple items on one line via following 2 ways:

Sample to print all items of array to console, using short form of console commands:



Those are some good tips.

I have a question about this line:



' -- Shuffle once
ARRAY SHUFFLE myarray() FOR 1


If you have a large array, say in the 100's ... what is the advantage of shuffling more than once?



' -- Shuffle twice
ARRAY SHUFFLE myarray() FOR 2


OR



' -- Shuffle thrice
ARRAY SHUFFLE myarray() FOR 3


In other words, how much more shuffled does it become? Is once good enough?

Mark

marcuslee
06-09-2008, 02:21
Here's what I was orginially trying to do when my dumb brain shut off on me. After I found the Array Shuffle command, I got excited because I thought that command could be used to choose randomly a series of database records. I haven't got that far yet. Baby steps, but here is an example of using Array Shuffle to shuffle strings (not just numbers):




USES "console"

TYPE mytype
numeric AS INTEGER
textmessage AS STRING * 100
END TYPE

DIM myarray( 9 ) AS INTEGER
DIM AnotherArray( 9 ) AS mytype
DIM x AS INTEGER

myarray( 1 ) = 1, 2, 3, 4, 5, 6, 7, 8, 9

FOR x = 1 TO 9
AnotherArray( x ).numeric = x
NEXT

AnotherArray( 1 ).textmessage = "one"
AnotherArray( 2 ).textmessage = "two"
AnotherArray( 3 ).textmessage = "three"
AnotherArray( 4 ).textmessage = "four"
AnotherArray( 5 ).textmessage = "five"
AnotherArray( 6 ).textmessage = "six"
AnotherArray( 7 ).textmessage = "seven"
AnotherArray( 8 ).textmessage = "eight"
AnotherArray( 9 ).textmessage = "nine"

ARRAY SHUFFLE myarray( ) FOR 1

'print the shuffled contents of an array of strings
FOR x = 1 TO 9
CONSOLE_WRITE AnotherArray( myarray( x )).numeric
CONSOLE_WRITE "-"
CONSOLE_WRITELINE AnotherArray( myarray( x )).textmessage
NEXT

WAITKEY



If the contents of AnotherArray were being assigned from a database that houses questions and answers for a multiple choice flash card program ... anyway, that's where my thoughts are leading me to.

Mark ;D

ErosOlmi
06-09-2008, 04:36
... what is the advantage of shuffling more than once?


To shuffle an array, thinBasic uses a pseudo random number generator firing a RANDOMIZE TIMER.
This is done for every time requested to shuffle the array adding more complexity to the shuffling process.

And because we are adding some tips ;)
FOR clause in shuffling is not mandatory, so when just one shuffling is enough (why more :D )


ARRAY SHUFFLE myarray


Also CONSOLE module implement classic PRINT and PRINTL statement. To reduce a little bit source code, the following:


FOR x = 1 TO 9
CONSOLE_WRITE AnotherArray( myarray( x )).numeric
CONSOLE_WRITE "-"
CONSOLE_WRITELINE AnotherArray( myarray( x )).textmessage
NEXT

is equivalent to


FOR x = 1 TO 9
PRINT AnotherArray( myarray( x )).numeric
PRINT "-"
PRINTL AnotherArray( myarray( x )).textmessage
NEXT

or even more reduced


FOR x = 1 TO 9
PRINTL AnotherArray( myarray( x )).numeric & "-" & AnotherArray( myarray( x )).textmessage
NEXT


Ciao
Eros

ErosOlmi
06-09-2008, 08:17
A way to shuffle string arrays.
_________________________________________________
ARRAY SHUFFLE ... statement only supports numeric arrays. So, how to shuffle a string array? I would like here just to recall what a dynamic string (single or array of) is because using the following string property it is possible to use ARRAY SHUFFLE ... and other interesting techniques on strings.

thinBasic implements dynamic string using OLE BSTR (http://msdn.microsoft.com/en-us/library/ms221069.aspx) concept (single byte). Mainly when a script defines a dynamic string (or an array of dynamic strings) in reality what is really allocated is a32 bit pointer to a memory area that at first is empty. See attached file to better understand the concept.


DIM s AS STRING
creates a 32bit pointer that initially points to nothing (its value will be zero at first)
When to s assigned something (in the image example the string "hello"), OLE engine allocates enough space for the string and puts into the 32bit pointer the memory address of the new string. But there is more: the allocated area is always preceded by another 32bit LONG data containing the length of the string. Plus the string is always terminated with a $NUL char in order to be compatible with API fucntions expecting $NUL terminated strings.

So, at the end, an array of dynamic strings is in reality an array of pointers to some memory areas where the strings are allocated. This let us manage the string array like an array of LONG. And more, changing the position of the pointers will not change or more the strings to where those pointers point.

In other words, we can over impose a dummy array of LONGs to our array of strings and use ARRAY SHUFFLE to exchange the position of the pointers. This will only change the sequence of the pointers but will not touch any string. See following example.

Regards
Eros



USES "console"

%MaxElements = 10
'---Define an array of strings
DIM myStringArray(%MaxElements) AS string

'---Fill the array
myStringArray( 1) = "one"
myStringArray( 2) = "two"
myStringArray( 3) = "three"
myStringArray( 4) = "four"
myStringArray( 5) = "five"
myStringArray( 6) = "six"
myStringArray( 7) = "seven"
myStringArray( 8) = "eight"
myStringArray( 9) = "nine"
myStringArray(10) = "ten"

'---Over impose a dummy array of longs to the string array pointers
dim MyPtrToStringArray(ubound(myStringArray)) as long at varptr(myStringArray(1))

'---Shuffle the new dummy array. This will shuffle the sequence
'---of the string pointers without touching the string content
ARRAY SHUFFLE MyPtrToStringArray

'---Print out values
FOR Counter as long = 1 TO %MaxElements
printl Counter, myStringArray(Counter)
NEXT

WAITKEY


References:
http://oreilly.com/catalog/win32api/chapter/ch06.html

marcuslee
06-09-2008, 14:15
FOR clause in shuffling is not mandatory, so when just one shuffling is enough (why more :D )


ARRAY SHUFFLE myarray



That's a good tip. (As well as the others you mentioned!)







... what is the advantage of shuffling more than once?


To shuffle an array, thinBasic uses a pseudo random number generator firing a RANDOMIZE TIMER.
This is done for every time requested to shuffle the array adding more complexity to the shuffling process.



When is more complexity needed?

I did a test. I filled a huge numeric array, shuffled it, then printed it on the screen. Just one shuffling seemed pretty shuffled to me. Here's the code:



USES "console"

DIM myarray( 2000 ) AS INTEGER
DIM x AS INTEGER

FOR x = 1 TO 2000
myarray( x ) = x
NEXT

ARRAY SHUFFLE myarray( )

'print the shuffled contents of a large numeric array

FOR x = 1 TO 2000
PRINTL myarray( x )
NEXT

WAITKEY




When would be a good time to shuffle twice or thrice? (2 or 3 times)



ARRAY SHUFFLE myarray( ) FOR 2


OR



ARRAY SHUFFLE myarray( ) FOR 3


Mark ::)

marcuslee
06-09-2008, 14:25
So, at the end, an array of dynamic strings is in reality an array of pointers to some memory areas where the strings are allocated. This let us manage the string array like an array of LONG. And more, changing the position of the pointers will not change or more the strings to where those pointers point.

In other words, we can over impose a dummy array of LONGs to our array of strings and use ARRAY SHUFFLE to exchange the position of the pointers. This will only change the sequence of the pointers but will not touch any string.


I think I understand your description of strings and pointers. And, your little trick for shuffling an array of strings seems sound. I'm trying to figure in my head if it would work with a UDT when the array of strings is just a member of that type. You might have other array of strings in the same type.

For example:



TYPE mytype
ques_ID AS INTEGER
titlemessage AS STRING * 100
question AS STRING * 500
ans_a AS STRING * 250
ans_b AS STRING * 250
ans_c AS STRING * 250
ans_d AS STRING * 250
END TYPE


How would I shuffle this type but the members would all shuffle together?

I could shuffle another numeric array as I have already done. But, is it possible to use your pointer tip to shuffle in this situation?

Mark ???

ErosOlmi
06-09-2008, 17:58
Arrays of UDT are not like dynamic strings.
UDT are placed in memory one after the other and no pointers are in place.

There are mainly two ways to shuffle arrays of UDT:

the one you already used (a parallel array used as index of the UDT array)
I implement native shuffle for UDT in one of the next thinBasic version.


Why are you so interested in ARRAY SHUFFLE?

Ciao
Eros

marcuslee
06-09-2008, 23:31
There are mainly two ways to shuffle arrays of UDT:

the one you already used (a parallel array used as index of the UDT array)
I implement native shuffle for UDT in one of the next thinBasic version.




That's great. You are always thinking of new things. How do you do it? That was basically rhetorical ... unless you want to expound on it.




Why are you so interested in ARRAY SHUFFLE?



Well, I've already decided to use a Microsoft Access DB in connection with ARRAY SHUFFLE in a flash card (SLASH) game I want to create. I plan on using it for all sorts of things, but right now I am working on building a database to help myself study the Bible. It's kinda like flash cards but with a multiple choice aspect. But, I want the "cards" to come randomly. I don't want the same set coming over and over. I wanted to make sure that ARRAY SHUFFLE could be used with hundreds of numbers. It can. It looks random to me, and it isn't the same each time, so I am happy.

When I get a little further along, I'll share a copy with everyone.

Mark ;D

P.S. - And, I am sure that I will have more questions.

ErosOlmi
07-09-2008, 04:31
Ok, I've developed native support for arrays of strings (dynamic) and UDT in ARRAY SHUFFLE statement.
Will be present in next release.

Ciao
Eros

marcuslee
07-09-2008, 05:10
Ok, I've developed native support for arrays of strings (dynamic) and UDT in ARRAY SHUFFLE statement.
Will be present in next release.


Okay, that was fast. Now I am curious! How do you do it?

Mark :o :o

ErosOlmi
07-09-2008, 05:12
I've tested with up to 10millions elements and all seems ok (apart time needed to do the job).
Up to 100000 elements filling and shuffling takes less than 1 second on my machine.

I could attach here the new thinCore.dll version but you need thinBasic preview version 1.7.0.0
So you have to wait official release of it or ask me via personal message here in forum to have preview version. I will send you the link where to get it.

Ciao
Eros



USES "console"

%MAXElements = 100000
TYPE mytype
numeric AS long
textmessage AS STRING * 100
END TYPE

printl "Dimensioning an array of UDT with " & %MAXElements & " elements"
DIM MyArray( %MAXElements ) AS mytype

printl "Filling ..."
DIM Counter AS long
FOR Counter = 1 TO %MAXElements
MyArray( Counter ).numeric = Counter
MyArray( Counter ).textmessage = string$(100, rnd(32, 127))
NEXT

printl "shuffling ..."
ARRAY SHUFFLE myarray

printl "Printing. PRESS A KEY WHEN READY ..."
waitkey
FOR Counter = 1 TO %MAXElements
printl Counter, MyArray(Counter).numeric, "-", MyArray(Counter).textmessage
NEXT
printl "---ALL DONE. PRESS A KEY WHEN READY---"

WAITKEY

ErosOlmi
07-09-2008, 05:16
Okay, that was fast. Now I am curious! How do you do it?

Mark :o :o


That is thinBasic way ;)
When we see people need something and that something is quite general, we try to develop it asap and have it in next available version.
Other thinBasic users will be able to confirm that this is our way. You do not have to wait ages to have new features or updates. We are usually very fast. I know this is not the standard out there in the software world but because we are users too of something else, we try not to do things we hate. As a user of a development tool I usually expect this, so we try to do it here.

If you need more technical "How do you do" let me know.

Ciao
Eros

marcuslee
07-09-2008, 05:19
I could attach here the new thinCore.dll version but you need thinBasic preview version 1.7.0.0
So you have to wait official release of it or ask me via personal message here in forum to have preview version. I will send you the link where to get it.


No, no. I can wait. That is just fine. I'm just sitting here, admiring your greatness! Talk about up to the minute!

I am curious about how much work it takes to update thinBasic. I haven't read your journal area. I will go there right after writing this post. But, it seems you are like Speedy Gonzalez. (I'll explain that if you don't know what I am talking about.)

How much work are we talking about to add one new feature to thinBasic? A few lines of code? A screenful of code?

Mark :o :o

ErosOlmi
07-09-2008, 05:30
thinBasic is developed using Power Basic compiler. Power Basic is a fantastic compiler that has the power of C (well, much more in my opinion) but the easy of use of Basic language. thinBasic syntax is very very close to Power Basic one so you can imagine how easy is to learn Power Basic.

To give you an idea of how much work, think that just thinBasic Core Engine (thinCore.dll) is more than 140000 lines of source code written by us (so not including the includes files the compiler gives us). And we have some other 15/20 modules in thinBasic to maintain.

Regarding speed of development, it is not something we can state so simple. It depends on what is asked, how the new code will interact with current code, if we have all the info already there and available or we have to search and document about the requested feature, if we need to change internal data structures or not, how much testing do we need to do, ... and many other reasons. All together compose the time we need to develop something. Sometimes we can develop in few hours, sometimes in days, sometimes some user is still waiting for the development.

Both Roberto and I are not professional programmer, in the sense that our real job is something else. We program mainly for passion (ok we also do some programming at work but it is not our main activity). I think passion is a good and perfect motivation to achieve results sometimes considered impossible to get.

That's all.

Ciao
Eros