Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

Tik-Tak-Toe


  • Please log in to reply
43 replies to this topic

#1 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 02 May 2009 - 02:29 AM

VERY simple.. lol i took the lazy way out.. see Unbeatable tick tack toe for a better one...

X=AI
O=USER

USER goes first

this has SOMEwhat of a strategy in it... and is MUCH harder to win has custom GUI's and messages... blah blah check it out.. post some comments on how i could do it better please... and i DON'T want to make it UNBEATABLE.. cause that wouldn't be fun.. maybe nearly unbeatable.. maybe later..

EDIT

its more difficult now but still has a few bugs X's replace O's spot in center some times and declares a AI WIN when it should have been a TIE

EDIT

fairly random scenarios based on a valued system.
3|2|3
2|4|2
3|2|3

if there isn't a spot to block\win it goes to find the most valuable, if there are multiple it randomizes it. not exactly predictable. or is it? :S

AutoIt         
Opt ('GuiOnEVentMode',1) Dim $GRID[3][3] Dim $row[3], $column[3],$diagonal[2] $nTieCount = 0 $nTurnCount = 0 $nLossCount = 0 $nWinCount = 0 $nAI = -1 $sAI = 'o' $nPLAYER = 1 $sPLAYER = 'x' $turn = $nPLAYER $w_h = 75 $guiw = ($w_h*3)+40 $guih = ($w_h*5) $font_s = ($w_h*2)/4 $window_hwnd = GUICreate ('tic tac toe',$guiw,$guih) GUISetOnEvent (-3,'End') $lWinCount = GUICtrlCreateLabel ('WINS:',10,40+($w_h*3),($guiw-20)/3,$w_h/2,0x0200) $lLossCount = GUICtrlCreateLabel ('LOSSES:',10+($guiw-20)/3,40+($w_h*3),($guiw-20)/3,$w_h/2,0x0200) $lTieCount = GUICtrlCreateLabel ('Ties:',$guiw-($guiw-20)/3,40+($w_h*3),($guiw-20)/3,$w_h/2,0x0200) For $x = 0 To 2     For $y = 0 To 2         $GRID[$x][$y] = GUICtrlCreateButton ('',10+(10*$x)+($x*$w_h),10+(10*$y)+($y*$w_h),$w_h,$w_h)             GUICtrlSetOnEvent ($GRID[$x][$y],'Clicked')     Next Next Dim $GRIDval2[4]     $GRIDval2[0] = $GRID[0][1]     $GRIDval2[1] = $GRID[2][0]     $GRIDval2[2] = $GRID[2][2]     $GRIDval2[3] = $GRID[2][1] Dim $GRIDval3[4]     $GRIDval3[0] = $GRID[0][0]     $GRIDval3[1] = $GRID[0][2]     $GRIDval3[2] = $GRID[2][0]     $GRIDval3[3] = $GRID[2][2] $diagonal[0] = $GRID[0][0] & '|' & $GRID[1][1] & '|' & $GRID[2][2] $diagonal[1] = $GRID[2][0] & '|' & $GRID[1][1] & '|' & $GRID[0][2] For $n = 0 To 2     $row[$n] = $GRID[$n][0] & '|' & $GRID[$n][1] & '|' & $GRID[$n][2]     $column[$n] = $GRID[0][$n] & '|' & $GRID[1][$n] & '|' & $GRID[2][$n] Next GUICtrlCreateButton ('Reset',10,(3*$w_h)+$w_h+20,$guiw-20,$w_h/2) GUICtrlSetOnEvent (-1,'Start') GUISetState () Start () While 1     CheckStats ()     CheckWin ()     Sleep (100) WEnd Func Start ()     $turn = $nPLAYER     $nTurnCount = 0     WinSetState ($window_hwnd,'',@SW_ENABLE)     For $n = 0 To 2         For $u = 0 To 2             GUICtrlSetData ($GRID[$n][$u],'')             GUICtrlSetState ($GRID[$n][$u],64)         Next     Next EndFunc Func CheckStats ()     If GUICtrlRead ($lWinCount) <> 'WINS:'&$nWinCount Then GUICtrlSetData ($lWinCount,'WINS:'&$nWinCount)     If GUICtrlRead ($lLossCount) <> 'LOSSES:'&$nLossCount Then GUICtrlSetData ($lLossCount,'LOSSES:'&$nLossCount)     If GUICtrlRead ($lTieCount) <> 'TIES:'&$nTieCount Then GUICtrlSetData ($lTieCount,'TIES:'&$nTieCount) EndFunc Func CheckWin ()     Local $eval, $n     $eval = StringEval($diagonal[0])     If $eval = -3 Or $eval = 3 Then Win ($eval)     $eval = StringEval($diagonal[1])     If $eval = -3 Or $eval = 3 Then Win ($eval)     For $n = 0 To 2         $eval = StringEval($row[$n])         If $eval = -3 Or $eval = 3 Then Win ($eval)         $eval = StringEval($column[$n])         If $eval = -3 Or $eval = 3 Then Win ($eval)     Next EndFunc Func Win ($value)     If $value/$nPLAYER = 3 Then         MsgBox (0,'WIN','Player Has Won!',25,$window_hwnd)         $nWinCount += 1     EndIf     If $value/$nAI = 3 Then         MsgBox (0,'WIN','Computer Has Won!',25,$window_hwnd)         $nLossCount += 1     EndIf     Start () EndFunc Func Check ()     Local $n     If $nTurnCount >= 8 Then         MsgBox (0,'TIE','Tie Game',25,$window_hwnd)         $nTieCount += 1         Start ()     Else         CheckMove(StringEval($diagonal[0]),$diagonal[0])         CheckMove(StringEval($diagonal[1]),$diagonal[1])         For $n = 0 To 2             CheckMove(StringEval($row[$n]),$row[$n])             CheckMove(StringEval($column[$n]),$column[$n])         Next         If $turn = $nAI Then             If GUICtrlRead ($GRID[1][1]) == '' Then                 Move($GRID[1][1])             Else                 If MiniMaxValuing ($GRIDval3) = -1 Then                     If MiniMaxValuing ($GRIDval2) = -1 Then                         Do                             $r = Random (0,2,1)                             $c = Random (0,2,1)                         Until GUICtrlRead ($GRID[$r][$c]) == ''                         Move ($GRID[$r][$c])                     EndIf                 EndIf             EndIf         EndIf     EndIf EndFunc Func Move ($ID)     GUICtrlSetData ($ID,$sAI)     GUICtrlSetState ($ID,128)     $turn = $nPLAYER     $nTurnCount += 1     WinSetState ($window_hwnd,'',@SW_ENABLE) EndFunc Func Clicked ()     $turn = $nAI     $nTurnCount += 1     GUICtrlSetData (@GUI_CtrlId,$sPLAYER)     GUICtrlSetState (@GUI_CtrlId,128)     WinSetState ($window_hwnd,'',@SW_DISABLE)     Check () EndFunc Func CheckMove ($value,$IDarray)     If $value = 3 Or $value = -3 Then         Win ($value)         If $turn = $nAI Then             If GUICtrlRead ($GRID[1][1]) == '' Then                 Move ($GRID[1][1])                 Return             EndIf             If $value = 2 Or $value = -2 Then                 Local $guiIDarray = StringSplit ($IDarray,'|',2)                 Local $n = 0                 For $n = 0 To UBound ($guiIDarray)-1                     $guiIDarray[$n] = Number ($guiIDarray[$n])                     If GUICtrlRead ($guiIDarray[$n]) == '' Then                         Move ($guiIDarray[$n])                         Return                     EndIf                 Next             EndIf             Return         EndIf     EndIf EndFunc Func StringEval ($IDarray)     Dim $guiIDarray = StringSplit ($IDarray,'|',2)     Dim $valuearray[UBound ($guiIDarray)]     Local $value = 0, $n = 0     For $n = 0 To UBound ($guiIDarray)-1         $guiIDarray[$n] = $guiIDarray[$n]         If GUICtrlRead ($guiIDarray[$n]) == '' Then $valuearray[$n] = 0         If GUICtrlRead ($guiIDarray[$n]) == $sPLAYER Then $valuearray[$n] = $nPLAYER         If GUICtrlRead ($guiIDarray[$n]) == $sAI Then $valuearray[$n] = $nAI         $value += $valuearray[$n]     Next     Return $value EndFunc Func MiniMaxValuing ($array)     Local $n, $Count = ''     For $n = 0 To UBound ($array,1)-1         If GUICtrlRead ($array[$n]) == '' Then $Count &= $n & '|'     Next     If $Count == '' Then Return -1     $Count = StringSplit (StringTrimRight ($Count,1),'|',2)     Move ($array[$Count[Random (0,UBound ($Count,1)-1,1)]])     Return 1 EndFunc Func End ()     Exit EndFunc

