Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

say one random item from list

Harminoff Hadlee
Registered User
Join date: 13 Jul 2004
Posts: 35
08-10-2004 15:08
i know that if you do the random list thing, it randomizes it and shows the whole random list. is it possible to make a list, and then pick one random word in that list and say that?


im making a card game, and need it to choose the cards at random.

i have two lists, one of numbers and one of card types sence there are aces and jacks and whatnot.

is there an easy way of doing this that im overlooking?
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
08-10-2004 16:34
<ramble mode="long winded">
well long ago i wrote a blackjack program for the TI 83. The TI 83 at the time wasn't a very powerful calculator as it is now. More over the implementation of basic they had leaked memory and was, well, very basic. But we did have arrays but no built in way to randomize arrays. All and all the TI 83 was a great way to prepare for programing in SL. The trouble with just randomly generating cards was sometimes you would get 5+ aces in play. The obvious solution was to generate an array that represented a deck and then randomly sort it. One of the other limits of the 83 was that it only supported numbers in arrays (the 83 had basicly no string manipulation functions; and there was no such thing as a character array). Some of the other limits of the 83 was it didn't support functions, it only had universaly global variables (ie variable values would persist after the program exited), variable names could only be 2 letter combinations (or was it 1?), lables for jumps could only be two letters. Basicly it sucked. Anyway so with the sorted list then i just stepped threw the array using cards and shuffling the deck when ever it was running low. Each card was represented as an integer. Due to memory leaks in the 83 you could play about 15 hands then the game would crash. Also built a number of racing style games for the 83... But i lost my 83 years ago *sigh*. But now i have an 89 and it's much more powerful, doesn't leak memory as much, has a bigger screen, and more memory for code execution so leaking it all is harder. I miss my 83.
</ramble>

represent all your cards as numbers then use a translate function for getting the play values from the card it self.

If i were doing this now i would probably do it a similar way.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
08-10-2004 17:51
CODE

list myList = ["Apple", "Pear", "Banana"];

default
{
touch_start(integer total_number)
{
list randomizedList;

//Randomize the List, and stuff in new variable
randomizedList = llListRandomize(myList, 0);

//Pull the first item from the randomized list
llSay(0, llList2String(randomizedList, 0));
}
}


This and many other examples can be found in the University of SL Library in Montara.
_____________________
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
Re: say one random item from list
08-10-2004 21:19
For a less script intensive approach:
CODE

list myList = ["Apple", "Pear", "Banana"];

default
{
touch_start(integer total_number)
{
// Get the length of myList
integer len = llGetListLength(myList);
// Get a random index in the list:
integer index = llFloor(llFrand(len));

//Pull the index from the list:
llSay(0, llList2String(myList, index));
}
}

==Chris
Alondria LeFay
Registered User
Join date: 2 May 2003
Posts: 725
08-10-2004 22:03
From: someone
Originally posted by Strife Onizuka

well long ago i wrote a blackjack program for the TI 83. The TI 83 at the time wasn't a very powerful calculator as it is now. ......


<Thread steal>
LOL.. I remember in my younger years doing coing on an TI85.. Wrote a tetris game, a chess game (no AI), and even had the starts to a war game before it met an untimely end (screen broke). Sad thing is, even it had more memory than LSL scripts.. but it definately was a good training on limited memory resources. I now have my Palm Tungsten and loving it. :)
Harminoff Hadlee
Registered User
Join date: 13 Jul 2004
Posts: 35
08-10-2004 22:14
i made blackjack for ti86, kicked ass and was all over school.

had money and everything. damn those little squares on the bottom where nice. my ai was nice also. it took me like 3 days to get it right, and those suck cause its hard to add thing later.

all hail the goto command i guess. i also started making a text rpg, but that went nowhere.


thanks for the code.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
08-11-2004 01:10
From: someone
Originally posted by Alondria LeFay
Sad thing is, even it had more memory than LSL scripts


yeah the 83 had 32 k...
the new 83's have 1.5 MB *cry* i checked out the site and they don't even want to sell 83's any more; they want to sell 84's.

The above solutions are just what the doctor ordered.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
Re: Re: say one random item from list
08-11-2004 07:34
From: someone
Originally posted by Christopher Omega
For a less script intensive approach:
CODE

list myList = ["Apple", "Pear", "Banana"];

default
{
touch_start(integer total_number)
{
// Get the length of myList
integer len = llGetListLength(myList);
// Get a random index in the list:
integer index = llFloor(llFrand(len));

//Pull the index from the list:
llSay(0, llList2String(myList, index));
}
}

==Chris


Actualy, that's incorrect. If you run the following tests, you'll see that using llRandomizeList is actually faster...

llRandomizeList Test
CODE

integer testLength = 1000;
list myList = ["Apple", "Pear", "Banana"];

default
{
state_entry()
{
llSetText(llGetObjectName(), <1,1,1>, 1);
}
touch_start(integer total_number)
{
integer x;
float timeElapsed;

list randomizedList;

timeElapsed = llGetTime();

for (x = 0; x < testLength; x += 1)
{
//Randomize the List, and stuff in new variable
randomizedList = llListRandomize(myList, 0);

//Pull the first item from the randomized list
//llSay(0, llList2String(randomizedList, 0));
}
timeElapsed = llGetTime() - timeElapsed;
llSay(0, "Test took " + (string)timeElapsed + " seconds.");
}
}


llFrand Test
CODE

integer testLength = 1000;
list myList = ["Apple", "Pear", "Banana"];

