Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Another Head Scratcher

Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 06:41
Once I stop messing with this script, I will be happy!
Anyhow, I have been running this script and it runs great until I choose the last tile.
Since it makes blocks = 0, I get a math error when I try to divide by Blocks (which is now 0)

I thought I could be slick and put a do-while loop in there so, when blocks = 1 it will go to a section that is exactly the same calculation, except it doesn't subtract 1 from blocks.

problem is, I can't figure out how to embed the if statement in the do-while loop.

Should I even do it this way? it seems to be the best way to do it in my mind.

here is the do-while portion of the code

CODE

@again;
tex = llFloor( llFrand( llGetListLength(textures) ) );
integer used = llList2Integer(giUsed, tex);
do{

if (!used)
{
blocks = blocks - 1;
chosen_texture = llList2String(textures, tex);
giUsed = llDeleteSubList(giUsed, tex, tex);
giUsed = llListInsertList(giUsed, [TRUE], tex);
amount_left = amount_left -llList2Integer(amount, tex);
number = amount_left/blocks/7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;
}

else
{
jump again;
}
}


while (cases > 1);
@last_block

if (!used)
{

chosen_texture = llList2String(textures, tex);
giUsed = llDeleteSubList(giUsed, tex, tex);
giUsed = llListInsertList(giUsed, [TRUE], tex);
amount_left = amount_left -llList2Integer(amount, tex);
number = amount_left/blocks/7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;

} else {
jump last_block;
}


all of the other code is fine, I just can't get the do-while to work too well...
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
05-17-2006 07:02
Hmm... Well, looking at your code, it doesn't look like it stops when blocks reaches zero.
Oh, wait, that looks like an infinite loop. In the first do loop, !used, if true to begin, will always be true.

I'd suggest writing this without jumps-- they make code much more difficult to read. Also, use the PHP tags instead of the CODE tags.
Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 07:25
CODE

@again;
tex = llFloor( llFrand( llGetListLength(textures) ) );
integer used = llList2Integer(giUsed, tex);
do{

if (!used)
{
blocks = blocks - 1;
chosen_texture = llList2String(textures, tex);
giUsed = llDeleteSubList(giUsed, tex, tex);
giUsed = llListInsertList(giUsed, [TRUE], tex);
amount_left = amount_left -llList2Integer(amount, tex);
number = amount_left/blocks/7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;
}

else
{
jump again;
}
}


while (blocks > 1);
@last_block

if (!used)
{

chosen_texture = llList2String(textures, tex);
giUsed = llDeleteSubList(giUsed, tex, tex);
giUsed = llListInsertList(giUsed, [TRUE], tex);
amount_left = amount_left -llList2Integer(amount, tex);
number = amount_left/blocks/7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;

} else {
jump last_block;
}

Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-17-2006 07:26
I can't quite figure how your code is supposed to flow, but it seems to try the following:
CODE

while( cases ) {

integer used;
do {
tex = llFloor( llFrand( llGetListLength(textures) ) );
used = llList2Integer(giUsed, tex);

} while( used == TRUE )

if( cases > 1 ) --blocks;

chosen_texture = llList2String( textures, tex );
giUsed = llDeleteSubList( giUsed, tex, tex );
giUsed = llListInsertList( giUsed, [TRUE], tex );
amount_left -= llList2Integer( amount, tex );
number = amount_left / blocks / 7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;
}