Edited by CodyBarrett, 27 October 2010 - 02:49 PM.








#2 Mat

Mat

    43 38 48 31 30 4E 34 4F 32

  • MVPs
  • 4,837 posts

Posted 02 May 2009 - 10:47 AM

.. post some comments on how i could do it better please...

of course ^_^
1) make the x's and o's bigger, so they fill the button.
2) don't show the 2nd gui when ai is working. it looks so much better like this:
Func _PC_Move ()     Do         $i = Random (0, 9)     Until GUICtrlRead ($Array[$i]) <> 'X' And GUICtrlRead ($Array[$i]) <> 'O'     GUICtrlSetData ($Array[$i], 'X')     GUICtrlSetState ($Array[$i], $GUI_DISABLE)     $Turn += 1     _MouseTrap () EndFunc

3) For other messages, try splashtexton...
Func _Tie_ ()     SplashTextOn ("Result!!", "You tied the game!! <>_<>", 300, 50, -1, -1)     Sleep (1000)     _Random_ ()     Sleep (1000)     SplashOff () EndFunc


generally, just make it better!! I had a bit of fun though.

MDiesel

{4d696768-744e-6f74-4265-556e69717565}

AutoIt Project Listing

#3 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 02 May 2009 - 04:50 PM

well thanks.... i put the "Please wait..." to make it SEEM like the copmuter is making its decision haha ^_^ ill try a few more things out

