This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

CofD Dice Script: mcr to tcl conversion

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
S
Steamwolf
Voice
Posts: 8
Joined: Mon May 08, 2017 5:32 pm

CofD Dice Script: mcr to tcl conversion

Post by Steamwolf »

Hello! :-)

Please bear with my incredible lack of experience. I've tried searching for an answer to this, and I've tried muscling through tutorials on tcl, but I have a long way to go before I even begin to understand what I'm doing.

I've recently started up my very first private irc server to run a game (Chronicles of Darkness) with some friends, which is great fun and a total adventure in learning technical things I've never thought I'd be able to do. That said, I have a few dice scripts coded in mIRC that I would very much like to port over to my Eggdrop bot, but I simply don't have the experience with tcl required to do so.

If anyone could possibly help me out, I'd be most appreciative.

Here's the code for my three current scripts in mIRC...

Code: Select all

on *:text:!roll*:#: {
  if ($2 !isnum) { msg # (( Sorry, but you need to tell me how many dice to roll! The correct syntax is !draw #pool #reroll explanation. )) | return }
  if ($3 !isnum) { msg # (( Sorry, but you need to tell me on what number to reroll. 10? 9? 8? The correct syntax is !draw #pool #reroll explanation. )) | return }
  if ($4 == $null) { msg # (( Sorry, but you need to tell me what you're trying to do. The correct syntax is !draw #pool #reroll explanation. )) | return }
  var %totsucs = 0
  var %c = $2
  if (%c > 100) {
    msg # No way, That's too many dice!
    halt
  }
  :reroll
  var %dice = %blank
  var %rers = %blank
  var %s10s = %blank
  var %s9s = %blank
  var %s8s = %blank
  var %sucs = %blank
  while (%c > 0) { 
    var %roll = $rand(1,10) 
    if (%roll = 1) { var %roll = $+ %roll } 
    elseif (%roll isnum 2-7) { var %roll = $+ %roll } 
    elseif (%roll isnum 8-9) { var %roll = $+ %roll } 
    else { var %roll = $+ %roll } 
    var %dice = %dice $+ $iif(%dice, $+ $chr(44)) %roll 
    dec %c
  }
  var %s10 = 10
  var %s9 = 9
  var %s8 = 8
  var %s10s = $count(%dice,%s10)
  var %s9s = $count(%dice,%s9)
  var %s8s = $count(%dice,%s8)
  var %sucs = $calc(%s10s + %s9s + %s8s)
  var %8rr = $calc(%s10s + %s9s + %s8s)
  var %9rr = $calc(%s10s + %s9s)
  var %10rr = $count(%dice,%s10)
  if ($3 = 8) { var %c = %8rr }
  elseif ($3 = 9) { var %c = %9rr }
  else { var %c = %10rr }
  msg # $nick -( %sucs )- $replace(%dice,$chr(46), $+ $chr(44) $+ $chr(32))
  var %temp = %sucs
  var %runtot = $calc(%runtot + %sucs)
  var %sucs = %blank
  var %temp = %blank
  if (%c > 0) {
  goto reroll }
  msg # $nick :: Grand Total Successes: %runtot ( $4- )
  if (%runtot > 4) { msg # $nick :: EXCEPTIONAL SUCCESS!! }
}

Code: Select all

on *:text:!rote*:#: {
  if ($2 !isnum) { msg # (( Sorry, but you need to tell me how many dice to roll! The correct syntax is !draw #pool #reroll explanation. )) | return }
  if ($3 !isnum) { msg # (( Sorry, but you need to tell me on what number to reroll. 10? 9? 8? The correct syntax is !draw #pool #reroll explanation. )) | return }
  if ($4 == $null) { msg # (( Sorry, but you need to tell me what you're trying to do. The correct syntax is !draw #pool #reroll explanation. )) | return }
  var %totsucs = 0
  var %c = $2
  var %rote = 0
  if (%c > 100) {
    msg # No way, That's too many dice!
    halt
  }
  :rotereroll
  while (%c > 0) { 
    var %roll = $rand(1,10) 
    if (%roll = 1) { var %roll = $+ %roll } 
    elseif (%roll isnum 2-7) { var %roll = $+ %roll } 
    elseif (%roll isnum 8-9) { var %roll = $+ %roll } 
    else { var %roll = $+ %roll } 
    var %dice = %dice $+ $iif(%dice, $+ $chr(44)) %roll 
    dec %c
  }
  var %s10 = 10
  var %s9 = 9
  var %s8 = 8
  var %s10s = $count(%dice,%s10)
  var %s9s = $count(%dice,%s9)
  var %s8s = $count(%dice,%s8)
  var %sucs = $calc(%s10s + %s9s + %s8s)
  msg # $nick -( %sucs )- $replace(%dice,$chr(46), $+ $chr(44) $+ $chr(32))
  var %c = $calc($2 - %sucs)
  inc %rote
  var %temp = %sucs
  var %runtot = $calc(%runtot + %sucs)
  var %sucs = %blank
  var %temp = %blank
  var %dice = %blank
  var %rers = %blank
  var %s10s = %blank
  var %s9s = %blank
  var %s8s = %blank
  var %sucs = %blank
  if (%rote < 2) { goto rotereroll }
  else { var %c = %runtot }
  :reroll
  var %dice = %blank
  var %rers = %blank
  var %s10s = %blank
  var %s9s = %blank
  var %s8s = %blank
  var %sucs = %blank
  while (%c > 0) { 
    var %roll = $rand(1,10) 
    if (%roll = 1) { var %roll = $+ %roll } 
    elseif (%roll isnum 2-7) { var %roll = $+ %roll } 
    elseif (%roll isnum 8-9) { var %roll = $+ %roll } 
    else { var %roll = $+ %roll } 
    var %dice = %dice $+ $iif(%dice, $+ $chr(44)) %roll 
    dec %c
  }
  var %s10 = 10
  var %s9 = 9
  var %s8 = 8
  var %s10s = $count(%dice,%s10)
  var %s9s = $count(%dice,%s9)
  var %s8s = $count(%dice,%s8)
  var %sucs = $calc(%s10s + %s9s + %s8s)
  var %8rr = $calc(%s10s + %s9s + %s8s)
  var %9rr = $calc(%s10s + %s9s)
  var %10rr = $count(%dice,%s10)
  if ($3 = 8) { var %c = %8rr }
  elseif ($3 = 9) { var %c = %9rr }
  else { var %c = %10rr }
  msg # $nick -( %sucs )- $replace(%dice,$chr(46), $+ $chr(44) $+ $chr(32))
  var %temp = %sucs
  var %runtot = $calc(%runtot + %sucs)
  var %sucs = %blank
  var %temp = %blank
  if (%c > 0) {
  goto reroll }
  msg # $nick :: Grand Total Successes: %runtot ( $4- )
  if (%runtot > 4) { msg # $nick :: EXCEPTIONAL SUCCESS!! }
}

Code: Select all

on *:text:!chance*:#: {
  if ($2 == $null) { msg # (( Sorry, but you need to tell me what you're trying to do. The correct syntax is !chance explanation. )) | return }
  var %totsucs = 0
  var %totsucs = 0
  var %c = 1
  :reroll
  var %dice = %blank
  var %rers = %blank
  var %s10s = 0
  var %s9s = %blank
  var %s8s = %blank
  var %s1s = %blank
  var %sucs = %blank
  while (%c > 0) { 
    var %roll = $rand(1,10) 
    if (%roll = 1) { var %roll = $+ %roll } 
    elseif (%roll isnum 2-7) { var %roll = $+ %roll } 
    elseif (%roll isnum 8-9) { var %roll = $+ %roll } 
    else { var %roll = $+ %roll } 
    var %dice = %dice $+ $iif(%dice, $+ $chr(44)) %roll 
    dec %c
  }
  var %s10 = 10
  var %s1 = 1
  var %s10s = $count(%dice,%s10)
  var %s1s = $count(%dice,%s1)
  var %sucs = %s10s
  var %botch = %s1s
  var %10rr = $count(%dice,%s10)
  var %c = %10rr
  msg # $nick -( %sucs )- $replace(%dice,$chr(46), $+ $chr(44) $+ $chr(32))
  if (%s1s > 0) { if (%s10s = 0) { msg # $nick -( !! DRAMATIC FAILURE !! )- } }
  var %temp = %sucs
  var %runtot = $calc(%runtot + %sucs)
  var %sucs = %blank
  var %temp = %blank
  if (%c > 0) {
  goto reroll }
  msg # $nick :: Grand Total Successes: %runtot ( $2- )
  if (%runtot > 4) { msg # $nick :: EXCEPTIONAL SUCCESS!! }
}
Last edited by Steamwolf on Tue May 09, 2017 7:12 am, edited 2 times in total.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Code: Select all

namespace eval diceGames {

	bind pub * !roll [namespace current]::pubRoll
	
	proc pubRoll {nick uhost hand chan text} {
		scan $text {%s%s%s} pool redraw explanation
		if {![string is integer $pool]} {
			puthelp "PRIVMSG $chan :Sorry, but you need to tell me how many dice to roll! The correct syntax is !roll #pool #redraw explanation."
			return
		}
		if {![string is integer $redraw]} {
			puthelp "Sorry, but you need to tell me on what number to redraw. 10? 9? 8? The correct syntax is !roll #pool #redraw explanation."
			return
		}
		if {![string length $explanation]} {
			puthelp "PRIVMSG $chan :Sorry, but you need to tell me what you're trying to do. The correct syntax is !roll #pool #redraw explanation."
			return
		}
		if {$redraw > 100} {
			puthelp "PRIVMSG $chan :No way, That's too many dice!"
			return
		}
		for {set x 0} {$x < $count} {incr x} {
			lappend dices [expr [rand 10] + 1]
		}
		set numbers "10 9 8"
		foreach no [split $numbers] {
			set count($no) [count $dices $no]
		}
		foreach {index value} [array get count] { incr sucs $value }
		switch -- $explanation { 8 { set c $sucs } 9 { set c [expr $count(10) + $count(9)] } default { set c $count(10) } }
		puthelp "PRIVMSG $chan :$nick -( $sucs )- [join $dices ", "]"
		puthelp "PRIVMSG $chan :$nick :: Grand Total Successes: $sucs ( $explanation )
		if ($sucs > 4) {
			puthelp "PRIVMSG $chan :$nick :: EXCEPTIONAL SUCCESS!!"
		}
	}

	proc rand {max} {
		return [expr {int(rand()*$max) + 1}]
	}

	proc count {haystack needle} {
		set c [set pos 0]
			while {[set pos [expr {[string first $needle $haystack $pos] + 1}]]} {
				incr c
			}
		return $c
	}
}
I'm not 100% sure I fully understood the code so give this a try and let me know if works and the result is as expected.
Once the game is over, the king and the pawn go back in the same box.
S
Steamwolf
Voice
Posts: 8
Joined: Mon May 08, 2017 5:32 pm

Post by Steamwolf »

Whoops! I just realized I had the word redraw in there instead of reroll. lol, my bad.

Thanks for the script! :-) I'll be able to test it in a few hours on my lunch break.

Basically, the first script responds to a command of "!roll #1 #2 explanation" by generating #1 random numbers from one to ten, counting any that come up as >= 8 as "successes" and then continuing to generate random numbers from one to ten for any that came up >= #2 until there are no more numbers >= #2 to reroll. It then tallies up all the successes and responds with that number. If the successes >= 5, it says "Exceptional Success"

The check for >100 is to check the pool, rather than the reroll number. if someone tries to roll more than 100 dice, the script should balk at them.

--

The second script does exactly the same thing, except it uses !rote instead of !roll, and on the first roll (before any rerolls), all "failures" ( dice that came up less than 8 ) are rerolled. After which, rerolls continue normally.

--

The last script responds to !chance by rolling a single die (random number one to ten) and seeing if the result is a ten. If it is, it adds one to the success tally and continues rerolling until the result is no longer ten. If the first roll is a one, it returns "Dramatic Failure"
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Don't know how mrc treats the jump to :reroll for instance so need to test that code and say if it dose as should or not and will take it from there with the rest.

Would be great if you could give me an example cos honestly don't know what #1, #2 or explanation are meant to be.
Once the game is over, the king and the pawn go back in the same box.
S
Steamwolf
Voice
Posts: 8
Joined: Mon May 08, 2017 5:32 pm

Post by Steamwolf »

I must be doing something wrong... I loaded the script, rehashed, and typed !roll 10 10 test

and nothing happened...

But then I came to realize, it seems that my eggdrop bot isn't responding to triggers from text on public channels at all... is there some setting I didn't realize I needed to turn on or something?





Here's an example using my current mIRC bot...

<~Jason> !roll 20 10 This is a test where I roll 20 ten sided dice and reroll any that come up tens
<+Paradigm> Jason -( 5 )- 2, 9, 8, 2, 7, 1, 9, 2, 2, 6, 10, 7, 10, 2, 4, 1, 4, 7, 6, 5
<+Paradigm> Jason -( 1 )- 3, 8
<+Paradigm> Jason :: Grand Total Successes: 6 ( This is a test where I roll 20 ten sided dice and reroll any that come up tens )
<+Paradigm> Jason :: EXCEPTIONAL SUCCESS!!
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Right so !roll 20 10 whatever will pick 20 random numbers from 1 to 10, let's say 2, 9, 8, 2, 7, 1, 9, 2, 2, 6, 10, 7, 10, 2, 4, 1, 4, 7, 6, 5 and then what?

If you loaded the code as it is then the bot should respond. You see any errors in DCC Chat/Telnet with it?
Once the game is over, the king and the pawn go back in the same box.
S
Steamwolf
Voice
Posts: 8
Joined: Mon May 08, 2017 5:32 pm

Post by Steamwolf »

omg I'm so sorry, I thought I replied to this!

willyw PM'd me, and together we managed to work everything out. I was reminded by a friend that sometimes players are denied re-rolls, so we just went with a single-roll system.

Thanks for the script! With our minor tweaking, it was exactly what I needed!
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Ah! Ok. No problem, glad you guys sorted it out. Would be great if could share what you altered just for the sake of understanding where i did wrong. :)
Once the game is over, the king and the pawn go back in the same box.
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

caesar wrote:Ah! Ok. No problem, glad you guys sorted it out. Would be great if could share what you altered just for the sake of understanding where i did wrong. :)
caesar:
I think what happened is that Steamwolf decided it was ok as-is. Because I barely remember discussing it with him... I haven't even spent enough time on it to really try to understand what is going on with it. :)

What I did with him was some sort of score keeping thing. Let's him read/write to a text file.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
S
Steamwolf
Voice
Posts: 8
Joined: Mon May 08, 2017 5:32 pm

Post by Steamwolf »

We did spend a bit of time on it in the beginning before we started working on the resources database project, though the edits were pretty minor.

Here's the final code :-) Thanks again for all the help guys!

Code: Select all

namespace eval cofdroll { 

   bind pub * !roll [namespace current]::pubRoll 
    
   proc pubRoll {nick uhost hand chan text} { 
      ###scan $text {%s%s} pool explanation

      set pool [lindex [split $text] 0 ]
      # set reroll [lindex [split $text] 1 ]
      set explanation [lrange [split $text] 1 end ]

      # use the following lines only for testing, then just comment them out when they irritate you
      # putserv "privmsg $chan :pool is: $pool   -  reroll is: $reroll "
      # putserv "privmsg $chan :explanation is: $explanation"
      # putserv "privmsg $chan : "

      if {![llength [split $text] ] } {
         putserv "privmsg $chan :Sorry, but you need to tell me how many dice to roll! The correct syntax is !roll #pool explanation."
         return
      } 
      if {![string is integer $pool]} { 
         puthelp "PRIVMSG $chan :Sorry, but you need to tell me how many dice to roll! The correct syntax is !roll #pool explanation." 
         return 
      } 
      # if {![string is integer $reroll]} { 
      #    puthelp "PRIVMSG $chan :Sorry, but you need to tell me on what number to reroll. 10? 9? 8? The correct syntax is !roll #pool explanation." 
      #    return 
      # } 
      if {![string length $explanation]} { 
         puthelp "PRIVMSG $chan :Sorry, but you need to tell me what you're trying to do. The correct syntax is !roll #pool explanation." 
         return 
      } 

      if {$pool > 50} {
      if {$nick != "Jason"} {
         putserv "kick $chan $nick :BAHAhaHAhaHahAH!! You're so funny!"
         putserv "invite $chan $nick"
         return
      }
      }
      for {set x 0} {$x < $pool} {incr x} { 
         lappend dices [expr [rand 10]] 
      } 
      set numbers "10 9 8" 
      foreach no [split $numbers] { 
         set count($no) [count $dices $no] 
      } 
      foreach {index value} [array get count] { incr sucs $value } 
      switch -- $explanation { 8 { set c $sucs } 9 { set c [expr $count(10) + $count(9)] } default { set c $count(10) } } 
      # puthelp "PRIVMSG $chan :$nick -( $sucs )- [join $dices ", "]" 
      # putserv "privmsg $chan :dices is: $dices"

      set num10s  [ llength [lsearch -all -inline $dices 10 ] ]
      set num9s  [ llength [lsearch -all -inline $dices 9 ] ]
      set numfails [expr $pool - $sucs]

      # putserv "privmsg $chan :10s is: $num10s"
      # putserv "privmsg $chan :9s is: $num9s"
      # putserv "privmsg $chan :failures is: $numfails"

      putserv "PRIVMSG $chan :=$nick= Rolled $sucs Success(es) for \"$explanation\" - Tens: $num10s, Nines: $num9s, Failures: $numfails ( $dices )"
      # if {$sucs > 4} { 
      #    puthelp "PRIVMSG $chan :$nick :: EXCEPTIONAL SUCCESS!!" 
      # } 
   } 

   proc rand {max} { 
      return [expr {int(rand()*$max) + 1}] 
   } 

   proc count {haystack needle} { 
      set c [set pos 0] 
         while {[set pos [expr {[string first $needle $haystack $pos] + 1}]]} { 
            incr c 
         } 
      return $c 
   } 
} 
I added the kick commentary myself ;-)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

You should replace:

Code: Select all

if {$nick != "Jason"} { 
with:

Code: Select all

if {![string equal -nocase $nick "Jason"]} {
to make it be case insensitive, meaning jason isn't equal with Jason or JASON for example.

Don't know why I didn't think about lsearch -all -inline in the first place cos is by far a better solution than the while loop I opted for.

Code: Select all

% time {llength [lsearch -all -inline $dices 9]} 1000
1.167 microseconds per iteration
% time {count $dices 9} 1000
3.851 microseconds per iteration
This means that if we run the two commands 1000 times then the results lsearch will be roughly 3.3 times faster. Good job willy! :)

With this info in mind i would consider dumping my old count function in favor of:

Code: Select all

proc count {haystack needle} {
	set count [llength [lsearch -all -inline $haystack $needle]]
}
then remove the:

Code: Select all

      set num10s  [ llength [lsearch -all -inline $dices 10 ] ]
      set num9s  [ llength [lsearch -all -inline $dices 9 ] ] 
and use $count(10) instead of $num10s and $count(9) instead of $num9s.

You can also drop the rand function cos I left it there because tclsh doesn't have the rand function and had to create it when was testing the code.
Once the game is over, the king and the pawn go back in the same box.
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

caesar wrote: ...
This means that if we run the two commands 1000 times then the results lsearch will be roughly 3.3 times faster. Good job willy! :)
...
No credit deserved. :)

This is where I admit that if that is true, then it was just dumb luck on my part... because I don't like using while loops, because I always screw them up, and have to go re-read a few times, to un-screw them.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
Post Reply