default
{
state_entry()
{
llSetText(llGetObjectName(), <1,1,1>, 1);
}
touch_start(integer total_number)
{
integer x;
float timeElapsed;

integer index;

timeElapsed = llGetTime();

// Get the length of myList
integer len = llGetListLength(myList);

for (x = 0; x < testLength; x += 1)
{
// Get a random index in the list:
index = llFloor(llFrand(len));

//Pull the index from the list:
//llSay(0, llList2String(myList, index))
}
timeElapsed = llGetTime() - timeElapsed;
llSay(0, "Test took " + (string)timeElapsed + " seconds.");
}
}


...and that's with giving the llFrand example the advantage by only getting the List's Length one time, instead of everytime in the loop.
_____________________
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
Re: Re: Re: say one random item from list
08-11-2004 11:38
From: someone
Originally posted by Hank Ramos
randomizedList = llListRandomize(myList, 0);


Does that actually do anything? Shouldnt the second parameter be 1 instead of 0?

Also, please post the test results you recieved, you say one is faster, but what really makes the difference is how *much* faster.

==Chris
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
08-11-2004 11:39
Also, when I said "less script intensive" i meant less computationally intensive as well is less memory intensive. When you use list randomization rather then a random list index, you have to make at least one (two if the LSL bytecode isnt optimized) additional copy(s) of the entire list in memory.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
Re: Re: Re: say one random item from list
08-11-2004 11:43
From: someone
Originally posted by Hank Ramos
...and that's with giving the llFrand example the advantage by only getting the List's Length one time, instead of everytime in the loop.

This is standard practice.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
Re: Re: Re: say one random item from list
08-11-2004 11:47
From: someone
Originally posted by Hank Ramos
timeElapsed = llGetTime();

// Get the length of myList
integer len = llGetListLength(myList);

Not only that, but the order in which these two lines are written in the script may somewhat slur the results. Try putting the length computation before getting the time, or globally declare the length of the nonchanging list (since its length is not going to change, its intuitive to declare the length of the list as a global along with the list itself.)
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
Re: Re: Re: Re: say one random item from list
08-11-2004 11:57
From: someone
Originally posted by Christopher Omega
Does that actually do anything? Shouldnt the second parameter be 1 instead of 0?

Also, please post the test results you recieved, you say one is faster, but what really makes the difference is how *much* faster.

==Chris


Actually, you're right. It should be 1, but 0 gives the same result.

I'll post exact numbers tonight, but from what I remember this morning...

llListRandomize example completed 1000 iterations in 26 seconds, llFrand (assuming we only get the list length once) completes in 29 seconds, and llFrand (retrieving the list length on each iteration) complets in like 43 seconds.

I'll post them tonight.
_____________________
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
08-11-2004 11:58
From: someone
Originally posted by Christopher Omega
Also, when I said "less script intensive" i meant less computationally intensive as well is less memory intensive. When you use list randomization rather then a random list index, you have to make at least one (two if the LSL bytecode isnt optimized) additional copy(s) of the entire list in memory.


It maybe more memory intensive to use llListRandomize, but you always trade off memory for speed.

As for computationally intensive, we know that the llListRandomize method is able to complete the iteration faster than the llFrand example.
_____________________
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
Re: Re: Re: Re: say one random item from list
08-11-2004 11:59
From: someone
Originally posted by Christopher Omega
Not only that, but the order in which these two lines are written in the script may somewhat slur the results. Try putting the length computation before getting the time, or globally declare the length of the nonchanging list (since its length is not going to change, its intuitive to declare the length of the list as a global along with the list itself.)


That wouldn't be a fair comparison. This would allow the llFrand example to obtain the list length without including that time in the results. However, with 1000 iterations, I doubt moving it outside of the time calculation would make much difference.
_____________________
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
Re: Re: Re: Re: say one random item from list
08-11-2004 12:01
From: someone
Originally posted by Christopher Omega
This is standard practice.


It would be standard if and only if the list never changed. I'll draw up more detailed test cases comparing...

> Large and Small Lists. Difference between llListRandomize and the llFrand examples using a small and large list.
> Fixed and Dynamically Changing Lists. Difference between needing to retrieve the list length on each iteration for a dynamic list, or just once for a fixed list.
_____________________
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
Re: Re: Re: Re: say one random item from list
08-11-2004 13:05
From: someone
Originally posted by Christopher Omega
This is standard practice.


Also read the bottom of that page, "Counter Opinion: Tweaks Considered Harmful". A more complex example may not be the best solution if it introduces additional steps.
_____________________
Tiger Crossing
The Prim Maker
Join date: 18 Aug 2003
Posts: 1,560
08-11-2004 13:50
Don't knock yourselves out in the speed comparison, guys. I think he wants to have unique results with each "draw" as you would when dealing a randomized stack of cards, not pick a card/put it back/pick another card.

So Hank's original code would do what he needs. The only suggestion I'd make is the use of a counter variable that keeps track of the "top" of the deck.
CODE
list myList = ["Ace of Spaces", "2 of Spades", "3 of Spades"];
integer listTop = 0;

Shuffle()
{
llSay( 0, "Shuffling..." );
// randomize the list
myList = llListRandomize( myList, 1 );
// point to the top of the deck
listTop = 0;
}

default
{
state_entry()
{
Shuffle();
}

touch_start( integer num )
{
// say the top card of deck and point to next card
llSay(0, llList2String( myList, listTop++));

// reset the script (and deck) when you run out of cards
if ( listTop >= llGetListLength( myList ) )
llShuffle();
}
}

Every time you click, you get a different card. When the deck runs out, it reshuffles.
_____________________
~ Tiger Crossing
~ (Nonsanity)