#4 yehia

yehia

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 275 posts

Posted 02 May 2009 - 09:39 PM

lol sooooo easy to take him down it needs more work on AI but still cool
GJ

#5 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 02 May 2009 - 11:18 PM

lol i made it in like.. 10 mins at school haha 7 of those minutes were googling how tic tac toe works... and i might still add a few strategies to the AI

if you didn't notice it has NO strategy.. just randomly pics out a black spot lmao

#6 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,572 posts

Posted 03 May 2009 - 12:27 AM

I want to play X, and go first.

^_^

#7 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 03 May 2009 - 12:53 AM

well... sorry haha but in the new version up at the top... i havent won once.. and your still O but you get to go first



EDIT

just tested 10 times.. all 10 i started in the center.. it was a 40% WIN.. 30% TIE and 20% LOSE haha and well.. 10% glitch (would have been a win but it said TIE and restarted)

Edited by CodyBarrett, 03 May 2009 - 01:07 AM.


#8 FinalVersion

FinalVersion

    0 ^ 1

  • Active Members
  • PipPipPipPipPipPip
  • 599 posts

Posted 03 May 2009 - 01:05 AM

well... sorry haha but in the new version up at the top... i havent won once.. and your still O but you get to go first

Lol I won first go ;) You Choose Bottom Left, Bottom Right, Then Middle Bottom. Simple ^_^

#9 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 03 May 2009 - 01:16 AM

lol sometimes it does that.. xD.. but then again.. i wanna keep the player interested and not frustrated... not like

"OMFG!! YOU DOU***BAG!! LEMME WIN ONCE!!! F***!!!"

but more like

"^_^ sweet i won!, lets play again!"

hahaha... but yeah anyone know how to fix the few bugs in there?
bugs i found:
#1 soemtimes if you go middle.. it replaces your O with an X and freezes... SOLUTION hit TAB then ENTER to restart
#2 sometimes when the AI is about to lose it calls a TIE...
#3 like the post above this.. sometimes it isn't very smart...SOLUTION make it smarter LMAO but nah...this isn't a real problem

#10 stinson6016

stinson6016

    Seeker

  • Active Members
  • 41 posts

Posted 03 May 2009 - 02:40 PM

he keeps placing his "x" ontop of my "o" to bet me
Gnatwork Networks

#11 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 03 May 2009 - 04:44 PM

thats my problem #1... just hit TAB ENTER and it will restart it.. because it freezes when it happens... im not sure why this is happening

EDIT

fixed it alittle... UPDATED AT TOP lol

FIXED:

*reduced the glitches now it only does it a few times..
*smarter AI
*harder to win
*i find it more fun ^_^

Edited by CodyBarrett, 03 May 2009 - 05:47 PM.


#12 enaiman

enaiman

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,922 posts

Posted 03 May 2009 - 11:23 PM

Very nice interface.

You will need to work on the code because the game is still bugged. Here is what I've noticed so far:
- sometimes the script replaces the upper corner with its own entry overwriting my own entry (work on _Find_Blank_Spot )
- sometimes the script decides it's a tie after only 2 moves
- the script freeze quite often during the game and it needs to be shut down

Other than that: keep up the good work ^_^

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)


#13 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 03 May 2009 - 11:43 PM

thanks enaiman..

#1 ill look into..
i realized #2 when i went Middle.. bottom left... and it said tie...
#3 haven't had this happen yet in the new one but if it does hit [TAB] [Enter] to reset game...

