Author Topic: 8x8 Connect 4: AI Challenge  (Read 9620 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #15 on: December 14, 2020, 05:59:16 pm »
@STxAxTIC   Oh ha! you make it look easy!

I just found an easy one when I go first in my port to JB. I thought I had that one fixed but apparently not for the symmetric side. I haven't been able to replicate that in  QB64 yet but I am rushing to get the port done.

I see a pattern in screen shots, so I should be able to confirm after Big Game tonight :)

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #16 on: December 14, 2020, 06:05:03 pm »
here is the exact sequence just in case
ss3.png
* ss3.png (Filesize: 5.96 KB, Dimensions: 494x494, Views: 254)
You're not done when it works, you're done when it's right.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #17 on: December 14, 2020, 06:10:33 pm »
I just replicated Static's moves and won, incredible!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #18 on: December 14, 2020, 06:42:49 pm »
Just confirmed STx Solution on my port.

If you go first and manage to get 3 on the bottom row with no blocks on either side, you won.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #19 on: December 14, 2020, 06:53:41 pm »
Bplus,

Out of the three games that I played I managed to win one. Conclusion: I am only more clever than your AI... sometimes... lol

Nicely done!
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #20 on: December 14, 2020, 08:02:46 pm »
Thanks Johnno

I have a tiny adjustment so you can do any NxN grid within reason.