(this is a guess the loop is supposed to run for as long as there's "cases" left. The issue is, since the code never actually touches the "cases" variable in any way, it'll run forever... was the "amount_left ..." or "number ... " line meant to be "cases ..." instead, by chance? o.O;
Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 07:30
Apologies for the confusion the line that stated (while cases >1) should read (while blocks >1)

I am trying to figure out if I need the do loop.

the code, without the do loop, looks like this

CODE

@again;
tex = llFloor( llFrand( llGetListLength(textures) ) );
integer used = llList2Integer(giUsed, tex);

if (!used)
{
blocks = blocks - 1;
chosen_texture = llList2String(textures, tex);
giUsed = llDeleteSubList(giUsed, tex, tex);
giUsed = llListInsertList(giUsed, [TRUE], tex);
amount_left = amount_left -llList2Integer(amount, tex);
number = amount_left/blocks/7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;
}

else
{
jump again;
}



This code compiles and runs fine (Until Blocks hits zero)
the (!used) is used to determine whether or not a certain texture has been used (to avoid duplicates)
I am trying to avoid the Math Error that I get when blocks hits zero (can't divide by zero)
If I can avoid using a do loop, I would like to, but it seems to me like there isn't another way to make it bypass the
CODE
blocks = blocks -1
line when blocks hits one.
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-17-2006 07:46
From: Artemis Cain
the (!used) is used to determine whether or not a certain texture has been used (to avoid duplicates)

Yup, i understand... reworked that part into do {} while( used ) loop, this way you don't need the 'else jump' thing.

The if( blocks > 1 ) --blocks check would do what you want, but then there's still issue with that loop you have there... i.e. it seems to lack any check on when it's "all done" and the program can move on, and which would be put in the outermost while() test.

(right now this isn't obvious because the code breaks earlier, when it divides by 0)

edit: nevermind, i got confused there and overthought that

CODE

integer used;
do {
tex = llFloor( llFrand( llGetListLength(textures) ) );
used = llList2Integer(giUsed, tex);

} while( used == TRUE )

if( blocks > 1 ) --blocks;

chosen_texture = llList2String( textures, tex );
giUsed = llDeleteSubList( giUsed, tex, tex );
giUsed = llListInsertList( giUsed, [TRUE], tex );
amount_left -= llList2Integer( amount, tex );
number = amount_left / blocks / 7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;
Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 07:54
to spare the expense of putting a huge bit of code in a post, I just took this one part out and posted it. I probably should have added some background to explain where this code is happening.

This part of the code is invoked when you touch a "block"
the block sends a message to the ROOT_PRIM asking for a texture.

the ROOT_PRIM runs this code to determine the texture to assign that "block"

it also uses this time to tally the score.

basically, once it sends the message, it stops running.

I get the math error when I try to assign the last available texture to the last available block. this way, each block is randomly given a texture that is different from all others, and doesn't always get the same texture.

I hope that clears things up a little!
Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 07:59
That is sort of what I am trying to accomplish, only with the while and if statements reversed.

I want it to check IF used = false WHILE blocks >1.

because, the used (TRUE/FALSE) keeps the script from duplicating textures/point value awarded to block.
Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 08:05
From: Joannah Cramer
Yup, i understand... reworked that part into do {} while( used ) loop, this way you don't need the 'else jump' thing.

The if( blocks > 1 ) --blocks check would do what you want, but then there's still issue with that loop you have there... i.e. it seems to lack any check on when it's "all done" and the program can move on, and which would be put in the outermost while() test.

(right now this isn't obvious because the code breaks earlier, when it divides by 0)

edit: nevermind, i got confused there and overthought that

CODE

integer used;
do {
tex = llFloor( llFrand( llGetListLength(textures) ) );
used = llList2Integer(giUsed, tex);

} while( used == TRUE )

if( blocks > 1 ) --blocks;

chosen_texture = llList2String( textures, tex );
giUsed = llDeleteSubList( giUsed, tex, tex );
giUsed = llListInsertList( giUsed, [TRUE], tex );
amount_left -= llList2Integer( amount, tex );
number = amount_left / blocks / 7;
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;

That is sort of what I am trying to accomplish, only with the while and if statements reversed.

I want it to check IF used = false WHILE blocks >1.

because, the used (TRUE/FALSE) keeps the script from duplicating textures/point value awarded to block.
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-17-2006 08:21
From: Artemis Cain
That is sort of what I am trying to accomplish, only with the while and if statements reversed.

I want it to check IF used = false WHILE blocks >1.

because, the used (TRUE/FALSE) keeps the script from duplicating textures/point value awarded to block.

Aye, the way i wrote it just probably makes it tiny bit more easier to write down and then process. It breaks the code into three sub-parts: first it keeps trying to pick a texture from list until the unused texture is found. Then the number of blocks is reduced unless it means reducing it to 0, and then the calculations of score are done.

If the code is run once per 'tile touch' then you probably don't really want to use the while() the way you originally had it -- while() is used to repeat a series of operations until something specific happens. Like trying to pick a texture that wasn't already utilized. On the other hand for your block variable test a simple if() check done during the single per-touch pass the code performs, is all that you'd need.

To make it a tad bit easier to read it could probably be re-arranged into:
CODE

// pick texture
integer used;
do {
tex = llFloor( llFrand( llGetListLength(textures) ) );
used = llList2Integer(giUsed, tex);

} while( used == TRUE )

// send it
chosen_texture = llList2String( textures, tex );
llMessageLinked( sender, 0, "tex_req", chosen_texture ) ;

// write down this texture is used
giUsed = llDeleteSubList( giUsed, tex, tex );
giUsed = llListInsertList( giUsed, [TRUE], tex );

// update the score
if( blocks > 1 ) --blocks;
amount_left -= llList2Integer( amount, tex );
number = amount_left / blocks / 7;
Artemis Cain
Take it or Leave it
Join date: 11 Apr 2005
Posts: 116
05-17-2006 08:28
Interesting, never thought of trying it that way. Let me try it...