EDIT

enaiman yours is VIRTUALY unbeatable(i haven't beaten it yet).. but i want mine to have some mercy on the user haha... ^_^

Edited by CodyBarrett, 03 May 2009 - 11:45 PM.


#14 WideBoyDixon

WideBoyDixon

    Code Monkey

  • Active Members
  • PipPipPipPipPipPip
  • 381 posts

Posted 04 May 2009 - 10:35 PM

I dug out my implementation of a zero-sum game where I implemented tic-tac-toe. I've posted here for reference should anyone find that they wanted to go down the route of using a minimax algorithm for a turn-based game. Apologies to CodyBarrett in advance to a little bit of thread hijacking. Sorry to say that mine doesn't let you win ^_^

AutoIt         
#include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <Array.au3> #include <Misc.au3> Global $aTree[10], $iSTM = Random(1, 2, 1) $aTree[0] = "000000000" Global $hBoard = GUICreate("Tic-Tac-Toe", 234, 234) GUISetBkColor(0x000000) Global $cBoard = GUICtrlCreateGraphic(8, 8, 218, 218) GUISetState(@SW_SHOW) _DrawBoard($aTree[0]) ; Make the first move if necessary If $iSTM = 2 Then     _FindBestMove(0, $iSTM)     $aTree[0] = $aTree[1]     $iSTM = 3 - $iSTM EndIf Local $iMsg, $aCI, $x, $y, $iMove Do     $iMsg = GUIGetMsg()     If $iMsg = $cBoard Then         $aCI = GUIGetCursorInfo($hBoard)         $aCI[0] -= 8         $aCI[1] -= 8         $x = Int($aCI[0] / 73)         $y = Int($aCI[1] / 73)         $iMove = $x + ($y * 3) + 1         If StringMid($aTree[0], $iMove, 1) = "0" Then             _MakeMove(0, $iMove, $iSTM)             _DrawBoard(1)             $aTree[0] = $aTree[1]             $iSTM = 3 - $iSTM             _FindBestMove(0, $iSTM)             $aTree[0] = $aTree[1]             $iSTM = 3 - $iSTM         EndIf     EndIf     Sleep(10) Until $iMsg = $GUI_EVENT_CLOSE Exit Func _RandomBoard()     Local $i     $aTree[1] = ""     For $i = 1 To 9         $aTree[1] &= String(Random(0, 2, 1))     Next     _DrawBoard(1) EndFunc Func _DrawBoard($iDepth)     Local $i, $x, $y     GUICtrlDelete($cBoard)     $cBoard = GUICtrlCreateGraphic(8, 8, 218, 218)     GUICtrlSetGraphic($cBoard, $GUI_GR_PENSIZE, 3)     GUICtrlSetGraphic($cBoard, $GUI_GR_COLOR, 0xffffff, 0x000000)     GUICtrlSetGraphic($cBoard, $GUI_GR_MOVE, 72, 0)     GUICtrlSetGraphic($cBoard, $GUI_GR_LINE, 72, 217)     GUICtrlSetGraphic($cBoard, $GUI_GR_MOVE, 145, 0)     GUICtrlSetGraphic($cBoard, $GUI_GR_LINE, 145, 217)     GUICtrlSetGraphic($cBoard, $GUI_GR_MOVE, 0, 72)     GUICtrlSetGraphic($cBoard, $GUI_GR_LINE, 217, 72)     GUICtrlSetGraphic($cBoard, $GUI_GR_MOVE, 0, 145)     GUICtrlSetGraphic($cBoard, $GUI_GR_LINE, 217, 145)     For $i = 1 To 9         $x = Mod(($i - 1), 3) * 73 + 4         $y = Int(($i - 1) / 3) * 73 + 4         Switch StringMid($aTree[$iDepth], $i, 1)             Case "1"                 GUICtrlSetGraphic($cBoard, $GUI_GR_ELLIPSE, $x, $y, 64, 64)             Case "2"                 GUICtrlSetGraphic($cBoard, $GUI_GR_MOVE, $x, $y)                 GUICtrlSetGraphic($cBoard, $GUI_GR_LINE, $x + 63, $y + 63)                 GUICtrlSetGraphic($cBoard, $GUI_GR_MOVE, $x + 63, $y)                 GUICtrlSetGraphic($cBoard, $GUI_GR_LINE, $x, $y + 63)         EndSwitch     Next     GUICtrlSetGraphic($cBoard, $GUI_GR_REFRESH) EndFunc Func _StaticEvaluator($iDepth)     Local $s = 0     $s += _ScoreLine($aTree[$iDepth], 1, 1)     $s += _ScoreLine($aTree[$iDepth], 4, 1)     $s += _ScoreLine($aTree[$iDepth], 7, 1)     $s += _ScoreLine($aTree[$iDepth], 1, 3)     $s += _ScoreLine($aTree[$iDepth], 2, 3)     $s += _ScoreLine($aTree[$iDepth], 3, 3)     $s += _ScoreLine($aTree[$iDepth], 1, 4)     $s += _ScoreLine($aTree[$iDepth], 3, 2)     Return $s EndFunc Func _ScoreLine(ByRef $sBoard, $a, $B)     Local $s = StringMid($sBoard, $a, 1) & StringMid($sBoard, $a + $b, 1) & StringMid($sBoard, $a + $b + $b, 1)     Switch $s         Case "001", "010", "100"             Return 1         Case "011", "101", "110"             Return 10         Case "111"             Return 1000         Case "002", "020", "200"             Return -1         Case "022", "202", "220"             Return -10         Case "222"             Return -1000         Case Else             Return 0     EndSwitch EndFunc Func _GetLegalMoves(ByRef $iDepth, ByRef $iSideToMove)     Local $s = "", $i = Random(0, 8, 1), $j     For $j = 1 To 9         If (StringMid($aTree[$iDepth], $i + 1, 1) = "0") Then             $s &= String($i + 1)         EndIf         $i = Mod($i + 1, 9)     Next     Return StringSplit($s, "") EndFunc Func _MakeMove($iDepth, ByRef $iMove, ByRef $iSideToMove)     $aTree[$iDepth + 1] = StringLeft($aTree[$iDepth], $iMove - 1) & String($iSideToMove) & StringMid($aTree[$iDepth], $iMove + 1) EndFunc Func _FindBestMove($iDepth, $iSideToMove)     Local $iScore = _StaticEvaluator($iDepth)     If $iDepth > 3 Then Return $iScore     If StringInStr($aTree[$iDepth], "0") = 0 Then Return $iScore ; No valid moves available     If ($iScore < -100) Or ($iScore > 100) Then Return $iScore ; Game is already won ... can't move any more     Local $aMoves = _GetLegalMoves($iDepth, $iSideToMove), $i     Local $iBestScore = _IIf(($iSideToMove = 1), -9999, 9999), $iNewScore, $iBestMove = 0     For $i = 1 To $aMoves[0]         _MakeMove($iDepth, $aMoves[$i], $iSideToMove)         $iNewScore = _FindBestMove($iDepth + 1, 3 - $iSideToMove)         If $iSideToMove = 1 Then             If $iNewScore > $iBestScore Then                 $iBestScore = $iNewScore                 $iBestMove = $i             EndIf         Else             If $iNewScore < $iBestScore Then                 $iBestScore = $iNewScore                 $iBestMove = $i             EndIf         EndIf     Next     If $iDepth = 0 Then         _MakeMove($iDepth, $aMoves[$iBestMove], $iSideToMove)         _DrawBoard($iDepth + 1)     EndIf     Return $iBestScore EndFunc


WBD

#15 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 04 May 2009 - 10:53 PM

no problem WideBoyDixon... the more unbeatable examples the better... ill eventualy fix it.. got other stuff to do though

#16 enaiman

enaiman

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,922 posts

Posted 04 May 2009 - 11:40 PM

@WideBoyDixon

Very nice approach - I really like it. Your example is exactly what I would expect from a good game algorythm.
It's a good algorythm and it finds always the best move. I like the way you keep the table info in a string ;)

Mine doesn't allow wins either but comparing to yours it looks like a "poor relative"

Very good job ^_^

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)


#17 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 04 May 2009 - 11:51 PM

ima look into each of your guys code anyway.. see if i can learn something about the algo

#18 WideBoyDixon

WideBoyDixon

    Code Monkey

  • Active Members
  • PipPipPipPipPipPip
  • 381 posts

Posted 04 May 2009 - 11:59 PM

http://en.wikipedia.org/wiki/Minimax

WBD

#19 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 05 May 2009 - 12:44 AM

lol its beyond me... can some one post a simplified version?..... ^_^ i wish i was a genius

#20 CodyBarrett

CodyBarrett

    I LOVE Juicy Fruit!!!

  • Active Members
  • PipPipPipPipPipPip
  • 1,225 posts

Posted 28 August 2010 - 07:06 PM

I was frustrated so i put this project aside. Now im trying it again... its still possible to win, can someone help me by showing me what i'm doin wrong? i think it doesnt have any bugs so far can you guys voice your oppinions?




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users