Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 546
» Latest member: zbnjaminyandexto370
» Forum threads: 3,018
» Forum posts: 27,905

Full Statistics

Latest Threads
Test Maximum Memory
Forum: Programs
Last Post: eoredson
1 hour ago
» Replies: 0
» Views: 6
Set of QB64 utilities.
Forum: Programs
Last Post: eoredson
2 hours ago
» Replies: 11
» Views: 1,594
Connection address weird ...
Forum: Help Me!
Last Post: DSMan195276
7 hours ago
» Replies: 1
» Views: 45
Using And with two InStr ...
Forum: Help Me!
Last Post: CMR
8 hours ago
» Replies: 3
» Views: 57
flood fill ?
Forum: Help Me!
Last Post: madscijr
9 hours ago
» Replies: 16
» Views: 175
First Person Shooter Game
Forum: Games
Last Post: Steffan-68
Yesterday, 03:49 PM
» Replies: 7
» Views: 102
Questions about INSTR
Forum: General Discussion
Last Post: SMcNeill
Yesterday, 12:41 PM
» Replies: 2
» Views: 70
QB64PE Offline Wiki (Marc...
Forum: Learning Resources and Archives
Last Post: mdijkens
Yesterday, 12:21 PM
» Replies: 2
» Views: 360
Replacement for VAL with ...
Forum: SMcNeill
Last Post: SMcNeill
Yesterday, 09:27 AM
» Replies: 2
» Views: 68
Serial and USB ports
Forum: Help Me!
Last Post: Parkland
Yesterday, 07:59 AM
» Replies: 11
» Views: 436

 
  Cube Game from scratch
Posted by: bplus - 10-18-2023, 02:12 AM - Forum: Programs - Replies (2)

Before I saw the correct version of Cube from Morristown I thought the game would benefit from a mapping display for "You are here." But the way input was setup with Morristown code it was clear where you've been and where you could go next. Anyway here is my version made from scratch.

Oh a couple of mods to game:
1. to make input as easy and simple as possible you only enter one letter for your move
2. that one letter increases player one step on x, y or z plane
3. Wager is out but when you succeed to 3,3,3 you earn 1000 first time and are offered the opportunity to play again to double your money or lose it all and end game.

Code: (Select All)
Option _Explicit ' best practice
DefLng A-Z '       all numbers are integers
Randomize Timer '  for different mining at start
_Title "Cube From Scratch" ' bplus 2023-10-17
' a demo of developing code from a commented text of code specs

' try standard demo screen for QB64
Const Xmax = 800, Ymax = 600 ' screen width and height
Screen _NewImage(Xmax, Ymax, 12) ' 12 is 16 color old QB system
_ScreenMove 240, 80

' Define all Shared variables here with caps
' So to do this game called Cube from scratch you need a Cube array (x, y, z)
' where each x, y, or z is a number from 1 to 3
Dim Shared Cube(1 To 3, 1 To 3, 1 To 3)
Dim Shared Px, Py, Pz ' players position
Dim Shared MoneyUnits ' points from success(es?)
Dim Shared GameOver '   player stepped on Mine flag
Dim Shared GameWin '    player made it to 3,3,3

Intro
Do ' how many times can you make it to 3,3,3 and double your money?
    InitGame
    Do '                game round
        DisplayCube 0 ' display cube but not the mines
        HandleRound '   <<< game ends in here
        If GameWin Then Exit Do
        _Limit 30
    Loop
Loop

Sub DisplayCube (showMines) ' flags both GameOver and GameWin
    Dim x, y, z, zz, yy, xx, rn
    Cls
    ' 3 grids one for each z level
    ' x ascends going right
    ' y ascends going down
    ' z ascends going right
    _PrintString (179, 170), "z = 1"
    drawGrid 150, 50, 50, 50, 2, 2
    _PrintString (379, 170), "z = 2"
    drawGrid 350, 50, 50, 50, 2, 2
    _PrintString (579, 170), "z = 3"
    drawGrid 550, 50, 50, 50, 2, 2
    For z = 1 To 3
        zz = 150 + 200 * (z - 1)
        For y = 1 To 3
            yy = 50 + 50 * (y - 1)
            For x = 1 To 3
                xx = zz + 50 * (x - 1)
                If Px = x And Py = y And Pz = z Then ' draw player
                    For rn = 0 To 6
                        Circle (xx, yy), rn, 9
                    Next
                    If Px = 3 And Py = 3 And Pz = 3 Then GameWin = -1 'celebrate!
                End If
                If Cube(x, y, z) Then ' a mine is here
                    If showMines Then
                        For rn = 1 To 10 Step 2
                            Circle (xx, yy), rn, 12
                        Next
                    End If
                    If Px = x And Py = y And Pz = z Then GameOver = -1 'doomed
                End If
            Next
        Next
    Next
End Sub

Sub HandleRound
    Dim ok$, plane$
    If GameOver Then ' Round ender
        DisplayCube -1 ' show where mines were
        Beep
        Color 14
        yCP 23, "BOOM!"
        yCP 25, "Player you stepped on a mine."
        yCP 27, "Game Over!"
        Sleep
        End
    ElseIf GameWin Then ' Round ender
        ' made it! award 1000 or double money and offer to double it
        DisplayCube -1 ' show where mines were
        If MoneyUnits Then MoneyUnits = 2 * MoneyUnits Else MoneyUnits = 1000
        yCP 12, "You have earned" + Str$(MoneyUnits)
        yCP 14, "Do you want to play again for chance to double your money?"
        yCP 16, "Just press y + enter or just enter for yes, any other + enter = quit."
        Locate 23, 50: Input ok$
        If ok$ = "" Or ok$ = "y" Then Else End
    Else ' still going round get next move, get player move
        Locate 20, 32
        Input "Enter x, y, or z for the next step "; plane$
        plane$ = LCase$(plane$)
        If Px < 3 And plane$ = "x" Then
            Px = Px + 1
        ElseIf Py < 3 And plane$ = "y" Then
            Py = Py + 1
        ElseIf Pz < 3 And plane$ = "z" Then
            Pz = Pz + 1
        End If
    End If
End Sub

Sub Intro ' Start with clear description of the Game as Intro:
    Dim ok$
    yCP 5, "*** Cube from scratch ***"
    yCP 6, "bplus 2023-10-17"
    yCP 10, "You, the player, are starting at position 1,1,1 on wire frame cube 3x3x3"
    yCP 11, "and your objective is to reach 3,3,3 in single step moves."
    yCP 12, "You move on x, y, or z planes by 1 step forward no side or back stepping."
    yCP 14, "A Miner has preceeded you from 1,1,1 to 3,3,3 and laid mines down his path."
    yCP 16, "If you step on a mine, BOOM Game Over, so sorry this is a stupid game of pure luck!"
    yCP 18, "If you make it to 3,3,3 you will be awarded 1000 money units PLUS"
    yCP 19, "you will be offered opportunity to double your money units and play again."
    yCP 22, "Press enter to play, any other + enter quits..."
    Locate 30, 50: Input ; ok$
    If ok$ <> "" Then System
End Sub

Sub InitGame ' Reset variables and mine cube
    Dim mx, my, mz ' Minor's position
    Dim rn ' random number
    Erase Cube
    Px = 1: Py = 1: Pz = 1
    mx = 1: my = 1: mz = 1
    GameWin = 0
    ' Mine the cube by making one path from start to goal
    ' So where cube(x,y,z) = 0 it is safe for player to go ie move into.
    While mx <> 3 Or my <> 3 Or mz <> 3
        rn = rndI&(1, 3)
        If rn = 1 Then
            If mx < 3 Then
                mx = mx + 1
            ElseIf my < 3 Then
                my = my + 1
            Else
                mz = mz + 1
            End If
        ElseIf rn = 2 Then
            If my < 3 Then
                my = my + 1
            ElseIf mz < 3 Then
                mz = mz + 1
            Else
                mx = mx + 1
            End If
        Else
            If mz < 3 Then
                mz = mz + 1
            ElseIf mx < 3 Then
                mx = mx + 1
            Else
                my = my + 1
            End If
        End If
        If mx = 3 And my = 3 And mz = 3 Then Else Cube(mx, my, mz) = 1 ' mined
    Wend
End Sub

Sub yCP (RowNum&, s$) ' for graphics screen Center Print rowNum * 20 per row = y
    _PrintString ((_Width - _PrintWidth(s$)) / 2, RowNum& * 20), s$
End Sub

Function rndI& (n1 As Long, n2 As Long) 'return an integer between 2 numbers
    Dim As Long l, h
    If n1 > n2 Then l = n2: h = n1 Else l = n1: h = n2
    rndI& = Int(Rnd * (h - l + 1)) + l
End Function

Sub drawGrid (x, y, xs, ys, xn, yn) ' top left x, y, x side, y side, number of x, nmber of y
    Dim As Long i, dx, dy
    dx = xs * xn: dy = ys * yn
    For i = 0 To xn
        _PrintString (x + xs * i - 4, y - 24), _Trim$(Str$(i + 1))
        Line (x + xs * i, y)-(x + xs * i, y + dy)
    Next
    For i = 0 To yn
        _PrintString (x - 20, y + ys * i - 8), _Trim$(Str$(i + 1))
        Line (x, y + ys * i)-(x + dx, y + ys * i)
    Next
End Sub

Print this item

  Ascii ClipDoodle (text screen art)
Posted by: James D Jarvis - 10-16-2023, 09:40 PM - Forum: Works in Progress - Replies (10)

A multi-window program to draw ASCII-art. 
The program consists of the main program and 2 other programs that must also be compiled for this to function properly.

sorry V0.2 for Windows only due to the clipboard use.  V0.3 doesn't use the clipboard commands

Thanks to SMcNeil for the excellent text screen saving routines.

EDIT: V0.3 entries for all 3 programs are in a later post to this thread. Hopefully it will work on other systems.

[Image: image.png]


Code: (Select All)
'Ascii Clipdoodle  V 0.2
'an ascii doodle pad that opens control panel apps in other windows
'
'sorry windows only
'
'loadtextimage and savetextimage from SMcNeil at  https://qb64phoenix.com/forum/showthread.php?tid=2022
'
'pickclip.exe and colorpick16.exe must be compiled before this program will function properly

Dim Shared reflag
reflag = -1
Dim Shared helpscreen As Long
Dim Shared twd, tht

twd = 80: tht = 25
helpscreen = _NewImage(twd, tht, 0)

Dim Shared mainscreen As Long
mainscreen = _NewImage(80, 25, 0) 'default size text screen. feel free to change it.
Screen mainscreen
_Title "Ascii ClipDoodle"
Cls
_Clipboard$ = "ClipDoodleOn" ' "clears" clipboard for use
Shell _DontWait "pickclip.exe" ' Open the pickclip control panel
Shell _DontWait "colorpick16.exe" ' Open the colorpick16 control panel
_ControlChr Off
AK = 42
Do
    _Limit 100
    Do While _MouseInput 'mouse status changes only
        _Limit 2000
        x = _MouseX
        y = _MouseY
        px = _MouseX: py = _MouseY
        If _MouseButton(1) Then
            _PrintString (x, y), brush$
        End If
    Loop
    kk$ = InKey$
    Select Case kk$
        Case "t", "T" 'type on current line with current color characteristics
            _KeyClear
            Do
                Do
                    _Limit 60
                    tk$ = InKey$
                Loop Until tk$ <> ""
                If tk$ = Chr$(8) Then
                    tk$ = ""
                    px = px - 1
                End If
                If tk$ <> Chr$(13) And tk$ <> "" Then
                    _PrintString (px, py), tk$
                    px = px + 1
                    If px > _Width Then tk$ = Chr$(13) 'exit type input if attempting to type outside screen
                End If
            Loop Until tk$ = Chr$(13)
        Case "S" 'save text screen
            filef = 0
            file$ = _SaveFileDialog$("Save File", "", "*.SAV", "SAved text screen")
            If file$ <> "" Then
                filef = 1
                _MessageBox "Information", "File will be saved to " + file$
            End If
            If filef = 1 Then
                SaveTextImage 0, file$
                _MessageBox "Image SAved", "Text Images SAVED to " + file$
            End If
            filef = 0
        Case "L", "O" 'load text screen
            file$ = _OpenFileDialog$("Open File", "", "*.SAV", "SAVed text screen", -1)
            If file$ <> "" Then
                _MessageBox "Information", "You selected " + file$
                'mainscreen = LoadTextImage(file$)
                Screen LoadTextImage(file$)
                tht = _Height
                twid = _Width
            End If

        Case "C" 'clear screen
            cc = _MessageBox("CLEAR SCREEN", "Are you sure you want to clear the screen? The image will be lost if it has not been saved. ", "yesnocancel", "warning", 0)
            If cc = 1 Then Cls
        Case Chr$(27)
            cc = _MessageBox("QUIT !", "Are you sure you wish to QUIT? The image will be lost if it has not been saved. ", "yesnocancel", "warning", 0)
            If cc = 1 Then Else kk$ = ""

        Case "R"
            do_resize
        Case "?" 'help
            do_help
    End Select

    ik$ = _Clipboard$
    If Left$(ik$, 2) = "AC" Then AK = Val(Right$(ik$, Len(ik$) - 2))
    If Left$(ik$, 2) = "CK" Then
        ff$ = " "
        n = 2
        Do
            n = n + 1
            A$ = Mid$(ik$, n, 1)
            If A$ <> "/" Then ff$ = ff$ + A$
        Loop Until A$ = "/"
        bb$ = ""
        Do
            A$ = Mid$(ik$, n, 1)
            If A$ <> "/" Then bb$ = bb$ + A$
            n = n + 1
        Loop Until n > Len(ik$)
        FG = Val(ff$): BG = Val(bb$)
        Color FG, BG
    End If
    brush$ = Chr$(AK)
Loop Until kk$ = Chr$(27)
_Clipboard$ = "QUITCOLORPICK16"
Sleep 1
_Clipboard$ = "QUITCLIPPICK"
System
Sub do_help
    ls& = _Dest
    Screen helpscreen
    Cls
    Print "HELP"
    Print "------------------"
    Print "use mouse to draw with ascii characters"
    Print "select character to draw and colors from control panels"
    Print " "
    Print "<ESC> to quit program"
    Print "t,T  -  To type a line of text in colors picked"
    Print
    Print "S    - To Save Screen"
    Print "L,O  - to Load Saved Screen"
    Print "C    - to clear screen"
    print "R    - to Resize Screen   (WARNING : DESTRUCTIVE)"
    Print
    Print "press any key to continue"
    Sleep
    Screen ls&
End Sub
Sub do_resize
    ls& = _Dest
    Screen helpscreen
    Cls
    Print "Resize"
    Print "------------------"
    Print "Current size "
    Print "width "; twd, "Height "; tht
    Print "Enter new coordinates"
    Input "Width "; twd
    Input "Height"; tht
    _FreeImage ls&

    Screen _NewImage(twd, tht, 0)
End Sub




Function LoadTextImage& (SaveFile As String) 'create and load to a new Screen 0 screen with our saved image
    Dim As Integer Wide, Tall, Flag: Wide = 80: Tall = 25: Flag = 0
    Dim As String ImageData
    Dim As _MEM M
    f = FreeFile
    Open SaveFile For Binary As #f
    compress$ = Space$(LOF(f))
    Get #f, 1, compress$
    Close #f
    temp$ = _Inflate$(compress$)
    Flag = Asc(temp$, 1): p = 2

    If Flag And 1 Then Wide = CVI(Mid$(temp$, p, 2)): p = p + 2
    If Flag And 2 Then Tall = CVI(Mid$(temp$, p, 2)): p = p + 2
    If Flag And 4 Then _Blink On Else _Blink Off
    If Flag And 8 Then _Font Asc(temp$, p): p = p + 1
    ImageData = Mid$(temp$, p)
    TempImage = _NewImage(Wide, Tall, 0)
    M = _MemImage(TempImage): _MemPut M, M.OFFSET, ImageData: _MemFree M
    LoadTextImage = TempImage
End Function

Sub SaveTextImage (ImageHandle As Long, SaveFile As String)
    Dim As Integer Wide, Tall, Flag
    Dim As Long ImageSize
    Dim As String ImageData
    Dim As _MEM M
    If _PixelSize(ImageHandle) <> 0 Then Error 5: Exit Sub 'only text images for this routine

    M = _MemImage(ImageHandle)
    Wide = _Width(ImageHandle): Tall = _Height(ImageHandle)
    temp$ = "0" 'placeholder for our finalized image flag which holds custom information

    If Wide <> 80 Then Flag = Flag + 1: temp$ = temp$ + MKI$(Wide)
    If Tall <> 25 Then Flag = Flag + 2: temp$ = temp$ + MKI$(Tall)
    If _Blink Then Flag = Flag + 4 'Set a flag saying that this image uses _Blink
    Select Case _Font(ImageHandle)
        Case 8: Flag = Flag + 8: temp$ = temp$ + Chr$(8)
        Case 9: Flag = Flag + 8: temp$ = temp$ + Chr$(9)
        Case 14: Flag = Flag + 8: temp$ = temp$ + Chr$(14)
        Case 15: Flag = Flag + 8: temp$ = temp$ + Chr$(15)
        Case 16 '16 needs no flag as it's the default for screen 0
        Case 17: Flag = Flag + 8: temp$ = temp$ + Chr$(17)
        Case Else
            'To be added once we get a _MemFont to retrieve custom font data back from QB64PE
    End Select
    ImageSize = Wide * Tall * 2
    ImageData = Space$(ImageSize): _MemGet M, M.OFFSET, ImageData: _MemFree M
    temp$ = temp$ + ImageData
    Mid$(temp$, 1) = Chr$(Flag) 'replace our placeholder with the proper value of the custom flag
    compress$ = _Deflate$(temp$)
    f = FreeFile
    Open SaveFile For Output As #f: Close #f
    Open SaveFile For Binary As #f: Put #f, 1, compress$: Close #f
End Sub

The color picker 
Code: (Select All)
'colorpick16  0.2
'
'a color picker for mode 0 screens.
'compile as colorpick16.exe
'
Screen _NewImage(32, 8, 0)
_ScreenMove 600, 400
_Title "colorpick16"
blinkflag = -1
hflag = -1
FB = 0
BB = 0

print_picker FB, BB
Do
    _Limit 100
    Do While _MouseInput 'mouse status changes only
        x = _MouseX
        y = _MouseY
        If _MouseButton(1) Then
            If y >= 1 And y <= 2 Then
                fk = (y - 1) * 8 + Int(x / 4) + FB
            End If
            Color fk, 0
            If fk = 0 Then Color fk, 8
            _PrintString (12, 4), "    "
            _PrintString (12, 4), Str$(fk)
            If y = 7 Then
                bk = Int(x / 4) + BB
            End If
            Color fk, bk
            _PrintString (12, 5), "    "
            _PrintString (12, 5), Str$(bk)
            _Clipboard$ = "CK" + _Trim$(Str$(fk)) + "/" + _Trim$(Str$(bk))
            If x = 31 And y = 4 Then
                blinkflag = blinkflag * -1
                Select Case blinkflag
                    Case -1
                        FB = 0
                        BB = 0
                        print_picker FB, BB

                    Case 1
                        FB = 16
                        BB = 8
                        print_picker FB, BB

                End Select
            End If
        End If
    Loop
    kk$ = InKey$
    Select Case kk$
        Case "B"
            FB = 16
            BB = 8
            print_picker FB, BB
        Case "b"
            FB = 0
            BB = 0
            print_picker FB, BB
        Case Chr$(27)
            cc = _MessageBox("QUIT !", "Are you sure you wish to QUIT? The program will lose functionality. ", "yesnocancel", "warning", 0)
            If cc = 1 Then cc = 1 Else kk$ = ""
    End Select
    ccheck$ = _Clipboard$
    If ccheck$ = "QUITCOLORPICK16" Then kk$ = "QUITCOLORPICK16"
Loop Until kk$ = Chr$(27) Or kk$ = "QUITCOLORPICK16"
_Clipboard$ = "pickcolor quit"

System
Sub print_picker (f, b)
    For y = 0 To 1
        For x = 0 To 7
            fk = y * 8 + x + f
            p$ = "[  ]"
            a$ = _Trim$(Str$(fk))
            If Len(a$) = 1 Then
                Mid$(p$, 3, 1) = a$
            Else
                Mid$(p$, 2, 2) = a$
            End If
            Color fk, 0
            If fk = 0 Then Color 0, 7
            _PrintString ((x + 1) * 4 - 3, y + 1), p$
        Next
    Next
    _PrintString (31, 4), "B"
    _PrintString (1, 4), "Foreground"
    _PrintString (1, 5), "Background"
    For x = 0 To 7
        bk = x + b
        p$ = "[  ]"
        a$ = _Trim$(Str$(bk))
        If bk < 8 Then Mid$(p$, 3, 1) = a$ Else Mid$(p$, 2, 2) = a$
        Color 0, bk
        If bk = 0 Then Color 15, 0
        _PrintString ((x + 1) * 4 - 3, 7), p$
    Next
    fk = 15: bk = 0



End Sub


The ascii character picker.
Code: (Select All)
'colorpick16  0.2
'
'a color picker for mode 0 screens.
'compile as colorpick16.exe
'
Screen _NewImage(32, 8, 0)
_ScreenMove 600, 400
_Title "colorpick16"
blinkflag = -1
hflag = -1
FB = 0
BB = 0

print_picker FB, BB
Do
    _Limit 100
    Do While _MouseInput 'mouse status changes only
        x = _MouseX
        y = _MouseY
        If _MouseButton(1) Then
            If y >= 1 And y <= 2 Then
                fk = (y - 1) * 8 + Int(x / 4) + FB
            End If
            Color fk, 0
            If fk = 0 Then Color fk, 8
            _PrintString (12, 4), "    "
            _PrintString (12, 4), Str$(fk)
            If y = 7 Then
                bk = Int(x / 4) + BB
            End If
            Color fk, bk
            _PrintString (12, 5), "    "
            _PrintString (12, 5), Str$(bk)
            _Clipboard$ = "CK" + _Trim$(Str$(fk)) + "/" + _Trim$(Str$(bk))
            If x = 31 And y = 4 Then
                blinkflag = blinkflag * -1
                Select Case blinkflag
                    Case -1
                        FB = 0
                        BB = 0
                        print_picker FB, BB

                    Case 1
                        FB = 16
                        BB = 8
                        print_picker FB, BB

                End Select
            End If
        End If
    Loop
    kk$ = InKey$
    Select Case kk$
        Case "B"
            FB = 16
            BB = 8
            print_picker FB, BB
        Case "b"
            FB = 0
            BB = 0
            print_picker FB, BB
        Case Chr$(27)
            cc = _MessageBox("QUIT !", "Are you sure you wish to QUIT? The program will lose functionality. ", "yesnocancel", "warning", 0)
            If cc = 1 Then cc = 1 Else kk$ = ""
    End Select
    ccheck$ = _Clipboard$
    If ccheck$ = "QUITCOLORPICK16" Then kk$ = "QUITCOLORPICK16"
Loop Until kk$ = Chr$(27) Or kk$ = "QUITCOLORPICK16"
_Clipboard$ = "pickcolor quit"

System
Sub print_picker (f, b)
    For y = 0 To 1
        For x = 0 To 7
            fk = y * 8 + x + f
            p$ = "[  ]"
            a$ = _Trim$(Str$(fk))
            If Len(a$) = 1 Then
                Mid$(p$, 3, 1) = a$
            Else
                Mid$(p$, 2, 2) = a$
            End If
            Color fk, 0
            If fk = 0 Then Color 0, 7
            _PrintString ((x + 1) * 4 - 3, y + 1), p$
        Next
    Next
    _PrintString (31, 4), "B"
    _PrintString (1, 4), "Foreground"
    _PrintString (1, 5), "Background"
    For x = 0 To 7
        bk = x + b
        p$ = "[  ]"
        a$ = _Trim$(Str$(bk))
        If bk < 8 Then Mid$(p$, 3, 1) = a$ Else Mid$(p$, 2, 2) = a$
        Color 0, bk
        If bk = 0 Then Color 15, 0
        _PrintString ((x + 1) * 4 - 3, 7), p$
    Next
    fk = 15: bk = 0
End Sub

Print this item

  Cube Game Question
Posted by: bplus - 10-16-2023, 01:06 PM - Forum: General Discussion - Replies (19)

From game by D.Ahl BASIC COMPUTER GAMES

Can someone explain this game to me? I've seen Davids Morristown version (Before QB) and now MG's QB64 update, I don't get what's going on.

I'd share QB64 code from another forum but might upset mnr's cohorts so I better not ;-))
I just wanna have fun!