Code: QB64: [Select]
  1. _TITLE "Connect 4 8x8: AI challenge" 'b+ 2020-12-14 rewrite
  2.  
  3. DEFLNG A-Z
  4. CONST SQ = 60 '            square or grid cell
  5. CONST N = 7 '             number of rows and columns
  6. CONST SW = SQ * (N + 2) '  screen width
  7. CONST SH = SQ * (N + 3) '  screen height
  8. CONST NM1 = N - 1 '        N minus 1
  9. CONST P = 1 '              Player is 1 on grid
  10. CONST AI = -1 '            AI is -1 on grid
  11. CONST XO = SQ '            x offset for grid
  12. CONST YO = 2 * SQ '        y offset for grid
  13.  
  14. REDIM SHARED Grid(NM1, NM1) ' 0 = empty  P=1 for Player,  AI=-1  for AI so -4 is win for AI..
  15. REDIM SHARED DX(7), DY(7), WinX, WinY, WinD, GameOn, Turn, AIX, AIY, GoFirst ' if find a win, draw it in ShowGrid
  16. DX(0) = 1: DY(0) = 0 ': DString$(0) = "East"
  17. DX(1) = 1: DY(1) = 1 ': DString$(1) = "South East"
  18. DX(2) = 0: DY(2) = 1 ': DString$(2) = "South"
  19. DX(3) = -1: DY(3) = 1 ': DString$(3) = "South West"
  20. DX(4) = -1: DY(4) = 0 ': DString$(4) = "West"
  21. DX(5) = -1: DY(5) = -1 ': DString$(5) = "North West"
  22. DX(6) = 0: DY(6) = -1 ': DString$(6) = "North"
  23. DX(7) = 1: DY(7) = -1 ' : DString$(7) = "North East"
  24.  
  25. SCREEN _NEWIMAGE(SW, SH, 32)
  26. _DELAY .25
  27. DIM mb, mx, my, row, col, r
  28. GameOn = -1: GoFirst = AI: Turn = AI
  29. ShowGrid
  30. WHILE GameOn
  31.     IF Turn = P THEN
  32.         WHILE _MOUSEINPUT: WEND
  33.         mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  34.         IF mb THEN 'get last place mouse button was down
  35.             _DELAY .25 'for mouse release
  36.             row = ((my - YO) / SQ - .5): col = ((mx - XO) / SQ - .5)
  37.             IF col >= 0 AND col <= NM1 AND row >= 0 AND row <= NM1 THEN
  38.                 r = GetOpenRow(col) 'find next space open on board
  39.                 IF r <> N THEN
  40.                     Grid(col, r) = P
  41.                     Turn = AI
  42.                 END IF
  43.             ELSE
  44.                 BEEP
  45.             END IF
  46.         END IF
  47.     ELSE
  48.         AIMove
  49.         Turn = P
  50.     END IF
  51.     ShowGrid
  52.     _DISPLAY
  53.     _LIMIT 60
  54.  
  55. SUB AIMove
  56.     ' What this sub does in English:
  57.     ' This sub assigns the value to playing each column, then plays the best value with following caveats:
  58.     ' + If it finds a winning move, it will play that immediately.
  59.     ' + If it finds a spoiler move, it will play that if no winning move was found.
  60.     ' + It will poisen the column's scoring, if opponent can play a winning move if AI plays this column,
  61.     '   but it might be the only legal move left.  We will have to play it if no better score was found.
  62.  
  63.     DIM c, r, d, cntA, cntP, bestScore, startR, startC, iStep, test, goodF, i
  64.     DIM openRow(NM1) ' find open rows once
  65.     DIM scores(NM1) ' evaluate each column's potential
  66.     AIX = -1: AIY = -1 ' set these when AI makes move, they are signal to display procedure AI's move.
  67.     FOR c = 0 TO NM1
  68.         openRow(c) = GetOpenRow(c)
  69.         r = openRow(c)
  70.         IF r <> N THEN
  71.             FOR d = 0 TO 3 ' 4 directions to build connect 4's that use cell c, r
  72.                 startC = c + -3 * DX(d): startR = r + -3 * DY(d)
  73.                 FOR i = 0 TO 3 ' here we backup from the potential connect 4 in opposite build direction of c, r
  74.                     cntA = 0: cntP = 0: goodF = -1 ' reset counts and flag for good connect 4
  75.                     'from this start position run 4 steps forward to count all connects involving cell c, r
  76.                     FOR iStep = 0 TO 3 ' process a potential connect 4
  77.                         test = GR(startC + i * DX(d) + iStep * DX(d), startR + i * DY(d) + iStep * DY(d))
  78.                         IF test = N THEN goodF = 0: EXIT FOR 'cant get connect4 from here
  79.                         IF test = AI THEN cntA = cntA + 1
  80.                         IF test = P THEN cntP = cntP + 1
  81.                     NEXT iStep
  82.                     IF goodF THEN 'evaluate the Legal Connect4 we could build with c, r
  83.                         IF cntA = 3 THEN ' we are done!  winner!
  84.                             AIX = c: AIY = r ' <<< this is the needed 4th cell to win tell ShowGrid last cell
  85.                             Grid(c, r) = AI '  <<< this is the needed 4th cell to win, add to grid this is AI move
  86.                             EXIT SUB
  87.                         ELSEIF cntP = 3 THEN 'next best move spoiler!
  88.                             AIX = c: AIY = r 'set the move but don't exit there might be a winner
  89.                         ELSEIF cntA = 0 AND cntP = 2 THEN
  90.                             scores(c) = scores(c) + 6
  91.                         ELSEIF cntA = 2 AND cntP = 0 THEN ' very good offense or defense
  92.                             scores(c) = scores(c) + 5 'play this to connect 3 or prevent player from Connect 3
  93.                         ELSEIF cntA = 0 AND cntP = 1 THEN
  94.                             scores(c) = scores(c) + 4
  95.                         ELSEIF (cntA = 1 AND cntP = 0) OR (cntA = 0 AND cntP = 1) THEN 'good offense or defense
  96.                             scores(c) = scores(c) + 3 ' play this to connect 2 or prevent player from Connect 2
  97.                         ELSEIF (cntA = 0 AND cntP = 0) THEN ' OK it's not a wasted move as it has potential for connect4
  98.                             scores(c) = scores(c) + 1 ' this is good move because this can still be a Connect 4
  99.                         END IF
  100.                     END IF ' in the board
  101.                 NEXT i
  102.             NEXT d
  103.             IF Stupid(c, r) THEN scores(c) = -1000 + scores(c) ' poison because if played the human can win
  104.         END IF
  105.     NEXT
  106.     IF AIX <> -1 THEN ' we found a spoiler so move there since we haven't found a winner
  107.         Grid(AIX, AIY) = AI ' make move on grid and done!
  108.         EXIT SUB
  109.     ELSE
  110.         bestScore = -1000 ' a negative score indicates that the player can beat AI with their next move
  111.         FOR c = 0 TO NM1
  112.             r = openRow(c)
  113.             IF r <> N THEN
  114.                 IF scores(c) > bestScore THEN bestScore = scores(c): AIY = r: AIX = c
  115.             END IF
  116.         NEXT
  117.         IF AIX <> -1 THEN
  118.             Grid(AIX, AIY) = AI ' make first best score move we found
  119.         ELSE 'We have trouble!  Oh but it could be there are no moves!!!
  120.             ' checkWin is run after every move by AI or Player if there were no legal moves left it should have caught that.
  121.             ' Just in case it didn't here is an error stop!
  122.  
  123.             'note: LOCATE here is Row, Column the reverse of Just Basic
  124.             BEEP: LOCATE 4, 2: PRINT "AI has failed to find a proper move, pess any to end..."
  125.             SLEEP ' <<< pause until user presses a key
  126.             END
  127.         END IF
  128.     END IF
  129.  
  130. FUNCTION GetOpenRow (forCol)
  131.     DIM i
  132.     GetOpenRow = N 'assume none open
  133.     IF forCol < 0 OR forCol > NM1 THEN EXIT FUNCTION
  134.     FOR i = NM1 TO 0 STEP -1
  135.         IF Grid(forCol, i) = 0 THEN GetOpenRow = i: EXIT FUNCTION
  136.     NEXT
  137.  
  138. FUNCTION Stupid (c, r)
  139.     DIM pr
  140.  
  141.     Grid(c, r) = AI
  142.     pr = GetOpenRow(c)
  143.     IF pr <> N THEN
  144.         Grid(c, pr) = P
  145.         IF CheckWin = 4 THEN Stupid = -1
  146.         Grid(c, pr) = 0
  147.     END IF
  148.     Grid(c, r) = 0
  149.  
  150. FUNCTION GR (c, r) ' if c, r are out of bounds returns N else returns grid(c, r)
  151.     ' need to check the grid(c, r) but only if c, r is on the board
  152.     IF c < 0 OR c > NM1 OR r < 0 OR r > NM1 THEN GR = N ELSE GR = Grid(c, r)
  153.  
  154. SUB ShowGrid
  155.     DIM i, r, c, check, s$, y$
  156.     CLS
  157.     FOR i = 0 TO N 'grid
  158.         LINE (SQ * i + XO, YO)-STEP(0, N * SQ), &HFF00FF00
  159.         LINE (XO, SQ * i + YO)-STEP(N * SQ, 0), &HFF00FF00
  160.     NEXT
  161.     FOR r = NM1 TO 0 STEP -1 'plays
  162.         FOR c = 0 TO NM1
  163.             'in grid rows are reversed 0 is top row
  164.             IF Grid(c, r) = P THEN
  165.                 LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFFFF0000, BF
  166.             ELSEIF Grid(c, r) = AI THEN
  167.                 IF c = AIX AND r = AIY THEN 'highlite last AI move
  168.                     LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFF5555FF, BF
  169.                 ELSE
  170.                     LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFF0000FF, BF
  171.                 END IF
  172.             END IF
  173.         NEXT
  174.     NEXT
  175.     _DISPLAY
  176.     check = CheckWin
  177.     IF check THEN 'report end of round ad see if want to play again
  178.         IF check = 4 OR check = -4 THEN
  179.             FOR i = 0 TO 3
  180.                 LINE ((WinX + i * DX(WinD)) * SQ + XO + 5, (WinY + i * DY(WinD)) * SQ + YO + 5)-STEP(SQ - 10, SQ - 10), &HFFFFFFFF, B
  181.             NEXT
  182.         END IF
  183.         IF check = -4 THEN
  184.             s$ = "AI is Winner!"
  185.         ELSEIF check = 4 THEN
  186.             s$ = "Human is Winner!"
  187.         ELSEIF check = N THEN
  188.             s$ = "Board is full, no winner." ' keep Turn the same
  189.         END IF
  190.         LOCATE 2, 2: PRINT s$
  191.         _DISPLAY
  192.         LOCATE 4, 2: INPUT "Play again? just press enter quit with any other ", y$
  193.         IF y$ = "" THEN
  194.             REDIM Grid(NM1, NM1)
  195.             IF GoFirst = P THEN GoFirst = AI ELSE GoFirst = P
  196.             Turn = GoFirst
  197.         ELSE
  198.             GameOn = 0
  199.         END IF
  200.     END IF
  201.  
  202. FUNCTION CheckWin
  203.     DIM gridFull, r, c, s, i
  204.     ' return WinX, WinY, WinD along with +/- score, returns N  if grid full, 0 if no win and grid not full
  205.     gridFull = N
  206.     FOR r = NM1 TO 0 STEP -1 'bottom to top
  207.         FOR c = 0 TO NM1
  208.             IF Grid(c, r) THEN 'check if c starts a row
  209.                 IF c < NM1 - 2 THEN
  210.                     s = 0
  211.                     FOR i = 0 TO 3
  212.                         s = s + Grid(c + i, r)
  213.                     NEXT
  214.                     IF s = 4 OR s = -4 THEN
  215.                         WinX = c: WinY = r: WinD = 0
  216.                         CheckWin = s: EXIT FUNCTION
  217.                     END IF
  218.                 END IF
  219.                 IF r > 2 THEN 'check if c starts a col
  220.                     s = 0
  221.                     FOR i = 0 TO 3
  222.                         s = s + Grid(c, r - i)
  223.                     NEXT
  224.                     IF s = 4 OR s = -4 THEN
  225.                         WinX = c: WinY = r: WinD = 6 'north
  226.                         CheckWin = s: EXIT FUNCTION
  227.                     END IF
  228.                 END IF
  229.                 IF r > 2 AND c < NM1 - 2 THEN 'check if c starts diagonal up to right
  230.                     s = 0
  231.                     FOR i = 0 TO 3
  232.                         s = s + Grid(c + i, r - i)
  233.                     NEXT
  234.                     IF s = 4 OR s = -4 THEN ' north  east
  235.                         WinX = c: WinY = r: WinD = 7
  236.                         CheckWin = s: EXIT FUNCTION
  237.                     END IF
  238.                 END IF
  239.                 IF r > 2 AND c > 2 THEN 'check if c starts a diagonal up to left
  240.                     s = 0
  241.                     FOR i = 0 TO 3
  242.                         s = s + Grid(c - i, r - i)
  243.                     NEXT
  244.                     IF s = 4 OR s = -4 THEN ' north west
  245.                         WinX = c: WinY = r: WinD = 5
  246.                         CheckWin = s: EXIT FUNCTION
  247.                     END IF
  248.                 END IF
  249.             ELSE
  250.                 gridFull = 0 ' at least one enpty cell left
  251.             END IF 'grid is something
  252.         NEXT
  253.     NEXT
  254.     CheckWin = gridFull
  255.  

