All pastes #69444 Raw Edit

Tic-Tac-Toe

public text v1 · immutable
#69444 ·published 2006-06-22 22:45 UTC
rendered paste body
;------------------------------- Tic-Tac-Toe --------------------------------
;http://www.hawkee.com/view.php?file_id=239

Options:   
Disable Syntax Highlighting Line Numbers Add indentation   
Tic-Tac-Toe  by Cobi (download) [Copy to clipboard]
Allows one to start a game of Tic-Tac-Toe in a channel or in private message.

More documentation is in the comments of the script.

A cool, non-abusive IRC Network where you can find me: irc.nfinate.org
;================================================================
;                  Tic-Tac-Toe By Cobi - Cobi@winbots.org
;================================================================
; Commands:
;  /ttt <channel|nick> <Player1> <Player2> -- Starts game.
;  !ttt <number> -- Put your x/o on <number>.
;  (if enabled) !startttt <nick> -- start a game with <nick>.
;
; Objective:
;  I think we all know how to play Tic-Tac-Toe, But the
;  objective is to get 3 of your marker (X or O) in a row.
;  The first person to achive this, wins.

;18/05/2006 10:35p.m. just finished adding bot code, removing %ttt. $+ $1 $+ .1 1 type code to make it easier
; Source Code:
on *:TEXT:.startttt*:*:{ ttt $iif($chan,$chan,$nick) $nick $2 $3 }

alias ttt {
  if # isin $1 && $3 == $null { msg $1 You need an opponent to play against $2 (try playing against confusbot) | return }
  if # isin $1 && $3 !ison $1 { msg $1 $3 Doesn't seem to be on the channel $2 so game not started | return }
  if # isin $1 && $3 == $2 { msg $1 Sorry $2 but you can't play yourself (try playing against confusbot) | return }
  if %ttt.T != $null) { msg $chan A game is already in progress with %ttt.X and %ttt.O they can use .ttt end to stop the game | return }
  set %ttt.1 1
  set %ttt.2 2
  set %ttt.3 3
  set %ttt.4 4
  set %ttt.5 5
  set %ttt.6 6
  set %ttt.7 7
  set %ttt.8 8
  set %ttt.9 9
  set %ttt.X $2
  set %ttt.O $3
  ; Randomly choose who goes first
  ;  set %ttt.T $2
  set %ttt.T $randphrase($2,$3)
  msg $1 $+(,%ttt.1,|,%ttt.2,|,%ttt.3,)
  msg $1 $+(,%ttt.4,|,%ttt.5,|,%ttt.6,)
  msg $1 $+(%ttt.7,|,%ttt.8,|,%ttt.9)
  msg $1 $+(%ttt.T,'s) go! (use .ttt num to play)
  ;setup code for when playing against bot
  if %ttt.O == $me {
    set %TTT.MoveStr 123456789
    set %TTT.Human 1 | set %TTT.Computer 4
    set %TTT.Humanxo x | set %TTT.Computerxo o
    set %TTTLevel 0
    if ($4 == High) || ($4 == Hard) { set %TTTLevel 0 }
    if ($4 == Med) || ($4 == Medium)  { set %TTTLevel 8 }
    if ($4 == Low) || ($4 == Easy) { set %TTTLevel 32 }
    if $me == %ttt.T { botsTurn }
  }
}

on *:TEXT:.ttt*:*:{
  ;echo tttTEXT1: $1-
  if %ttt.T == $null { msg $chan There is no TicTacToe game currently running, type: .startttt YourOpponent to start a new game | return }
  if $2 == end || $2 == quit || $2 = stop { if (($nick == %ttt.X) || ($nick == %ttt.O)) { msg $iif($chan,$chan,$nick) TicTacToe Game Ended by $nick | unset %ttt.* | return } }
  ;echo tttTEXT2: %ttt.T *method: $iif($chan,$chan,$nick)
  tttmove $nick $iif($chan,$chan,$nick) $2
}
on *:INPUT:*:{
  if ($1 == .ttt) {
    if %ttt.T == $null { msg $chan There is no TicTacToe game currently running, type: .startttt YourOpponent to start a new game | return }
    if $2 == end || $2 == quit || $2 = stop { if (($nick == %ttt.X) || ($nick == %ttt.O)) { msg $iif($chan,$chan,$nick) TicTacToe Game Ended by $nick | unset %ttt.* | return } }
    tttmove $me $iif($chan,$chan,$target) $2
  }
}