Print this item

  Everything Date
Posted by: SMcNeill - 10-16-2023, 04:41 AM - Forum: SMcNeill - Replies (3)

I thought a few of you guys might have use for some of these inside your own works.  (Note that these are all going into my toolbox project as well.  I just thought I'd share them independent here for a preview of sorts for folks to enjoy.)

Code: (Select All)
Print "Is the date in proper format?  The skies say "; CheckDayFormat(Date$)
Print "The Date = "; Date$
Print "Weekday  = "; GetWeekDayName(Date$); ", which is day number"; GetWeekDay(Date$); "of the week."
Print "Day      ="; GetDay(Date$)
Print "Month    ="; GetMonth(Date$)
Print "Year    ="; GetYear(Date$)
Print
Print "And to reverse the process we take those values and make them a date with :"; MakeDate(GetMonth(Date$), GetDay(Date$), GetYear(Date$))
Print
Print
Print
Print "And we can always fancify our date to universal formats: "
Print UniDate$("mm/dd/yyyy", Date$)
Print UniDate$("w, MM dd, YYYY", Date$)
Print UniDate$("W, MM DD, YYYY", Date$)
Print UniDate$("dd/mm/yyyy", Date$)
Print UniDate$("W, E D, YYYY", Date$)
Print UniDate$("mm-dd-yy", Date$)


Function CheckDayFormat (Day As String) 'use MM/DD/YYYY format
    Dim As String DD, MM, YYYY, TD, TM, TY
    If Len(Day$) <> 10 Then Glitch = -1
    DD = Left$(Day, 2)
    MM = Mid$(Day, 4, 2)
    YYYY = Right$(Day, 4)
    TD = Right$("00" + _Trim$(Str$(Val(DD))), 2)
    TM = Right$("00" + _Trim$(Str$(Val(MM))), 2)
    TY = Right$("0000" + _Trim$(Str$(Val(YYYY))), 4)
    If TD <> DD Then Glitch = -1
    If TM <> MM Then Glitch = -1
    If TY <> YYYY Then Glitch = -1
    If Glitch = 0 Then CheckDayFormat = -1
End Function

Function GetDay& (Day As String) 'use MM/DD/YYYY format
    If CheckDayFormat(Day$) = 0 Then GetDay = 0: Exit Function
    GetDay = Val(Mid$(Day, 4, 2))
End Function

Function GetMonth& (Day As String) 'use MM/DD/YYYY format
    If CheckDayFormat(Day$) = 0 Then GetMonth = 0: Exit Function
    GetMonth = Val(Left$(Day, 2))
End Function

Function GetYear& (Day As String) 'use MM/DD/YYYY format
    If CheckDayFormat(Day$) = 0 Then GetYear = 0: Exit Function
    GetYear = Val(Right$(Day, 4))
End Function

Function GetWeekDay& (Day$) 'use MM/DD/YYYY format
    'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
    If CheckDayFormat(Day$) = 0 Then GetWeekDay = 0: Exit Function
    Dim As Long century, zerocentury, result
    Dim As Long MM, DD, YYYY
    MM = GetMonth(Day$): DD = GetDay(Day$): YYYY = GetYear(Day$)
    If MM < 3 Then MM = MM + 12: YYYY = YYYY - 1
    century = YYYY Mod 100
    zerocentury = YYYY \ 100
    result = (DD + Int(13 * (MM + 1) / 5) + century + Int(century / 4) + Int(zerocentury / 4) + 5 * zerocentury) Mod 7
    If result = 0 Then result = 7
    GetWeekDay& = result 'results are 1 to 7, from Sunday to Saturday
End Function

Function GetWeekDayName$ (Day$) 'use MM/DD/YYYY format
    Dim result As Long
    result = GetWeekDay(Day$)
    Select Case result
        Case 1: GetWeekDayName = "Sunday"
        Case 2: GetWeekDayName = "Monday"
        Case 3: GetWeekDayName = "Tuesday"
        Case 4: GetWeekDayName = "Wednesday"
        Case 5: GetWeekDayName = "Thursday"
        Case 6: GetWeekDayName = "Friday"
        Case 7: GetWeekDayName = "Saturday"
    End Select
End Function

Function MakeDate$ (MM As _Unsigned Long, DD As _Unsigned Long, YYYY As _Unsigned Long)
    Dim As String TD, TM, TY
    TM = Right$("00" + _Trim$(Str$(MM)), 2)
    TD = Right$("00" + _Trim$(Str$(DD)), 2)
    TY = Right$("0000" + _Trim$(Str$(YYYY)), 4)
    MakeDate = TM + "-" + TD + "-" + TY
End Function

Function UniDate$ (format$, userdate$)
    'some basic documentation for formatting:
    'dates sent via userdate$ should be in the standardized QB64 DATE$ format -- MM/DD/YYYY
    'To customize your return date format, use the following syntax
    'w = short weekday names.  (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
    'W = long weekday names.  (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
    'E = Extended month names.  (January, February, March....)
    'M = long month names.  (Jan, Feb, Mar...)
    'm = short month names.  (01, 02, 03...)
    'D = long day names.  (01st, 02nd, 03rd...)
    'd = short day names.  (01, 02, 03...)
    'Y or y (case insensitive) = year.  Number of Yy present determines the number of digits we return.
    '      YY = 2-digit year
    '      YYYY = 4 digit year
    '      Y with any additional number of y's = 4 digit year by default, so a typo of YYYYY is the same as YYYY.
    'Any other character is simply considered part of the desired output and faithfully carried over into the proper spot.
    '      For example, "mm/dd/yyyy" gives us "02/10/2023" for Feb 10th, 2023.
    '      Second example, "dd.mm.yyyy" gives us "10.02.2023" for the same date.
    '      Third example, "dd EE YYYY" gives us "02 February 2023" for that same date.
    'Note:  Extra digits of most of these codes are simply ignored for error proofing purposes, with only the initial code being accepted.
    '      For example "mM YYYY" is actually processed as a simple "m YYYY".  The process won't mix short, long, or extended results.
    '      Also for example, "m YY" is the *exact* same as "mm YY".
    '      Feel free to use extra digits as you desire to help you keep track of positional spacing in your format string.
    '      Even though "M D, yyyy" may process the same as "MMM DDDD, YYYY", the second may work better for you if you're trying to track
    '            position of formatted objects.  (The output would be "Feb 10th, 2023", and those extra characters help hold that
    '            positioning for us easily.)

    'And, I think that's it.  Enjoy, guys!

    Dim As String temp, m, d, y, firstchar, Day
    Dim out$
    Dim As Long MonthSet, DaySet, WeekdaySet, result, YearSet, mm, dd, yyyy, century, zerocentury

    temp$ = userdate$
    If temp$ = "" Then temp$ = Date$
    m$ = Left$(temp$, 2)
    d$ = Mid$(temp$, 4, 2)
    y$ = Right$(temp$, 4)
    temp$ = format$
    Do
        firstchar$ = Left$(temp$, 1)
        Select Case firstchar$
            Case "E" 'extended month
                temp$ = Mid$(temp$, 2)
                If Not MonthSet Then
                    MonthSet = -1
                    Select Case Val(m$)
                        Case 1: out$ = out$ + "January"
                        Case 2: out$ = out$ + "February"
                        Case 3: out$ = out$ + "March"
                        Case 4: out$ = out$ + "April"
                        Case 5: out$ = out$ + "May"
                        Case 6: out$ = out$ + "June"
                        Case 7: out$ = out$ + "July"
                        Case 8: out$ = out$ + "August"
                        Case 9: out$ = out$ + "September"
                        Case 10: out$ = out$ + "October"
                        Case 11: out$ = out$ + "November"
                        Case 12: out$ = out$ + "December"
                    End Select
                End If
            Case "M" 'long month
                temp$ = Mid$(temp$, 2)
                If Not MonthSet Then
                    MonthSet = -1
                    Select Case Val(m$)
                        Case 1: out$ = out$ + "Jan"
                        Case 2: out$ = out$ + "Feb"
                        Case 3: out$ = out$ + "Mar"
                        Case 4: out$ = out$ + "Apr"
                        Case 5: out$ = out$ + "May"
                        Case 6: out$ = out$ + "Jun"
                        Case 7: out$ = out$ + "Jul"
                        Case 8: out$ = out$ + "Aug"
                        Case 9: out$ = out$ + "Sep"
                        Case 10: out$ = out$ + "Oct"
                        Case 11: out$ = out$ + "Nov"
                        Case 12: out$ = out$ + "Dec"
                    End Select
                End If
            Case "m" 'short month
                temp$ = Mid$(temp$, 2)
                If Not MonthSet Then
                    MonthSet = -1
                    Select Case Val(m$)
                        Case 1: out$ = out$ + "01"
                        Case 2: out$ = out$ + "02"
                        Case 3: out$ = out$ + "03"
                        Case 4: out$ = out$ + "04"
                        Case 5: out$ = out$ + "05"
                        Case 6: out$ = out$ + "06"
                        Case 7: out$ = out$ + "07"
                        Case 8: out$ = out$ + "08"
                        Case 9: out$ = out$ + "09"
                        Case 10: out$ = out$ + "10"
                        Case 11: out$ = out$ + "11"
                        Case 12: out$ = out$ + "12"
                    End Select
                End If
            Case "D" 'long day
                temp$ = Mid$(temp$, 2)
                If Not DaySet Then
                    DaySet = -1
                    out$ = out$ + Right$("00" + _Trim$(d$), 2)
                    Select Case Val(d$)
                        Case 1, 11, 21, 31: out$ = out$ + "st"
                        Case 2, 22: out$ = out$ + "nd"
                        Case 3, 23: out$ = out$ + "rd"
                        Case Else: out$ = out$ + "th"
                    End Select
                End If
            Case "d" 'short day
                temp$ = Mid$(temp$, 2)
                If Not DaySet Then
                    DaySet = -1
                    out$ = out$ + Right$("00" + _Trim$(d$), 2)
                End If

            Case "W" 'long weekday
                temp$ = Mid$(temp$, 2)
                If Not WeekdaySet Then
                    GoSub getday
                    Select Case result
                        Case 0: Day$ = "Saturday"
                        Case 1: Day$ = "Sunday"
                        Case 2: Day$ = "Monday"
                        Case 3: Day$ = "Tuesday"
                        Case 4: Day$ = "Wednesday"
                        Case 5: Day$ = "Thursday"
                        Case 6: Day$ = "Friday"
                    End Select
                    out$ = out$ + Day$
                End If
            Case "w" 'short weekday
                temp$ = Mid$(temp$, 2)
                If Not WeekdaySet Then
                    GoSub getday
                    Select Case result
                        Case 0: Day$ = "Sat"
                        Case 1: Day$ = "Sun"
                        Case 2: Day$ = "Mon"
                        Case 3: Day$ = "Tue"
                        Case 4: Day$ = "Wed"
                        Case 5: Day$ = "Thr"
                        Case 6: Day$ = "Fri"
                    End Select
                    out$ = out$ + Day$
                End If
            Case "Y", "y" 'year
                If Not YearSet Then
                    YearSet = -1
                    If Left$(UCase$(temp$), 4) = "YYYY" Then
                        temp$ = Mid$(temp$, 5)
                        out$ = out$ + y$
                    ElseIf Left$(UCase$(temp$), 2) = "YY" Then
                        temp$ = Mid$(temp$, 3)
                        out$ = out$ + Right$(y$, 2)
                    Else
                        temp$ = Mid$(temp$, 2)
                        out$ = out$ + y$
                    End If
                Else
                    temp$ = Mid$(temp$, 2)
                End If
            Case Else 'seperator
                temp$ = Mid$(temp$, 2)
                out$ = out$ + firstchar$
        End Select
    Loop Until temp$ = ""
    UniDate$ = out$
    Exit Function

    getday:
    WeekdaySet = -1
    'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
    mm = Val(m$): dd = Val(d$): yyyy = Val(y$)
    If mm < 3 Then mm = mm + 12: yyyy = yyyy - 1
    century = yyyy Mod 100
    zerocentury = yyyy \ 100
    result = (dd + Int(13 * (mm + 1) / 5) + century + Int(century / 4) + Int(zerocentury / 4) + 5 * zerocentury) Mod 7
    Return
End Function

Print this item

  MouseMovement Demo
Posted by: SMcNeill - 10-15-2023, 11:42 PM - Forum: SMcNeill - No Replies

Code: (Select All)
SCREEN _NEWIMAGE(1024, 720, 32)

arrow = _NEWIMAGE(75, 100, 32)

font = _LOADFONT("courbd.ttf", 100, "monospaced")
_DEST arrow
_FONT font
_CONTROLCHR ON
PRINT "";
_DEST 0


DO
    WHILE _MOUSEINPUT
        angle = angle + _MOUSEMOVEMENTX
    WEND
    CLS , 0
    PRINT "Angle:"; angle
    DisplayImage arrow, 512, 360, 3, 3, angle, 0
    _LIMIT 15
    _DISPLAY
LOOP UNTIL _MOUSEBUTTON(2)



SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, xscale AS SINGLE, yscale AS SINGLE, angle AS SINGLE, mode AS _BYTE)
    'Image is the image handle which we use to reference our image.
    'x,y is the X/Y coordinates where we want the image to be at on the screen.
    'angle is the angle which we wish to rotate the image.
    'mode determines HOW we place the image at point X,Y.
    'Mode 0 we center the image at point X,Y
    'Mode 1 we place the Top Left corner of oour image at point X,Y
    'Mode 2 is Bottom Left
    'Mode 3 is Top Right
    'Mode 4 is Bottom Right

    DIM AS INTEGER px(3), py(3), w, h, w1, h1
    DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
    w = _WIDTH(Image): h = _HEIGHT(Image)
    w1 = w * xscale: h1 = h * yscale
    SELECT CASE mode
        CASE 0 'center
            px(0) = -w1 / 2: py(0) = -h1 / 2: px(3) = w1 / 2: py(3) = -h1 / 2
            px(1) = -w1 / 2: py(1) = h1 / 2: px(2) = w1 / 2: py(2) = h1 / 2
        CASE 1 'top left
            px(0) = 0: py(0) = 0: px(3) = w1: py(3) = 0
            px(1) = 0: py(1) = h1: px(2) = w1: py(2) = h1
        CASE 2 'bottom left
            px(0) = 0: py(0) = -h1: px(3) = w1: py(3) = -h1
            px(1) = 0: py(1) = 0: px(2) = w1: py(2) = 0
        CASE 3 'top right
            px(0) = -w1: py(0) = 0: px(3) = 0: py(3) = 0
            px(1) = -w1: py(1) = h1: px(2) = 0: py(2) = h1
        CASE 4 'bottom right
            px(0) = -w1: py(0) = -h1: px(3) = 0: py(3) = -h1
            px(1) = -w1: py(1) = 0: px(2) = 0: py(2) = 0
    END SELECT
    sinr = SIN(angle / 57.2957795131): cosr = COS(angle / 57.2957795131)
    FOR i = 0 TO 3
        x2 = (px(i) * cosr + sinr * py(i)) + x: y2 = (py(i) * cosr - px(i) * sinr) + y
        px(i) = x2: py(i) = y2
    NEXT
    _MAPTRIANGLE (0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MAPTRIANGLE (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB

I think a lot of folks misunderstand what MouseMovementX and MouseMovementY are for.  

First thing to note:  They're NOT for tracking your mouse's absolute position on the screen.  There's _MouseX and _MouseY for that.

So what are they for??

Let's move our thinking from QB64PE out to just playing some game.  Now, in this game, you're in a spaceship flying through outer space.  To control your ship, it's set up to use a simple scroll ball as the navigation tool.

Scroll that ball right, and the ship turns right.
Scroll that ball left, and the ship turns left.
Scroll that ball up, and the ship flys down.  (The arse end goes up, the nose goes down.)
Scroll that ball down, and the ship flys up.  (The arse end goes down, the nose goes up.)

Now, tracking mouse position in this situation is just foolish.  You scroll right.... right... right.... right.... Hit the edge of the screen with the mouse, and BOOM!!  Your ship can no longer rotate to the right in outer space!!

See the problem with trying to use _MouseX in this situation?   You can turn right and go around in circles till the end of time.  Your mouse cursor, however, is going to stop at the edge of your screen.

So, how to track this "ball rotated right" event??    _MouseMovementX.    Even if the mouse is at the right edge of the screen, you can scroll that mouseball on your desk endlessly to the right.  It won't move the mouse pointer -- it's already at the limit -- but _MouseMovementX will record that rotation and report it to you.

MouseMovementX  simply tells you if your mouseball has rotated left or right.
MouseMovementY tells you if that mouseball has rotated up or down.

It has nothing to do with screen coordinates.  Just mouse wheel scrolling itself.   I hope the demo above helps to highlight what these commands are actually used for, for us.  Smile

Print this item

  Can _MOUSEMOVEMENTX & Y be used for something like this?
Posted by: Dav - 10-15-2023, 11:17 PM - Forum: Help Me! - Replies (4)

I'm trying to grasp using_MOUSEMOVEMENTX & Y in  a program, not sure I fully understand these two functions yet.  I have run the wiki examples, but I'm not seeing how they could be used for something like below.   Could those functions be used to easier compute mouse movement for like grabing an object and move it only for as much as the mouse has moved since clicking on it?

Here's some code I was playing with for testing.  Could something like this be streamlined with _MOUSEMOVEMENTX & Y instead of using another DO/LOOP to calculate mouse movement?

- Dav 

Code: (Select All)

Screen _NewImage(800, 600, 32)

cx = 400: cy = 400

Do

    Cls , _RGB(32, 0, 0)

    Locate 1, 1: Print "Click on and drag curves to shape...";

    While _MouseInput: Wend

    'grabbed screen
    If _MouseButton(1) Then
        startmx = _MouseX: startmy = _MouseY

        '=====================================================
        'Can _MOUSEMOVEMENTX/Y be used instead of below?
        Do
            Cls , _RGB(32, 0, 0)
            While _MouseInput: Wend
            newcx = cx + (_MouseX - startmx)
            newcy = cy + (_MouseY - startmy)
            For c = -300 To 300 Step 20
                Curve 400, 100, 400, 500, newcx + c, newcy, _RGB(255, 0, 0)
            Next
            _Limit 30
            _Display
        Loop Until _MouseButton(1) = 0
        cx = newcx: cy = newcy
        '=====================================================

    End If

    For c = -300 To 300 Step 20
        Curve 400, 100, 400, 500, cx + c, cy, _RGB(255, 0, 0)
    Next

    _Limit 30
    _Display
Loop

Sub Curve (x1, y1, x2, y2, cx, cy, clr&)
    'Draws a curved line using a quadratic bezier curve formula
    'x1/y1 = start point
    'x2/y2 = end point
    'cx.cy = control point
    Do While t <= 1
        x = (1 - t) ^ 2 * x1 + 2 * (1 - t) * t * cx + t ^ 2 * x2
        y = (1 - t) ^ 2 * y1 + 2 * (1 - t) * t * cy + t ^ 2 * y2
        PSet (x, y), clr&
        t = t + .001
    Loop
End Sub

Print this item

  Help a lazy developer!
Posted by: SMcNeill - 10-15-2023, 08:14 PM - Forum: General Discussion - Replies (22)

Terry posted an idea for improving QB64PE here:  https://qb64phoenix.com/forum/showthread.php?tid=2075

Basically, his idea was simple -- Add an optional parameter to CLS so you don't have to change _DEST when using it.

And hey, let's be honest, that's a GREAT idea!!   But, let's take it a step further:  How many times have you wished you could just do a simple PSET (x, y), color, optional_imagehandle?  Set a color of a pixel on an image, without having to alter source and dest to do so!

And how many other commands are there that could benefit from this type improvement?  Off the top of my head, I can think of:

CLS ,background, imagehandle
PSET (x, y), color, imagehandle
LINE (x, y) - (x,y), color, BF, imagehandle
CIRCLE (though I'm too lazy to look up all its syntax), imagehandle

Now, here's my question for you guys, and here's where you can help with some easy development tasks: Give me a list of any and all other commands which could benefit from this simple optional parameter addition. A change like this won't affect existing code at all. Your old stuff won't break. All it'll do is allow a little more flexibility to be added to new stuff, and make it just a little simpler to code things in the future. And, honestly, making such changes is more or less a trivial matter which even someone like myself can push into the repo with just a few hours work and a couple lines of code.

Wrack your brain and help list what needs this style improvement. Heck, if you're brain damaged like me, yet have a ton of free time, pop over to the wiki and scroll down the command list and see what it seems like an optional parameter could help improve.

List those ideas here, and I'll see about taking a little free time this week and next weekend, and making the changes for us and push them into the repo for folks to enjoy in future versions of QB64PE. I'm getting older, and my eyes go all crosseyed and I fall asleep scrolling up and down lists of raw documentation anymore. You guys make me a list, and I'll make what changes I can. You won't get a better offer than that for $1.29 at your local McDonalds!

Print this item

  Pixel life
Posted by: James D Jarvis - 10-15-2023, 04:11 PM - Forum: Programs - Replies (9)

An attempt to do Conways' game of life as two images without using defined arrays. Not sure it works right but it simulates working right.  The overall program can surely be trimmed down. I posted this on a facebook group a couple weeks a go and figured.. heck why not post it here?

Code: (Select All)
'pixel_life
' an attmept to repilicate Conway's game of life without arrays by using 2 images
'not sure if I got it working right just yet
'feel free to fiddle with it, press <esc> to exit the program at any time
'there are multiple start states you can change by editing the comments
Dim Shared xmax, ymax
xmax = 400: ymax = 400 'change these as you wish , high numbers may be slow on older machines
Dim Shared s0 As Long
Dim Shared s1 As Long
Dim Shared klr As _Unsigned Long
s0 = _NewImage(xmax, ymax, 32)
s1 = _NewImage(xmax, ymax, 32)
Screen s0
_Title "Pixel Life      <esc> to exit"
'_FullScreen
Randomize Timer
klr = _RGB32(30, 200, 0)
'use comments to change starting population of dots
'rand_gen0
test_genA
'test_genB
'test_mousepop
t = 0
rr = 0: gg = 80: bb = 0
Do
    _Limit 6 'I want to be able to see the changes as the generations go on
    gg = gg + 2
    t = t + 1
    _PutImage (0, 0), s1, s0
    update_gen
Loop Until InKey$ = Chr$(27)
_Dest s0
Print t, " generations"
End

Sub test_genA
    _Dest s1
    Cls , _RGB32(0, 0, 0)
    PSet (xmax \ 2, ymax \ 2 - 2), klr
    PSet (xmax \ 2, ymax \ 2 - 1), klr
    PSet (xmax \ 2, ymax \ 2), klr
    PSet (xmax \ 2, ymax \ 2 + 1), klr
    PSet (xmax \ 2, ymax \ 2 + 2), klr
    PSet (xmax \ 2 + 1, ymax \ 2), klr
    PSet (xmax \ 2 - 1, ymax \ 2), klr
End Sub
Sub test_genB
    _Dest s1
    Cls , _RGB32(0, 0, 0)
    PSet (xmax \ 2, ymax \ 2), klr
    PSet (xmax \ 2 + 1, ymax \ 2), klr
    PSet (xmax \ 2 + 2, ymax \ 2 + 1), klr
    PSet (xmax \ 2, ymax \ 2 + 2), klr
    PSet (xmax \ 2 + 1, ymax \ 2 + 2), klr
    PSet (xmax \ 2 + 2, ymax \ 2 + 2), klr
    PSet (xmax \ 2 + 3, ymax \ 2 + 2), klr
End Sub
Sub test_mousepop
    _Dest s1
    Screen s1
    Cls , _RGB32(0, 0, 0)
    Do
        ' press space when done drawing
        Do While _MouseInput
            mx = _MouseX
            my = _MouseY
            If mx > 0 And mx < xmax And my > 0 And my < ymax Then
                If _MouseButton(2) Then
                    PSet (mx, my), klr
                End If
            End If
        Loop
    Loop Until InKey$ = Chr$(32)
    Screen s0
    _Dest s0
End Sub
Sub rand_gen0
    _Dest s1
    Cls , _RGB32(0, 0, 0)
    For y = 0 To ymax - 1
        For x = 0 To xmax - 1
            If Rnd * 30 < 2 Then PSet (x, y), klr
        Next
    Next
    _Dest s0
End Sub
Sub update_gen
    'change each generation
    _Dest s1
    Cls , _RGB32(0, 0, 0)
    _Dest s0
    For y = 0 To ymax - 1
        For x = 0 To xmax - 1
            update_cell x, y
        Next
    Next
End Sub
Sub update_cell (sx, sy)
    'check each cell for neighbors and update life
    _Source s0
    _Dest s1
    ds = -1 'set to -1 because we are going to count the cell itself and ignore it this way
    If sx > 1 Then x0 = sx - 1 Else x0 = 0
    If sy > 1 Then y0 = sy - 1 Else y0 = 0
    If sx < xmax - 1 Then x1 = sx + 1 Else x1 = xmax - 1
    If sy < ymax - 1 Then y1 = sy + 1 Else y1 = ymax - 1
    For y = y0 To y1
        For x = x0 To x1
            If Point(x, y) <> _RGB32(0, 0, 0) Then ds = ds + 1
        Next
    Next
    Select Case ds
        Case 0, 1
            PSet (sx, sy), _RGB32(0, 0, 0)
        Case 2,3
            PSet (sx, sy), klr
       ' Case 3     'yeah this was strange... keeping it here as comments for reasons
        '    If Point(sx, sy) = _RGB32(0, 0, 0) Then PSet (sx, sy), klr Else PSet (sx, sy), klr
        Case Is > 3
            PSet (sx, sy), _RGB32(0, 0, 0)
    End Select
End Sub

Print this item

  Is my Logic wrong or QB64's ?
Posted by: bplus - 10-15-2023, 08:15 AM - Forum: Help Me! - Replies (10)

I am doing a demo of setting up Conways Game of Life at other forum and run into a problem getting proper neighbor counts of a cell with this code:

Code: (Select All)
nc = 0
            For yy = y - 1 To y + 1
                For xx = x - 1 To x + 1
                    If (xx <> x) And (yy <> y) Then 'dont count cell(x, y) the cell whose neighbors we are counting
                        If Cells(xx, yy) Then nc = nc + 1 ' : Beep ' debug OK
                    End If
                Next
            Next
x and y are just in outer loops scanning the whole array to display on screen.


If I rework that first IF line to this:
Code: (Select All)
nc = 0
            For yy = (y - 1) To (y + 1)
                For xx = (x - 1) To (x + 1)
                    If xx = x And yy = y Then
                        'dont count cell(x, y) the cell whose neighbors we are counting
                    Else
                        If Cells(xx, yy) Then nc = nc + 1: Beep ' debug OK
                    End If
                Next
            Next

All is well! Fine I can get the code to work as expected with 2nd block but I am not understanding what is going wrong with the first code example?

A professional Basic coder (non QB64 fan) said the logic is correct, has QB64 another glitch?
BTW he showed a much better method to do count without IF.

If anyone a connoisseur of methods it was this:
Code: (Select All)
nc = 0
            For yy = y - 1 To y + 1
                For xx = x - 1 To x + 1
                    nc = nc + Cells(xx, yy) ' no ifs
                Next
            Next
            nc = nc - Cells(x, y)
I switched from using -1's to using 1's for live cell (0 for dead)

As I recall my debug checks with the first block of code was messing up neighbor counts of live cells not that it should matter but with either -1 or 1 for live cell signal.

oh wait, I see it now, the logic is wrong because if I break the first IF line into 2 it becomes obvious why the counts were failing:
Code: (Select All)
nc = 0
For yy = y - 1 To y + 1
    For xx = x - 1 To x + 1
        If (xx <> x) Then
            If (yy <> y) Then
                'dont count cell(x, y) the cell whose neighbors we are counting
                If Cells(xx, yy) Then nc = nc + 1 ' : Beep ' debug OK
            End If
        End If
    Next
Next

OK never mind, I got it now Smile

Print this item

  A retro calendar for embedding in HTML pages
Posted by: CharlieJV - 10-15-2023, 12:26 AM - Forum: QBJS, BAM, and Other BASICs - No Replies

Definitely not pretty, however kind of cool in a nostalgic way: aside from a few mods, it is GW-BASIC code used to create a simple calendar that can be embedded as a kind of gadget via an iframe:

Calendar (a GW-BASIC program ported to BAM)

Print this item