Time for Big Game!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #21 on: December 15, 2020, 01:30:18 am »
I have a mod coming for any amount of rows and columns but have to check out why the AI made a Stupid move when I was checking out a 10x6 grid. I suspect my CheckWin Function fails for rectangular shaped grids though no "Subscript out of range" error was reported.

Dang! What a game, 47 to 42, too bad Browns lost but it was a hell of a game!

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #22 on: December 15, 2020, 04:36:44 am »
"What a game."? I thought the game was Connect-4... "Browns lost"? Connect-4 uses basically blue and red.

I am obviously suffering from caffeine withdrawal....
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #23 on: December 15, 2020, 10:27:36 am »
"What a game."? I thought the game was Connect-4... "Browns lost"? Connect-4 uses basically blue and red.

I am obviously suffering from caffeine withdrawal....

No not caffeine, American football, the game was between Cleveland Browns (Browns Town) and Baltimore Ravens.
Ravens specially vile ;-) because previous Browns owner sold team to Baltimore and we were without Browns team for awhile, we've not seen a season so far above 500 for a long time. This game was something too, not often both teams are in the 40 somethings in score.

Anyway, all this tells me the colors for Connect 4 had better be Brown (very orange brown) and Purple (a very dark and red purple almost black like raven). The grid(iron) is already green but maybe that should be white with field green fill. ;-))

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #24 on: December 15, 2020, 11:44:27 pm »
Here is an update where you see the scoring system in the bottom row of numbers:
Code: QB64: [Select]
  1. OPTION _EXPLICIT ' Connect 4 NumRows X NumCols 2020_12_15.bas update bplus
  2. ' New: any number of rows or columns within reason, colors changed, STx Win against AI fix.
  3.  
  4. DEFLNG A-Z
  5. CONST SQ = 60 '       square or grid cell
  6. CONST NumCols = 8 '   number of columns
  7. CONST NumRows = 8 '   you guessed it
  8. CONST NCM1 = NumCols - 1 ' NumCols minus 1
  9. CONST NRM1 = NumRows - 1 ' you can guess surely
  10. CONST SW = SQ * (NumCols + 2) '  screen width
  11. CONST SH = SQ * (NumRows + 3) '  screen height
  12. CONST P = 1 '       Player is 1 on grid
  13. CONST AI = -1 '     AI is -1 on grid
  14. CONST XO = SQ '     x offset for grid
  15. CONST YO = 2 * SQ ' y offset for grid
  16.  
  17. REDIM SHARED Grid(NCM1, NRM1) ' 0 = empty  P=1 for Player,  AI=-1  for AI so -4 is win for AI..
  18. REDIM SHARED DX(7), DY(7), WinX, WinY, WinD, GameOn, Turn, AIX, AIY, GoFirst ' if find a win, draw it in ShowGrid
  19. DX(0) = 1: DY(0) = 0 ': DString$(0) = "East"
  20. DX(1) = 1: DY(1) = 1 ': DString$(1) = "South East"
  21. DX(2) = 0: DY(2) = 1 ': DString$(2) = "South"
  22. DX(3) = -1: DY(3) = 1 ': DString$(3) = "South West"
  23. DX(4) = -1: DY(4) = 0 ': DString$(4) = "West"
  24. DX(5) = -1: DY(5) = -1 ': DString$(5) = "North West"
  25. DX(6) = 0: DY(6) = -1 ': DString$(6) = "North"
  26. DX(7) = 1: DY(7) = -1 ' : DString$(7) = "North East"
  27. REDIM SHARED Scores(NCM1)
  28.  
  29. SCREEN _NEWIMAGE(SW, SH, 32)
  30. _SCREENMOVE 360, 60
  31. DIM mb, mx, my, row, col, r
  32. _TITLE "Connect 4: " + _TRIM$(STR$(NumCols)) + "x" + _TRIM$(STR$(NumRows)) + " with bplus AI"
  33. GameOn = -1: GoFirst = AI: Turn = AI
  34. ShowGrid
  35. WHILE GameOn
  36.     IF Turn = P THEN
  37.         WHILE _MOUSEINPUT: WEND
  38.         mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  39.         IF mb THEN 'get last place mouse button was down
  40.             _DELAY .25 'for mouse release
  41.             row = ((my - YO) / SQ - .5): col = ((mx - XO) / SQ - .5)
  42.             IF col >= 0 AND col <= NCM1 AND row >= 0 AND row < 8 THEN
  43.                 'find next space open on board
  44.                 r = GetOpenRow(col)
  45.                 IF r <> NumRows THEN
  46.                     Grid(col, r) = P
  47.                     Turn = AI
  48.                 END IF
  49.             ELSE
  50.                 BEEP
  51.             END IF
  52.         END IF
  53.     ELSE
  54.         AIMove
  55.         Turn = P
  56.     END IF
  57.     ShowGrid
  58.     _DISPLAY
  59.     _LIMIT 60
  60.  
  61. SUB AIMove
  62.     ' What this sub does in English:
  63.     ' This sub assigns the value to playing each column, then plays the best value with following caveats:
  64.     ' + If it finds a winning move, it will play that immediately.
  65.     ' + If it finds a spoiler move, it will play that if no winning move was found.
  66.     ' + It will poisen the column's scoring, if opponent can play a winning move if AI plays this column,
  67.     '   but it might be the only legal move left.  We will have to play it if no better score was found.
  68.  
  69.     DIM c, r, d, cntA, cntP, bestScore, startR, startC, iStep, test, goodF, i
  70.     DIM openRow(NCM1) ' find open rows once
  71.     REDIM Scores(NCM1) ' evaluate each column's potential
  72.     AIX = -1: AIY = -1 ' set these when AI makes move, they are signal to display procedure AI's move.
  73.     FOR c = 0 TO NCM1
  74.         openRow(c) = GetOpenRow(c)
  75.         r = openRow(c)
  76.         IF r <> NumRows THEN
  77.             FOR d = 0 TO 3 ' 4 directions to build connect 4's that use cell c, r
  78.                 startC = c + -3 * DX(d): startR = r + -3 * DY(d)
  79.                 FOR i = 0 TO 3 ' here we backup from the potential connect 4 in opposite build direction of c, r
  80.                     cntA = 0: cntP = 0: goodF = -1 ' reset counts and flag for good connect 4
  81.                     'from this start position run 4 steps forward to count all connects involving cell c, r
  82.                     FOR iStep = 0 TO 3 ' process a potential connect 4
  83.                         test = GR(startC + i * DX(d) + iStep * DX(d), startR + i * DY(d) + iStep * DY(d))
  84.                         IF test = NumRows THEN goodF = 0: EXIT FOR 'cant get connect4 from here
  85.                         IF test = AI THEN cntA = cntA + 1
  86.                         IF test = P THEN cntP = cntP + 1
  87.                     NEXT iStep
  88.                     IF goodF THEN 'evaluate the Legal Connect4 we could build with c, r
  89.                         IF cntA = 3 THEN ' we are done!  winner!
  90.                             AIX = c: AIY = r ' <<< this is the needed 4th cell to win tell ShowGrid last cell
  91.                             Grid(c, r) = AI '  <<< this is the needed 4th cell to win, add to grid this is AI move
  92.                             Scores(c) = 1000
  93.                             EXIT SUB
  94.                         ELSEIF cntP = 3 THEN 'next best move spoiler!
  95.                             AIX = c: AIY = r 'set the move but don't exit there might be a winner
  96.                             Scores(c) = 999
  97.                         ELSEIF cntA = 0 AND cntP = 2 THEN
  98.                             Scores(c) = Scores(c) + 8
  99.                         ELSEIF cntA = 2 AND cntP = 0 THEN ' very good offense or defense
  100.                             Scores(c) = Scores(c) + 4 'play this to connect 3 or prevent player from Connect 3
  101.                         ELSEIF cntA = 0 AND cntP = 1 THEN
  102.                             Scores(c) = Scores(c) + 4
  103.                         ELSEIF (cntA = 1 AND cntP = 0) THEN 'good offense or defense
  104.                             Scores(c) = Scores(c) + 2 ' play this to connect 2 or prevent player from Connect 2
  105.                         ELSEIF (cntA = 0 AND cntP = 0) THEN ' OK it's not a wasted move as it has potential for connect4
  106.                             Scores(c) = Scores(c) + 1 ' this is good move because this can still be a Connect 4
  107.                         END IF
  108.                     END IF ' in the board
  109.                 NEXT i
  110.             NEXT d
  111.             IF Stupid(c, r) THEN Scores(c) = -1000 + Scores(c) ' poison because if played the human can win
  112.         END IF
  113.     NEXT
  114.     IF AIX <> -1 THEN ' we found a spoiler so move there since we haven't found a winner
  115.         Grid(AIX, AIY) = AI ' make move on grid and done!
  116.         EXIT SUB
  117.     ELSE
  118.         bestScore = -1000 ' a negative score indicates that the player can beat AI with their next move
  119.         FOR c = 0 TO NCM1
  120.             r = openRow(c)
  121.             IF r <> NumRows THEN
  122.                 IF Scores(c) > bestScore THEN bestScore = Scores(c): AIY = r: AIX = c
  123.             END IF
  124.         NEXT
  125.         IF AIX <> -1 THEN
  126.             Grid(AIX, AIY) = AI ' make first best score move we found
  127.         ELSE 'We have trouble!  Oh but it could be there are no moves!!!
  128.             ' checkWin is run after every move by AI or Player if there were no legal moves left it should have caught that.
  129.             ' Just in case it didn't here is an error stop!
  130.             BEEP: LOCATE 4, 2: PRINT "AI has failed to find a proper move, pess any to end..."
  131.             SLEEP ' <<< pause until user presses a key
  132.             END
  133.         END IF
  134.     END IF
  135.  
  136. FUNCTION GetOpenRow (forCol)
  137.     DIM i
  138.     GetOpenRow = NumRows 'assume none open
  139.     IF forCol < 0 OR forCol > NCM1 THEN EXIT FUNCTION
  140.     FOR i = NRM1 TO 0 STEP -1
  141.         IF Grid(forCol, i) = 0 THEN GetOpenRow = i: EXIT FUNCTION
  142.     NEXT
  143.  
  144. FUNCTION Stupid (c, r)
  145.     DIM pr
  146.     Grid(c, r) = AI
  147.     pr = GetOpenRow(c)
  148.     IF pr <> NumRows THEN
  149.         Grid(c, pr) = P
  150.         IF CheckWin = 4 THEN Stupid = -1
  151.         Grid(c, pr) = 0
  152.     END IF
  153.     Grid(c, r) = 0
  154.  
  155. FUNCTION GR (c, r) ' if c, r are out of bounds returns N else returns grid(c, r)
  156.     ' need to check the grid(c, r) but only if c, r is on the board
  157.     IF c < 0 OR c > NCM1 OR r < 0 OR r > NRM1 THEN GR = NumRows ELSE GR = Grid(c, r)
  158.  
  159. SUB ShowGrid
  160.     DIM i, r, c, check, s$, k$
  161.     CLS
  162.     LINE (XO, YO)-STEP(NumCols * SQ, NumRows * SQ), &HFF004400, BF
  163.     FOR i = 0 TO NumCols 'grid
  164.         LINE (SQ * i + XO, YO)-STEP(0, NumRows * SQ), &HFFFFFFFF
  165.     NEXT
  166.     FOR i = 0 TO NumRows
  167.         LINE (XO, SQ * i + YO)-STEP(NumCols * SQ, 0), &HFFFFFFFF
  168.     NEXT
  169.     FOR r = NRM1 TO 0 STEP -1 'plays
  170.         FOR c = 0 TO NCM1
  171.             'in grid rows are reversed 0 is top row
  172.             IF Grid(c, r) = P THEN
  173.                 LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFFFF2200, BF
  174.             ELSEIF Grid(c, r) = AI THEN
  175.                 IF c = AIX AND r = AIY THEN 'highlite last AI move
  176.                     LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFF660088, BF
  177.                 ELSE
  178.                     LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFF440066, BF
  179.                 END IF
  180.             END IF
  181.             s$ = _TRIM$(STR$(Scores(c)))
  182.             _PRINTSTRING (XO + c * SQ + (60 - LEN(s$) * 8) / 2, YO + SQ * NumRows + 22), s$
  183.         NEXT
  184.     NEXT
  185.     _DISPLAY
  186.     check = CheckWin
  187.     IF check THEN 'report end of round ad see if want to play again
  188.         IF check = 4 OR check = -4 THEN
  189.             FOR i = 0 TO 3
  190.                 LINE ((WinX + i * DX(WinD)) * SQ + XO + 5, (WinY + i * DY(WinD)) * SQ + YO + 5)-STEP(SQ - 10, SQ - 10), &HFFFFFF00, B
  191.             NEXT
  192.         END IF
  193.         IF check = -4 THEN
  194.             s$ = "AI is Winner!"
  195.         ELSEIF check = 4 THEN
  196.             s$ = "Human is Winner!"
  197.         ELSEIF check = NumRows THEN
  198.             s$ = "Board is full, no winner." ' keep Turn the same
  199.         END IF
  200.         LOCATE 2, ((SW - LEN(s$) * 8) / 2) / 8: PRINT s$
  201.         s$ = "Play again? press spacebar, any other to quit... "
  202.         LOCATE 4, ((SW - LEN(s$) * 8) / 2) / 8: PRINT s$
  203.         _DISPLAY
  204.         WHILE LEN(k$) = 0
  205.             k$ = INKEY$
  206.             _LIMIT 200
  207.         WEND
  208.         IF k$ = " " THEN
  209.             REDIM Grid(NCM1, NRM1), Scores(NCM1)
  210.             IF GoFirst = P THEN GoFirst = AI ELSE GoFirst = P
  211.             Turn = GoFirst
  212.         ELSE
  213.             GameOn = 0
  214.         END IF
  215.     END IF
  216.  
  217. FUNCTION CheckWin ' return WinX, WinY, WinD along with +/- 4, returns NumRows if grid full, 0 if no win and grid not full
  218.     DIM gridFull, r, c, s, i
  219.  
  220.     gridFull = NumRows
  221.     FOR r = NRM1 TO 0 STEP -1 'bottom to top
  222.         FOR c = 0 TO NCM1
  223.             IF Grid(c, r) THEN 'check if c starts a row
  224.                 IF c < NCM1 - 2 THEN
  225.                     s = 0
  226.                     FOR i = 0 TO 3
  227.                         s = s + Grid(c + i, r)
  228.                     NEXT
  229.                     IF s = 4 OR s = -4 THEN
  230.                         WinX = c: WinY = r: WinD = 0
  231.                         CheckWin = s: EXIT FUNCTION
  232.                     END IF
  233.                 END IF
  234.                 IF r > 2 THEN 'check if c starts a col
  235.                     s = 0
  236.                     FOR i = 0 TO 3
  237.                         s = s + Grid(c, r - i)
  238.                     NEXT
  239.                     IF s = 4 OR s = -4 THEN
  240.                         WinX = c: WinY = r: WinD = 6 'north
  241.                         CheckWin = s: EXIT FUNCTION
  242.                     END IF
  243.                 END IF
  244.                 IF r > 2 AND c < NCM1 - 2 THEN 'check if c starts diagonal up to right
  245.                     s = 0
  246.                     FOR i = 0 TO 3
  247.                         s = s + Grid(c + i, r - i)
  248.                     NEXT
  249.                     IF s = 4 OR s = -4 THEN ' north  east
  250.                         WinX = c: WinY = r: WinD = 7
  251.                         CheckWin = s: EXIT FUNCTION
  252.                     END IF
  253.                 END IF
  254.                 IF r > 2 AND c > 2 THEN 'check if c starts a diagonal up to left
  255.                     s = 0
  256.                     FOR i = 0 TO 3
  257.                         s = s + Grid(c - i, r - i)
  258.                     NEXT
  259.                     IF s = 4 OR s = -4 THEN ' north west
  260.                         WinX = c: WinY = r: WinD = 5
  261.                         CheckWin = s: EXIT FUNCTION
  262.                     END IF
  263.                 END IF
  264.             ELSE
  265.                 gridFull = 0 ' at least one enpty cell left
  266.             END IF 'grid is something
  267.         NEXT
  268.     NEXT
  269.     CheckWin = gridFull
  270.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #25 on: December 16, 2020, 06:22:50 pm »
