vs (Very Simple) GUI - bplus - 07-12-2022
Trying out an array of Buttons with vs GUI.
I finally got around to fixing the AI to make it unbeatable in Tic Tac Toe. Hear that ARB? UNBEATABLE ;-))
Here is a screen shot:
Simply 9 buttons on the screen with message box comments thrown in as needed so as to not spoil the board setup.
In the snap you see the listing of the zip file which includes the fixed Tic Tac Toe with AI code I updated today before converting it to GUI.
Here is what the code looks like for GUI (without the BI/BM).
Code: (Select All) Option _Explicit
' _Title "GUI Tic Tac Toe with AI" ' b+ 2022-07-12 try GUI version with fixed AI and a Btn Array!
' Needs fixing https://www.youtube.com/watch?v=5n2aQ3UQu9Y
' you start at corner
' they AI play middle to at least tie
' you play opposite corner
' they or AI plays corner will loose!!! I am saying in AI always play corner is not always right!!!
' they have to play side to just tie
'
' 2022-07-12 finally got around to fixing this program
' 2022-07-12 Now try it out with vsGUI, can I use an array of control handles? Yes.
'$include:'vs GUI.BI'
' Set Globals from BI your Title here VVV
Xmax = 502: Ymax = 502: GuiTitle$ = "GUI Tic-Tac-Toe with AI"
OpenWindow Xmax, Ymax, GuiTitle$, "ARLRDBD.TTF"
Dim Shared As Long Btn(0 To 8) ' our 9 buttons for the game
Dim As Long x, y, i
For y = 0 To 2 ' yes in, vs GUI, we Can have arrays of controls!!!
For x = 0 To 2
Btn(i) = NewControl(1, x * 175 + 1, y * 175 + 1, 150, 150, 120, 600, 668, "")
i = i + 1
Next
Next ' that's all for the GUI
' one time sets
Dim Shared Player$, AI$, Turn$, Winner$
Dim Shared As Long PlayerStarts, Count, Done
Dim Shared board$(2, 2) 'store X and O here 3x3
Player$ = "X": AI$ = "O": PlayerStarts = 0
ResetGame
MainRouter
Sub ResetGame
Dim As Long i, rc, bx, by
Winner$ = "": Count = 0: Done = 0: Erase board$ 'reset
For i = 0 To 8
con(Btn(i)).Text = ""
drwBtn i + 1, 0
Next
PlayerStarts = 1 - PlayerStarts
If PlayerStarts Then Turn$ = Player$ Else Turn$ = AI$
If Turn$ = AI$ Then
rc = AIchoice
con(rc + 1).Text = AI$
bx = rc Mod 3: by = Int(rc / 3)
board$(bx, by) = AI$
_Delay 3 'let player think AI is thinking
drwBtn rc + 1, 0
Count = Count + 1
'If checkwin Then Winner$ = AI$
Turn$ = Player$
mBox "The AI has started the next game.", "It's your turn."
'now wait for MainRouter to detect a Button click
End If
End Sub
Function checkwin
Dim As Long i
For i = 0 To 2
If (board$(0, i) = board$(1, i) And board$(1, i) = board$(2, i)) And (board$(2, i) <> "") Then checkwin = 1: Exit Function
Next
For i = 0 To 2
If (board$(i, 0) = board$(i, 1) And board$(i, 1) = board$(i, 2)) And board$(i, 2) <> "" Then checkwin = 1: Exit Function
Next
If (board$(0, 0) = board$(1, 1) And board$(1, 1) = board$(2, 2)) And board$(2, 2) <> "" Then checkwin = 1: Exit Function
If (board$(0, 2) = board$(1, 1) And board$(1, 1) = board$(2, 0)) And board$(2, 0) <> "" Then checkwin = 1
End Function
Function AIchoice
Dim As Long r, c
'test all moves to win
For r = 0 To 2
For c = 0 To 2
If board$(c, r) = "" Then
board$(c, r) = AI$
If checkwin Then
board$(c, r) = ""
AIchoice = 3 * r + c
Exit Function
Else
board$(c, r) = ""
End If
End If
Next
Next
'still here? then no winning moves for AI, how about for player$
For r = 0 To 2
For c = 0 To 2
If board$(c, r) = "" Then
board$(c, r) = Player$
If checkwin Then
board$(c, r) = ""
AIchoice = 3 * r + c 'spoiler move!
Exit Function
Else
board$(c, r) = ""
End If
End If
Next
Next
'still here? no winning moves, no spoilers then is middle sq available
If board$(1, 1) = "" Then AIchoice = 4: Exit Function
' one time you dont want a corner when 3 moves made human has opposite corners, then defense is any side!
If (board$(0, 0) = Player$ And board$(2, 2) = Player$) Or (board$(2, 0) = Player$ And board$(0, 2) = Player$) Then
' try a side order?
If board$(1, 0) = "" Then AIchoice = 1: Exit Function
If board$(0, 1) = "" Then AIchoice = 3: Exit Function
If board$(2, 1) = "" Then AIchoice = 5: Exit Function
If board$(1, 2) = "" Then AIchoice = 7: Exit Function
'still here still? how about a corner office?
If board$(0, 0) = "" Then AIchoice = 0: Exit Function
If board$(2, 0) = "" Then AIchoice = 2: Exit Function
If board$(0, 2) = "" Then AIchoice = 6: Exit Function
If board$(2, 2) = "" Then AIchoice = 8: Exit Function
Else
'still here still? how about a corner office?
If board$(0, 0) = "" Then AIchoice = 0: Exit Function
If board$(2, 0) = "" Then AIchoice = 2: Exit Function
If board$(0, 2) = "" Then AIchoice = 6: Exit Function
If board$(2, 2) = "" Then AIchoice = 8: Exit Function
'still here??? a side order then!
If board$(1, 0) = "" Then AIchoice = 1: Exit Function
If board$(0, 1) = "" Then AIchoice = 3: Exit Function
If board$(2, 1) = "" Then AIchoice = 5: Exit Function
If board$(1, 2) = "" Then AIchoice = 7: Exit Function
End If
End Function
Sub BtnClickEvent (i As Long) ' Basically the game is played here with player's button clicks
Dim As Long rc, bx, by
' note Btn(0) = 1, Btn(1) = 2...
rc = i - 1 ' from control number to button number
bx = rc Mod 3: by = Int(rc / 3) ' from button number to board$ x, y location
If board$(bx, by) = "" Then ' update board, check win, call AI for it's turn, update board, check win
con(i).Text = Player$
drwBtn i, 0
board$(bx, by) = Player$
If checkwin Then
mBox "And the Winner is", "You! Congratulations AI was supposed to be unbeatable."
ResetGame
Else
Count = Count + 1
If Count >= 9 Then
mBox "Out of Spaces:", "The Game is a draw."
ResetGame
Else ' run the ai
rc = AIchoice
con(rc + 1).Text = AI$
bx = rc Mod 3: by = Int(rc / 3)
board$(bx, by) = AI$
_Delay 1 'let player think AI is thinking
drwBtn rc + 1, 0
If checkwin Then
mBox "And the Winner is", "AI, the AI is supposed to be unbeatable."
ResetGame
Else
Count = Count + 1
If Count >= 9 Then
mBox "Out of Spaces:", "The Game is a draw."
ResetGame
Else
Turn$ = Player$
End If
End If
End If
End If
Else
Beep: mBox "Player Error:", "That button has already been played."
End If
End Sub
' this is to keep MainRouter in, vs GUI.BM, happy =========================================
Sub LstSelectEvent (control As Long)
Select Case control
End Select
End Sub
Sub PicClickEvent (i As Long, Pmx As Long, Pmy As Long)
Select Case i
End Select
End Sub
Sub PicFrameUpdate (i As Long)
Select Case i
End Select
End Sub
'$include:'vs GUI.BM'
RE: vs (Very Simple) GUI - Jack - 07-13-2022
I think that the payer that moves first can always win
RE: vs (Very Simple) GUI - bplus - 07-13-2022
0 1 2
3 4 5
6 7 8
0 is top left, 4 middle, 8 bottom right.
You move first, I bet I tie at least.
I have watched this and have a defense: https://www.youtube.com/watch?v=5n2aQ3UQu9Y
RE: vs (Very Simple) GUI - bplus - 07-15-2022
Sometime ago I created a Tabulator App that took a Function F(x) = (string), a bunch of variables = values in a chr$(10) delimited string and xStart, xEnd, xInc like a For... Next Loop all these go into a TableIn.txt file that the Tabulator reads and produces a Table of x F(x) Data that could be read in by another bas app that needed the data for a function on the fly ie doesn't have to be formally defined in the app.
Then I made a demo of how to use the Tabulator and that was that, until now I have GUI.
Now I can use GUI to Interface with the Tabulator and Graph Functions. Here are a few I tried tonight:
Simple Quadratic:
A trig function:
Another:
Here is the code for GUI:
Code: (Select All) Option _Explicit ' _Title "GUI Interface with Tabulator for Plotting F(x)" ' b+ 2022-07-14
'$include:'vs GUI.BI'
' Set Globals from BI
Xmax = 1280: Ymax = 700: GuiTitle$ = "GUI Interface with Tabulator for Plotting F(x)" ' <<<<< Window size shared throughout program
OpenWindow Xmax, Ymax, GuiTitle$, "arial.ttf" ' need to do this before drawing anything from NewControls
' name = NewControl(0, 0, 0, 0, 0, 0, 0, 0, "text")
' GUI Controls
' Dim and set Globals for GUI app
Dim Shared As Long lbFx, tbFx, lbVV, tbVV, btAdd, lbVLst, lsVV, btEdit, btDelete, btPlot, lbx, tbStart, tbEnd, tbInc, pPlot
lbFx = NewControl(4, 10, 10, 560, 30, 30, 0, 0, "Formula F(x)")
tbFx = NewControl(2, 10, 40, 560, 30, 20, 0, 0, "")
lbVV = NewControl(4, 10, 80, 560, 30, 30, 0, 0, "Variable = Value")
tbVV = NewControl(2, 10, 110, 490, 30, 20, 0, 0, "")
btAdd = NewControl(1, 510, 110, 60, 30, 20, 0, 0, "Add")
lbVLst = NewControl(4, 10, 150, 560, 30, 30, 0, 0, "Variable and Value List:")
lsVV = NewControl(3, 10, 180, 560, 380, 20, 0, 0, "")
btEdit = NewControl(1, 10, 570, 180, 40, 30, 0, 0, "Edit")
btDelete = NewControl(1, 200, 570, 180, 40, 30, 0, 0, "Delete")
btPlot = NewControl(1, 390, 570, 180, 40, 30, 0, 0, "Plot")
lbx = NewControl(4, 10, 620, 550, 30, 20, 0, 0, "X:Start X:End ")
tbStart = NewControl(2, 10, 650, 180, 40, 20, 0, 0, "")
tbEnd = NewControl(2, 200, 650, 180, 40, 20, 0, 0, "")
'tbInc = NewControl(2, 390, 650, 180, 40, 20, 0, 0, "")
pPlot = NewControl(5, 580, 0, 700, 700, 0, 999, 0, "")
' End GUI Controls
MainRouter ' after all controls setup
' EDIT these to your programs needs
Sub BtnClickEvent (i As Long) ' attach you button click code in here
Dim item$
Select Case i
Case btAdd
If _Trim$(con(tbVV).Text) <> "" Then
If _Trim$(con(lsVV).Text) <> "" Then
con(lsVV).Text = con(lsVV).Text + "~" + _Trim$(con(tbVV).Text)
Else
con(lsVV).Text = con(tbVV).Text
End If
con(tbVV).Text = ""
drwTB tbVV, tbVV = ActiveControl
drwLst lsVV, lsVV = ActiveControl
End If
Case btEdit
ReDim lst(1 To 1) As String
Split con(lsVV).Text, "~", lst()
item$ = lst((con(lsVV).N1 - 1) * con(lsVV).N4 + con(lsVV).N2)
con(tbVV).Text = item$
drwTB tbVV, tbVV = ActiveControl
Remove item$, lst()
con(lsVV).Text = Join$(lst(), "~")
drwLst lsVV, tbVV = ActiveControl
Case btDelete ' what is the highlited
ReDim lst(1 To 1) As String
Split con(lsVV).Text, "~", lst()
item$ = lst((con(lsVV).N1 - 1) * con(lsVV).N4 + con(lsVV).N2)
Remove item$, lst()
con(lsVV).Text = Join$(lst(), "~")
drwLst lsVV, 0
Case btPlot
' make call to Tabulator (in Shell)
ReDim As Long j
Dim xStart, xEnd, yMin, yMax, dx, y(700), dy, x, y
Dim fx$
ReDim lst(0)
xStart = Val(_Trim$(con(tbStart).Text)): xEnd = Val(_Trim$(con(tbEnd).Text))
dx = (xEnd - xStart) / 700: fx$ = _Trim$(con(tbFx).Text)
Split con(lsVV).Text, "~", lst()
item$ = Join$(lst(), Chr$(10)) ' reusing something already DIM's this is our variable list delimited by chr$(10)
ReDim arr$(0)
If dx = 0 Then Cls: Print "dx = 0": End
forXEqual xStart, xEnd, dx, fx$, 0, item$, arr$() ' 0 = using radians for trig
' hopefully arr$ has the data we need to make our plot
'debug
'item$ = Join$(arr$(), Chr$(10)) ' debug
'mBox "Our Data Array", item$ ' debug with 700 items in table probably don't want to check in mbox
' need to find min, max y and convert values to number
For j = 0 To 700
y(j) = Val(_Trim$(RightOf$(arr$(j), " ")))
If j = 0 Then
yMax = y(j): yMin = y(j)
Else
If y(j) < yMin Then
yMin = y(j)
ElseIf y(j) > yMax Then
yMax = y(j)
End If
End If
Next j
yMin = yMin - 10
yMax = yMax + 10
dy = yMax - yMin
If dy <> 0 Then ' dont divide by 0
_Dest con(pPlot).N1
Line (0, 0)-Step(con(pPlot).W - 1, con(pPlot).H - 1), &HFFEEEEFF, BF
If 0 >= xStart And 0 <= xEnd Then
Line (700 * (0 - xStart) / (xEnd - xStart), 0)-Step(0, 700), Black ' y axis
For y = -10 To 10
Line (700 * (-xStart) / (xEnd - xStart) - 3, 700 - 700 * (y - yMin) / (yMax - yMin))-Step(6, 0), Black
Next
End If
If 0 >= yMin And 0 <= yMax Then
Line (0, 700 - 700 * (0 - yMin) / (yMax - yMin))-Step(700, 0), Black ' y axis
For x = -10 To 10
Line (700 * (x - xStart) / (xEnd - xStart), 700 - 700 * (0 - yMin) / (yMax - yMin) - 3)-Step(0, 6), Black ' y axis
Next
End If
For j = 0 To 700
Circle (j, con(pPlot).H - 1 - 700 * (y(j) - yMin) / dy), 1, &HFF0000FF
PSet (j, con(pPlot).H - 1 - 700 * (y(j) - yMin) / dy), &HFF0000FF
Next
_Dest 0
_PutImage (con(pPlot).X, con(pPlot).Y)-Step(con(pPlot).W, con(pPlot).H), con(pPlot).N1, 0
End If
End Select
End Sub
Sub LstSelectEvent (control As Long)
Select Case control
End Select
End Sub
Sub PicClickEvent (i As Long, Pmx As Long, Pmy As Long) ' attach your Picture click code in here
Select Case i
End Select
End Sub
Sub PicFrameUpdate (i As Long) ' attach your Picture click code in here
Select Case i
End Select
End Sub
Sub forXEqual (start, toFinish, incStep, formula$, dFlag As Long, variablesCHR10$, outputArr$())
Dim fLine$
If _FileExists("TableOut.txt") Then Kill "TableOut.txt"
Open "TableIn.txt" For Output As #1
Print #1, _Trim$(Str$(start))
Print #1, _Trim$(Str$(toFinish))
Print #1, _Trim$(Str$(incStep))
Print #1, formula$
Print #1, TS$(dFlag)
Print #1, variablesCHR10$
Close #1
ReDim outputArr$(0)
Shell _Hide "Tabulator.exe"
_Delay .5 ' sometimes it compiles in time sometimes not, 3 reduces the nots
If _FileExists("TableOut.txt") Then
Open "TableOut.txt" For Input As #1
While Not EOF(1)
Line Input #1, fLine$
sAppend outputArr$(), fLine$
Wend
Close #1
End If
End Sub
''append to the string array the string item
Sub sAppend (arr() As String, addItem$)
ReDim _Preserve arr(LBound(arr) To UBound(arr) + 1) As String
arr(UBound(arr)) = addItem$
End Sub
'$include:'vs GUI.BM'
And here is the zip with the Tabulator.exe for Windows so can run GUI right out of package if on Windows, otherwise compile for your OS before running GUI Interface. Again the Tabulator works with 2 simple files TableIn.txt and TableOut.txt. Included also is the Tabulator Demo for using in bas code.
Update 2022-07-17: I am updating the zip file with an improved plotting, drawing a line from last x to next, this radically changes the 3rd graph shown above without effecting the other 2.
RE: vs (Very Simple) GUI - bplus - 07-15-2022
BTW I have found things to be much simpler by assuming the highlighted item in a List Box IS the selected item when working with an associated Button for a selected item out of the list. That is how the Edit and Delete buttons are working for the above GUI Interface.
I kinda like the default colors for vs GUI, reminds me of a favorite PL IDE.
RE: vs (Very Simple) GUI - SierraKen - 07-16-2022
I'm trying your Tic-Tac-Toe game but I can't get your libraries to be found for some reason. I've tried moving files around, etc. but no luck. Is there a certain folder they need to go in now? I've used them before but I just had to keep them in the same directory.
RE: vs (Very Simple) GUI - bplus - 07-16-2022
Everything you need is in that zip folder.
OK you've downloaded the zip,
Extracted the files as a folder all together.
Have QB64 IDE Run Menu set Output exe to Source Folder ( a little bullet on the left).
Loaded the GUI TTT with AI.bas file into the IDE
Run the file and the TTT Board should come up.
Everything is self contained in the folder. Don't move the files around, they all have to be together in the one folder, the BI, BM with the bas and the exe ends up there too.
RE: vs (Very Simple) GUI - bplus - 07-16-2022
@ARB the program is an exe file only, no source .bas file, correct?
RE: vs (Very Simple) GUI - bplus - 07-16-2022
Quote:Do you mean your AI has finally caught up with mine! ? Smile Well sorry to say your a year behind my Perfect playing program attached Big Grin ...
yeah well... different priorities I guess ;-))
Quote:bplus Wrote: Wrote:@ARB the program is an exe file only, no source .bas file, correct?
Yes! ? Just run the program in one Window and your program in another and play them against each other move by move,if your Paranoid about my program being able to read what your program is thinking ? then run them on different Computers,or even off an external USB Linux live distro running Wine.
No I am not paranoid about your exe's, it's just that the bas is what is interesting to me. I like to see how you get it to do what it does.
Otherwise, I might as well download a random TTT program off Internet to play TTT, it's boring playing a black box!
We are a programming forum honing and showing off our QB64 coding skills; game sharing and playing is for other places.
For instance, this is the code I added for AI to defend against the human should they start at one corner (AI picks middle) and human picks the corner opposite the first corner. A guaranteed win for human IF AI played a corner so the fix was this addition:
Code: (Select All) ' one time you dont want a corner when 3 moves made human has opposite corners, then defense is any side!
If (board$(0, 0) = Player$ And board$(2, 2) = Player$) Or (board$(2, 0) = Player$ And board$(0, 2) = Player$) Then
' try a side order?
If board$(1, 0) = "" Then AIchoice = 1: Exit Function
If board$(0, 1) = "" Then AIchoice = 3: Exit Function
If board$(2, 1) = "" Then AIchoice = 5: Exit Function
If board$(1, 2) = "" Then AIchoice = 7: Exit Function
'still here still? how about a corner office?
If board$(0, 0) = "" Then AIchoice = 0: Exit Function
If board$(2, 0) = "" Then AIchoice = 2: Exit Function
If board$(0, 2) = "" Then AIchoice = 6: Exit Function
If board$(2, 2) = "" Then AIchoice = 8: Exit Function
Else
Now that is something useful a QB64 coder might use for their TTT perfect playing AI.
RE: vs (Very Simple) GUI - SierraKen - 07-16-2022
I might have found the problem, it probably has to do with the fact that I keep all my QB64 apps in a completely different directory than QB64. I started doing that recently so I wouldn't lose them when I update QB64. But I just opened the .BI file inside QB64 and the error was that it couldn't locate direntry.h I tried to put that in the same directory as your game but no luck. Then I tried putting it outside of the directory but still no luck. I also tried putting it in its own directory in both locations and no luck. But the strange thing is, I also tried your game inside my QB64 folder and it still wouldn't find it. I might be using the wrong direntry.h file or just don't have the right one. Your BI file says to look at your GUI.txt file but that wasn't included in your zip so I don't have it.
|