TCL 931
Grok.tc By siosios on 1st September 2025 10:58:46 AM
  1. package require http
  2. package require json
  3.  
  4. # Configuration
  5. set ai(link) "http://127.0.0.1:5000/chat"        ;# Flask API endpoint for Grok
  6. set ai(secured) "0"                               ;# HTTPS disabled (0 = HTTP, 1 = HTTPS)
  7. set ai(rate_limit) 5                              ;# Seconds between user requests per channel (non-poker commands)
  8. set ai(max_msg_length) 400                        ;# Max IRC message length
  9. set ai(max_request_age) 3600                      ;# Clean request records older than 1 hour
  10. array set ai_last_request {}                      ;# Track last request time per user-channel
  11. array set poker_games {}                          ;# Track poker games per channel
  12.  
  13. # Enable HTTPS if configured
  14. if {$ai(secured) == 1} {
  15.     package require tls
  16.     http::register https 443 [list ::tls::socket -autoservername true]
  17. }
  18.  
  19. # Bind to public messages
  20. bind pubm - * ai:botnickTalk
  21. setudef flag grok
  22.  
  23. proc ai:botnickTalk {nick uhost handle target args} {
  24.     global botnick ai ai_last_request poker_games
  25.     set message [join [lrange $args 0 end] " "]
  26.     putlog "Received message from $nick in $target: $message"
  27.    
  28.     # Check for $botnick, $botnick:, $botnick,, grok, grok:, grok,, or exact $botnick/grok
  29.     if {![string match -nocase "$botnick *" $message] &&
  30.         ![string match -nocase "$botnick:*" $message] &&
  31.         ![string match -nocase "$botnick,*" $message] &&
  32.         ![string equal -nocase $botnick $message] &&
  33.         ![string match -nocase "grok *" $message] &&
  34.         ![string match -nocase "grok:*" $message] &&
  35.         ![string match -nocase "grok,*" $message] &&
  36.         ![string equal -nocase "grok" $message]} {
  37.         return
  38.     }
  39.    
  40.     if {![channel get $target grok]} {
  41.         putlog "Grok not enabled for channel $target"
  42.         putquick "PRIVMSG $target :Grok is not enabled for this channel."
  43.         return
  44.     }
  45.    
  46.     # Extract the message content based on the addressing style
  47.     if {[string match -nocase "$botnick *" $message]} {
  48.         set message [string trim [string range $message [string length $botnick] end]]
  49.     } elseif {[string match -nocase "$botnick:*" $message]} {
  50.         set message [string trim [string range $message [expr {[string length $botnick] + 1}] end]]
  51.     } elseif {[string match -nocase "$botnick,*" $message]} {
  52.         set message [string trim [string range $message [expr {[string length $botnick] + 1}] end]]
  53.     } elseif {[string equal -nocase $botnick $message]} {
  54.         set message ""
  55.     } elseif {[string match -nocase "grok *" $message]} {
  56.         set message [string trim [string range $message 4 end]]
  57.     } elseif {[string match -nocase "grok:*" $message]} {
  58.         set message [string trim [string range $message 5 end]]
  59.     } elseif {[string match -nocase "grok,*" $message]} {
  60.         set message [string trim [string range $message 5 end]]
  61.     } elseif {[string equal -nocase "grok" $message]} {
  62.         set message ""
  63.     }
  64.    
  65.     if {$message == ""} {
  66.         putquick "PRIVMSG $target :Please provide a message!"
  67.         return
  68.     }
  69.    
  70.     if {[string equal -nocase "channels" $message]} {
  71.         putlog "Processing channels command from $nick in $target"
  72.         ai:list_channels $nick $target
  73.         return
  74.     }
  75.    
  76.     if {[string equal -nocase "reload" $message]} {
  77.         putlog "Processing reload command from $nick in $target"
  78.         ai:reload_scripts $nick $target $uhost
  79.         return
  80.     }
  81.    
  82.     if {[string equal -nocase "clearpoker" $message]} {
  83.         global poker_games
  84.         if {[info exists poker_games($target)]} {
  85.             unset poker_games($target)
  86.             putquick "PRIVMSG $target :Poker game data cleared."
  87.             putlog "Poker game data cleared for $target by $nick"
  88.         } else {
  89.             putquick "PRIVMSG $target :No poker game data to clear."
  90.         }
  91.         return
  92.     }
  93.    
  94.     if {[string equal -nocase "debug" $message]} {
  95.         putlog "Processing debug command from $nick in $target"
  96.         ai:debug_channel $nick $target
  97.         return
  98.     }
  99.    
  100.     if {[string match -nocase "poker *" $message]} {
  101.         putlog "Processing poker command from $nick in $target: $message"
  102.         poker:handle_command $nick $target [string range $message 6 end]
  103.         return
  104.     }
  105.    
  106.     set user_key "$nick:$target"
  107.     set current_time [clock seconds]
  108.     if {[info exists ai_last_request($user_key)] && [expr {$current_time - $ai_last_request($user_key)}] < $ai(rate_limit)} {
  109.         putquick "PRIVMSG $target :Please wait a few seconds before asking again!"
  110.         return
  111.     }
  112.     set ai_last_request($user_key) $current_time
  113.    
  114.     ai:clean_old_requests $current_time
  115.    
  116.     set encodedMessage [::http::formatQuery message $message nick $nick]
  117.     set url "$ai(link)?$encodedMessage"
  118.     putlog "Sending request to $url"
  119.    
  120.     set attempts 0
  121.     set max_attempts 3
  122.     while {$attempts < $max_attempts} {
  123.         incr attempts
  124.         if {[catch {
  125.             ::http::geturl $url -timeout 30000 -command [list ai:callback $target $nick] -headers {Accept application/json}
  126.         } error]} {
  127.             putlog "HTTP error (attempt $attempts/$max_attempts): $error"
  128.             if {$attempts < $max_attempts} {
  129.                 putlog "Retrying after [expr {1000 * (2 ** ($attempts - 1))}]ms"
  130.                 after [expr {1000 * (2 ** ($attempts - 1))}]
  131.                 continue
  132.             }
  133.             putquick "PRIVMSG $target :Sorry, I couldn't connect to Grok! (Error: $error, Attempt: $attempts/$max_attempts)"
  134.             return
  135.         }
  136.         return
  137.     }
  138. }
  139.  
  140. proc ai:debug_channel {nick target} {
  141.     global botnick
  142.     set channel_list [channels]
  143.     set user_list [chanlist $target]
  144.     set user_count [llength [lsearch -all -not -inline $user_list $botnick]]
  145.     set modes [getchanmode $target]
  146.     set debug_msg "Debug for $target: Bot in channel: [expr {[lsearch -nocase $channel_list $target] >= 0}], Users: [join $user_list ", "], Count (excl. bot): $user_count, Modes: $modes, Grok enabled: [channel get $target grok]"
  147.     putquick "PRIVMSG $target :$debug_msg"
  148.     putlog "Debug requested by $nick in $target: $debug_msg"
  149. }
  150.  
  151. proc ai:list_channels {nick target} {
  152.     set channel_list [channels]
  153.     if {[llength $channel_list] == 0} {
  154.         putquick "PRIVMSG $target :I'm not in any channels."
  155.         putlog "Channels command by $nick in $target: No channels"
  156.         return
  157.     }
  158.     putquick "PRIVMSG $target :I'm currently in: [join $channel_list ", "]"
  159.     putlog "Channels command by $nick in $target: Listed channels [join $channel_list ", "]"
  160. }
  161.  
  162. proc ai:reload_scripts {nick target uhost} {
  163.     global botnick
  164.     if {![matchattr [nick2hand $nick $uhost] n]} {
  165.         putquick "PRIVMSG $target :$nick, you don't have permission to reload scripts."
  166.         putlog "Reload failed: $nick ($uhost) is not an owner in $target"
  167.         return
  168.     }
  169.    
  170.     if {[catch {
  171.         rehash
  172.         putquick "PRIVMSG $target :Scripts reloaded successfully by $nick."
  173.         putlog "Scripts reloaded successfully by $nick in $target"
  174.     } error]} {
  175.         putquick "PRIVMSG $target :Failed to reload scripts: $error"
  176.         putlog "Reload failed: Error reloading scripts for $nick in $target: $error"
  177.     }
  178. }
  179.  
  180. proc ai:clean_old_requests {current_time} {
  181.     global ai ai_last_request
  182.     foreach key [array names ai_last_request] {
  183.         if {[expr {$current_time - $ai_last_request($key)}] > $ai(max_request_age)} {
  184.             unset ai_last_request($key)
  185.         }
  186.     }
  187. }
  188.  
  189. proc ai:callback {target nick token} {
  190.     global ai
  191.     set status [::http::status $token]
  192.     set response [::http::data $token]
  193.     set http_code [::http::ncode $token]
  194.     ::http::cleanup $token
  195.    
  196.     if {$status != "ok" || $http_code != 200} {
  197.         putlog "HTTP error: status=$status, code=$http_code, response=$response"
  198.         putquick "PRIVMSG $target :Sorry, I couldn't connect to Grok! (Status: $status, Code: $http_code)"
  199.         return
  200.     }
  201.    
  202.     if {[catch {set json_data [::json::json2dict $response]} error]} {
  203.         putlog "JSON parse error: $error, response=$response"
  204.         putquick "PRIVMSG $target :Sorry, I couldn't parse the Grok response!"
  205.         return
  206.     }
  207.    
  208.     if {[dict exists $json_data reply]} {
  209.         set output [dict get $json_data reply]
  210.         ai:displayMessage $output $target $nick
  211.     } else {
  212.         set fallback [dict exists $json_data fallback] ? [dict get $json_data fallback] : "Sorry, no response from Grok!"
  213.         putlog "JSON missing reply key: $response"
  214.         putquick "PRIVMSG $target :$fallback"
  215.     }
  216. }
  217.  
  218. proc ai:displayMessage {output target nick} {
  219.     global ai
  220.     set output [string map {\\\" "\"" \\n "\n" \\t "\t"} $output]
  221.     foreach line [split $output "\n"] {
  222.         if {$line == ""} {
  223.             continue
  224.         }
  225.         while {[string length $line] > $ai(max_msg_length)} {
  226.             set chunk [string range $line 0 [expr {$ai(max_msg_length) - 1}]]
  227.             set last_space [string last " " $chunk]
  228.             if {$last_space > 0} {
  229.                 set chunk [string range $line 0 [expr {$last_space - 1}]]
  230.                 set line [string range $line $last_space end]
  231.             } else {
  232.                 set line [string range $line $ai(max_msg_length) end]
  233.             }
  234.             putquick "PRIVMSG $target :$chunk"
  235.         }
  236.         if {$line != ""} {
  237.             putquick "PRIVMSG $target :$line"
  238.         }
  239.     }
  240. }
  241.  
  242. proc isbotconnected {} {
  243.     global server
  244.     if {[info exists server] && [string length $server] > 0} {
  245.         return 1
  246.     }
  247.     return 0
  248. }
  249.  
  250. proc poker:handle_command {nick target command} {
  251.     global poker_games ai
  252.     set command [string tolower [string trim $command]]
  253.    
  254.     putlog "Handling poker command: '$command' from $nick in $target"
  255.    
  256.     if {$command == "start"} {
  257.         poker:start_game $nick $target
  258.     } elseif {$command == "join"} {
  259.         poker:join_game $nick $target
  260.     } elseif {[string match "bet *" $command]} {
  261.         set amount [lindex [split $command] 1]
  262.         putlog "Parsed bet amount: '$amount' for $nick in $target"
  263.         poker:bet $nick $target $amount
  264.     } elseif {$command == "fold"} {
  265.         poker:fold $nick $target
  266.     } elseif {$command == "call"} {
  267.         poker:call $nick $target
  268.     } elseif {$command == "status"} {
  269.         poker:status $nick $target
  270.     } elseif {$command == "stop"} {
  271.         poker:stop_game $nick $target
  272.     } elseif {$command == "debug"} {
  273.         poker:debug_state $nick $target
  274.     } else {
  275.         putquick "PRIVMSG $target :Unknown poker command. Try: start, join, bet <amount>, fold, call, status, stop, debug"
  276.         putlog "Unknown command: $command"
  277.     }
  278. }
  279.  
  280. proc poker:start_game {nick target} {
  281.     global poker_games
  282.     if {[info exists poker_games($target)]} {
  283.         putquick "PRIVMSG $target :A poker game is already running in this channel!"
  284.         putlog "Game already exists in $target"
  285.         return
  286.     }
  287.    
  288.     set poker_games($target) [dict create \
  289.         players [list $nick] \
  290.         hands [dict create $nick [poker:deal_cards]] \
  291.         community_cards {} \
  292.         pot 0 \
  293.         current_bet 0 \
  294.         stage "preflop" \
  295.         active_players [list $nick] \
  296.         chips [dict create $nick 1000]
  297.     ]
  298.    
  299.     putlog "Game started by $nick in $target. Players: [dict get $poker_games($target) players], Active: [dict get $poker_games($target) active_players]"
  300.     putquick "PRIVMSG $target :Poker game started by $nick! Use 'Grok poker join' to join."
  301.     poker:notify_player $nick $target
  302.     poker:send_grok_comment $target "A new poker game has started! Let's see who has the best poker face."
  303. }
  304.  
  305. proc poker:join_game {nick target} {
  306.     global poker_games
  307.     if {![info exists poker_games($target)]} {
  308.         putquick "PRIVMSG $target :No poker game running. Start one with 'Grok poker start'."
  309.         putlog "No game found in $target for $nick to join"
  310.         return
  311.     }
  312.    
  313.     set game $poker_games($target)
  314.     if {[lsearch [dict get $game players] $nick] >= 0} {
  315.         putquick "PRIVMSG $target :$nick, you're already in the game!"
  316.         putlog "$nick already in game in $target"
  317.         return
  318.     }
  319.    
  320.     dict lappend game players $nick
  321.     dict set game hands $nick [poker:deal_cards]
  322.     dict lappend game active_players $nick
  323.     dict set game chips $nick 1000
  324.     set poker_games($target) $game
  325.    
  326.     putlog "$nick joined game in $target. Players: [dict get $game players], Active: [dict get $game active_players]"
  327.     putquick "PRIVMSG $target :$nick has joined the poker game!"
  328.     poker:notify_player $nick $target
  329.     poker:send_grok_comment $target "$nick joins the table. Time to shuffle up and deal!"
  330. }
  331.  
  332. proc poker:deal_cards {} {
  333.     set suits {♠ ♥ ♦ ♣}
  334.     set ranks {2 3 4 5 6 7 8 9 10 J Q K A}
  335.     set deck {}
  336.     foreach suit $suits {
  337.         foreach rank $ranks {
  338.             lappend deck "$rank$suit"
  339.         }
  340.     }
  341.     set card1 [lindex $deck [expr {int(rand() * [llength $deck])}]]
  342.     set deck [lremove $deck $card1]
  343.     set card2 [lindex $deck [expr {int(rand() * [llength $deck])}]]
  344.     putlog "Dealt cards: $card1, $card2"
  345.     return [list $card1 $card2]
  346. }
  347.  
  348. proc poker:bet {nick target amount} {
  349.     global poker_games
  350.     putlog "Attempting bet by $nick in $target with amount: '$amount'"
  351.    
  352.     if {![info exists poker_games($target)]} {
  353.         putquick "PRIVMSG $target :No poker game running. Start one with 'Grok poker start'."
  354.         putlog "Bet failed: No game for $nick in $target"
  355.         return
  356.     }
  357.    
  358.     set game $poker_games($target)
  359.     set active_players [dict get $game active_players]
  360.     putlog "Current game state in $target: Players=[dict get $game players], Active=[dict get $game active_players], Stage=[dict get $game stage], Pot=[dict get $game pot], CurrentBet=[dict get $game current_bet]"
  361.    
  362.     if {[lsearch $active_players $nick] < 0} {
  363.         putquick "PRIVMSG $target :$nick, you're not in the active game!"
  364.         putlog "Bet failed: $nick not in active_players: $active_players"
  365.         return
  366.     }
  367.    
  368.     if {![string is integer -strict $amount] || $amount <= 0} {
  369.         putquick "PRIVMSG $target :Please specify a valid bet amount!"
  370.         putlog "Bet failed: Invalid amount '$amount' by $nick"
  371.         return
  372.     }
  373.    
  374.     set chips [dict get $game chips $nick]
  375.     if {$amount > $chips} {
  376.         putquick "PRIVMSG $target :$nick, you only have $chips chips!"
  377.         putlog "Bet failed: $nick tried to bet $amount but has $chips"
  378.         return
  379.     }
  380.    
  381.     dict incr game pot $amount
  382.     dict incr game chips $nick [expr {-1 * $amount}]
  383.     dict set game current_bet $amount
  384.     set poker_games($target) $game
  385.    
  386.     putlog "Bet successful: $nick bet $amount in $target. New pot: [dict get $game pot], Chips: [dict get $game chips $nick], Active: $active_players"
  387.     putquick "PRIVMSG $target :$nick bets $amount chips. Pot is now [dict get $game pot]."
  388.     poker:advance_game $target
  389. }
  390.  
  391. proc poker:fold {nick target} {
  392.     global poker_games
  393.     if {![info exists poker_games($target)]} {
  394.         putquick "PRIVMSG $target :No poker game running. Start one with 'Grok poker start'."
  395.         putlog "No game for fold by $nick in $target"
  396.         return
  397.     }
  398.    
  399.     set game $poker_games($target)
  400.     set active_players [dict get $game active_players]
  401.     if {[lsearch $active_players $nick] < 0} {
  402.         putquick "PRIVMSG $target :$nick, you're not in the active game!"
  403.         putlog "$nick not in active_players: $active_players for fold in $target"
  404.         return
  405.     }
  406.    
  407.     dict set game active_players [lremove $active_players $nick]
  408.     set poker_games($target) $game
  409.    
  410.     putlog "$nick folded in $target. Active: [dict get $game active_players]"
  411.     putquick "PRIVMSG $target :$nick folds."
  412.     poker:advance_game $target
  413. }
  414.  
  415. proc poker:call {nick target} {
  416.     global poker_games
  417.     if {![info exists poker_games($target)]} {
  418.         putquick "PRIVMSG $target :No poker game running. Start one with 'Grok poker start'."
  419.         putlog "No game for call by $nick in $target"
  420.         return
  421.     }
  422.    
  423.     set game $poker_games($target)
  424.     set active_players [dict get $game active_players]
  425.     if {[lsearch $active_players $nick] < 0} {
  426.         putquick "PRIVMSG $target :$nick, you're not in the active game!"
  427.         putlog "$nick not in active_players: $active_players for call in $target"
  428.         return
  429.     }
  430.    
  431.     set current_bet [dict get $game current_bet]
  432.     set chips [dict get $game chips $nick]
  433.     if {$current_bet > $chips} {
  434.         putquick "PRIVMSG $target :$nick, you don't have enough chips to call ($current_bet)!"
  435.         putlog "$nick tried to call $current_bet but has $chips in $target"
  436.         return
  437.     }
  438.    
  439.     dict incr game pot $current_bet
  440.     dict incr game chips $nick [expr {-1 * $current_bet}]
  441.     set poker_games($target) $game
  442.    
  443.     putlog "$nick called $current_bet in $target. Pot: [dict get $game pot], Active: $active_players"
  444.     putquick "PRIVMSG $target :$nick calls $current_bet chips. Pot is now [dict get $game pot]."
  445.     poker:advance_game $target
  446. }
  447.  
  448. proc poker:status {nick target} {
  449.     global poker_games
  450.     if {![info exists poker_games($target)]} {
  451.         putquick "PRIVMSG $target :No poker game running. Start one with 'Grok poker start'."
  452.         putlog "No game for status by $nick in $target"
  453.         return
  454.     }
  455.    
  456.     set game $poker_games($target)
  457.     set players [dict get $game players]
  458.     set community_cards [dict get $game community_cards]
  459.     set pot [dict get $game pot]
  460.     set stage [dict get $game stage]
  461.     set active_players [dict get $game active_players]
  462.    
  463.     putquick "PRIVMSG $target :Poker game status: Stage: $stage, Pot: $pot, Players: [join $players ", "], Active: [join $active_players ", "], Community cards: [join $community_cards ", "]"
  464.     foreach player $players {
  465.         poker:notify_player $player $target
  466.     }
  467.     putlog "Status requested by $nick in $target. Players: $players, Active: $active_players, Stage: $stage"
  468. }
  469.  
  470. proc poker:stop_game {nick target} {
  471.     global poker_games
  472.     if {![info exists poker_games($target)]} {
  473.         putquick "PRIVMSG $target :No poker game running."
  474.         putlog "No game to stop by $nick in $target"
  475.         return
  476.     }
  477.    
  478.     unset poker_games($target)
  479.     putlog "Game stopped by $nick in $target"
  480.     putquick "PRIVMSG $target :Poker game stopped by $nick."
  481.     poker:send_grok_comment $target "Game over! Thanks for playing, everyone."
  482. }
  483.  
  484. proc poker:debug_state {nick target} {
  485.     global poker_games
  486.     if {![info exists poker_games($target)]} {
  487.         putquick "PRIVMSG $target :No poker game running to debug."
  488.         putlog "No game to debug by $nick in $target"
  489.         return
  490.     }
  491.    
  492.     set game $poker_games($target)
  493.     set debug_msg "Debug state for $target: Players=[dict get $game players], Active=[dict get $game active_players], Stage=[dict get $game stage], Pot=[dict get $game pot], CurrentBet=[dict get $game current_bet], CommunityCards=[dict get $game community_cards]"
  494.     foreach player [dict get $game players] {
  495.         append debug_msg ", $player Hand=[dict get $game hands $player], Chips=[dict get $game chips $player]"
  496.     }
  497.     putquick "PRIVMSG $target :$debug_msg"
  498.     putlog "Debug state requested by $nick in $target: $debug_msg"
  499. }
  500.  
  501. proc poker:notify_player {nick target} {
  502.     global poker_games
  503.     if {![info exists poker_games($target)]} {
  504.         return
  505.     }
  506.    
  507.     set game $poker_games($target)
  508.     set hand [dict get $game hands $nick]
  509.     set chips [dict get $game chips $nick]
  510.     putquick "PRIVMSG $target :$nick's hand: [join $hand ", "]. Chips: $chips."
  511.     putlog "Notified $target of $nick's hand: [join $hand ", "], Chips: $chips"
  512. }
  513.  
  514. proc poker:advance_game {target} {
  515.     global poker_games
  516.     if {![info exists poker_games($target)]} {
  517.         putlog "No game to advance in $target"
  518.         return
  519.     }
  520.    
  521.     set game $poker_games($target)
  522.     set stage [dict get $game stage]
  523.     set active_players [dict get $game active_players]
  524.    
  525.     putlog "Advancing game in $target. Stage: $stage, Active players: $active_players"
  526.    
  527.     if {[llength $active_players] <= 1} {
  528.         set winner [lindex $active_players 0]
  529.         set pot [dict get $game pot]
  530.         dict incr game chips $winner $pot
  531.         putquick "PRIVMSG $target :$winner wins the pot of $pot chips!"
  532.         unset poker_games($target)
  533.         poker:send_grok_comment $target "$winner takes it all! Want to play another round?"
  534.         putlog "Game ended in $target. Winner: $winner, Pot: $pot"
  535.         return
  536.     }
  537.    
  538.     if {$stage == "preflop"} {
  539.         set community_cards [poker:deal_community_cards 3]
  540.         dict set game community_cards $community_cards
  541.         dict set game stage "flop"
  542.         set poker_games($target) $game
  543.         putquick "PRIVMSG $target :Flop: [join $community_cards ", "]"
  544.         putlog "Dealt flop in $target: [join $community_cards ", "]"
  545.     } elseif {$stage == "flop"} {
  546.         set community_cards [concat [dict get $game community_cards] [poker:deal_community_cards 1]]
  547.         dict set game community_cards $community_cards
  548.         dict set game stage "turn"
  549.         set poker_games($target) $game
  550.         putquick "PRIVMSG $target :Turn: [join $community_cards ", "]"
  551.         putlog "Dealt turn in $target: [join $community_cards ", "]"
  552.     } elseif {$stage == "turn"} {
  553.         set community_cards [concat [dict get $game community_cards] [poker:deal_community_cards 1]]
  554.         dict set game community_cards $community_cards
  555.         dict set game stage "river"
  556.         set poker_games($target) $game
  557.         putquick "PRIVMSG $target :River: [join $community_cards ", "]"
  558.         putlog "Dealt river in $target: [join $community_cards ", "]"
  559.     } elseif {$stage == "river"} {
  560.         set winner [lindex $active_players 0] ;# Simplified: first active player wins
  561.         set pot [dict get $game pot]
  562.         dict incr game chips $winner $pot
  563.         putquick "PRIVMSG $target :$winner wins the pot of $pot chips!"
  564.         unset poker_games($target)
  565.         poker:send_grok_comment $target "What a game! $winner wins! Ready for another?"
  566.         putlog "Game ended in $target. Winner: $winner, Pot: $pot"
  567.         return
  568.     }
  569.    
  570.     dict set game current_bet 0
  571.     set poker_games($target) $game
  572.     poker:send_grok_comment $target "What's your move? Bet, call, or fold!"
  573. }
  574.  
  575. proc poker:deal_community_cards {count} {
  576.     set suits {♠ ♥ ♦ ♣}
  577.     set ranks {2 3 4 5 6 7 8 9 10 J Q K A}
  578.     set deck {}
  579.     foreach suit $suits {
  580.         foreach rank $ranks {
  581.             lappend deck "$rank$suit"
  582.         }
  583.     }
  584.     set cards {}
  585.     for {set i 0} {$i < $count} {incr i} {
  586.         set card [lindex $deck [expr {int(rand() * [llength $deck])}]]
  587.         lappend cards $card
  588.         set deck [lremove $deck $card]
  589.     }
  590.     putlog "Dealt community cards: [join $cards ", "]"
  591.     return $cards
  592. }
  593.  
  594. proc poker:send_grok_comment {target comment} {
  595.     global ai
  596.     set encodedMessage [::http::formatQuery message $comment nick "Grok"]
  597.     set url "$ai(link)?$encodedMessage"
  598.     putlog "Sending poker comment to $url"
  599.    
  600.     if {[catch {
  601.         ::http::geturl $url -timeout 30000 -command [list ai:callback $target "Grok"] -headers {Accept application/json}
  602.     } error]} {
  603.         putlog "HTTP error for poker comment: $error"
  604.         putquick "PRIVMSG $target :$comment"
  605.     }
  606. }
  607.  
  608. proc lremove {list item} {
  609.     set idx [lsearch $list $item]
  610.     if {$idx >= 0} {
  611.         return [lreplace $list $idx $idx]
  612.     }
  613.     return $list
  614. }
  615.  
  616. putlog "grok.tcl loaded"

N/U PasteBin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.