| View previous topic :: View next topic |
| Author |
Message |
Landslyde Halfop
Joined: 01 May 2014 Posts: 46
|
Posted: Wed Apr 27, 2016 9:20 pm Post subject: Array producing crazy indexes |
|
|
So this is my first-ever script. It's a dice game I use to play growing up way back in the stone age. The dice array is acting weird though. The array information I'm using is from http://www.tcl.tk/man/tcl8.5/tutorial/Tcl22.html.
| Code: |
set dice {
"1"
"2"
"3"
"4"
"5"
"6"
}
proc roll:dice {nick host handle chan arg} {
global dice fPRVMSG fChan numbers
set die1 [lindex $dice [rand [llength $dice]]]
set die2 [lindex $dice [rand [llength $dice]]]
set die3 [lindex $dice [rand [llength $dice]]]
set die4 [lindex $dice [rand [llength $dice]]]
set die5 [lindex $dice [rand [llength $dice]]]
set die6 [lindex $dice [rand [llength $dice]]]
set rolled [list $die1 $die2 $die3 $die4 $die5 $die6]
array set arolled [list $die1 $die2 $die3 $die4 $die5 $die6]
putquick "$fPRVMSG $chan :$nick rolls \002\0030,4 $die1 \003 \002\0030,4 $die2 \003 \002\0030,4 $die3 \003 \002\0030,4 $die4 \003 \002\0030,4 $die5 \003 \002\0030,4 $die6 \003"
putquick "$fPRVMSG $fChan :The rolled numbers are: [array get arolled]"
putquick "$fPRVMSG $fChan :Dice 3 and 5 were: $arolled(2) and $arolled(4)"
}
|
Following the three outputs, this is what I get from my bot:
| Code: | [19:54:30] <@Slyde> .roll
[19:54:31] <Shianne> Slyde rolls 4 2 6 5 2 3
[19:54:32] <Shianne> The rolled numbers are: 4 2 2 3 6 5
[19:54:32] <Shianne> Dice 3 and 5 were: 3 and 2 |
The indexes are off from the way I stored them in the last two outputs. But, like I said, this is my first tcl script. So maybe I'm not using the arrays the right way. Will someone please tell me what I'm doing wrong? Thanks. |
|
| Back to top |
|
 |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Wed Apr 27, 2016 9:55 pm Post subject: Re: Array producing crazy indexes |
|
|
| Landslyde wrote: |
...
putquick "$fPRVMSG $fChan :The rolled numbers are: [array get arolled]"
....
|
See:
http://www.tcl.tk/man/tcl8.5/TclCmd/array.htm#M8
"... The order of the pairs is undefined...."
Is that it?
I hope this helps. _________________ For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia ! |
|
| Back to top |
|
 |
Landslyde Halfop
Joined: 01 May 2014 Posts: 46
|
Posted: Thu Apr 28, 2016 12:35 am Post subject: |
|
|
Thank you for the link. It has a lot more info on arrays. I think I'll be able to sort out what I need, which is allowing the user to select the dice they want to re-roll. That's why having the indexes be static as set in the array is important.
Say the roll is: 2 5 4 6 5 5
They wld want to keep the three 5s and re-roll the 2 4 6. Set in the array, those wld be indexes 0, 2, and 3. Then I'd unset those in the array and append the re-roll to the three 5s. That's why having the indexes static and not rearranging themselves is necessary.
But thank you for the link, willyw. I'll study what they have there and see what I can come up with. |
|
| Back to top |
|
 |
caesar Mint Rubber

Joined: 14 Oct 2001 Posts: 3741 Location: Mint Factory
|
Posted: Thu Apr 28, 2016 1:45 am Post subject: |
|
|
Instead of all this:
| Code: |
set die1 [lindex $dice [rand [llength $dice]]]
set die2 [lindex $dice [rand [llength $dice]]]
set die3 [lindex $dice [rand [llength $dice]]]
set die4 [lindex $dice [rand [llength $dice]]]
set die5 [lindex $dice [rand [llength $dice]]]
set die6 [lindex $dice [rand [llength $dice]]]
|
I would use this code:
| Code: |
proc dice:roll {count} {
for {set x 0} {$x<$count} {incr x} {
lappend roll [expr [rand 6] + 1]
}
return $roll
}
|
to get a roll of 6 dices then:
| Code: |
set roll [dice:roll 6]
|
Now, if taking your example where you got a list of 3 positions to swap and want to generate 3 new rolls, we have the positions stored in a variable, for example:
| Code: |
set pos [list 0 2 3]
|
and to generate 3 or an unknown number of rolls:
| Code: |
set swap [dice:roll [llength $pos]]
|
and then to do the actual swap use this code:
| Code: |
proc dice:swap {pos roll swap} {
set count [llength $pos]
for {set x 0} {$x<$count} {incr x} {
set ele [lindex $pos $x]
set roll [lreplace $roll $ele $ele [lindex $swap $x]]
}
return $roll
}
|
and call it:
| Code: |
set newRoll [dice:swap $pos $roll $swap]
|
From here do whatever you want with $newRoll as is a list with 6 rolls that have been changed in the positions you asked for.
And here's the result:
| Code: |
% set roll [list 2 5 4 6 5 5]
2 5 4 6 5 5
% set pos [list 0 2 3]
0 2 3
% set swap [list 4 6 2]
4 6 2
% dice:swap $pos $roll $swap
4 5 6 2 5 5
|
Hope this helps.  _________________ Once the game is over, the king and the pawn go back in the same box.
Last edited by caesar on Thu Apr 28, 2016 10:19 am; edited 1 time in total |
|
| Back to top |
|
 |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Thu Apr 28, 2016 5:33 am Post subject: |
