|
Post by bplus on Feb 27, 2024 19:27:11 GMT
Yeah I will see about inserting MiniMax into a normal TTT Game with AI.
|
|
|
Post by bplus on Feb 28, 2024 0:44:54 GMT
took awhile to force MiniMax into a previous TTT Game I had coded.
Option _Explicit _Title "TTT play MiniMax" ' b+ 2024-02-27 comb MiniMax code with TTT game Dim Shared As Integer xmax, ymax: xmax = 400: ymax = 400 ' screen width height Dim Shared P$(1): P$(0) = "o": P$(1) = "x" ' x is always first o is always even ' x plays on moves 1, 3, 5, 7, 9 ' o plays on moves 2, 4, 6, 8 ' the number of spaces left mod 2 says x or o eg 9 spaces = x move Dim Shared WhoseBestMove$, Opponent$, debug As Integer
' in this main part we just setup a board and and call FindBestMove Dim board$(2, 2)
Screen _NewImage(xmax, ymax, 32) _ScreenMove 440, 160
Dim Shared player$, AI$ Dim As Integer i, j, moveR, moveC, bx, by Dim winner$, turn$, m, mb, mx, my, s$
Dim As Integer count, done, sq, xoff, yoff sq = 16 * (1 + 2) ' 48 x 48 cells into which x or o goes in center xoff = (xmax - 3 * sq) / 2 yoff = (ymax - 3 * sq) / 2
While 1 Cls winner$ = "": count = 0: done = 0: ClearBoard board$()
'get player's choice tryagain: Cls Locate 7, 9: Print "*** Tic Tac Toe against MiniMax ***" Locate 10, 14: Print "Enter 'x' to go first or" Locate 11, 14: Print "enter 'o' to go 2nd or" Locate 12, 14: Input "enter nothing to quit "; player$ player$ = LCase$(player$) If player$ = "" Then End ElseIf player$ = "x" Then turn$ = player$: AI$ = "o" ElseIf player$ = "o" Then AI$ = "x": turn$ = AI$ Else GoTo tryagain End If
'make # grid once Cls For i = 1 To 2 Line (sq * i + xoff, yoff)-Step(0, 3 * sq) Line (xoff, sq * i + yoff)-Step(3 * sq, 0) Next For i = 0 To 2 For j = 0 To 2 If board$(i, j) <> "_" Then _PrintString (xoff + (i - 1) * 48 + 20, yoff + (j - 1) * 48 + 16), board$(i, j) Next Next
'take turns filling out the board until a winner$ is found or board is out of spaces Do If turn$ = AI$ Then moveR = -1: moveC = -1 findBestMove board$(), moveR, moveC If moveR = -1 Then 'no move to make Beep: End Else board$(moveR, moveC) = AI$ _PrintString (moveC * sq + xoff + sq / 2 - _PrintWidth(AI$) / 2, moveR * sq + yoff + sq / 2 - 8), AI$ count = count + 1 If isWin%(board$()) Then winner$ = AI$ count = count + 1 turn$ = player$ End If Else 'player's turn from mouse click
'this might NOT be too intuitive but proper mouse catching demands we wait for mouse button release m = _MouseInput: mb = _MouseButton(1): mx = _MouseX: my = _MouseY If mb Then 'get last place mouse button was down mb = _MouseButton(1): mx = _MouseX: my = _MouseY While mb 'left button down, wait for mouse button release before doing anything as a "click" 'this updates mx, my while waiting for button release m = _MouseInput: mb = _MouseButton(1): mx = _MouseX: my = _MouseY Wend
'board x and board y? ' board is offset by (xoff, yoff) = top left corner, so subtract these from mouse mx, my ' then divide by the size of the square (sq) to get the position in the board array ' check that position is inbounds of board array bx = Int((mx - xoff) / sq): by = Int((my - yoff) / sq)
'now we have mouse pixels converted to board position of array If bx >= 0 And bx <= 2 And by >= 0 And by <= 2 Then 'caught mouse in a box! ' note: minimax uses a board (row, col) If board$(by, bx) <> "_" Then Beep 'NO good! already clicked! Else 'OK it all checks out, update the board array and the screen display _PrintString (bx * sq + xoff + sq / 2 - _PrintWidth(player$) / 2, by * sq + yoff + sq / 2 - 8), player$ board$(by, bx) = player$ ' note: minimax uses a board (row, col) count = count + 1 If isWin%(board$()) Then winner$ = player$ turn$ = AI$ End If Else Beep 'you are clicking out of bounds of board! End If End If End If 'turn If winner$ <> "" Then done = 1 If done = 0 And NSpaces%(board$()) = 0 Then done = -1 Loop Until done
If done = -1 Then s$ = "Out of spaces, tie." Else s$ = winner$ + " is the winner!" _PrintString ((xmax - _PrintWidth(s$)) / 2, 2 * _FontHeight), s$ s$ = "Wait 5 secs for next game..." _PrintString ((xmax - _PrintWidth(s$)) / 2, 4 * _FontHeight), s$ _Delay 5 Wend
Sub findBestMove (board$(), moveRow%, moveCol%) Dim As Integer i, j, spaces, bestVal, bestRow, bestCol, moveVal
' whoseBestMove are we trying to optimize x or o ' if amount of spaces mod 2 = 1 then x as x moves first with 9 spaces ' and then every odd number of spaces ' else it is o every even number of spaces spaces = NSpaces%(board$())
' if the board does not already have a winner and if there are spaces left we continue ' else we are done If isWin%(board$()) = 0 And spaces > 0 Then ' not done!
' set whoseBestMove we are trying to come up with here ' we use this in isWin% to assign a good value 10 ' or bad value -10 if the opponent to whoseBestMove ' this is shared so isWin% knows if they won or lost WhoseBestMove$ = P$(spaces Mod 2): bestVal = -1000: bestRow = -1: bestCol = -1 ' also need opponent$ set and shared with isWin% Opponent$ = P$((spaces + 1) Mod 2) For i = 0 To 2: For j = 0 To 2 'now play minimax game If board$(i, j) = "_" Then board$(i, j) = WhoseBestMove$ ' player took a space moveVal = minimax%(board$(), spaces - 1) ' go deep into recursive dive If moveVal > bestVal Then ' remember this move bestRow = i: bestCol = j: bestVal = moveVal End If board$(i, j) = "_" ' put back the space player took End If Next j, i moveRow% = bestRow: moveCol% = bestCol Else ' we are done moveRow% = -1: moveCol% = -1 ' signal no move to make End If End Sub
Function minimax% (board$(), spaces%) Dim As Integer score, best, i, j Dim turn$ score = isWin%(board$())
' are we done yet? signals ' 1) end of line with win 10 or loss-10 ' 2) no more places to move 'the best win is the earliest that is detected by the most spaces If score = 10 Or score = -10 Then minimax% = score + spaces%: Exit Function If spaces% <= 0 Then minimax% = 0: Exit Function
If debug Then ' check to see how the recursive calls are going Dim w$ For i = 0 To 2: For j = 0 To 2: Print board$(i, j);: Next: Print: Next Print "Spaces left coming to minimax is:"; spaces%; " board score:"; score Input " press enter..."; w$ End If
'copy board because QB64 doesn't do by val need recursive level dependent values Dim copyB$(2, 2) ' make a copy of this recursive instance of the board For i = 0 To 2: For j = 0 To 2: copyB$(i, j) = board$(i, j): Next j, i 'whose turn is it, decided by number of spaces left If spaces% Mod 2 = 1 Then turn$ = P$(1) Else turn$ = P$(0) ' x or o turn
If turn$ = WhoseBestMove$ Then ' is turn the one we are finding best move for? best = -1000 For i = 0 To 2: For j = 0 To 2 If copyB$(i, j) = "_" Then copyB$(i, j) = turn$ best = max%(best, minimax%(copyB$(), spaces% - 1)) copyB$(i, j) = "_" End If Next j, i minimax% = best Else ' or is it whoseBestMoves opponents turn best = 1000 For i = 0 To 2: For j = 0 To 2 If copyB$(i, j) = "_" Then copyB$(i, j) = turn$ best = min%(best, minimax%(copyB$(), spaces% - 1)) copyB$(i, j) = "_" End If Next j, i minimax% = best End If End Function
Function isWin% (b$()) ' winner? return +/-10 or 0 if not Dim As Integer row, col For row = 0 To 2 If b$(row, 0) = b$(row, 1) And b$(row, 1) = b$(row, 2) Then If b$(row, 0) = WhoseBestMove$ Then isWin% = 10: Exit Function ElseIf b$(row, 0) = Opponent$ Then isWin% = -10: Exit Function End If End If Next For col = 0 To 2 If b$(0, col) = b$(1, col) And b$(1, col) = b$(2, col) Then If b$(0, col) = WhoseBestMove$ Then isWin% = 10: Exit Function ElseIf b$(0, col) = Opponent$ Then isWin% = -10: Exit Function End If End If Next If b$(0, 0) = b$(1, 1) And b$(1, 1) = b$(2, 2) Then If b$(0, 0) = WhoseBestMove$ Then isWin% = 10: Exit Function ElseIf b$(0, 0) = Opponent$ Then isWin% = -10: Exit Function End If End If If b$(0, 2) = b$(1, 1) And b$(1, 1) = b$(2, 0) Then If b$(0, 2) = WhoseBestMove$ Then isWin% = 10: Exit Function ElseIf b$(0, 2) = Opponent$ Then isWin% = -10: Exit Function End If End If End Function
Function max% (n1%, n2%) If n1% > n2% Then max% = n1% Else max% = n2% End Function
Function min% (n1%, n2%) If n1% > n2% Then min% = n2% Else min% = n1% End Function
Function NSpaces% (board$()) Dim As Integer i, j, spaces For i = 0 To 2: For j = 0 To 2 ' count spaces left on board If board$(i, j) = "_" Then spaces = spaces + 1 Next j, i NSpaces% = spaces End Function
Sub ClearBoard (board$()) Dim As Integer i, j For i = 0 To 2: For j = 0 To 2 board$(i, j) = "_" Next j, i End Sub
|
|
|
Post by anthonyrbrown on Mar 2, 2024 10:56:30 GMT
Very nice bplus The only improvement I would like to see,is there any chance of making the O & X BIGGER! ? And of course I am sure you can Jazz it up with some of your Amazing graphics? How about an Explosion (with sound) when you move the pieces to the board squares! ? And a NUKE! event if a player get's a Winning line!? which I am sure will never happen? A.R.B
|
|
|
Post by bplus on Mar 2, 2024 14:38:10 GMT
Honestly I am more curious about trying a MiniMax out on Connect 4 boards, checkers, even chess than spending time jazzing up a game a human can't win.
I used a different rating system in my older versions of Connect 4 but this MiniMax plays out ALL the scenerios so plays perfectly everytime.
For me, it is a better coding challenge. I have checkers game already started and awaiting an AI. It was tricky judging in code whether a move was legal or not because in checkers if you can jump a piece you have to play the jump or a jump someplace else.
|
|
|
Post by anthonyrbrown on Mar 2, 2024 17:24:22 GMT
Honestly I am more curious about trying a MiniMax out on Connect 4 boards, checkers, even chess than spending time jazzing up a game a human can't win. I used a different rating system in my older versions of Connect 4 but this MiniMax plays out ALL the scenerios so plays perfectly everytime. For me, it is a better coding challenge. I have checkers game already started and awaiting an AI. It was tricky judging in code whether a move was legal or not because in checkers if you can jump a piece you have to play the jump or a jump someplace else. Yes! of course I did not really think you would want to go any further with the TIC-TAC-TOE I am working on my ARBC4 and ARBA4 updates they will be the Final versions! and just to let you know MiniMax can only calculate so far before it becomes unusable! because of the time it takes involved to search so Deep,so it's not the absolute answer,you will find out more about that as you try it and to give you something else to think about the so called Optimum move may not be the best move in all situations! ? Now that's a bit Deep to understand I still have not been able to start my ARBCHECKERS as I have some other more important things I am doing,as far as Chess goes the MINIMAX Chess I posted is a good start and about as good for again the problem with how long it takes to calculate very Deep! which that version can't! A.R.B
|
|
|
Post by anthonyrbrown on Mar 3, 2024 16:05:33 GMT
Some people might find this Chart I am posting interesting,it shows my latest AI Game Engines V1 & V2 playing against each other to show which one is the best! There is also a bit of a lesson attached to this regarding if you find some strange results,in your Test results,which I did! The two top Results show TARBOXV3X3V1XVSV2ONRM2000RSK2000RESULTS Which is my AI Game Engines V1 & V2,playing using a Tic-Tac-Toe 3x3 space,it's not my actual Tic-Tac-Toe program,as that will always Draw games,it's just an extra Test,each Test run for 2000 Games NRM = Normal play and 2000 RSK = Risky play,which shows V1 (X) as the best version. The next two Results TARBC4V7X6V1XVSV2ONRM100RSK100RESULTS-T1 is where it gets interesting! Results T1 and T2 were first completed before T3N and T4N which were played last after I done all the other Tests. All the other Results showed V1 (X) as the best except the TARBC47X6 versions above? so I thought I would remake the TARBC47X6 version and check all the code again line by line,and sure enough there was some hidden difference? I ran the Tests again and this time with T3N and T4N it showed V1 (X) as the best,well it was a win with T3N,and a Draw with T4N,enough to show V1 (X) was the best version! considering all the other Results as a whole So watch this space I will be uploading links to all the New versions soon! A.R.B
|
|
|
Post by anthonyrbrown on Mar 25, 2024 10:29:44 GMT
This is funny bplus,and the first time I ever see this happen?
I converted your TTT program to UPPER CASE letters below,and offset the code to the left side,then when I ran the program it would not run past your choose who moves first window for X or O ?
LOCATE 7, 9: PRINT "*** TIC TAC TOE AGAINST MINIMAX ***" LOCATE 10, 14: PRINT "ENTER 'X' TO GO FIRST OR" LOCATE 11, 14: PRINT "ENTER 'O' TO GO 2ND OR" LOCATE 12, 14: INPUT "ENTER NOTHING TO QUIT "; PLAYER$
$CHECKING:ON OPTION _EXPLICIT _TITLE "TTT PLAY MINIMAX" ' B+ 2024-02-27 COMB MINIMAX CODE WITH TTT GAME DIM SHARED AS INTEGER XMAX, YMAX: XMAX = 400: YMAX = 400 ' SCREEN WIDTH HEIGHT DIM SHARED P$(1): P$(0) = "O": P$(1) = "X" ' X IS ALWAYS FIRST O IS ALWAYS EVEN ' X PLAYS ON MOVES 1, 3, 5, 7, 9 ' O PLAYS ON MOVES 2, 4, 6, 8 ' THE NUMBER OF SPACES LEFT MOD 2 SAYS X OR O EG 9 SPACES = X MOVE DIM SHARED WHOSEBESTMOVE$, OPPONENT$, DEBUG AS INTEGER
' IN THIS MAIN PART WE JUST SETUP A BOARD AND AND CALL FINDBESTMOVE DIM BOARD$(2, 2)
SCREEN _NEWIMAGE(XMAX, YMAX, 32) _SCREENMOVE 440, 160
DIM SHARED PLAYER$, AI$ DIM AS INTEGER I, J, MOVER, MOVEC, BX, BY DIM WINNER$, TURN$, M, MB, MX, MY, S$
DIM AS INTEGER COUNT, DONE, SQ, XOFF, YOFF SQ = 16 * (1 + 2) ' 48 X 48 CELLS INTO WHICH X OR O GOES IN CENTER XOFF = (XMAX - 3 * SQ) / 2 YOFF = (YMAX - 3 * SQ) / 2
WHILE 1 CLS WINNER$ = "": COUNT = 0: DONE = 0: CLEARBOARD BOARD$()
'GET PLAYER'S CHOICE TRYAGAIN: CLS LOCATE 7, 9: PRINT "*** TIC TAC TOE AGAINST MINIMAX ***" LOCATE 10, 14: PRINT "ENTER 'X' TO GO FIRST OR" LOCATE 11, 14: PRINT "ENTER 'O' TO GO 2ND OR" LOCATE 12, 14: INPUT "ENTER NOTHING TO QUIT "; PLAYER$ PLAYER$ = LCASE$(PLAYER$) IF PLAYER$ = "" THEN END ELSEIF PLAYER$ = "X" THEN TURN$ = PLAYER$: AI$ = "O" ELSEIF PLAYER$ = "O" THEN AI$ = "X": TURN$ = AI$ ELSE GOTO TRYAGAIN END IF
'MAKE # GRID ONCE CLS FOR I = 1 TO 2 LINE (SQ * I + XOFF, YOFF)-STEP(0, 3 * SQ) LINE (XOFF, SQ * I + YOFF)-STEP(3 * SQ, 0) NEXT FOR I = 0 TO 2 FOR J = 0 TO 2 IF BOARD$(I, J) <> "_" THEN _PRINTSTRING (XOFF + (I - 1) * 48 + 20, YOFF + (J - 1) * 48 + 16), BOARD$(I, J) NEXT NEXT
'TAKE TURNS FILLING OUT THE BOARD UNTIL A WINNER$ IS FOUND OR BOARD IS OUT OF SPACES DO IF TURN$ = AI$ THEN MOVER = -1: MOVEC = -1 FINDBESTMOVE BOARD$(), MOVER, MOVEC IF MOVER = -1 THEN 'NO MOVE TO MAKE BEEP: END ELSE BOARD$(MOVER, MOVEC) = AI$ _PRINTSTRING (MOVEC * SQ + XOFF + SQ / 2 - _PRINTWIDTH(AI$) / 2, MOVER * SQ + YOFF + SQ / 2 - 8), AI$ COUNT = COUNT + 1 IF ISWIN%(BOARD$()) THEN WINNER$ = AI$ COUNT = COUNT + 1 TURN$ = PLAYER$ END IF ELSE 'PLAYER'S TURN FROM MOUSE CLICK
'THIS MIGHT NOT BE TOO INTUITIVE BUT PROPER MOUSE CATCHING DEMANDS WE WAIT FOR MOUSE BUTTON RELEASE M = _MOUSEINPUT: MB = _MOUSEBUTTON(1): MX = _MOUSEX: MY = _MOUSEY IF MB THEN 'GET LAST PLACE MOUSE BUTTON WAS DOWN MB = _MOUSEBUTTON(1): MX = _MOUSEX: MY = _MOUSEY WHILE MB 'LEFT BUTTON DOWN, WAIT FOR MOUSE BUTTON RELEASE BEFORE DOING ANYTHING AS A "CLICK" 'THIS UPDATES MX, MY WHILE WAITING FOR BUTTON RELEASE M = _MOUSEINPUT: MB = _MOUSEBUTTON(1): MX = _MOUSEX: MY = _MOUSEY WEND
'BOARD X AND BOARD Y? ' BOARD IS OFFSET BY (XOFF, YOFF) = TOP LEFT CORNER, SO SUBTRACT THESE FROM MOUSE MX, MY ' THEN DIVIDE BY THE SIZE OF THE SQUARE (SQ) TO GET THE POSITION IN THE BOARD ARRAY ' CHECK THAT POSITION IS INBOUNDS OF BOARD ARRAY BX = INT((MX - XOFF) / SQ): BY = INT((MY - YOFF) / SQ)
'NOW WE HAVE MOUSE PIXELS CONVERTED TO BOARD POSITION OF ARRAY IF BX >= 0 AND BX <= 2 AND BY >= 0 AND BY <= 2 THEN 'CAUGHT MOUSE IN A BOX! ' NOTE: MINIMAX USES A BOARD (ROW, COL) IF BOARD$(BY, BX) <> "_" THEN BEEP 'NO GOOD! ALREADY CLICKED! ELSE 'OK IT ALL CHECKS OUT, UPDATE THE BOARD ARRAY AND THE SCREEN DISPLAY _PRINTSTRING (BX * SQ + XOFF + SQ / 2 - _PRINTWIDTH(PLAYER$) / 2, BY * SQ + YOFF + SQ / 2 - 8), PLAYER$ BOARD$(BY, BX) = PLAYER$ ' NOTE: MINIMAX USES A BOARD (ROW, COL) COUNT = COUNT + 1 IF ISWIN%(BOARD$()) THEN WINNER$ = PLAYER$ TURN$ = AI$ END IF ELSE BEEP 'YOU ARE CLICKING OUT OF BOUNDS OF BOARD! END IF END IF END IF 'TURN IF WINNER$ <> "" THEN DONE = 1 IF DONE = 0 AND NSPACES%(BOARD$()) = 0 THEN DONE = -1 LOOP UNTIL DONE
IF DONE = -1 THEN S$ = "OUT OF SPACES, TIE." ELSE S$ = WINNER$ + " IS THE WINNER!" _PRINTSTRING ((XMAX - _PRINTWIDTH(S$)) / 2, 2 * _FONTHEIGHT), S$ S$ = "WAIT 5 SECS FOR NEXT GAME..." _PRINTSTRING ((XMAX - _PRINTWIDTH(S$)) / 2, 4 * _FONTHEIGHT), S$ _DELAY 5 WEND
SUB FINDBESTMOVE (BOARD$(), MOVEROW%, MOVECOL%) DIM AS INTEGER I, J, SPACES, BESTVAL, BESTROW, BESTCOL, MOVEVAL
' WHOSEBESTMOVE ARE WE TRYING TO OPTIMIZE X OR O ' IF AMOUNT OF SPACES MOD 2 = 1 THEN X AS X MOVES FIRST WITH 9 SPACES ' AND THEN EVERY ODD NUMBER OF SPACES ' ELSE IT IS O EVERY EVEN NUMBER OF SPACES SPACES = NSPACES%(BOARD$())
' IF THE BOARD DOES NOT ALREADY HAVE A WINNER AND IF THERE ARE SPACES LEFT WE CONTINUE ' ELSE WE ARE DONE IF ISWIN%(BOARD$()) = 0 AND SPACES > 0 THEN ' NOT DONE!
' SET WHOSEBESTMOVE WE ARE TRYING TO COME UP WITH HERE ' WE USE THIS IN ISWIN% TO ASSIGN A GOOD VALUE 10 ' OR BAD VALUE -10 IF THE OPPONENT TO WHOSEBESTMOVE ' THIS IS SHARED SO ISWIN% KNOWS IF THEY WON OR LOST WHOSEBESTMOVE$ = P$(SPACES MOD 2): BESTVAL = -1000: BESTROW = -1: BESTCOL = -1 ' ALSO NEED OPPONENT$ SET AND SHARED WITH ISWIN% OPPONENT$ = P$((SPACES + 1) MOD 2) FOR I = 0 TO 2: FOR J = 0 TO 2 'NOW PLAY MINIMAX GAME IF BOARD$(I, J) = "_" THEN BOARD$(I, J) = WHOSEBESTMOVE$ ' PLAYER TOOK A SPACE MOVEVAL = MINIMAX%(BOARD$(), SPACES - 1) ' GO DEEP INTO RECURSIVE DIVE IF MOVEVAL > BESTVAL THEN ' REMEMBER THIS MOVE BESTROW = I: BESTCOL = J: BESTVAL = MOVEVAL END IF BOARD$(I, J) = "_" ' PUT BACK THE SPACE PLAYER TOOK END IF NEXT J, I MOVEROW% = BESTROW: MOVECOL% = BESTCOL ELSE ' WE ARE DONE MOVEROW% = -1: MOVECOL% = -1 ' SIGNAL NO MOVE TO MAKE END IF END SUB
FUNCTION MINIMAX% (BOARD$(), SPACES%) DIM AS INTEGER SCORE, BEST, I, J DIM TURN$ SCORE = ISWIN%(BOARD$())
' ARE WE DONE YET? SIGNALS ' 1) END OF LINE WITH WIN 10 OR LOSS-10 ' 2) NO MORE PLACES TO MOVE 'THE BEST WIN IS THE EARLIEST THAT IS DETECTED BY THE MOST SPACES IF SCORE = 10 OR SCORE = -10 THEN MINIMAX% = SCORE + SPACES%: EXIT FUNCTION IF SPACES% <= 0 THEN MINIMAX% = 0: EXIT FUNCTION
IF DEBUG THEN ' CHECK TO SEE HOW THE RECURSIVE CALLS ARE GOING DIM W$ FOR I = 0 TO 2: FOR J = 0 TO 2: PRINT BOARD$(I, J);: NEXT: PRINT: NEXT PRINT "SPACES LEFT COMING TO MINIMAX IS:"; SPACES%; " BOARD SCORE:"; SCORE INPUT " PRESS ENTER..."; W$ END IF
'COPY BOARD BECAUSE QB64 DOESN'T DO BY VAL NEED RECURSIVE LEVEL DEPENDENT VALUES DIM COPYB$(2, 2) ' MAKE A COPY OF THIS RECURSIVE INSTANCE OF THE BOARD FOR I = 0 TO 2: FOR J = 0 TO 2: COPYB$(I, J) = BOARD$(I, J): NEXT J, I 'WHOSE TURN IS IT, DECIDED BY NUMBER OF SPACES LEFT IF SPACES% MOD 2 = 1 THEN TURN$ = P$(1) ELSE TURN$ = P$(0) ' X OR O TURN
IF TURN$ = WHOSEBESTMOVE$ THEN ' IS TURN THE ONE WE ARE FINDING BEST MOVE FOR? BEST = -1000 FOR I = 0 TO 2: FOR J = 0 TO 2 IF COPYB$(I, J) = "_" THEN COPYB$(I, J) = TURN$ BEST = MAX%(BEST, MINIMAX%(COPYB$(), SPACES% - 1)) COPYB$(I, J) = "_" END IF NEXT J, I MINIMAX% = BEST ELSE ' OR IS IT WHOSEBESTMOVES OPPONENTS TURN BEST = 1000 FOR I = 0 TO 2: FOR J = 0 TO 2 IF COPYB$(I, J) = "_" THEN COPYB$(I, J) = TURN$ BEST = MIN%(BEST, MINIMAX%(COPYB$(), SPACES% - 1)) COPYB$(I, J) = "_" END IF NEXT J, I MINIMAX% = BEST END IF END FUNCTION
FUNCTION ISWIN% (B$()) ' WINNER? RETURN +/-10 OR 0 IF NOT DIM AS INTEGER ROW, COL FOR ROW = 0 TO 2 IF B$(ROW, 0) = B$(ROW, 1) AND B$(ROW, 1) = B$(ROW, 2) THEN IF B$(ROW, 0) = WHOSEBESTMOVE$ THEN ISWIN% = 10: EXIT FUNCTION ELSEIF B$(ROW, 0) = OPPONENT$ THEN ISWIN% = -10: EXIT FUNCTION END IF END IF NEXT FOR COL = 0 TO 2 IF B$(0, COL) = B$(1, COL) AND B$(1, COL) = B$(2, COL) THEN IF B$(0, COL) = WHOSEBESTMOVE$ THEN ISWIN% = 10: EXIT FUNCTION ELSEIF B$(0, COL) = OPPONENT$ THEN ISWIN% = -10: EXIT FUNCTION END IF END IF NEXT IF B$(0, 0) = B$(1, 1) AND B$(1, 1) = B$(2, 2) THEN IF B$(0, 0) = WHOSEBESTMOVE$ THEN ISWIN% = 10: EXIT FUNCTION ELSEIF B$(0, 0) = OPPONENT$ THEN ISWIN% = -10: EXIT FUNCTION END IF END IF IF B$(0, 2) = B$(1, 1) AND B$(1, 1) = B$(2, 0) THEN IF B$(0, 2) = WHOSEBESTMOVE$ THEN ISWIN% = 10: EXIT FUNCTION ELSEIF B$(0, 2) = OPPONENT$ THEN ISWIN% = -10: EXIT FUNCTION END IF END IF END FUNCTION
FUNCTION MAX% (N1%, N2%) IF N1% > N2% THEN MAX% = N1% ELSE MAX% = N2% END FUNCTION
FUNCTION MIN% (N1%, N2%) IF N1% > N2% THEN MIN% = N2% ELSE MIN% = N1% END FUNCTION
FUNCTION NSPACES% (BOARD$()) DIM AS INTEGER I, J, SPACES FOR I = 0 TO 2: FOR J = 0 TO 2 ' COUNT SPACES LEFT ON BOARD IF BOARD$(I, J) = "_" THEN SPACES = SPACES + 1 NEXT J, I NSPACES% = SPACES END FUNCTION
SUB CLEARBOARD (BOARD$()) DIM AS INTEGER I, J FOR I = 0 TO 2: FOR J = 0 TO 2 BOARD$(I, J) = "_" NEXT J, I END SUB
|
|
|
Post by bplus on Mar 25, 2024 13:04:33 GMT
funny the mistake you make yelling at the ide with all capital letters lol 9my main shift key is broken, no yelling for me0 works fine now; just one letter off...
|
|
|
Post by anthonyrbrown on Mar 25, 2024 13:48:48 GMT
OK! ? Can you show me the code where the mistake is?
|
|
|
Post by bplus on Mar 25, 2024 13:59:02 GMT
i did, it's in the snapshot look closely ;]
|
|
|
Post by anthonyrbrown on Mar 25, 2024 19:19:15 GMT
OK! Got it thank's I have my own problem at the moment I have made a very Advanced games search algorithm which looks like the Bees! Knees! and may be the Ultimate!? but when I run it after about 100 games is slows to a Stop! almost? because it is doing so much!
|
|