Oh sorry, I just noticed 
Quote
...STx Win against AI fix.
in comments.

Not yet, it may play different but weaker? Coming soon, game recording and feeding AI the players last move for more info to work on.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #26 on: December 17, 2020, 12:48:06 am »
Well I went full circle from recording games in txt file then tried adding Steve's humongous SaveImage BI, BM and then decided it is enough to number the squares by move number and get a screen shot when you've got a winner, a bit like Stx showed when he found a winning combination.

I have ruined Stx quick game win pattern with kind of a simple instruction to play on top of the last move, all other things being equal. I suck at playing this game so not sure if the AI is stronger, much stronger or the same. It can't be weaker.

OK so after a win or tie, all the squares get numbered so if you've got a winner just take a snapshot and brag about it here, please!

Code: QB64: [Select]
  1. OPTION _EXPLICIT ' Connect 4 NumRows X NumCols 2020_12_16.bas update bplus
  2. DEFLNG A-Z
  3. CONST SQ = 60 '       square or grid cell
  4. CONST NumCols = 8 '   number of columns
  5. CONST NumRows = 8 '   you guessed it
  6. CONST NCM1 = NumCols - 1 ' NumCols minus 1
  7. CONST NRM1 = NumRows - 1 ' you can guess surely
  8. CONST SW = SQ * (NumCols + 2) '  screen width
  9. CONST SH = SQ * (NumRows + 3) '  screen height
  10. CONST P = 1 '       Player is 1 on grid
  11. CONST AI = -1 '     AI is -1 on grid
  12. CONST XO = SQ '     x offset for grid
  13. CONST YO = 2 * SQ ' y offset for grid
  14.  
  15. REDIM SHARED Grid(NCM1, NRM1) ' 0 = empty  P=1 for Player,  AI=-1  for AI so -4 is win for AI..
  16. REDIM SHARED DX(7), DY(7) ' Directions
  17. DX(0) = 1: DY(0) = 0 ': DString$(0) = "East"
  18. DX(1) = 1: DY(1) = 1 ': DString$(1) = "South East"
  19. DX(2) = 0: DY(2) = 1 ': DString$(2) = "South"
  20. DX(3) = -1: DY(3) = 1 ': DString$(3) = "South West"
  21. DX(4) = -1: DY(4) = 0 ': DString$(4) = "West"
  22. DX(5) = -1: DY(5) = -1 ': DString$(5) = "North West"
  23. DX(6) = 0: DY(6) = -1 ': DString$(6) = "North"
  24. DX(7) = 1: DY(7) = -1 ' : DString$(7) = "North East"
  25. REDIM SHARED Scores(NCM1) ' rating column for AI and displaying them
  26. REDIM SHARED AIX, AIY ' last move of AI for highlighting in display
  27. REDIM SHARED WinX, WinY, WinD ' display Winning Connect 4
  28. REDIM SHARED GameOn, Turn, GoFirst, PlayerLastMoveCol, PlayerLastMoveRow, MoveNum ' game tracking
  29. REDIM SHARED Record$(NCM1, NRM1)
  30.  
  31. SCREEN _NEWIMAGE(SW, SH, 32)
  32. _SCREENMOVE 360, 60
  33. DIM mb, mx, my, row, col, r
  34. _TITLE "Connect 4: " + _TRIM$(STR$(NumCols)) + "x" + _TRIM$(STR$(NumRows)) + " with AI"
  35. GameOn = -1: GoFirst = AI: Turn = AI: MoveNum = 0
  36. ShowGrid
  37. WHILE GameOn
  38.     IF Turn = P THEN
  39.         WHILE _MOUSEINPUT: WEND
  40.         mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  41.         IF mb THEN 'get last place mouse button was down
  42.             _DELAY .25 'for mouse release
  43.             row = ((my - YO) / SQ - .5): col = ((mx - XO) / SQ - .5)
  44.             IF col >= 0 AND col <= NCM1 AND row >= 0 AND row < 8 THEN
  45.                 r = GetOpenRow(col)
  46.                 IF r <> NumRows THEN
  47.                     Grid(col, r) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = r: MoveNum = MoveNum + 1
  48.                 END IF
  49.             ELSE
  50.                 BEEP
  51.             END IF
  52.         END IF
  53.     ELSE
  54.         AIMove
  55.         Turn = P: MoveNum = MoveNum + 1
  56.     END IF
  57.     ShowGrid
  58.     _DISPLAY
  59.     _LIMIT 60
  60.  
  61. SUB AIMove
  62.     ' What this sub does in English:
  63.     ' This sub assigns the value to playing each column, then plays the best value with following caveats:
  64.     ' + If it finds a winning move, it will play that immediately.
  65.     ' + If it finds a spoiler move, it will play that if no winning move was found.
  66.     ' + It will poisen the column's scoring, if opponent can play a winning move if AI plays this column,
  67.     '   but it might be the only legal move left.  We will have to play it if no better score was found.
  68.  
  69.     DIM c, r, d, cntA, cntP, bestScore, startR, startC, iStep, test, goodF, i
  70.     DIM openRow(NCM1) ' find open rows once
  71.     REDIM Scores(NCM1) ' evaluate each column's potential
  72.     AIX = -1: AIY = -1 ' set these when AI makes move, they are signal to display procedure AI's move.
  73.     FOR c = 0 TO NCM1
  74.         openRow(c) = GetOpenRow(c)
  75.         r = openRow(c)
  76.         IF r <> NumRows THEN
  77.             FOR d = 0 TO 3 ' 4 directions to build connect 4's that use cell c, r
  78.                 startC = c + -3 * DX(d): startR = r + -3 * DY(d)
  79.                 FOR i = 0 TO 3 ' here we backup from the potential connect 4 in opposite build direction of c, r
  80.                     cntA = 0: cntP = 0: goodF = -1 ' reset counts and flag for good connect 4
  81.                     'from this start position run 4 steps forward to count all connects involving cell c, r
  82.                     FOR iStep = 0 TO 3 ' process a potential connect 4
  83.                         test = GR(startC + i * DX(d) + iStep * DX(d), startR + i * DY(d) + iStep * DY(d))
  84.                         IF test = NumRows THEN goodF = 0: EXIT FOR 'cant get connect4 from here
  85.                         IF test = AI THEN cntA = cntA + 1
  86.                         IF test = P THEN cntP = cntP + 1
  87.                     NEXT iStep
  88.                     IF goodF THEN 'evaluate the Legal Connect4 we could build with c, r
  89.                         IF cntA = 3 THEN ' we are done!  winner!
  90.                             AIX = c: AIY = r ' <<< this is the needed 4th cell to win tell ShowGrid last cell
  91.                             Grid(c, r) = AI '  <<< this is the needed 4th cell to win, add to grid this is AI move
  92.                             Scores(c) = 1000
  93.                             EXIT SUB
  94.                         ELSEIF cntP = 3 THEN 'next best move spoiler!
  95.                             AIX = c: AIY = r 'set the move but don't exit there might be a winner
  96.                             Scores(c) = 900
  97.                         ELSEIF cntA = 0 AND cntP = 2 THEN
  98.                             Scores(c) = Scores(c) + 8
  99.                         ELSEIF cntA = 2 AND cntP = 0 THEN ' very good offense or defense
  100.                             Scores(c) = Scores(c) + 4 'play this to connect 3 or prevent player from Connect 3
  101.                         ELSEIF cntA = 0 AND cntP = 1 THEN
  102.                             Scores(c) = Scores(c) + 4
  103.                         ELSEIF (cntA = 1 AND cntP = 0) THEN 'good offense or defense
  104.                             Scores(c) = Scores(c) + 2 ' play this to connect 2 or prevent player from Connect 2
  105.                         ELSEIF (cntA = 0 AND cntP = 0) THEN ' OK it's not a wasted move as it has potential for connect4
  106.                             Scores(c) = Scores(c) + 1 ' this is good move because this can still be a Connect 4
  107.                         END IF
  108.                     END IF ' in the board
  109.                 NEXT i
  110.             NEXT d
  111.             IF Stupid(c, r) THEN Scores(c) = -1000 + Scores(c) ' poison because if played the human can win
  112.         END IF
  113.     NEXT
  114.     IF AIX <> -1 THEN ' we found a spoiler so move there since we haven't found a winner
  115.         Grid(AIX, AIY) = AI ' make move on grid and done!
  116.         EXIT SUB
  117.     ELSE
  118.         IF GetOpenRow(PlayerLastMoveCol) < NumRows THEN 'all things being equal play on top of player's last move
  119.             bestScore = Scores(PlayerLastMoveCol): AIY = PlayerLastMoveRow - 1: AIX = PlayerLastMoveCol
  120.         ELSE
  121.             bestScore = -1000 ' a negative score indicates that the player can beat AI with their next move
  122.         END IF
  123.         FOR c = 0 TO NCM1
  124.             r = openRow(c)
  125.             IF r <> NumRows THEN
  126.                 IF Scores(c) > bestScore THEN bestScore = Scores(c): AIY = r: AIX = c
  127.             END IF
  128.         NEXT
  129.         IF AIX <> -1 THEN
  130.             Grid(AIX, AIY) = AI ' make first best score move we found
  131.         ELSE 'We have trouble!  Oh but it could be there are no moves!!!
  132.             ' checkWin is run after every move by AI or Player if there were no legal moves left it should have caught that.
  133.             ' Just in case it didn't here is an error stop!
  134.             BEEP: LOCATE 4, 2: PRINT "AI has failed to find a proper move, press any to end..."
  135.             SLEEP ' <<< pause until user presses a key
  136.             END
  137.         END IF
  138.     END IF
  139.  
  140. FUNCTION GetOpenRow (forCol)
  141.     DIM i
  142.     GetOpenRow = NumRows 'assume none open
  143.     IF forCol < 0 OR forCol > NCM1 THEN EXIT FUNCTION
  144.     FOR i = NRM1 TO 0 STEP -1
  145.         IF Grid(forCol, i) = 0 THEN GetOpenRow = i: EXIT FUNCTION
  146.     NEXT
  147.  
  148. FUNCTION Stupid (c, r)
  149.     DIM pr
  150.     Grid(c, r) = AI
  151.     pr = GetOpenRow(c)
  152.     IF pr <> NumRows THEN
  153.         Grid(c, pr) = P
  154.         IF CheckWin = 4 THEN Stupid = -1
  155.         Grid(c, pr) = 0
  156.     END IF
  157.     Grid(c, r) = 0
  158.  
  159. FUNCTION GR (c, r) ' if c, r are out of bounds returns N else returns grid(c, r)
  160.     ' need to check the grid(c, r) but only if c, r is on the board
  161.     IF c < 0 OR c > NCM1 OR r < 0 OR r > NRM1 THEN GR = NumRows ELSE GR = Grid(c, r)
  162.  
  163. SUB ShowGrid
  164.     STATIC lastMoveNum
  165.     DIM i, r, c, check, s$, k$
  166.     IF MoveNum <> lastMoveNum THEN ' file newest move
  167.         IF MoveNum = 1 THEN REDIM Record$(NCM1, NRM1)
  168.         IF Turn = -1 THEN
  169.             Record$(PlayerLastMoveCol, PlayerLastMoveRow) = _TRIM$(STR$(MoveNum)) + " " + "P"
  170.         ELSE
  171.             Record$(AIX, AIY) = _TRIM$(STR$(MoveNum)) + " " + "A"
  172.         END IF
  173.         lastMoveNum = MoveNum
  174.     END IF
  175.     CLS
  176.     LINE (XO, YO)-STEP(NumCols * SQ, NumRows * SQ), &HFF004400, BF
  177.     FOR i = 0 TO NumCols 'grid
  178.         LINE (SQ * i + XO, YO)-STEP(0, NumRows * SQ), &HFFFFFFFF
  179.     NEXT
  180.     FOR i = 0 TO NumRows
  181.         LINE (XO, SQ * i + YO)-STEP(NumCols * SQ, 0), &HFFFFFFFF
  182.     NEXT
  183.     FOR r = NRM1 TO 0 STEP -1 ''in grid rows are reversed 0 is top row
  184.         FOR c = 0 TO NCM1
  185.             IF Grid(c, r) = P THEN
  186.                 LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFFFF2200, BF
  187.             ELSEIF Grid(c, r) = AI THEN
  188.                 IF c = AIX AND r = AIY THEN 'highlite last AI move
  189.                     LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFF680044, BF
  190.                 ELSE
  191.                     LINE (c * SQ + XO + 3, r * SQ + YO + 3)-STEP(SQ - 6, SQ - 6), &HFF390027, BF
  192.                 END IF
  193.             END IF
  194.             s$ = _TRIM$(STR$(Scores(c)))
  195.             _PRINTSTRING (XO + c * SQ + (60 - LEN(s$) * 8) / 2, YO + SQ * NumRows + 22), s$
  196.         NEXT
  197.     NEXT
  198.     _DISPLAY
  199.     check = CheckWin
  200.     IF check THEN 'report end of round ad see if want to play again
  201.         IF check = 4 OR check = -4 THEN
  202.             FOR i = 0 TO 3
  203.                 LINE ((WinX + i * DX(WinD)) * SQ + XO + 5, (WinY + i * DY(WinD)) * SQ + YO + 5)-STEP(SQ - 10, SQ - 10), &HFFFFFF00, B
  204.             NEXT
  205.         END IF
  206.         FOR r = 0 TO NRM1
  207.             FOR c = 0 TO NCM1
  208.                 IF Record$(c, r) <> "" THEN
  209.                     s$ = MID$(Record$(c, r), 1, INSTR(Record$(c, r), " ") - 1)
  210.                     IF RIGHT$(Record$(c, r), 1) = "A" THEN COLOR , &HFF390027 ELSE COLOR , &HFFFF2200
  211.                     _PRINTSTRING (SQ * c + XO + (SQ - LEN(s$) * 8) / 2, SQ * r + YO + 22), s$
  212.                 END IF
  213.             NEXT
  214.             COLOR , &HFF000000
  215.         NEXT
  216.         IF check = -4 THEN
  217.             s$ = " AI is Winner!"
  218.         ELSEIF check = 4 THEN
  219.             s$ = " Human is Winner!"
  220.         ELSEIF check = NumRows THEN
  221.             s$ = " Board is full, no winner." ' keep Turn the same
  222.         END IF
  223.         LOCATE 2, ((SW - LEN(s$) * 8) / 2) / 8: PRINT s$
  224.         s$ = " Play again? press spacebar, any other to quit... "
  225.         LOCATE 4, ((SW - LEN(s$) * 8) / 2) / 8: PRINT s$
  226.         _DISPLAY
  227.         WHILE LEN(k$) = 0
  228.             k$ = INKEY$
  229.             _LIMIT 200
  230.         WEND
  231.         IF k$ = " " THEN
  232.             REDIM Grid(NCM1, NRM1), Scores(NCM1)
  233.             IF GoFirst = P THEN GoFirst = AI ELSE GoFirst = P
  234.             Turn = GoFirst: MoveNum = 0
  235.         ELSE
  236.             GameOn = 0
  237.         END IF
  238.     END IF
  239.  
  240. FUNCTION CheckWin ' return WinX, WinY, WinD along with +/- 4, returns NumRows if grid full, 0 if no win and grid not full
  241.     DIM gridFull, r, c, s, i
  242.     gridFull = NumRows
  243.     FOR r = NRM1 TO 0 STEP -1 'bottom to top
  244.         FOR c = 0 TO NCM1
  245.             IF Grid(c, r) THEN ' check if c starts a row
  246.                 IF c < NCM1 - 2 THEN
  247.                     s = 0
  248.                     FOR i = 0 TO 3 ' east
  249.                         s = s + Grid(c + i, r)
  250.                     NEXT
  251.                     IF s = 4 OR s = -4 THEN WinX = c: WinY = r: WinD = 0: CheckWin = s: EXIT FUNCTION
  252.                 END IF
  253.                 IF r > 2 THEN ' check if c starts a col
  254.                     s = 0
  255.                     FOR i = 0 TO 3 ' north
  256.                         s = s + Grid(c, r - i)
  257.                     NEXT
  258.                     IF s = 4 OR s = -4 THEN WinX = c: WinY = r: WinD = 6: CheckWin = s: EXIT FUNCTION
  259.                 END IF
  260.                 IF r > 2 AND c < NCM1 - 2 THEN 'check if c starts diagonal up to right
  261.                     s = 0
  262.                     FOR i = 0 TO 3 ' north  east
  263.                         s = s + Grid(c + i, r - i)
  264.                     NEXT
  265.                     IF s = 4 OR s = -4 THEN WinX = c: WinY = r: WinD = 7: CheckWin = s: EXIT FUNCTION
  266.                 END IF
  267.                 IF r > 2 AND c > 2 THEN 'check if c starts a diagonal up to left
  268.                     s = 0
  269.                     FOR i = 0 TO 3 ' north west
  270.                         s = s + Grid(c - i, r - i)
  271.                     NEXT
  272.                     IF s = 4 OR s = -4 THEN WinX = c: WinY = r: WinD = 5: CheckWin = s: EXIT FUNCTION
  273.                 END IF
  274.             ELSE
  275.                 gridFull = 0 ' at least one enpty cell left
  276.             END IF 'grid is something
  277.         NEXT
  278.     NEXT
  279.     CheckWin = gridFull
  280.  
  281.  

 
Connect 12-16.PNG
« Last Edit: December 17, 2020, 01:13:00 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #27 on: December 17, 2020, 03:13:55 am »
OK STx pattern still wins just have to play it different order:
 
STx Pattern still works.PNG

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #28 on: December 17, 2020, 09:34:22 am »
I damn near fell alseep at my desk trying to beat this thing last night and couldn't... but then this morning I finally did, got the screenshot all ready... only to find this most recent post ^. Nice work m8.

I was gonna add too, the AI got a lot more clever with this update. Nice and aggressive!
You're not done when it works, you're done when it's right.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: 8x8 Connect 4: AI Challenge
« Reply #29 on: December 17, 2020, 10:33:02 am »
Finally beat it!  I said just before... "Ok..this is my last try."

- Dav

 
8x8win.jpg