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