|
Post by Anthony.R.Brown on Jun 23, 2021 9:07:38 GMT
To make it a contest we need formal rules one of ways is "server" program and "gamer" program - "gamers" program competes one against other(s)! There needs to be protocol for program to read state / make next move Interesting stuff, really The contest would be simple where players do not see the other players code! this is important even though it's not the norm! the obvious reason is stop stealing the other players code & AI ideas This is being worked on at the moment over at the qb64.freeforums.net link below,as an example with the 8x8 Connect 4: AI Challenge,myself and bplus are trying to get Two .exe AI programs to talk to each other and play the moves in an external file something like MOVES.txt unfortunately bplus is not able to help at the moment,but it will be solved at some time,maybe someone clever on here knows how to do it ? Progress has been made below by bplus's last reply... Jun 15, 2021 at 2:40am bplus said: Well still some work to do like giving the first player a color and the 2nd player a color for both exe's. These 2 AI's think the same and will play the same moves over and over... but at least I got it hacked for them to play each other from 2 running exe's. qb64.freeforums.net/thread/133/8x8-connect-4-ai-challengeA.R.B
|
|
|
Post by B+ on Jun 23, 2021 10:55:10 GMT
Yes, the 2 player programs are sharing a common file (C4 Game.txt) in which the moves are on separate line numbers.
The first player has the odd number lines, the 2nd even. Both players (exe's) track what move they are on and wait for other players move by monitoring the file line to be completed and update their board array.
ARB's move format is Letter column A through H (for 8 column Connect 4) then a digit for Row. Also the bottom rows (first played) are row 1.
So you have to adapt your move communications accordingly.
Dang it I can't Log-In 2 different ProBoards Forums at once!
Also the first player resets the file by opening the for output, from then on it is opened for append. This allows games to be Date&Time stamped if want to be saved, the first player program could probably do that too.
|
|
|
Post by tsh73 on Jun 23, 2021 10:55:56 GMT
|
|
|
Post by B+ on Jun 23, 2021 11:04:15 GMT
Here is my main QB64 code for 1st player Exe regulating moves:
Option _Explicit ' Connect 4 NumRows X NumCols 2020_12_16.bas update bplus _Title "B+C4 AI player goes 2nd" DefLng A-Z Const SQ = 60 ' square or grid cell Const NumCols = 8 ' number of columns Const NumRows = 8 ' you guessed it Const NCM1 = NumCols - 1 ' NumCols minus 1 Const NRM1 = NumRows - 1 ' you can guess surely Const SW = SQ * (NumCols + 2) ' screen width Const SH = SQ * (NumRows + 3) ' screen height Const P = 1 ' Player is 1 on grid Const AI = -1 ' AI is -1 on grid Const XO = SQ ' x offset for grid Const YO = 2 * SQ ' y offset for grid Const File$ = "C4 Game.txt"
ReDim Shared Grid(NCM1, NRM1) ' 0 = empty P=1 for Player, AI=-1 for AI so -4 is win for AI.. ReDim Shared DX(7), DY(7) ' Directions DX(0) = 1: DY(0) = 0 ': DString$(0) = "East" DX(1) = 1: DY(1) = 1 ': DString$(1) = "South East" DX(2) = 0: DY(2) = 1 ': DString$(2) = "South" DX(3) = -1: DY(3) = 1 ': DString$(3) = "South West" DX(4) = -1: DY(4) = 0 ': DString$(4) = "West" DX(5) = -1: DY(5) = -1 ': DString$(5) = "North West" DX(6) = 0: DY(6) = -1 ': DString$(6) = "North" DX(7) = 1: DY(7) = -1 ' : DString$(7) = "North East" ReDim Shared Scores(NCM1) ' rating column for AI and displaying them ReDim Shared AIX, AIY ' last move of AI for highlighting in display ReDim Shared WinX, WinY, WinD ' display Winning Connect 4 ReDim Shared GameOn, Turn, GoFirst, PlayerLastMoveCol, PlayerLastMoveRow, MoveNum ' game tracking ReDim Shared Record$(NCM1, NRM1)
Screen _NewImage(SW, SH, 32) _ScreenMove 360, 60 'Dim mb, mx, my, r Dim row, col, lineCount, move$
'Open File$ For Output As #1 'reset file responsiblity of player #1 'Close #1 GameOn = -1: GoFirst = P: Turn = P: MoveNum = 0 ShowGrid While GameOn If Turn = P Then
'While _MouseInput: Wend 'mb = _MouseButton(1): mx = _MouseX: my = _MouseY 'If mb Then 'get last place mouse button was down ' _Delay .25 'for mouse release ' row = ((my - YO) / SQ - .5): col = ((mx - XO) / SQ - .5) ' If col >= 0 And col <= NCM1 And row >= 0 And row < 8 Then ' r = GetOpenRow(col) ' If r <> NumRows Then ' Grid(col, r) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = r: MoveNum = MoveNum + 1 ' End If ' Else ' Beep ' End If 'End If Do 'hand out here until the other moves lineCount = 0 Open File$ For Input As #1 While Not EOF(1) Input #1, move$ If move$ <> "" Then lineCount = lineCount + 1 If lineCount = MoveNum + 1 Then col = InStr("ABCDEFGH", Left$(move$, 1)) - 1 row = 8 - Val(Right$(move$, 1)) Grid(col, row) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = row: MoveNum = MoveNum + 1 Close #1 Exit Do End If End If Wend Close #1 _Delay .25 '? Loop
Else AIMove Turn = P: MoveNum = MoveNum + 1 Open File$ For Append As #1 Print #1, Mid$("ABCDEFGH", AIX + 1, 1) + _Trim$(Str$(8 - AIY)) Close #1
End If ShowGrid 'this will end game _PrintString (10, 10), Space$(50) _PrintString (10, 10), Str$(MoveNum) + "," + Str$(AIX) + Str$(AIY) _Display _Limit 1 Wend
Probably should be fairly easy to translate to JB
|
|
|
Post by B+ on Jun 23, 2021 11:06:21 GMT
So can we run 2 JB programs at same time? Probably yes
|
|
|
Post by Anthony.R.Brown on Jun 23, 2021 16:23:03 GMT
Here is my main QB64 code for 1st player Exe regulating moves: Option _Explicit ' Connect 4 NumRows X NumCols 2020_12_16.bas update bplus _Title "B+C4 AI player goes 2nd" DefLng A-Z Const SQ = 60 ' square or grid cell Const NumCols = 8 ' number of columns Const NumRows = 8 ' you guessed it Const NCM1 = NumCols - 1 ' NumCols minus 1 Const NRM1 = NumRows - 1 ' you can guess surely Const SW = SQ * (NumCols + 2) ' screen width Const SH = SQ * (NumRows + 3) ' screen height Const P = 1 ' Player is 1 on grid Const AI = -1 ' AI is -1 on grid Const XO = SQ ' x offset for grid Const YO = 2 * SQ ' y offset for grid Const File$ = "C4 Game.txt"
ReDim Shared Grid(NCM1, NRM1) ' 0 = empty P=1 for Player, AI=-1 for AI so -4 is win for AI.. ReDim Shared DX(7), DY(7) ' Directions DX(0) = 1: DY(0) = 0 ': DString$(0) = "East" DX(1) = 1: DY(1) = 1 ': DString$(1) = "South East" DX(2) = 0: DY(2) = 1 ': DString$(2) = "South" DX(3) = -1: DY(3) = 1 ': DString$(3) = "South West" DX(4) = -1: DY(4) = 0 ': DString$(4) = "West" DX(5) = -1: DY(5) = -1 ': DString$(5) = "North West" DX(6) = 0: DY(6) = -1 ': DString$(6) = "North" DX(7) = 1: DY(7) = -1 ' : DString$(7) = "North East" ReDim Shared Scores(NCM1) ' rating column for AI and displaying them ReDim Shared AIX, AIY ' last move of AI for highlighting in display ReDim Shared WinX, WinY, WinD ' display Winning Connect 4 ReDim Shared GameOn, Turn, GoFirst, PlayerLastMoveCol, PlayerLastMoveRow, MoveNum ' game tracking ReDim Shared Record$(NCM1, NRM1)
Screen _NewImage(SW, SH, 32) _ScreenMove 360, 60 'Dim mb, mx, my, r Dim row, col, lineCount, move$
'Open File$ For Output As #1 'reset file responsiblity of player #1 'Close #1 GameOn = -1: GoFirst = P: Turn = P: MoveNum = 0 ShowGrid While GameOn If Turn = P Then
'While _MouseInput: Wend 'mb = _MouseButton(1): mx = _MouseX: my = _MouseY 'If mb Then 'get last place mouse button was down ' _Delay .25 'for mouse release ' row = ((my - YO) / SQ - .5): col = ((mx - XO) / SQ - .5) ' If col >= 0 And col <= NCM1 And row >= 0 And row < 8 Then ' r = GetOpenRow(col) ' If r <> NumRows Then ' Grid(col, r) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = r: MoveNum = MoveNum + 1 ' End If ' Else ' Beep ' End If 'End If Do 'hand out here until the other moves lineCount = 0 Open File$ For Input As #1 While Not EOF(1) Input #1, move$ If move$ <> "" Then lineCount = lineCount + 1 If lineCount = MoveNum + 1 Then col = InStr("ABCDEFGH", Left$(move$, 1)) - 1 row = 8 - Val(Right$(move$, 1)) Grid(col, row) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = row: MoveNum = MoveNum + 1 Close #1 Exit Do End If End If Wend Close #1 _Delay .25 '? Loop
Else AIMove Turn = P: MoveNum = MoveNum + 1 Open File$ For Append As #1 Print #1, Mid$("ABCDEFGH", AIX + 1, 1) + _Trim$(Str$(8 - AIY)) Close #1
End If ShowGrid 'this will end game _PrintString (10, 10), Space$(50) _PrintString (10, 10), Str$(MoveNum) + "," + Str$(AIX) + Str$(AIY) _Display _Limit 1 Wend
Probably should be fairly easy to translate to JB Hi bplus Your Code is doing strange things again if I try to open it in QB64 it's the "unexpected character on line ?" problem we had before ? I am trying to understand what you have coded is there any chance you can give me a simple A,B,C etc. example on how I should use it in my Connect 4 Engine player ? I have you as player BPLUSAIO where you are playing as "O" and the reply I need from your move generator so that I can make my move is MOVTYPN = "O" and the move you make as an example MOVMADE = "D1" A.R.B
|
|
|
Post by B+ on Jun 23, 2021 19:03:57 GMT
The code I posted was for 1st player of 2 player exe's. The 2nd player exe works as compliment by waiting for odd number line in C4 Game.txt file to ie when line 1 has something there in file, then move is translated and the AI makes the move to the even number next in the common file.
That way your 2 exe's can work any dang way they please and nobody has to know the code that produced the next move in the Game file.
All you need is 1st player reporting their move on odd number lines and 2nd player reporting their move on even number lines, nobody cares what you use to mark the game boards, x's or o's or colored game pieces, doesn't matter.
Just report your move with a letter and a digit on the appropriate line (odd for first player even for 2nd) when the last player finishes their move.
|
|
|
Post by Anthony.R.Brown on Jun 24, 2021 7:32:07 GMT
No I still don't get it! it seems like a lot of code to me to do a simple thing like read and write to an external .txt file ? I will find a more simple way of doing it if I can ? A.R.B
|
|
|
Post by B+ on Jun 24, 2021 19:54:32 GMT
The code I posted did have the strange character for tab, sorry just highlite one or those and change ALL to nothing or space or 4 spaces for indent.
Doesn't matter though because it's QB64 code and only showing the file handling code, it is missing ALL the other Subs and Functions that make it work for only player #1 in QB64.
Again, it was just showing how the file was accessed for getting the other player's moves. There is a complimentary code for player #2 exe that does basically the same thing. For demo purposes only, not meant to be RUN by either QB64 or JB.
You should be able to figure all that out.
The only thing complicated in this:
Do 'hand out here until the other moves lineCount = 0 Open File$ For Input As #1 While Not EOF(1) Input #1, move$ If move$ <> "" Then lineCount = lineCount + 1 If lineCount = MoveNum + 1 Then col = InStr("ABCDEFGH", Left$(move$, 1)) - 1 row = 8 - Val(Right$(move$, 1)) Grid(col, row) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = row: MoveNum = MoveNum + 1 Close #1 Exit Do End If End If Wend Close #1 _Delay .25 '? Loop
is converting my board array notation to yours or yours to mine as shown above, where you make the bottom row 1 and it was 7 for me, plus converting columns 0 - 7 to Capital Letters A - H.
If you (ARB) can do it in less code I'd be surprised!
|
|
|
Post by carlgundel on Jun 25, 2021 0:32:26 GMT
No I still don't get it! it seems like a lot of code to me to do a simple thing like read and write to an external .txt file ? I will find a more simple way of doing it if I can ? Just BASIC file reading and writing is very simple, and is almost the same as Microsoft BASIC. The following commands are common with many BASICs, including Just BASIC, Liberty BASIC, Microsoft BASIC, etc. OPEN "filename.ext" for INPUT/OUTPUT as #handle INPUT #handle, var PRINT #handle, expression CLOSE #handle LOF(#handle) EOF(#handle) And there are more, and again mostly common. -Carl
|
|
|
Post by Anthony.R.Brown on Jun 25, 2021 15:10:43 GMT
No I still don't get it! it seems like a lot of code to me to do a simple thing like read and write to an external .txt file ? I will find a more simple way of doing it if I can ? Just BASIC file reading and writing is very simple, and is almost the same as Microsoft BASIC. The following commands are common with many BASICs, including Just BASIC, Liberty BASIC, Microsoft BASIC, etc. OPEN "filename.ext" for INPUT/OUTPUT as #handle INPUT #handle, var PRINT #handle, expression CLOSE #handle LOF(#handle) EOF(#handle) And there are more, and again mostly common. -Carl Looks good carlgundel A.R.B
|
|
|
Post by Anthony.R.Brown on Jun 25, 2021 15:23:22 GMT
The code I posted did have the strange character for tab, sorry just highlite one or those and change ALL to nothing or space or 4 spaces for indent. Doesn't matter though because it's QB64 code and only showing the file handling code, it is missing ALL the other Subs and Functions that make it work for only player #1 in QB64. Again, it was just showing how the file was accessed for getting the other player's moves. There is a complimentary code for player #2 exe that does basically the same thing. For demo purposes only, not meant to be RUN by either QB64 or JB. You should be able to figure all that out. The only thing complicated in this: Do 'hand out here until the other moves lineCount = 0 Open File$ For Input As #1 While Not EOF(1) Input #1, move$ If move$ <> "" Then lineCount = lineCount + 1 If lineCount = MoveNum + 1 Then col = InStr("ABCDEFGH", Left$(move$, 1)) - 1 row = 8 - Val(Right$(move$, 1)) Grid(col, row) = P: Turn = AI: PlayerLastMoveCol = col: PlayerLastMoveRow = row: MoveNum = MoveNum + 1 Close #1 Exit Do End If End If Wend Close #1 _Delay .25 '? Loop is converting my board array notation to yours or yours to mine as shown above, where you make the bottom row 1 and it was 7 for me, plus converting columns 0 - 7 to Capital Letters A - H. If you (ARB) can do it in less code I'd be surprised! I have nearly got my way of doing this working ? and then I had a moment of inspiration which might be a better way to do the whole thing! I got the idea from how they do it with Chess using a GUI (Graphical User Interface) and mainly the Free! Arena Chess at the link below... www.playwitharena.deSo I am sure the same could be done with Connect 4,to explain using Arena Chess basically their is a protocol regarding how Chess engines are made,UCI communication protocol,just like the one below for xboard another GUI www.gnu.org/software/xboard/engine-intf.htmlSo anyone can make a UCI Chess engine that will then work with any Chess GUI. And for a Connect 4 GUI it would play the moves and talk to any Connect 4 engine,while it knows the rules and only accepts legal moves,and then gives the Winner etc.,and even printing off games can be done,as well as saving to an external Game file. All we need is someone who could do it A.R.B
|
|
|
Post by Anthony.R.Brown on Jun 26, 2021 13:04:30 GMT
The code I posted was for 1st player of 2 player exe's. The 2nd player exe works as compliment by waiting for odd number line in C4 Game.txt file to ie when line 1 has something there in file, then move is translated and the AI makes the move to the even number next in the common file. That way your 2 exe's can work any dang way they please and nobody has to know the code that produced the next move in the Game file. All you need is 1st player reporting their move on odd number lines and 2nd player reporting their move on even number lines, nobody cares what you use to mark the game boards, x's or o's or colored game pieces, doesn't matter. Just report your move with a letter and a digit on the appropriate line (odd for first player even for 2nd) when the last player finishes their move. Hi bplus Can you provide me with a version of you Connect 4 move generator in it's simplest form ? I don't need any of the Mouse input code or Graphics etc. just the way it outputs it's moves! Below is the way I would like it as simple as possible then I can use it in my program!... So below is exactly how I would copy it into my program as a move generator for the player BPLUSAIO "O" REM ######################################################################################### BPLUSAIO: REM ######################################################################################### IF GMOVERX = 1 THEN GOTO NEXTGAME IF GMOVERO = 1 THEN GOTO NEXTGAME IF GMOVERD = 1 THEN GOTO NEXTGAME REM ...................................................................................................... COMP02MOVED = 0 COMPMAXVAL2 = 0 MOVMADE = "" MOVTYPN = "O" PRINT " BPLUSAI(O) THINKING!...........................GMS("; GAMESPLAYED + 1; ") LAST(GM) "; LASTGMRESULT REM ---------------------------------------------------------------------------------------------------------------------------------------------------------------- My move generator will send it's move to you using the same format for the move it has found form A1 - H8 as below... MOVTYPN = "X" MOVMADE = "E1" REM ---------------------------------------------------------------------------------------------------------------------------------------------------------------- This is where you put your code so that it makes it's moves... Example using the same format for the move it has found form A1 - H8 MOVTYPN = "O" MOVMADE = "D1" REM ---------------------------------------------------------------------------------------------------------------------------------------------------------------- REM ######################################################################################### BPLUSAIO: REM ######################################################################################### Below is a Screenshot of me beating your Connect 4 AI... and I went second in the game! A.R.B
|
|