|
|
| Landslyde wrote: |
...
That's why having the indexes be static as set in the array is important.
...
That's why having the indexes static and not rearranging themselves is necessary.
...
|
Or, is it just necessary to be able to find them somehow? Maybe it would be better to ask that.
This is assuming you are really wanting to work with arrays and learn what they can do. This is not to say that an array is the best tool for your present job.
I don't think that an array works that way - held in position. (Perhaps caesar and nml375 will comment)
When this happens, it can be time to find another way with TCL, to do what you are envisioning. See caesar's code.
If mastering arrays right now is not the main focus, but finding a way to roll your dice is, then spend some time experimenting with his code, piece by piece. Figure out how he is doing it. It is interesting.
I was thinking of lists, but had not gone further.
caesar:
set swap [split $swap]
Just curious - why split? Isn't $swap already a list? _________________ For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia ! |
|
| Back to top |
|
 |
caesar Mint Rubber

Joined: 14 Oct 2001 Posts: 3741 Location: Mint Factory
|
Posted: Thu Apr 28, 2016 9:36 am Post subject: |
|
|
Ah! Right. Power of habit.  _________________ Once the game is over, the king and the pawn go back in the same box. |
|
| Back to top |
|
 |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Thu Apr 28, 2016 9:58 am Post subject: |
|
|
| caesar wrote: | Ah! Right. Power of habit.  |
ahh..
I was doubting myself. I looked it, and again, and again...
Finally, I just had to ask.
By the way:
I forget about for loops. I'm glad you posted that.
Sometimes - not often - I will use a while loop.
With just a quick overview of both, it seems like in many cases, either could be used. _________________ For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia ! |
|
| Back to top |
|
 |
caesar Mint Rubber

Joined: 14 Oct 2001 Posts: 3741 Location: Mint Factory
|
Posted: Thu Apr 28, 2016 10:16 am Post subject: |
|
|
Since the $swap was already a list the split wasn't needed. Thanks for pointing that out. Fixed the above code.
The only notable difference between the for loop and while loop lays in the number of lines you use, else you will get the same results. For example with a while loop the dice:roll function would be:
| Code: |
proc dice:roll {count} {
set x 0
while {$x<$count} {
lappend roll [expr [rand 6] + 1]
incr x
}
return $roll
}
|
As a rule of thumb I tend to stay away from while loops cos if you screw up something, like let's say you forget that increment of the x variable, it has the potential to loop indefinitely and don't want that.
The for loop has all the stuff defined right away in the same line and it's next to impossible to screw up something to make it run indefinitely.  _________________ Once the game is over, the king and the pawn go back in the same box. |
|
| Back to top |
|
 |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Thu Apr 28, 2016 10:29 am Post subject: |
|
|
| caesar wrote: | Since the $swap was already a list...
|
It sure looked like it to me.
| Quote: |
The only notable difference between the for loop and while loop lays in the number of lines you use, else you will get the same results. ...
|
Good.
| Quote: |
As a rule of thumb I tend to stay away from while loops cos if you screw up something, like let's say you forget that increment of the x variable, it has the potential to loop indefinitely and don't want that.
|
I don't forget it, but I still manage to screw it up somehow on the first draft.
| Quote: |
The for loop has all the stuff defined right away in the same line and it's next to impossible to screw up something to make it run indefinitely.  |
Next time I need something like this, and after these few posts here now, maybe I'll remember to utilize the for loop.
Thanks. _________________ For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia ! |
|
| Back to top |
|
 |
Landslyde Halfop
Joined: 01 May 2014 Posts: 46
|
Posted: Tue May 03, 2016 8:10 pm Post subject: |
|
|
willyw and caesar:
Thank you both for your input. I get what you said, all but the $swap / split stuff. I'll work with this and see what I can do. Really appreciated.
And sorry for the pate response. I just set my IRC network back up and have been going hard at it there.
Thanks again  |
|
| Back to top |
|
 |
|