alias -l tttmove {
  ;echo tttmove1: %ttt.T
  if ($1 == %ttt.T) {
    if (($1 == %ttt.X) || ($1 == %ttt.O)) {
      if (($3 == 1) || ($3 == 2) || ($3 == 3) || ($3 == 4) || ($3 == 5) || ($3 == 6) || ($3 == 7) || ($3 == 8) || ($3 == 9)) {
        ;echo tttmove2: %ttt.T
        if (%ttt. [ $+ [ $3 ] ] != $3) { msg $2 $1 $+ : You cant move there! }
        else {
          set %ttt. $+ $3 $iif($1 == %ttt.X,X,O)
          if ((!$tttcheckwin($2)) && (!$tttchecknowin($2))) {
            if %ttt.O == $me {
              ;if (( %ttt. [ $+ [ $chan ] $+ ] .X == %ttt. [ $+ [ $2 ] $+ ] .T ) { %TTT.MoveStr = $replace( %TTT.MoveStr, $3 , %TTT.Humanxo ) }
              if $1 == %ttt.t { %TTT.MoveStr = $replace( %TTT.MoveStr, $3 , %TTT.Humanxo ) }
              ;echo tttmove3: %ttt.T *set: %TTT.MoveStr = replace( %TTT.MoveStr, $3 , %TTT.Humanxo )
            }
            if %ttt.T == $me || %ttt.O != $me {
              msg $2 $+(,%ttt.1,|,%ttt.2,|,%ttt.3,)
              msg $2 $+(,%ttt.4,|,%ttt.5,|,%ttt.6,)
              msg $2 $+(%ttt.7,|,%ttt.8,|,%ttt.9)
            }
            set %ttt.T $iif($1 == %ttt.X,%ttt.O,%ttt.X)
            msg $2 $+(%ttt.T,'s) go! - Last play by $iif(%ttt.T == %ttt.X,%ttt.O,%ttt.X) $+ ( $+ $iif(%ttt.T == %ttt.X,O,X) $+ ): $3
            ;echo tttmove4: msg'd game
          }
          else { msg $2 End of Game! | unset %ttt.* }
        }
      }
      else { msg $2 $1 $+ : You cant move there! }
    }
    else { msg $2 $1 $+ : You aren't in the game! }
  }
  else { msg $2 $1 $+ : Not Your Go! }

  if %ttt.O == $me {
    ;echo tttmove5: %ttt.T
    if $me == %ttt.T { botsTurn }
  }

}


alias -l tttcheckwin {
  ; lines:
  ; 123 456 789 147 258 369 159 357
  var %nick = %ttt.T
  var %type = $iif(%nick == %ttt.X,X,O)
  if ($tttcheckline($1,%type,1,2,3)) { return $true }
  if ($tttcheckline($1,%type,4,5,6)) { return $true }
  if ($tttcheckline($1,%type,7,8,9)) { return $true }
  if ($tttcheckline($1,%type,1,4,7)) { return $true }
  if ($tttcheckline($1,%type,2,5,8)) { return $true }
  if ($tttcheckline($1,%type,3,6,9)) { return $true }
  if ($tttcheckline($1,%type,1,5,9)) { return $true }
  if ($tttcheckline($1,%type,3,5,7)) { return $true }
  return $false
}
alias -l tttchecknowin {
  if (%ttt.1 == 1) { return $false }
  if (%ttt.2 == 2) { return $false }
  if (%ttt.3 == 3) { return $false }
  if (%ttt.4 == 4) { return $false }
  if (%ttt.5 == 5) { return $false }
  if (%ttt.6 == 6) { return $false }
  if (%ttt.7 == 7) { return $false }
  if (%ttt.8 == 8) { return $false }
  if (%ttt.9 == 9) { return $false }
  msg $1 Tie Game!
  return $true
}
alias -l tttcheckline {
  if ((%ttt. [ $+ [ $3 ] ] == $2) && (%ttt. [ $+ [ $4 ] ] == $2) && (%ttt. [ $+ [ $5 ] ] == $2)) {
    set %ttt. $+ $1 $+ . $+ $3 04 $+ %ttt. [ $+ [ $3 ] ] $+ 
    set %ttt. $+ $1 $+ . $+ $4 04 $+ %ttt. [ $+ [ $4 ] ] $+ 
    set %ttt. $+ $1 $+ . $+ $5 04 $+ %ttt. [ $+ [ $5 ] ] $+ 
    msg $1 $+(,%ttt.1,|,%ttt.2,|,%ttt.3,)
    msg $1 $+(,%ttt.4,|,%ttt.5,|,%ttt.6,)
    msg $1 $+(%ttt.7,|,%ttt.8,|,%ttt.9)
    msg $1 %ttt. [ $+ [ $2 ] ] wins!
    return $true
  }
  return $false
}

;Simple alias to merge both scripts, so the ttt script triggers the bot script and the bot script talks back to the ttt script

alias botsTurn {
  ;echo running botsTurn
  TTTBestMove
  tttmove $me #vortexed %TTT.BestCompMove
}


;:::::::::::::::::::::::::::::::::::::::::::: ALIAS TTTFAVOR :::::::::::::::::::::::::::::::::

;Determines who the game favors based on numerical evaluation of board.  Negative numbers favor user, positive favor
;the computer.

alias TTTFavor {
  set %TTT.PosEval $TTTEvaluate($TTTMathStr(%TTT.MoveStr))
  if ( %TTT.PosEval == 0 ) { set %TTT.Favor Evaluation: $chr(91) %TTT.PosEval $chr(93)  Even }
  elseif ( %TTT.PosEval < 0 ) { set %TTT.Favor Evaluation:  $chr(91) %TTT.PosEval $chr(93) Your Favor! }
  elseif ( %TTT.PosEval > 0 ) { set %TTT.Favor Evaluation: $chr(91) %TTT.PosEval $chr(93) Puter's Favor! }
}

;:::::::::::::::::::::::::::::::::::::::::::: ALIAS TTTEVALSUM ::::::::::::::::::::::::::::::::::::::

;Sums the values in a numeric string (000114000) for a row, col, or diag

alias TTTEvalSum {
  %TTT.EvalSum = $calc( $mid(%TTT.EvalStr,$1,1) + $mid(%TTT.EvalStr,$2,1) + $mid(%TTT.EvalStr,$3,1))
  return %TTT.EvalSum
}

;::::::::::::::::::::::::::::::::::::::: ALIAS TTTEVALBOARD :::::::::::::::::::::::::::::::::::

;Increments or decreases evaluation based on the sum of a row, col, or diag.

alias TTTEvalBoard {
  if ( $1  == %TTT.Computer ) { inc %TTT.Eval 1 }
  elseif ( $1 == $calc(%TTT.Computer * 2 )) { inc %TTT.Eval 8 }
  elseif ( $1 == $calc(%TTT.Computer * 3 )) { inc %TTT.Eval 128 }
  elseif ( $1 == %TTT.Human ) { dec %TTT.Eval 1 }
  elseif ( $1 == $calc(%TTT.Human * 2 )) { dec %TTT.Eval 8 }
  elseif ( $1 == $calc(%TTT.Human * 3 )) { dec %TTT.Eval 128 }
}

;:::::::::::::::::::::::::::::::::::::::: ALIAS TTTEVALUATE ::::::::::::::::::::::::::::::::::

;Evaluates board position by getting sum for each row, col, diag and getting associated evaluation for each sum

alias TTTEvaluate {
  set %TTT.EvalStr $1
  set %TTT.Eval 0
  set %TTT.TempSum $TTTEvalSum(1,2,3)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(4,5,6)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(7,8,9)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(1,4,7)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(2,5,8)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(3,6,9)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(1,5,9)
  TTTEvalBoard %TTT.TempSum
  set %TTT.TempSum $TTTEvalSum(3,5,7)
  TTTEvalBoard %TTT.TempSum
  return %TTT.Eval
}

;::::::::::::::::::::::::::::::::::::::: ALIAS TTTMATHSTR :::::::::::::::::::::::::::::::

;Converts aphanumeric input string  to a numeric string for computations (123XXO789) =>>(000114000) if human is x or
;(000441000) if puter is x

alias TTTMathStr {
  set %TTT.Temp.var 1 | unset %TTT.NumStr
  :msloop
  if (%TTT.Temp.var > 9) { goto msloopend }
  if ( $mid( $1,%TTT.Temp.var,1) == %TTT.Computerxo ) { %TTT.NumStr = %TTT.NumStr $+ %TTT.Computer }
  elseif ( $mid( $1,%TTT.Temp.var,1 ) == %TTT.Humanxo ) { %TTT.NumStr = %TTT.NumStr $+ %TTT.Human }
  else { %TTT.NumStr = %TTT.NumStr $+ 0 }
  inc %TTT.Temp.var | goto msloop
  :msloopend
  return %TTT.NumStr
}

;::::::::::::::::::::::::::::::::::::::::::::::: ALIAS TTTBESTMOVE :::::::::::::::::::::::::::::::::::::

;Finds best move for computer by trying all available  moves for the computer and evaluating the board position
; after each possible human response to those moves.

alias TTTBestMove {
  set %TTT.BestCompMove 0
  set %TTT.BestCompEval -256 | set %TTT.CombinedEval 0
  set %TTT.BestStr %TTT.MoveStr
  set %TTT.Temp.var1 1
  :bestloop1
  if (%TTT.Temp.var1 > 9 ) { goto bestloop1end }
  if ( %TTT.Temp.var1 isin %TTT.BestStr ) {
    %TTT.BestStr = $replace(%TTT.BestStr, %TTT.Temp.var1, %TTT.Computerxo)
    %TTT.BestCompStr = $TTTMathStr(%TTT.BestStr)
    if ($TTTEvaluate(%TTT.BestCompStr) > 64) { %TTT.BestHumanEval = 128 }
    else {
      set %TTT.BestHumanMove 0 | set %TTT.BestHumanEval 256
      set %TTT.Temp.var2 1 | set %TTT.BestStrloop2 %TTT.BestStr
      :bestloop2
      if (%TTT.Temp.var2 > 9) { goto bestloop2end }
      if ( %TTT.Temp.var2 isin %TTT.BestStrloop2 ) {
        %TTT.BestStrloop2 = $replace(%TTT.BestStrloop2, %TTT.Temp.var2, %TTT.Humanxo)
        %TTT.BestCompStr = $TTTMathStr(%TTT.BestStrloop2)
        set %TTT.CombinedEval $TTTEvaluate(%TTT.BestCompStr)
        if (%TTT.CombinedEval < %TTT.BestHumanEval ) { set %TTT.BestHumanEval %TTT.CombinedEval | set %TTT.BestHumanMove %TTT.Temp.var2 }
        %TTT.BestStrloop2 = %TTT.BestStr
      }
      inc %TTT.Temp.var2 | goto bestloop2
      :bestloop2end
    }
    if ($calc(%TTT.BestHumanEval - %TTTLevel) > %TTT.BestCompEval) { set %TTT.BestCompEval %TTT.BestHumanEval | set %TTT.BestCompMove %TTT.Temp.var1 }
    %TTT.BestStr = %TTT.MoveStr
  }
  inc %TTT.Temp.var1 | goto bestloop1
  :bestloop1end
  ;  echo tttbot1: %TTT.MoveStr , %TTT.BestCompMove , %TTT.Computerxo
  %TTT.MoveStr = $replace(%TTT.MoveStr, %TTT.BestCompMove, %TTT.Computerxo)
  ;  echo tttbot2: %TTT.MoveStr , %TTT.BestCompMove , %TTT.Computerxo
}