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

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 483
» Latest member: aplus
» Forum threads: 2,803
» Forum posts: 26,424

Full Statistics

Latest Threads
_IIF limits two question...
Forum: General Discussion
Last Post: Pete
13 minutes ago
» Replies: 4
» Views: 42
DeflatePro
Forum: a740g
Last Post: Petr
4 hours ago
» Replies: 1
» Views: 34
New QBJS Samples Site
Forum: QBJS, BAM, and Other BASICs
Last Post: dbox
6 hours ago
» Replies: 25
» Views: 881
Raspberry OS
Forum: Help Me!
Last Post: Jack
6 hours ago
» Replies: 7
» Views: 135
InForm-PE
Forum: a740g
Last Post: Kernelpanic
6 hours ago
» Replies: 80
» Views: 6,135
GNU C++ Compiler error
Forum: Help Me!
Last Post: RhoSigma
Yesterday, 11:57 AM
» Replies: 1
» Views: 59
Merry Christmas Globes!
Forum: Programs
Last Post: SierraKen
Yesterday, 03:46 AM
» Replies: 10
» Views: 133
Text-centring subs
Forum: Utilities
Last Post: Pete
Yesterday, 02:50 AM
» Replies: 3
» Views: 85
Screw Text Centering. How...
Forum: Utilities
Last Post: Pete
Yesterday, 01:44 AM
» Replies: 0
» Views: 41
List of file sound extens...
Forum: Help Me!
Last Post: aplus
12-19-2024, 11:50 PM
» Replies: 16
» Views: 296

 
  HELP TO RUN QBASIC CODE FROM 90s !
Posted by: musss1 - 06-10-2024, 08:46 AM - Forum: Help Me! - Replies (12)

Hello everyone, I am having a hard time trying to run a code, (which I copied and pasted from a PDF text book ^^), 
The program was written in Microsoft QuickBASIC for Apple Macintosh, so i investigated a little and   
close to that i found QB64 programing languaje , i dont know if the syntax is the same, but the file (.bas), gets executed,
 
If someone can help me resolve the problem, I would appreciate it. ♥
I am leaving the link to the GitHub repository if you want to download the files and try them out yourselves.
its strange because the code is from a book, So it shouldn't be an issue ! 
I am also attaching a video with two images, showing what happens when I try to run the code completely! 

link to github :
https://github.com/musss1s/programingQBASIC.git

first image : 
The main program, calls the file "uflo.dat",which i highlighted in yellow, it stores numbers in a 21x41 array format, 
with 21 columns and each column containing 41 numbers, separated by commas. 
I = 21 and J = 41.
 
It is used to perform some calculations for sonic and subsonic flow, "gas dynamics."
[Image: c02dd121885ba3e20f76be7cdc10603c.png]


second image:
i marked in red where the syntaxis problem is 
[Image: b9484f8039912bc41a00b3747cc28810.png]

reference video:



the code should look like this :

[Image: 81ad2207c7346cfd0e26c4c84101d1b3.png]


please help !!! Sad   thank you guys

Print this item

  SUB & FUNCTION when declaring dynamic library
Posted by: TerryRitchie - 06-09-2024, 05:33 PM - Forum: Help Me! - Replies (9)

I just ran across something that is confusing me.

The User32 function SetCursorPos as outlined here in the Microsoft docs:

https://learn.microsoft.com/en-us/window...tcursorpos

is a function. However, it's being declared as a SUB in the Wiki example code here:

https://qb64phoenix.com/qb64wiki/index.p...Mouse_Area

At first I though this was a typo but the code works. Is this a typo that somehow works? Or is it possible to declare FUNCTIONs as SUBs in certain circumstances?

Print this item

  Lesson 10: Slot Machine
Posted by: SMcNeill - 06-08-2024, 11:02 PM - Forum: Terry Ritchie's Tutorial - Replies (7)

So, I saw the other post for the slot machine, and thought I'd take a quick shot at seeing how I'd come up with something like you suggested.  Wink

Code: (Select All)
SCREEN _NEWIMAGE(340, 340, 32)
_TITLE "Slot Machine!"
RANDOMIZE TIMER
$COLOR:32
COLOR White, 0
Money = 300
DIM AS _FLOAT spin1, spin2, spin3
DO
CLS , DarkGray
CenterText 10, "ENTER TO SPIN! (You have $" + STR$(Money) + ")"
CenterText 140, "PAYOUTS"
CenterText 160, "Three Double Circles -- 500"
CenterText 180, "Three Squares -- 25"
CenterText 200, "Three Triangles -- 25"
CenterText 220, "Three Circles -- 25"
CenterText 240, "Two Circles -- 10"
CenterText 260, "Three Diamonds -- 10"
CenterText 280, "Two Diamonds -- 5"
CenterText 300, "One Diamond -- 1"
DO: a$ = INPUT$(1): LOOP UNTIL a$ = CHR$(13) OR a$ = CHR$(27)
IF a$ = CHR$(27) THEN SYSTEM
LINE (0, 0)-(340, 340), DarkGray, BF
spin1 = TIMER + RND * 2 + 1: spin2 = RND * 2 + 1 + spin1: spin3 = RND * 2 + 1 + spin2
DO
finished = -1
IF spin1 > TIMER THEN slot1 = Slot(INT(RND * 32)): DrawSlot 0, slot1
IF spin2 > TIMER THEN slot2 = Slot(INT(RND * 32)): DrawSlot 1, slot2
IF spin3 > TIMER THEN slot3 = Slot(INT(RND * 32)): DrawSlot 2, slot3: finished = 0
_LIMIT 10
_DISPLAY
LOOP UNTIL finished
_AUTODISPLAY
win = -10 'the "ante" of $10 to spin.
IF slot1 = slot2 AND slot2 = slot3 THEN 'three of a kind!
SELECT CASE slot1
CASE 1: win = 250 '3 circles
CASE 2: win = 250 '3 triangles
CASE 3: win = 100 '3 diamonds
CASE 4: win = 5000 '3 double circles
CASE 5: win = 250 '3 squares
END SELECT
END IF
diamond = 0: circles = 0
IF slot1 = 3 THEN diamond = diamond + 1 ELSE IF slot1 = 1 THEN circles = circles + 1
IF slot2 = 3 THEN diamond = diamond + 1 ELSE IF slot2 = 1 THEN circles = circles + 1
IF slot3 = 3 THEN diamond = diamond + 1 ELSE IF slot2 = 1 THEN circles = circles + 1
IF diamond = 1 THEN win = 10 ELSE IF diamond = 2 THEN win = 50 '1 diamond or 2 diamond
IF circles = 2 THEN win = 100 '2 circles
IF win < 0 THEN CenterText 250, "Sorry. No Match. You lose." ELSE CenterText 250, "Congrats! You win!"
Money = Money + win
_KEYCLEAR: SLEEP: _DELAY .5: _KEYCLEAR
LOOP

SUB DrawSlot (where, what)
LINE (10 + 110 * where, 50)-STEP(100, 100), Black, BF
w = 110 * where
SELECT CASE what
CASE 1: CircleFill 60 + w, 100, 50, Blue 'circle
CASE 2: FillTriangle 60 + w, 50, 10 + w, 150, 110 + w, 150, Yellow 'triangle
CASE 3: FillQuad 60 + w, 50, 10 + w, 100, 60 + w, 150, 110 + w, 100, Green 'diamond
CASE 4: CircleFill 60 + w, 100, 50, Red: CircleFill 60 + w, 100, 25, Yellow 'double circle
CASE 5: LINE (20 + 110 * where, 60)-STEP(80, 80), Gold, BF: 'square
END SELECT
END SUB

FUNCTION Slot (roll AS INTEGER)
SELECT CASE roll
CASE 0 TO 1: Slot = 1
CASE 1 TO 3: Slot = 2
CASE 3 TO 7: Slot = 5
CASE 7 TO 15: Slot = 4
CASE ELSE: Slot = 3
END SELECT
END FUNCTION

SUB CenterText (y, text$)
l = _PRINTWIDTH(text$)
w = _WIDTH
x = (w - l) \ 2
_PRINTSTRING (x, y), text$
END SUB

SUB FillTriangle (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
STATIC a&, m AS _MEM
IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32): m = _MEMIMAGE(a&)
_MEMPUT m, m.OFFSET, K
_MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
END SUB
SUB FillQuad (x1, y1, x2, y2, x3, y3, x4, y4, K AS _UNSIGNED LONG)
FillTriangle x1, y1, x2, y2, x3, y3, K
FillTriangle x3, y3, x4, y4, x1, y1, K
END SUB

SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
DIM Radius AS INTEGER, RadiusError AS INTEGER
DIM X AS INTEGER, Y AS INTEGER
Radius = ABS(R)
RadiusError = -Radius
X = Radius
Y = 0
IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
LINE (CX - X, CY)-(CX + X, CY), C, BF
WHILE X > Y
RadiusError = RadiusError + Y * 2 + 1
IF RadiusError >= 0 THEN
IF X <> Y + 1 THEN
LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
END IF
X = X - 1
RadiusError = RadiusError - X * 2
END IF
Y = Y + 1
LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
WEND
END SUB

About 120ish lines of code, and I don't think I missed anything out of the instructions. Did I?

I haven't looked to see how anyone else has tackled this task yet, as I wanted to give it a go all on my own, so I'm hoping I didn't hit too far off the mark. Wink

Print this item

  Memory Warning
Posted by: Dimster - 06-08-2024, 12:21 PM - Forum: Site Suggestions - Replies (10)

I have a vague recollection that a discussion on memory usage was kicked around however I can't seem to find if that discussion specifically dealt with a Warning being displayed in the IDE. 

Every now and then I could use a quick guide to how much memory a particular array that I have just dimmed will take up. I know the act of dimming sets aside memory for the array however the amount of memory set aside is not immediately known. You have to do the math yourself.

As well, how much available memory is also difficult to know at the time of dimming. I don't know if the IDE, in reserving the memory would have access to the total ram in one's computer and therefore, knowing the size of the array being set up in memory, would also be able to calculate the amount of memory left for future arrays.

Would it be possible for the IDE to have a Warning on Memory Available ... or if upon Dimming an array the amount of memory set aside be displayed ... or if the Warning on Unused arrays and variables would display the amount of memory.

Just a thought

Print this item

  Simple Sudoku puzzle (updated with 500 puzzles)
Posted by: Dav - 06-08-2024, 01:59 AM - Forum: Games - Replies (7)

This is a simple to play sudoku puzzle with 500 easy level puzzles to solve.   I hesitated sharing this because the code is so jumbled up, but I probably won't ever clean it up so here it is.  Maybe somebody would like a portable sudoku program.  Screen size will adjust to 75% of users desktop height, so the puzzle should look nice on any screen.  If you want to see a REALLy good sudoku in QB64 then I highly  recommend looking up the one @bplus made. 

Left click to add a number to a cell, right click on a number to erase it.
SPACE will reset puzzle, ENTER will go to a random puzzle #.
Use +/- keys to jump to different puzzles quickly.
Press T to play with  timer (shows in title bar).
R will reset all puzzles to unsolved.

Game progress now saved to a sudoko.dat file in current directory so you can continue where you left off.

- Dav

EDIT: Updated version - now saves game progress and solved puzzles.

Code: (Select All)
'==========
'SUDOKU.BAS v1.2
'==========
'A simple and easy to use sudoku puzzle.
'Contains 500 solvable easy level puzzles.
'Coded by Dav JUN/2024 using QB64PE v3.13.0
'
'Added:  Puzzle progress now saved.
'        Continue where you left off!
'        (sudoku.dat file is saved in dir)
'Added:  Press 'R' to reset all 500 puzzles

'==================================================

'This is a classic sudoku puzzle implementation.

'Left click on a cell to assign a number to it.
'A number box will pop up. Click on desired number.
'(keys 1 - 9 can also be used when number box shows)
'Number turn red whenever there's a conflict.

'Right click on numbers to remove them off the board.
'(or select same number from numbox to remove it).

'The current puzzle number is displayed in Title bar.

'Use +/- keys to navigate to a certain puzzle number.

'ENTER gets a random puzzle number.

'SPACE will reset current puzzle.

'R will reset(clear) all puzzles.

'ESC key quits the game.

'You can press T to turn Timer ON/OFF if you want
'to play with a timer. (time shows in title bar).
'The timer shows how long you has spent on the
'current puzzle.

'When the current puzzle is solved the next puzzle
'number is selected automatically.

'Visit my little QB64PE Programming Corner here:
'https://qb64phoenix.com/forum/showthread.php?tid=128

'-Dav

grid = 9 '  grid size is is 9x9
cells = grid * grid ' number of cells on grid

Dim cellx(grid * grid), celly(grid * grid) 'top x/y cords of cells
Dim cellx2(grid * grid), celly2(grid * grid) ' bottom x/y cords of cells
Dim Shared cellstate(grid * grid) 'flag that for hard coded numbers (can't change these on board)
Dim Shared cellvalue(grid * grid) 'holds the cell number values
Dim Shared puznum, puzmax: puzmax = 500
Dim Shared puz$(puzmax)

dh = _DesktopHeight * .75
size = Int(dh / grid) ' size of cells
Screen _NewImage(size * grid, size * grid, 32)

BIGFONT Int(_Height / 9)

Randomize 1234 'define seed so generated puzzle # stay same every run

puznum = 1 'defaults to puzzle 1

On Timer(1) GoSub TitleTimer
TimerFlag = 0

'========
createdat:
'========

If Not _FileExists("sudoku.dat") Then

    Open "sudoku.dat" For Output As #1

    '=== Generate 500 puzzles
    For p = 1 To puzmax
        puz$(p) = NewPuz$
        Print #1, puz$(p); 'save puzzle data
    Next

    Print #1, MKL$(1); 'save current puzzle #
    Close 1
End If

Open "sudoku.dat" For Binary As #1

'check for correct data size
If LOF(1) <> ((162 * puzmax) + 4) Then
    Close 1
    Kill "sudoku.dat"
    GoTo createdat
End If

'load puzzle data
For p = 1 To puzmax
    in$ = Input$(162, 1) 'load puzzle data
    puz$(p) = in$
Next

'=== load current puzzle
puznum = CVL(Input$(4, 1))

Close 1


'========
Start:
'========

_Title "Sudoku #" + _Trim$(Str$(puznum))

bc = 1 'counter
For col = 1 To grid
    For row = 1 To grid
        x = (row * size): y = (col * size)
        cellx(bc) = x - size: cellx2(bc) = x ' generate x/y values
        celly(bc) = y - size: celly2(bc) = y
        cellvalue(bc) = Val(Mid$(puz$(puznum), bc, 1))
        cellstate(bc) = Val(Mid$(puz$(puznum), 81 + bc, 1))
        bc = bc + 1
    Next
Next



If TimerFlag = 1 Then
    StartTime = Timer
    Timer On
Else
    Timer Off
End If

_PrintMode _KeepBackground

GoSub UpdateBoard



Do

    ky$ = InKey$

    If ky$ = " " Then
        'clear puz$ data with cellstate of 0
        For p = 1 To 81
            If cellstate(p) = 0 Then Mid$(puz$(puznum), p, 1) = "0"
        Next
        GoTo Start 'SPACE resets puzzle
    End If

    If ky$ = Chr$(13) Then 'get a random puzzle to play
        'sets a random new puzzle
        'make sure it's not same as current puznum
        curpuz = puznum
        Do
            puznum = Int(Rnd * puzmax) + 1
        Loop Until puznum <> curpuz
        GoTo Start
    End If

    If ky$ = "+" Then
        puznum = puznum + 1
        If puznum > puzmax Then
            puznum = 1
        End If
        GoTo Start
    End If

    If ky$ = "-" Then
        puznum = puznum - 1
        If puznum < 1 Then
            puznum = puzmax
        End If
        GoTo Start
    End If

    If UCase$(ky$) = "R" Then
        Kill "sudoku.dat"
        GoTo createdat
    End If

    If UCase$(ky$) = "T" Then
        _Delay .25
        If TimerFlag = 1 Then
            Timer Off
            TimerFlag = 0
            'refresh titlebar without time display
            _Title "Sudoku #" + _Trim$(Str$(puznum))
        Else
            TimerFlag = 1
            StartTime = Timer
            Timer On
        End If
        _KeyClear
    End If

    If ky$ = Chr$(27) Then System

    While _MouseInput: Wend

    If _MouseButton(1) Or _MouseButton(2) Then
        mx = _MouseX: my = _MouseY

        'see if a button was pressed
        For T = 1 To cells
            bx = cellx(T): bx2 = cellx2(T)
            by = celly(T): by2 = celly2(T)

            If mx >= bx And mx <= bx2 And my >= by And my <= by2 Then

                If _MouseButton(1) Then

                    'only if clicking no assigned number
                    If cellstate(T) = 0 Then

                        'popup number box here

                        'keep x box values in bounds
                        x1 = cellx(T) + (size / 2) - size
                        If x1 < (size / 2) Then x1 = (size / 2)
                        If x1 + (size * 3) > _Width Then
                            x1 = _Width - (size * 3) - (size / 2)
                        End If
                        x2 = x1 + (size * 3)
                        'keep y box values in bounds
                        y1 = celly(T) + (size / 2) - size
                        If y1 < (size / 2) Then y1 = (size / 2)
                        If y1 + (size * 3) > _Height Then
                            y1 = _Height - (size * 3) - (size / 2)
                        End If
                        y2 = y1 + (size * 3)

                        'highlight the number to change
                        Line (cellx(T), celly(T))-(cellx2(T), celly2(T)), _RGBA(255, 255, 255, 100), BF
                        _Display
                        _Delay .25

                        'wait until mouse button up to continue
                        While _MouseButton(1) <> 0: n = _MouseInput: Wend

                        'draw popup box
                        tk = size * .03
                        Line (x1, y1)-(x2, y2), _RGBA(255, 255, 0, 200), BF
                        Line (x1 + tk, y1 + tk)-(x2 - tk, y2 - tk), _RGBA(132, 62, 32, 164), BF

                        'make temp numbox values (assign and show)
                        ReDim boxx(9), boxy(9), boxx2(9), boxy2(9), boxv(9)


                        'first row
                        '1
                        boxx(1) = x1: boxy(1) = y1: boxx2(1) = x1 + size: boxy2(1) = y1 + size: boxv(1) = 1
                        bx = boxx(1) - (Int(_Height / 9) / 4.5): by = boxy(1) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(1))
                        '2
                        boxx(2) = x1 + size: boxy(2) = y1: boxx2(2) = x1 + (size * 2): boxy2(2) = y1 + size: boxv(2) = 2
                        bx = boxx(2) - (Int(_Height / 9) / 4.5): by = boxy(2) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(2))
                        '3
                        boxx(3) = x1 + (size * 2): boxy(3) = y1: boxx2(3) = x1 + (size * 3): boxy2(3) = y1 + size: boxv(3) = 3
                        bx = boxx(3) - (Int(_Height / 9) / 4.5): by = boxy(3) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(3))

                        'second row
                        '4
                        boxx(4) = x1: boxy(4) = y1 + size: boxx2(4) = x1 + size: boxy2(4) = y1 + (size * 2): boxv(4) = 4
                        bx = boxx(4) - (Int(_Height / 9) / 4.5): by = boxy(4) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(4))
                        '5
                        boxx(5) = x1 + size: boxy(5) = y1 + size: boxx2(5) = x1 + (size * 2): boxy2(5) = y1 + (size * 2): boxv(5) = 5
                        bx = boxx(5) - (Int(_Height / 9) / 4.5): by = boxy(5) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(5))
                        '6
                        boxx(6) = x1 + (size * 2): boxy(6) = y1 + size: boxx2(6) = x1 + (size * 3): boxy2(6) = y1 + (size * 2): boxv(6) = 6
                        bx = boxx(6) - (Int(_Height / 9) / 4.5): by = boxy(6) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(6))

                        'third row
                        '7
                        boxx(7) = x1: boxy(7) = y1 + (size * 2): boxx2(7) = x1 + size: boxy2(7) = y1 + (size * 7): boxv(7) = 7
                        bx = boxx(7) - (Int(_Height / 9) / 4.5): by = boxy(7) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(7))
                        '8
                        boxx(8) = x1 + size: boxy(8) = y1 + (size * 2): boxx2(8) = x1 + (size * 2): boxy2(8) = y1 + (size * 3): boxv(8) = 8
                        bx = boxx(5) - (Int(_Height / 9) / 4.5): by = boxy(8) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(8))
                        '9
                        boxx(9) = x1 + (size * 2): boxy(9) = y1 + (size * 2): boxx2(9) = x1 + (size * 3): boxy2(9) = y1 + (size * 3): boxv(9) = 9
                        bx = boxx(6) - (Int(_Height / 9) / 4.5): by = boxy(9) + (Int(_Height / 9) / 12.5)
                        Color _RGBA(255, 255, 0, 200): _PrintString (bx, by), Str$(boxv(9))

                        _Display


                        'wait until mouse button up to continue
                        While _MouseButton(1) <> 0: n = _MouseInput: Wend
                        'Sleep 1


                        'get click in numbox
                        Do

                            While _MouseInput: Wend

                            If _MouseButton(1) Then

                                mmx = _MouseX: mmy = _MouseY

                                'see if a button was pressed in numbox
                                For tt = 1 To 9

                                    If mmx >= boxx(tt) And mmx <= boxx2(tt) And mmy >= boxy(tt) And mmy <= boxy2(tt) Then

                                        Line (boxx(tt), boxy(tt))-Step(size, size), _RGBA(255, 255, 255, 100), BF
                                        _Display
                                        _Delay .25

                                        'assign picked number with board number
                                        If boxv(tt) = cellvalue(T) Then
                                            cellvalue(T) = 0 'if same, then clear it
                                            Mid$(puz$(puznum), T, 1) = "0"
                                        Else
                                            cellvalue(T) = boxv(tt)
                                            Mid$(puz$(puznum), T, 1) = _Trim$(Str$(cellvalue(T)))
                                        End If

                                        Exit Do
                                    End If
                                Next
                            End If

                            'optional keyboard input
                            k$ = InKey$
                            Select Case k$
                                Case Is = "1", "2", "3", "4", "5", "6", "7", "8", "9"
                                    kv = Val(k$)
                                    If kv = cellvalue(T) Then
                                        cellvalue(T) = 0 'if same, then clear it
                                        Mid$(puz$(puznum), T, 1) = "0"
                                    Else
                                        cellvalue(T) = kv
                                        Mid$(puz$(puznum), T, 1) = _Trim$(Str$(kv))
                                    End If
                                    Exit Do
                            End Select

                            _Limit 200

                        Loop Until _MouseButton(1)

                        'wait until mouse button up to continue
                        While _MouseButton(1) <> 0: n = _MouseInput: Wend

                    End If
                Else

                    'must be right click, so remove number here

                    'only if clicking no assigned number
                    If cellstate(T) = 0 Then
                        cellvalue(T) = 0
                        Mid$(puz$(puznum), T, 1) = "0"
                    End If


                End If

            End If

        Next

        GoSub UpdateBoard

        '===================
        'check for win here...
        'first see if any 0's present (empty cells)
        'and if any conflicts are present
        solved = 1
        For c = 1 To 81
            If cellvalue(c) = 0 Then solved = 0: Exit For
            If Conflict(c) = -1 Then solved = 0: Exit For
        Next

        'if solved = 1 then level solved!.
        If solved = 1 Then
            Line (size * 2, size * 2)-(size * 7, size * 4), _RGBA(32, 32, 32, 200), BF
            Line (size * 2.1, size * 2.1)-(size * 6.9, size * 3.9), _RGBA(250, 200, 200, 200), B
            Color _RGBA(250, 250, 250, 200)
            _PrintString (size * 2.5, size * 2.5), "Solved!!"
            _Display
            _Delay 4
            GoSub UpdateBoard
            _Delay 2
            puznum = puznum + 1
            If puznum > puzmax Then
                puznum = 1
            End If
            GoTo Start
        End If

    End If

    _Limit 200

Loop

End

'==========
UpdateBoard:
'==========

Cls , _RGB(100, 0, 0)

bc = 1
For row = 1 To grid
    For col = 1 To grid
        bx = cellx(bc) - (Int(_Height / 9) / 4.5)
        by = celly(bc) + (Int(_Height / 9) / 14.5)
        'if value not a zero...
        If cellvalue(bc) <> 0 Then
            'shadow
            Color _RGB(0, 0, 0)
            _PrintString (bx + (size * .03), by + (size * .03)), Str$(cellvalue(bc))
            'if assigned puz number
            If cellstate(bc) = 1 Then
                Color _RGB(230, 130, 80)
            Else

                'check if conflict on row or column here <<<<<
                If Conflict(bc) = -1 Then
                    'red color
                    Color _RGB(255, 64, 64)
                Else
                    Color _RGB(255, 180, 125)
                End If

            End If
            _PrintString (bx, by), Str$(cellvalue(bc))
        End If
        Line (cellx(bc), celly(bc))-(cellx2(bc), celly2(bc)), _RGB(200, 100, 50), B
        bc = bc + 1
    Next
Next

'draw thicker lines
tk = size * .03
Line (0, size * 3 - tk)-(_Width, size * 3 + tk + tk), _RGB(0, 0, 0), BF
Line (0, size * 3 - tk)-(_Width, size * 3 + tk), _RGB(200, 100, 50), BF
Line (0, size * 6 - tk)-(_Width, size * 6 + tk + tk), _RGB(0, 0, 0), BF
Line (0, size * 6 - tk)-(_Width, size * 6 + tk), _RGB(200, 100, 50), BF
Line (size * 3 - tk, 0)-(size * 3 + tk, _Height), _RGB(200, 100, 50), BF
Line (size * 6 - tk, 0)-(size * 6 + tk, _Height), _RGB(200, 100, 50), BF

For f = 0 To (size * .06)
    Line (0 + f, 0 + f)-(_Width - f, _Height - f), _RGB(200, 100, 50), B
Next
_Display

'====== Update sudoku.dat with changes

Open "sudoku.dat" For Output As 1
For p = 1 To puzmax
    Print #1, puz$(p);
Next
'save current puzzle place#
Print #1, MKL$(puznum);
Close 1

Return


'=========
TitleTimer:
'=========

Elapsed = Timer - StartTime
secs = Elapsed
If Elapsed >= 60 Then
    Mins = Fix(Elapsed / 60)
    secs = Elapsed - (60 * Mins)
End If
If Mins >= 60 Then
    Hrs = Fix(Mins / 60)
    Mins = Mins - (60 * Hrs)
End If

secs = Fix(secs)

Hrs$ = _Trim$(Str$(Hrs)): If Len(Hrs$) = 1 Then Hrs$ = "0" + Hrs$
min$ = _Trim$(Str$(Mins)): If Len(min$) = 1 Then min$ = "0" + min$
Secs$ = _Trim$(Str$(secs)): If Len(Secs$) = 1 Then Secs$ = "0" + Secs$

tit$ = Hrs$ + ":" + min$ + ":" + Secs$

_Title "Sudoku #" + _Trim$(Str$(puznum)) + " - " + tit$

Return


Function NewPuz$

    'generates different sudoku puzzles using randomizing techniques
    'and from a pool of pre-made solved sudoku puzzles.

    'select from a pool of 15 puzzles
    p = Int(Rnd * 15) + 1
    If p = 1 Then p$ = "564973128819624375372815946247356891938741652651289734126597483495138267783462519"
    If p = 2 Then p$ = "743589162219634758856271349137956284684723591592148673368417925475392816921865437"
    If p = 3 Then p$ = "395842716762931845841765293986123457417589362253476981674218539538697124129354678"
    If p = 4 Then p$ = "954182367163794258278563194749625813681379425532418976426851739395247681817936542"
    If p = 5 Then p$ = "387142695954386271126957483571263948248579316639418752893721564462895137715634829"
    If p = 6 Then p$ = "859643271371925684264187359927316845543872916618594723735261498192438567486759132"
    If p = 7 Then p$ = "547368291296751348183429675871543962965872134432196587714935826328617459659284713"
    If p = 8 Then p$ = "329654817761389524584712369843971652615423798972865143458197236296538471137246985"
    If p = 9 Then p$ = "254376819178594362369281745495762138632819457781453296513628974846937521927145683"
    If p = 10 Then p$ = "184597362923684571765132489649273815518469723237815694472958136391746258856321947"
    If p = 11 Then p$ = "314872695857469321296135748529741863731986452468523917943217586175698234682354179"
    If p = 12 Then p$ = "248931657637852914915647238586423791194768523372519846853274169429186375761395482"
    If p = 13 Then p$ = "734521986962873145158469372345796821817235469629184537571648293283917654496352718"
    If p = 14 Then p$ = "795243618138659427624178539263497185549812763871536294452981376917365842386724951"
    If p = 15 Then p$ = "416598723259743861873162495624815379791324586385679214962437158148256937537981642"

    'load selected puz$ into cellvalue()
    For c = 1 To 81
        cellvalue(c) = Val(Mid$(p$, c, 1))
    Next

    '========== swap rows

    'swap top 3 rows randomly
    Select Case Int(Rnd * 4) + 1
        Case 1 'swap row 1 and 2
            For s = 1 To 9: Swap cellvalue(s), cellvalue(s + 9): Next
        Case 2 'swap row 1 and 3
            For s = 1 To 9: Swap cellvalue(s), cellvalue(s + 18): Next
        Case 3 'swap row 2 and 3
            For s = 10 To 18: Swap cellvalue(s), cellvalue(s + 9): Next
    End Select

    'swap middle 3 rows randomly
    Select Case Int(Rnd * 4) + 1
        Case 1 'swap row 4 and 5
            For s = 28 To 36: Swap cellvalue(s), cellvalue(s + 9): Next
        Case 2 'swap row 4 and 6
            For s = 28 To 36: Swap cellvalue(s), cellvalue(s + 18): Next
        Case 3 'swap row 5 and 6
            For s = 37 To 45: Swap cellvalue(s), cellvalue(s + 9): Next
    End Select

    'swap bottom 3 rows a few times
    Select Case Int(Rnd * 4) + 1
        Case 1 'swap row 7 and 8
            For s = 55 To 63: Swap cellvalue(s), cellvalue(s + 9): Next
        Case 2 'swap row 7 and 9
            For s = 55 To 63: Swap cellvalue(s), cellvalue(s + 18): Next
        Case 3 'swap row 8 and 9
            For s = 64 To 72: Swap cellvalue(s), cellvalue(s + 9): Next
    End Select

    '============ swap columns

    'swap left 3 columns
    Select Case Int(Rnd * 4) + 1
        Case 1 'swap column 1 and 2
            For s = 1 To 73 Step 9: Swap cellvalue(s), cellvalue(s + 1): Next
        Case 2 'swap column 1 and 3
            For s = 1 To 73 Step 9: Swap cellvalue(s), cellvalue(s + 2): Next
        Case 3 'swap column 2 and 3
            For s = 2 To 74 Step 9: Swap cellvalue(s), cellvalue(s + 1): Next
    End Select

    'swap middle 3 columns
    Select Case Int(Rnd * 4) + 1
        Case 1 'swap column 4 and 5
            For s = 4 To 76 Step 9: Swap cellvalue(s), cellvalue(s + 1): Next
        Case 2 'swap column 4 and 6
            For s = 4 To 76 Step 9: Swap cellvalue(s), cellvalue(s + 2): Next
        Case 3 'swap column 5 and 6
            For s = 5 To 77 Step 9: Swap cellvalue(s), cellvalue(s + 1): Next
    End Select

    'swap right 3 columns
    Select Case Int(Rnd * 4) + 1
        Case 1 'swap column 7 and 8
            For s = 7 To 79 Step 9: Swap cellvalue(s), cellvalue(s + 1): Next
        Case 2 'swap column 7 and 9
            For s = 7 To 79 Step 9: Swap cellvalue(s), cellvalue(s + 2): Next
        Case 3 'swap column 8 and 9
            For s = 8 To 80 Step 9: Swap cellvalue(s), cellvalue(s + 1): Next
    End Select


    '====== now swap blocks of rows (3)

    Select Case Int(Rnd * 4) + 1
        Case 1 'swap top row of blocks with and middle row
            For s = 1 To 9
                Swap cellvalue(s), cellvalue(s + 27)
                Swap cellvalue(s + 9), cellvalue(s + 36)
                Swap cellvalue(s + 18), cellvalue(s + 45)
            Next
        Case 2 'swap top row of blocks with bottom row of blocks
            For s = 1 To 9
                Swap cellvalue(s), cellvalue(s + 54)
                Swap cellvalue(s + 9), cellvalue(s + 63)
                Swap cellvalue(s + 18), cellvalue(s + 72)
            Next
        Case 3 'swap middle row of blocks with bottom row of blocks
            For s = 28 To 36
                Swap cellvalue(s), cellvalue(s + 27)
                Swap cellvalue(s + 9), cellvalue(s + 36)
                Swap cellvalue(s + 18), cellvalue(s + 45)
            Next
    End Select


    '====== now swap columns of blocks

    Select Case Int(Rnd * 4) + 1
        Case 1 'swap left block column with middle
            For s = 1 To 73 Step 9
                Swap cellvalue(s), cellvalue(s + 3)
                Swap cellvalue(s + 1), cellvalue(s + 4)
                Swap cellvalue(s + 2), cellvalue(s + 5)
            Next
        Case 2 'swap left block column with right
            For s = 1 To 73 Step 9
                Swap cellvalue(s), cellvalue(s + 6)
                Swap cellvalue(s + 1), cellvalue(s + 7)
                Swap cellvalue(s + 2), cellvalue(s + 8)
            Next
        Case 3 'swap middle block of columns withright one
            For s = 4 To 76 Step 9
                Swap cellvalue(s), cellvalue(s + 3)
                Swap cellvalue(s + 1), cellvalue(s + 4)
                Swap cellvalue(s + 2), cellvalue(s + 5)
            Next

    End Select

    '=========== swap some numbers..

    Select Case Int(Rnd * 5) + 1
        Case 1 'swap 1's and 5's
            For c = 1 To 81
                Select Case cellvalue(c)
                    Case 1: cellvalue(c) = 5
                    Case 5: cellvalue(c) = 1
                End Select
            Next
        Case 2 'swap 2's and 6's
            For c = 1 To 81
                Select Case cellvalue(c)
                    Case 2: cellvalue(c) = 6
                    Case 6: cellvalue(c) = 2
                End Select
            Next
        Case 3 'swap 3's and 7's
            For c = 1 To 81
                Select Case cellvalue(c)
                    Case 3: cellvalue(c) = 7
                    Case 7: cellvalue(c) = 3
                End Select
            Next
        Case 4 'swap 4's and 8's
            For c = 1 To 81
                Select Case cellvalue(c)
                    Case 4: cellvalue(c) = 8
                    Case 8: cellvalue(c) = 4
                End Select
            Next
        Case 5 'swap 9's and 1's
            For c = 1 To 81
                Select Case cellvalue(c)
                    Case 1: cellvalue(c) = 9
                    Case 9: cellvalue(c) = 1
                End Select
            Next
    End Select

    t$ = ""

    'Build NewPuz$, clearing some pieces
    For c = 1 To 81
        If Int(Rnd * 2) = 1 Then
            t$ = t$ + _Trim$(Str$(cellvalue(c)))
        Else
            t$ = t$ + "0"
        End If
    Next

    e$ = ""
    For c = 1 To Len(t$)
        If Mid$(t$, c, 1) = "0" Then
            e$ = e$ + "0"
        Else
            e$ = e$ + "1"
        End If
    Next

    t$ = t$ + e$

    NewPuz$ = t$

End Function



Function Conflict (num)
    'this function checks rows/columns/blocks for any conflicts.
    'p$ holds all the other cell numbers to compare 'num' with.
    Select Case num
        'first row, 01-09
        Case 1: p$ = "0203040506070809101928374655647311122021"
        Case 2: p$ = "0103040506070809112029384756657410121921"
        Case 3: p$ = "0102040506070809122130394857667510111920"
        Case 4: p$ = "0102030506070809132231404958677614152324"
        Case 5: p$ = "0102030406070809142332415059687713152224"
        Case 6: p$ = "0102030405070809152433425160697813142223"
        Case 7: p$ = "0102030405060809162534435261707917182627"
        Case 8: p$ = "0102030405060709172635445362718016182527"
        Case 9: p$ = "0102030405060708182736455463728116172526"
            'second row, 10-18
        Case 10: p$ = "1112131415161718011928374655647302032021"
        Case 11: p$ = "1012131415161718022029384756657401031921"
        Case 12: p$ = "1011131415161718032130394857667501021920"
        Case 13: p$ = "1011121415161718042231404958677605062324"
        Case 14: p$ = "1011121315161718052332415059687704062224"
        Case 15: p$ = "1011121314161718062433425160697804052223"
        Case 16: p$ = "1011121314151718072534435261707908092627"
        Case 17: p$ = "1011121314151618082635445362718007092527"
        Case 18: p$ = "1011121314151617092736455463728107082526"
            'third row, 19-27
        Case 19: p$ = "2021222324252627011028374655647302031112"
        Case 20: p$ = "1921222324252627021129384756657401031012"
        Case 21: p$ = "1920222324252627031230394857667501021011"
        Case 22: p$ = "1920212324252627041331404958677605061415"
        Case 23: p$ = "1920212224252627051432415059687704061315"
        Case 24: p$ = "1920212223252627061533425160697804051314"
        Case 25: p$ = "1920212223242627071634435261707908091718"
        Case 26: p$ = "1920212223242527081735445362718007091618"
        Case 27: p$ = "1920212223242526091836455463728107081617"
            'forth row,28-36
        Case 28: p$ = "2930313233343536011019374655647338394748"
        Case 29: p$ = "2830313233343536021120384756657437394648"
        Case 30: p$ = "2829313233343536031221394857667537384647"
        Case 31: p$ = "2829303233343536041322404958677641425051"
        Case 32: p$ = "2829303133343536051423415059687740424951"
        Case 33: p$ = "2829303132343536061524425160697840414950"
        Case 34: p$ = "2829303132333536071625435261707944455354"
        Case 35: p$ = "2829303132333436081726445362718043455254"
        Case 36: p$ = "2829303132333435091827455463728143445253"
            'fifth row,37-45
        Case 37: p$ = "3839404142434445011019284655647329304748"
        Case 38: p$ = "3739404142434445021120294756657428304648"
        Case 39: p$ = "3738404142434445031221304857667528294647"
        Case 40: p$ = "3738394142434445041322314958677632335051"
        Case 41: p$ = "3738394042434445051423325059687731334951"
        Case 42: p$ = "3738394041434445061524335160697831324950"
        Case 43: p$ = "3738394041424445071625345261707935365354"
        Case 44: p$ = "3738394041424345081726355362718034365254"
        Case 45: p$ = "3738394041424344091827365463728134355253"
            'sixth row,46-54
        Case 46: p$ = "4748495051525354011019283755647329303839"
        Case 47: p$ = "4648495051525354021120293856657428303739"
        Case 48: p$ = "4647495051525354031221303957667528293738"
        Case 49: p$ = "4647485051525354041322314058677632334142"
        Case 50: p$ = "4647484951525354051423324159687731334042"
        Case 51: p$ = "4647484950525354061524334260697831324041"
        Case 52: p$ = "4647484950515354071625344361707935364445"
        Case 53: p$ = "4647484950515254081726354462718034364345"
        Case 54: p$ = "4647484950515253091827364563728134354344"
            'seventh row, 55-63
        Case 55: p$ = "5657585960616263011019283746647365667475"
        Case 56: p$ = "5557585960616263021120293847657464667375"
        Case 57: p$ = "5556585960616263031221303948667564657374"
        Case 58: p$ = "5556575960616263041322314049677668697778"
        Case 59: p$ = "5556575860616263051423324150687767697678"
        Case 60: p$ = "5556575859616263061524334251697867687677"
        Case 61: p$ = "5556575859606263071625344352707971728081"
        Case 62: p$ = "5556575859606163081726354453718070727981"
        Case 63: p$ = "5556575859606162091827364554728170717980"
            'eight row, 64-72
        Case 64: p$ = "6566676869707172011019283746557356577475"
        Case 65: p$ = "6466676869707172021120293847567455577375"
        Case 66: p$ = "6465676869707172031221303948577555567374"
        Case 67: p$ = "6465666869707172041322314049587659607778"
        Case 68: p$ = "6465666769707172051423324150597758607678"
        Case 69: p$ = "6465666768707172061524334251607858597677"
        Case 70: p$ = "6465666768697172071625344352617962638081"
        Case 71: p$ = "6465666768697072081726354453628061637981"
        Case 72: p$ = "6465666768697071091827364554638161627980"
            'ninth row, 73-81
        Case 73: p$ = "7475767778798081011019283746556456576566"
        Case 74: p$ = "7375767778798081021120293847566555576466"
        Case 75: p$ = "7374767778798081031221303948576655566465"
        Case 76: p$ = "7374757778798081041322314049586759606869"
        Case 77: p$ = "7374757678798081051423324150596858606769"
        Case 78: p$ = "7374757677798081061524334251606958596768"
        Case 79: p$ = "7374757677788081071625344352617062637172"
        Case 80: p$ = "7374757677787981081726354453627161637072"
        Case 81: p$ = "7374757677787980091827364554637261627071"
    End Select
    For c = 1 To Len(p$) Step 2
        chk = Val(Mid$(p$, c, 2))
        If cellvalue(chk) = cellvalue(num) Then Conflict = -1
    Next
End Function

Sub BIGFONT (size)
    'make/load another CP437 font (like QB64's built-in one)'
    'This one is resizable so you can make/use larger size SCREEN font.
    A$ = ""
    A$ = A$ + "haIgm]0MLEMMXkS^ST\\T]lHiaboe<Nl8c71HYa3f0VPiWa9H07n5a_0bn:K"
    A$ = A$ + ";#FB8;c773hBD8T42E_#C:=QBC39PSQB=DB2UhdhVBB^9=_D2EQ#Ala?JFmi"
    A$ = A$ + "ejeGKNiYTV4\UNkOWcmL791Y0Iefg<NdmNWiLfWmIoO_?WkeP10H6`NP0HS["
    A$ = A$ + "KMGj5l9Nf7lH0HC;3of5MAGb9ef>>V6V60Vfa[_^=_m>j[Y]NOC7PDY`?kKc"
    A$ = A$ + "gd0IQB1o20VfnaO?eFkH7m=nh8TP=]8ljY]e^_e]DhRj<;0CoG1`5>lfj\S`"
    A$ = A$ + "IOn5Z6o]G6oLbK3oRZONcW6QoL`[Gfffn0gBQ5]P_=NmC3#5__^kMcMlg=[o"
    A$ = A$ + "a=RPjY`[?W]ga]dWICVEPonZafW]W>fNWObWOGk3P[h7POg7[_Nga07oM<8f"
    A$ = A$ + "f[2agZnF0=g`?kjkmmOT[]nel;PVZJ]hg0?OKcLadaGiKoLOB06[_P\Y8lOJ"
    A$ = A$ + "#5Pl2kCZm?FO04TU^4o[1Bn:5m=VLhOH8jj9mj4UF4Te<4D9R7[U6eP\fS#H"
    A$ = A$ + "5]c]X6G?2l1mUORGl9Rl3CcgPP3Yf?27leNXQi017VViP9PXlI5<D`Bg[8lC"
    A$ = A$ + "8OFXkk2MW7jMNL?lKIT21l_VF:3>F2D;LOV8TRaP9n:<aIA^f=aF7iJaK2<#"
    A$ = A$ + "L8<Ak3Q9<_mJcKe[TDPTc\936fA:ngRlXaf?Q:5<^GQ:NaoU>Jo437Vj6iV1"
    A$ = A$ + "CjiCm;DJYL^oDO^mEPnIARTN`G4_b`GW:h^aS?8:nE5\4h>P72nB`S0?6lT`"
    A$ = A$ + "G3n6`g4n^`g3nA`;PJd_>l_2S2oK`APa=OZPk;hn3NXP7>h;7l41OUP36l\1"
    A$ = A$ + "OW\;=kJbN7IOTLOjLkMY;HY=]dSMY[OYM\d>cGAnIU?G1X#55Z[`\:<W2c[`"
    A$ = A$ + "R:\\2]DHU5FCQ^;\W23Fh^;L?5^_2On2?FQW\`cDh05Nf2o]5n7JN==_fV?["
    A$ = A$ + "V_^VgLcKYiK0]l#_nl<n]?Ho`G1N64oNF7nmJ`?5no0oBhG?1lkY#lk_a3o6"
    A$ = A$ + "2a_i_dUXhG8SOIW2lKS>lKXb`_G\iCeQOMfleChgho?6o#SoJSo:SoBSoRSo"
    A$ = A$ + "2SoS7o7=nc=ngKl_mh7LloZao6SOPaojSo<SodSglAKnX;mXckXcmXciXchX"
    A$ = A$ + "eNDcA6o8SMX7j#Ol3]n3Uke>UGKi_jGkEOZGmAOe?i[^cGM7_b?iEnn_bGOT"
    A$ = A$ + "GITGNTonAN^An_?bgOT_k87LTobANbANdA^oAn8SLWSL7S\kA^eAfn8KJT[I"
    A$ = A$ + "T;OT;KT;LTe?bJNYGnUn7NYGlUnj_dOi;md_dG1if?hKUTeoQnbPBTY#kYE1"
    A$ = A$ + "ESFZ[1V>D;D7jiJVX]gjQI1YQI3=0c1b0c5J4V7<OH1`2Aig5SB]=QF<c1;5"
    A$ = A$ + "b3;3:0=3;7>6hHQS3>NX5h4#keW4\2XEX=X8\BX4Lb`ZPE3W2LZ`Y1[1>Mhm"
    A$ = A$ + "0W1JUo<Qc2>KhLPc5F7LN`jQg;lnPc7f0L1`52G4\Ahm3G<L9`U2G6Li`70J"
    A$ = A$ + "7^2h:Q[2^JhJP?8L]`e1M0K2f<Zke9\5H[`fP^P[7^1XKHk#?#_#O`=2m3k0"
    A$ = A$ + "60f9LC`=3g2L[`^P?4\KhfPK7ejf3B0Z2o4TZbZZNJe<mJ[K6c\RjWEjIg`L"
    A$ = A$ + "b<g6WglG`2GdRGBCIc]dl;[#c;oH>fSkhKi4>aCJ5]fFaEFjTGeZ?UCmdFcY"
    A$ = A$ + "oN>SeNVWeIO>Wkj>_eoNOOWo6^P;lRfhkoR_T;mb^l?#kGaENEGmel1_f[[S"
    A$ = A$ + "=]i`>gbFgFGGo=dmfkYgn^anga0klV^iKiFge7Jggf]O7kiCoI^ooX?kWk1n"
    A$ = A$ + "CN`?oO:l5nR?lGjAfknnb?jSmWmWohko9PWj_h[lEQ?n7N`kjKO_oa2;k?4N"
    A$ = A$ + "n?a?i5o8X?Fh_6nX3m=N8h?h>oHoXWn73gmo=hgcSeBVBdGon_Ub1Ll68O[5"
    A$ = A$ + "Tn_7d>d?4niViJ>Ec5J^NcmJN6coD5c\REDAgEL?ElHEllElc2VE`E7\]P?E"
    A$ = A$ + "`S5lM2NmD#ZIUJUYf#Z#lmNBMoYNfDoZ:?V:_^:k_bQZlaZliZlWFi_\Z:ZJ"
    A$ = A$ + "VEeFEQE][ZfKE?GEoZZWGe[Yj[^jk^j7_j3Fm;<]:VfLWfI=]]<]kJJ?nd6N"
    A$ = A$ + "JSECfJFG=K[Vk_VmGcgYV3=mY=mU>me>m?hdgedo\Co_Jj_N]cZfFZm\Z=\f"
    A$ = A$ + "k\f7_fOH]7Y^IFg:[KMe]Ujj_^1[K_emm[k`cX^I\RILYcHgch1VaGM63?SO"
    A$ = A$ + "c<Wi<?^I^^I^YINGcLOc<JVobjWKm]Eo6Zoj[ocDoG]nG]naVe\Ve9>[e?[^"
    A$ = A$ + "aggm\NlIm2YQdK8MgYO`d?NjXd_n\[JfIWmJWm5>knVmGHf_D3;ZQef`0=lH"
    A$ = A$ + "=llcYZidfLfdL^WilhcIh<EUIeIj9c3TIhi2cmHVkE>g?nL?hLoI=>k6GISG"
    A$ = A$ + "ISkZamfhcghAVga=_;MNM?_?cl>hlnGVoLWoI=o]=oM=om=oGL1YF`:F#k;h"
    A$ = A$ + ">G`3_P3\PGL1S^`U^`CNQGj2kKQ?h2?`2OQ5ncGDM;J5;jbGdNFdm^Xm]XO`"
    A$ = A$ + "RNi5mcGlBFlZGLhR_g5oT;nK]hGLao;;ng\TY]Ti]TSI9WjBf`B^^U<`B^[U"
    A$ = A$ + "lIGbC]TXUlB;iWeDE=U]YEfdjKjjJjVJjNJjQKj0=ml=m?W=Ef5UmmTmbcfG"
    A$ = A$ + "fk=k3Wm0IOi\obLc<g9VKSij;g3TKOiNjLOWL3WkeGj3^\Y]\WJIO[Um3Gfo"
    A$ = A$ + "DQZ:\T2_W2KZ`]GHO5>DceeljK^_VOPV?HcodUGeb?^U_nUOmXESBXnd[Vjh"
    A$ = A$ + "#k:E3WhCHPCJ=?IeYPog]m4EEi;_VW<X2lDh92X_^Bj[ObZ[bLTelT6jk;V>"
    A$ = A$ + "Gj2iBW[Ti;?fmH>San[CML_a;D:hPP69H#F<>]JAkB#YRUX6W;Mn<i<I:F:4"
    A$ = A$ + "SnK\n27KHc#AAQELPa6nXk=<H`#fYLe^n6`m^1dBf2A[G#Yd5Cg#YLIbW9OY"
    A$ = A$ + "PB5cT;OYR=T?MAC^<iBSOOHXIX`8l_]4B7>jiDAk7M_EdNH#fSL8jkTO1oNj"
    A$ = A$ + ";TQ;U7N:S3=:8\:BXJY6bD4afRU:D\Dn:;U?3RfHog;1N4mYQ31NH82=nLNH"
    A$ = A$ + "i917o06WJF4V`l=8<b`O#Xb_;A_aFc]WA<Yo4DE#``8TQ1REY9BH966lk4`a"
    A$ = A$ + "oU0WhGalR1AJY5K4h#<Td1jE4b4=f`AdTPR9S>1I#]<f`S=L8bUdHR8h<5h3"
    A$ = A$ + "bA`_QaW8QHPCW8T5;H2?KIhPa_EAkHloe2#1J28P9_ID^1J39lFc:9PTQV_9"
    A$ = A$ + "GJS`>`nT9O#FTA49SBE[mGO`:>0gIJn6Bd]:>02OLn^ZHniYkgOQDAH8?Rj5"
    A$ = A$ + ":CTWZ96o5ZH0=7CWWT2CgPRg4KP`678laZf]SS:EZl3>76[D]B;AXVVA]<5E"
    A$ = A$ + "i_CcT>O2^:Q^Af[6[_8ETQc=RVg2LIiHBc#Whi]H9=8[2oV85RAd;jPIdHT?"
    A$ = A$ + ":D08RWSo0\^1Y32\6<2UdjARBPTIJVRb7\43ZG]KFDnXWCH`QYiJE>IV0E;>"
    A$ = A$ + "?6g1#<RUc65`g2bQBRi;QOG63nQd^[4IE4f55ZoQ\E4=FMAR#29HBcND2U^d"
    A$ = A$ + "Z>jYkPdRDKPT0J=]E:eCc1O;<KFj<e6BXbT\o>IM6S5M>jMDLG<S:7OSWBPP"
    A$ = A$ + "AT1IN<\:R`W>_Wn2B4EmGNfa2<j7a#5=a\cUD>n:ISV]W^:\kXNLj6eS2STN"
    A$ = A$ + "IJYR3PDOmXWMhIPa62iHb<=58I3\SXL[P1H[AcJ13NTMSC5478iE#U1Hj#A<"
    A$ = A$ + "n?XEbZ[Kn[ZBUHa\<iiojK=P>R>7\:LT=6QII9IATTSNiHeIWiFM`9LQdi8?"
    A$ = A$ + "n3:V6#lgLYYc7[?V^;dZVNcXkRUZTdnS^g9BnEI1;<A:O39PFndZfN4ImQNQ"
    A$ = A$ + ">M>#imIEZL^eRMXXd5BNn#NU_<K4KgZ1BVSXcNB\hX:NgHkcN6i;_O2nQDn<"
    A$ = A$ + "2GQ\7CmP]dUXSNSIkD=J8o[i#NdXXZ6>oCRCaflcD<1NYc9oGZ]5WnU__\jI"
    A$ = A$ + "]o4n>L\IA782:[mY5On>oMFJM5]K=OQbYH_ZXMKl6=TFmfVVD?bTGlXPLYf9"
    A$ = A$ + "n;iA3=OdG4KcTVMXlMUTgX6HeK3KcT=b#n^B]1TdaVKR]M?XHknd=ZlUBCDi"
    A$ = A$ + ";VVD`:MXl<AfWn3Qd\?EbD>2GIn>nZAlHoF[SX4:6HEndNBK\o1[1MQVCc2;"
    A$ = A$ + "UV2VBXgReMNTHCS3[^=0]6KJ<5T]H`gdF9OSST9IbJLa<iC`KYiADTcU^SA`"
    A$ = A$ + "TC?OK5`L;EOK>;4TVG9U:EB=3aF84KaR^WXB:aN8RBjg8fhKQ?#SX8O6BJn8"
    A$ = A$ + "o3SJd`Z9HlPTNB45H6K3chT=J#R6#WXY]DE;la>A^[U8l\j7Nm=fnOa<fHiR"
    A$ = A$ + "B#6\MFdK2b6[gTGUA4Ga5EI4a6ThQ;:JBRMS\S4YabDN\Bj;=f\XaO0d9N;4"
    A$ = A$ + "M8W#6BCB_ZWBEGf<4B]6UT28M:RbAh:Gk]AaI:nm5`n:`f;6f5nV;WDVlAR3"
    A$ = A$ + "NbL4=DTiHN#>7=T\dMJDJ15U`OJ0AO[dPe>\85hcN4j]8fiI_M6<ObJe7iaF"
    A$ = A$ + "?[LOahCLc[3ChB[YSWF<Mc9Y:_Ao4Rm9:bH[GND3`9[6;kh5gQhgWdS9]HB["
    A$ = A$ + "EQ<>OU8kR8^2ma2eaZ;dZf6JeI3mdWbT8ZKNV9J?5C_lRUD^P6?HTed53FR4"
    A$ = A$ + "bfNBPO=h`_dDjCil`[j`4bZSS7D`941W8n#I;ihT<UBQ#A4H<9:D11KjD\IK"
    A$ = A$ + "CK:9N8aCb^CUY62#^mA2M?h`D_`8B6RW8#IbD^\fR3h=6C:aHC<=fBf]TJMR"
    A$ = A$ + "aGU`nE3fLUbiTB9J]>oHhaad[n64?;RgLl<2HE#eMg<:Zo#a]AJ_\HYXMaVA"
    A$ = A$ + "1a_5gVZI=l<R2>g^Q4S2BhiAabh3Bb]=<1EAG\G9R?e575ORE0>QAV:Xjccf"
    A$ = A$ + "HHlTb`f#IC;I?c6QKaJ;b=n[bUcR6;h4S_f5OLBLXlQ_LJNjHM#EP8GV68_#"
    A$ = A$ + "<b;ncXh]TT\h`oY\2RU]7TcF9>[?j<B6_431DNRlDRR2T869A<D4afBR7;dc"
    A$ = A$ + "b#6eJOjLH2PfL7UiShS:<>h?:<;>=f4bXB=<XXWi<7]BX5Hi1:3?a^6RJ43W"
    A$ = A$ + "LLEVHYWnBCnf?c;XCJ9]fRZ]DK0Haf3Hh7I=M69fU[`3ola>ENOiZmH[DS`l"
    A$ = A$ + "8TC=0S0=Ym>52B6BYe^[Zd2AbI_413IFRVVb<5MA53[6WBHUa3>C4:ncYi3i"
    A$ = A$ + "V2:5CSZ<_0N?J5IDHD^#0UA_TX>Z;9OXFF21=MaB6YiXR6KHbDUIXS<?cXff"
    A$ = A$ + "77G:DXHLa38KZ^DF9RZ?\[GR5gFW1f^LT]L5Te6KAWVLj_TG][>2<UcEE\Hj"
    A$ = A$ + "_6D[Z4A;bJIhPER8V7ZIPH7NGL5afbeL]U8UBcaYVF\QAmk`dhOTi9EAKZjK"
    A$ = A$ + "66kE>ObnJJ19]3YM^2?NAm9[KWc6]emS5SY59fG^_QTJU8];CPCSTT]BX?BF"
    A$ = A$ + "3ULRGM\NClhFTmALJ6>e3[?RQU8HLh#TVhg4\kEVe1JnCYfK]>4iQ;A\_#d?"
    A$ = A$ + "=S?9RWAlY7WQNIIVKmac\A_<`AjDT4CCTV76?k;;ggdiLa\C#B#<>Ll3`DIb"
    A$ = A$ + ">:ZNF^NB9[NR<fAdXAEJPnT#6Flh:FcBW\FYNnbdBL4WlLHIbAR^SlfV=VdO"
    A$ = A$ + "jM`PXIJbSm1`AgEGC;m;^X6IR=ZV?faJ6_8]LJCf8am>9A<Y=`ITJa7;m[TU"
    A$ = A$ + "#cic`N>XTdEc2`KJLZIbK3Jb6U:[OZ\=eOTee]Omb47XNfUZF\;AaLQN29L8"
    A$ = A$ + "REflmWbend_6JnE1[\LoU86\HR`MPb6?f:5Vgg#Al<65Z?blHn0Ua4V3LSCB"
    A$ = A$ + "mUER_ec[eETGL4L>d1I7o18?_I#Z4EK;nkS26d<:2G:7A1DfL4?LHRhfAeB["
    A$ = A$ + "6=m>CAKVZ<?C2NTC8=RmF8QZGWUhV`Vd<dZhTfYgUF[^#;R27ak36DLPe7Y?"
    A$ = A$ + "L8V[kS;aaaTAXHR7NEaEeTlBO`GFNnaEFVm98c3Ej;D[4AXjfSWCTbXjFb>?"
    A$ = A$ + "#L8=ViQ3;RaQ6#b3gjj\XA;RoC6PQZ8\R?];hSHQ[HJ??bJF<FYEE1O8[c:["
    A$ = A$ + "KM2>T6[T?M6>GjLJlnD1YUZ:8n9UdMdBOd774Th9Pn;kd\<O7=hiiTZZ_Fi8"
    A$ = A$ + "5SHC6\gBbN;ijQfhBaeKZVh<>Yn;EKR3HHh8NTYEfj`B]A2YiP]F\D6_B<8D"
    A$ = A$ + "09LMFhj1a>VYBMCZ58;9enSPYd?OiVWV<ole9G`5M:Y^H=naTHS8Y5YKnbQY"
    A$ = A$ + "iJ\JG1;m=;o#S1K]iXk53iQ<PEWW\CeBekTNYN9C79NJR\4C;9e[O_enceca"
    A$ = A$ + "Snb6X^;CCe#8\MW4L5:P;S?^j#R81ijcZg53WBU9K9E<V]1H5]2MhQEb:Z<m"
    A$ = A$ + "g<>In<>INENgYoIS^VC=f[_FOiUVBOiIVJOiClE2ObILfG5m?KV3YSdj7B9\"
    A$ = A$ + "g^LDP6AW;S_bNIY8NTJKcJNT]P8>aa#m_an1anE?Go]d>Okne2WRHVnT`O^c"
    A$ = A$ + "6hKRol:JW\1QSmXJIkB#3K=I=kV#]o\nDBh?ggHD\G\HiS6lSYA[<#9=fV#^"
    A$ = A$ + "d9L`RTL=9FTTnSmOaNeC;?cBCF`YLR4Qc=>VPJDH<bilIi7OQJG=?7m8;gTV"
    A$ = A$ + "5bRc\9Ai>0Yn4D]7TeERFK8^4:Bm9Xf?DIS1;_`e]Em<Ba065:EffEdIWAKe"
    A$ = A$ + "O^4kXVE_EB;S8n[A577W09SI[kOSN[=Z6eA1M1B]l6M=SlFMDYD5U_N0NBMU"
    A$ = A$ + "Bk]N0l2M;QX7<XG<KYfP^^M9[oNJGmF\aSJ3kSeoL:OAnaDP`RigC^[?QPh;"
    A$ = A$ + "bQPiXk=:Y?`j2C4;NC4o>^Rb^J:cI=8eK?:d?PDFF:bFfN]Z5Jl:oWbeg;PZ"
    A$ = A$ + "L6SG1RgB^ZD5IG\82RiHUG<``i1aag>Z4mb`\f197IGC\Uk_ZHan:;<A_WUL"
    A$ = A$ + "f0\cSX9^Q:LB[jJD9[M65YGndELP89V8MmhYO5W3bJBI;[U5o]:;BlflDg]N"
    A$ = A$ + "]IUml#[L]hdBnShH#FdBP`751^89f0cXHl]K`_2ai;[Ff5ejH7ib8P;CU7?P"
    A$ = A$ + "SOn1\[iFVBaFL9cCQjRFAa6X6ZSlfK9_MGOI3Y0BKn0:VMS\f3lRBhT1JWU1"
    A$ = A$ + "ZG\a9b09XR<Z4C9EaP#=7\bT3TEN<^NU4UYQ9\>[5;i4:M[NW_0[_P<SWbJg"
    A$ = A$ + "]1N=e>N_egLBF\TPd5W_aE3obbMBCV\\U#QH^SEWhL3]<DfhEl]LlX8J;U?N"
    A$ = A$ + "5hh8I:KLUUWTLEDGi[PSo`kVcCjj08NFMI8`[LHT\D0Lm5dUTT3<F]gVbIST"
    A$ = A$ + "PCC9bd=^^[dND:CJ]f[N[89]MU4lVR:C:R:7::ER\3cD;FJ8NLf?kGQg3:]j"
    A$ = A$ + "_:DNef=M\RC^Ea[<9K8fJdDUeRL[fWTDH2359Y?c?N\\ikT;]DKW<^Z[Z4U\"
    A$ = A$ + "QFoW4AWcUf^f`8\>Fk^gJb[mKA=F4[]<oZ0[aU`NldjXKmEIAj:Ld8JMjR[n"
    A$ = A$ + "G9N_4`^Z<abGdNhk0AlbHAeOG67>XAIa]UJmiA;HhVOb[bG#IA7hZjGDLL23"
    A$ = A$ + "bdNdn1Ao[c2NkNhSUQ\kF`4i>8b>YcI\[Q0Q\bb0akm#IEK8`OTMCeabOmUL"
    A$ = A$ + "`<A=\88FPRR`:Ic#RfDQl6;D#eb[=[GE2Uh#dXBY<=E97aD3eK]ZfJ5L>b^M"
    A$ = A$ + "d`=`B_CI5:J`I:S\<V\J5ZT#i5]##F?Mjgba`G6HB7S9<4I;g^1?6;o]J<:J"
    A$ = A$ + "cHJRSCXHJNZ6YbFoUhm?jT>J1JTDU?:B0RCf8h9OXFCVjIRcMEYL8cObZQT]"
    A$ = A$ + "DBC1[9In#iWPG<iXFoIRNE<ShGAc\B8HF_:AARi;ISiPaDZnlG\=NgL9Re=f"
    A$ = A$ + "VRHQ;bFcBIg\hfdZ2`mX;DMSb=EE>:M2idb[RT:XVXFBNk]_O;73e[8;Y>aa"
    A$ = A$ + "`Vd\g#X62;3n5Vbi`4TAW`HX2Y9W8^P7PHoOX<:=FcWcDH2SVjm;WQUAm65["
    A$ = A$ + "I<oQP;\QGN#T1H96d<D<Xa1kfP[VEan8`NYk4bS<?]fE^LY#HD313_JMi5_A"
    A$ = A$ + "TK[iX4FZ\GnjmflZZQl7F6<lXR>hHC#CPdPN4]0_m3YVK0_SAE8BD;19JA]V"
    A$ = A$ + "BK:E7Hl];D=7cQ[2E;_<_#EZ[3S^;J4o#\>P]ZEN15bUbZ<o6;LREaZL9o9A"
    A$ = A$ + "XGZ[E\0oK=<CHA^LHj1bF:gfX2cVV:HVDjNb4\C2I6fabd_inSEYi988CPDF"
    A$ = A$ + "[<1`J^0JM12dM:1B7;P`Lij>ZH\nhM3X61]gl[JIel]E[bg3I3NE^BMM55Go"
    A$ = A$ + ":EVk87bF8[Y6VNdOc4PYO=a\J4>Pj3c6]gS3Z?Y4LPThZ[d3^R]M0WLhiHag"
    A$ = A$ + "DNbiejh3>?NF8BWkLgU4E]XY\nd1Bm_B\WKV#=`hk;SBLU0RRgQ<lE9;8Vj8"
    A$ = A$ + "5L[KSToJ6AGd_D9YMefgV3AX=GDDUci2b]_k\cINO1Cf4`hDiEVOh8<BZHmo"
    A$ = A$ + "1I^hKjnA[T6>MVlU]Odd\1RlGl5e7[gjV5_o:U#bciE4UbZf77=]]FSnEl;f"
    A$ = A$ + "4CD\MDkn?eFQ:Y4RFlWi0lFCUe6DcDl6Lf5ACLQ=em8YU^ISl?AfATg8MciU"
    A$ = A$ + "FFWaTk>?c#f[i<Gd=IKMne<foN[YDRJ`J_?7R[iRj\LDOlTZ0Mllo`R_bEIW"
    A$ = A$ + "nB>Ki\Y<RI^9cNf?`#jB`kO_CHIKlNA;D[EHSfm7ZM7]Uc]OA2e]d6KFUn8Y"
    A$ = A$ + "oIaE_jmQfX#kCid2Q#ilaaFPJXd2F;iK<i[eAnhki3RW5C5\[dQoHT>I=EiA"
    A$ = A$ + ";S[4Jai2;[7OPFWV1In#>Y^hLdNfL7ejl#5h]AnZ#G#A^K;4k^NTa<nFgRf4"
    A$ = A$ + "KofNoll>lnH#[5DReDJEj2BYkRF^>JfEeQ9HafGYeY[9MM\8Nkl95liKR_k0"
    A$ = A$ + "TMU\^5a\ZLHd#Ad=<fQSRT<?E>^UGlfOOgofiN:h]km7`kTk5QgYkkogm^?H"
    A$ = A$ + "nMbmfQFoaAm[ohXNe_Wm;E_^BndVT#:3E9J?N>T\Fc3Q0<H#:RIIMI8I>I_O"
    A$ = A$ + "[e>8NGT:Jgl^jaNW4Zih[i1Zk?eO[^_<4o0ejEK1dOWFfMak=E>2oJPF_N?;"
    A$ = A$ + "T8:gb[mR;Bg8_c\<HohlXiIRHb>MS\cA=lN;WTJ5kM^=Rb4lOe#nb:JYGn91"
    A$ = A$ + "8D\5OeNXRf;K7\bKFQ9c_X_KgTk<e:]`e1IJgkVXFhl_l^fJAUHM2:akfJJ3"
    A$ = A$ + "F;ke2A6T^?3Um:UA;M0aBhJWC#13=hgl?GiL\aF`kUUJSGGD=f8Y>2S=LZ=#"
    A$ = A$ + "g5Jjnm?8KlnmWNF\8kgOJCZbgGSPQF9oASB]oOm1[J]>L1kCUTn0OoQV5]7R"
    A$ = A$ + "h::>=8_6Xmaj;^el#ZHoAf=olGQdW6R_W9YnccE:LPaZ;enYk9`\Z\;]WbM]"
    A$ = A$ + "Y4e6RlUJoH`Q\Y>;NXkI76>i58=L43ZSL82M]hS]MiEXaE[UVCXNPefY>_ZF"
    A$ = A$ + "X5ac\Q4=57mbK<;9H?Mg3c3J2H9l0;^IK[\mRKAaAk`cn_6R]94HaP2<7QJS"
    A$ = A$ + "N?^8]SbTi0<_Qg]BY?n:TUT5=TY<9UfP`Z6;?RliXl9JQ`aAVBSWae8MNGSB"
    A$ = A$ + "OH?<XY;ZD]VQ8VZ>mUaVQKURT81f:SK?_Y3aV`E8PU6LdO1GB;E0SgK84J`d"
    A$ = A$ + "f`ghYTWL#dlB`3A^9_\NIQFY76;Z#JW57TF^L1V3akjK]eA4L?\WlF=:_8SC"
    A$ = A$ + "VKHA^S3>Gh_AN]]X6D;ALi5:#U#aP=4JQC>^FK[[V38TJ?G70\CN#gG^^6E^"
    A$ = A$ + "^D\\]8D`9oXkI5jNaaQ;i4gb8\Y5h;De4\hR]]FL11K1i>lQJ?=0T`Q2LN_a"
    A$ = A$ + "6[oD[?M9O<UIH;bcJB:_WUm]cglFI?9aHOe>Djdfn:U8i<\LB1VTBi0SBnbJ"
    A$ = A$ + "3PhVJl#fZ6_aCAgFd#2MgJMj^UldOmdQIRV:K`j62>Vg8kCddL50#R#TCWW>"
    A$ = A$ + "0jm`]SfEO\45e?Johakd:i^;FU[8:H5]SXXNoWckgUJS]J8j]\N^XjB2^JNO"
    A$ = A$ + "Z^VfJk>URX5Q>3=\LNP3f9`[22ETlQ:JXSE7?64V9jLQ^m9QcFE]NF[XNZF\"
    A$ = A$ + "8dCHaVA]kEL]?>9JWD7]aTEE0WLGP[m1XDJmF[FDG4n<=GRhHBR4CHbF`Qhb"
    A$ = A$ + "#2kT=4KKXX_\XDd7W09K^#g3#Z=YbPQKO0iX]AjCE0ZcfH>R9cD=#lTCC;k\"
    A$ = A$ + "DO:Ml\aAaSWBnTm9<gXkJ7a7:mL1Phk:Q;F>8P_gVba?o96U[mPakI:Pf?ii"
    A$ = A$ + "4PCOHXhOSbM`nKdifnQLKlgLoJF8dmKEWh9V1]b47?LB#AHE`Y1W1Lf`i1W?"
    A$ = A$ + "LA`U0O0hZP[5f<\Eh6PNQM0g<lQPk#^oSJDo#aV]HSL\4NmZ`?E:EJ=CedWR"
    A$ = A$ + "bM8JejgAgknfn`mgoSnm5ljS]O1Nm?iFjES_[l0cN;KPl?nACP;QHj57QNHX"
    A$ = A$ + "Dk9M1KShUoCkAkj=9`QSkW\]n:oGI_e[eSGn>S^oQQ?:l9POOhnPo#hc1o9`"
    A$ = A$ + "31?2lX`O>lG0O=h[3OCh_1n^`O;lg1om`?161N=hO4nO2o_PoEho;l_1_1<^"
    A$ = A$ + "\C1W<JZUGIn]Q_RlVFYfhM<]geFNISJZFffH:[?]ZS1E9_Zc[Ka#mjPbPK1M"
    A$ = A$ + "LcHg0CNbEdgKd[]YginXO?Un>G7iT_R[6jD9UDf[4K=Y9ie4gBUC\7bjBk9o"
    A$ = A$ + "i;=YBJkm=AhLg>8Ie2hB_b[c]]DHNXQ01FjU;BQVhQ;cO5N2\dkLBkm;1fGY"
    A$ = A$ + "KB[aaQXHTM]ijTY?1XEX4L:`Y3W9L^`k5^0hm3G6L5`e0M0M2M1K7^AHW`]2"
    A$ = A$ + "g6m#\RbYd^cclnTAc\TbIV[RVl;[ba_adX`OYAmH3hAZZ<E[O2`V_HSL\4N]"
    A$ = A$ + "A_Vo=lcbmJC<Q9b]94]g_3_9l]hK_h9me_nP9^L24c9b<A>N<kgm]JM#JGll"
    A$ = A$ + "_:=?mHo5`To\\hOo?c4\[9mKgWi9okiI^`kdWA:_KmLji]kc9XOGmlmioOhi"
    A$ = A$ + "GeoAmLkig1?3SLk1Wg=OF;m^ec2[gEOfLmObNNSmfiIofk6?cY0HV`S3fWEa"
    A$ = A$ + "E2eYWK`cGRNN5XFj:ec3`_MGjidcFc_TNNUHF?OCmlZ`[nadC3fDdc[hYcmR"
    A$ = A$ + ">gPW?Kml:`aMIji1`J`gbiY`fl7YWG9fj7E?_:lkoNH\QK4a4:BAh\gh:;B7"
    A$ = A$ + "V`gLaX7g]RNKk6mmf?NIWKMWMg1Nbj`H8k16P?f?fR>aL1>ElC<4T[K3mTCn"
    A$ = A$ + "cK5oKK`:`?]RM^gN6HMmfoFk<kYVU77lHKU>QFKm4JK5]ejTQ6G>>0dSWc^h"
    A$ = A$ + "Q=;n6^l>kO7MeK?Ic>I]70kC4jaG=h^38lOIbQOZ`4HBIZdDUYJcd<eHV^YF"
    A$ = A$ + "CMVIHVYYNc\<Y=cfdPI>V<ViJJd<?cl=;`\#cR<;f\4CCV\84VZW8ZoGRW7Z"
    A$ = A$ + "VUJbSak?8lAP?3LG`O<lUQ_8V?`mIF6V;`MSAnoP`nPO1<:l5hWLZ3im\CmS"
    A$ = A$ + "1G?b:XWNZm0ONTULS#O<kIWX4QldCMGHlIdC?eW6cahfQmPAZm<`3K:HJf\L"
    A$ = A$ + "caH>FcaI>NC;`WcL2VCdLB`7e\2C[Vf<5=[dDbLbVEIF]iD<W:Z?lY<WVI=`"
    A$ = A$ + "SH>Mh?0ndVgSi<<[eLVVcbLfVcaL^VeI>?cj=_GckcLnV=H^0c5J^8c6=_Oc"
    A$ = A$ + "5K^4cUJ^<cUKn0Vf=GQi:=GUiZ=GSi3J^FceIj`\9cV=QV>=Ka\Ecf<MI^Nc"
    A$ = A$ + "=Hjf\MC?VN=mI^ACoVMH6`\Cc=I^Ic]H^Ec^<O8c^=gVif=gQI?VO?cMJn`V"
    A$ = A$ + "1=OTZgI?M]2lUNlLdS]Z7KC?FD?^BmH9mh9[7GUNLejaCA?NVjacB?NfjacE"
    A$ = A$ + "?^>iH[jhgZ>^]ZSK[jhfZ>^]ZSK[jhfZ>^]ZSK[jhfZ>^]ZSK[jhfZ>oJE7o"
    A$ = A$ + "FeaOEjacDaScZ]:?_>fnfkXb;MKM>#7EN9M]e]gA`6gFGl_Fl<?U:kXknfF7"
    A$ = A$ + "E6fIg3dAeMfg>jZkNkYbM`]JP>fI#OK[[JjlFfLgM\m`=e=eWf`AXZnjL78`"
    A$ = A$ + "ZYSnk_gK^k>gb0EcW]cnV>O\o^fjf6#na`N_iNTcfD_3\]JdV5fCM^cfd>jT"
    A$ = A$ + "1KK]N:C_gn7HKm^eNkYS^[[[N60]XdiV70=ZDKWgh>kjVjXk>kIcMFifjMWk"
    A$ = A$ + "XcIdOWgDgm^e^fL7MgC_3<MZaK]o>jNPnLW^Y1VfU\^F9aQE#WdZNb:LWDdN"
    A$ = A$ + "BKfCFYmTEK?iD\WLbfCFUmTBj9[d2Wf\M_TM8:IQLA;LJcn=]IKCKFhDbRZ["
    A$ = A$ + "dfhRFdX=g9fA_=;nDdMRmWFYM8Je=XF8gV5EGY[aF8_B;n\Bglb2iEJkN9g4"
    A$ = A$ + "d1WE:ZKm]Y^kMcg#e8_T>FYLEgKA>fo0je3\S]eAHWEbo]j`KP?FcFjZk^k<"
    A$ = A$ + "LCmN;CG>[OTSGm0mgE7KMWm97kG_>\7iHgKYZ=gEoK^k>[Y[N^Y=]C\C3#WY"
    A$ = A$ + "Og>fNGXlH7K^CD0jVLG4\SMfCEKYc]SR#YXoDi>j37lDK^kM^Y:gFWMP3AHG"
    A$ = A$ + "M\mNk9\f]_cMX2EM>C_cAIOa=ehScNbHoGSl3nVg6Mdooo4noEAM%%h1"
    btemp$ = ""
    For i& = 1 To Len(A$) Step 4: B$ = Mid$(A$, i&, 4)
        If InStr(1, B$, "%") Then
            For C% = 1 To Len(B$): F$ = Mid$(B$, C%, 1)
                If F$ <> "%" Then C$ = C$ + F$
            Next: B$ = C$: End If: For j = 1 To Len(B$)
            If Mid$(B$, j, 1) = "#" Then
        Mid$(B$, j) = "@": End If: Next
        For t% = Len(B$) To 1 Step -1
            B& = B& * 64 + Asc(Mid$(B$, t%)) - 48
            Next: X$ = "": For t% = 1 To Len(B$) - 1
            X$ = X$ + Chr$(B& And 255): B& = B& \ 256
    Next: btemp$ = btemp$ + X$: Next
    BASFILE$ = _Inflate$(btemp$, 25152): btemp$ = ""
    _Font _LoadFont(BASFILE$, size, "memory, monospace")
End Sub

   

Print this item

  GetWindowTextW - can you get it to work?
Posted by: TerryRitchie - 06-07-2024, 07:01 PM - Forum: Help Me! - Replies (12)

I'm trying to get the name of the current window that has focus. I've already successfully figured out how to get the window handle of any window in focus but I'm having trouble getting the window's title. According to Microsoft's docs here:

https://learn.microsoft.com/en-us/window...indowtextw

GetWindowTextW should be able to do this. ( There is also a GetWindowTextA function for ASCII return but that's not working for me either. )

It's pretty straight forward:

DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION GetWindowTextW (BYVAL hWnd AS _INTEGER64, lpString AS STRING, BYVAL nMaxCount AS INTEGER)
END DECLARE

DIM Dummy AS INTEGER
DIM n AS STRING

_TITLE "This is a test"
Dummy = GetWindowTextW(_WINDOWHANDLE, n, 255)
PRINT n

Does anyone have any insights on why this is not working? The string seems to be null and Dummy returns the value of 0.

Print this item

  Extended KotD #16: _UPRINTWIDTH
Posted by: SMcNeill - 06-07-2024, 09:01 AM - Forum: Keyword of the Day! - No Replies

Now, since my last couple of entries was for _UPrintString, I imagine that everyone could guess that _UPrintWidth is probably some sort of helper function for that command.   Right?  

Big Grin

I also imagine that since most folks already know that _PrintWidth will tell you how many pixels wide a text string is, most can probably hazard a guess as to what _UPrintWidth does.   Right?

Big Grin Big Grin

Well, for those who aren't brave enough to guess, let me tell you!   _UPrintWidth tells you the pixel width of a text string that will be printed to the screen!

And, I can hear some of you guys muttering under your breath, saying stuff like, "And we needed a new command for this?  Why?!  We already have _PrintWidth!"

.
.
.

And, I hope the basic answer to that was already stressed via my last couple of posts.  _UPrintString tends to print wider and taller characters than _PrintString and PRINT does, as they both can tend to "clip" characters off with various fonts and font sizes.

_PRINTWIDTH returns the width of text that is going to be printed to the screen using _PRINTSCREEN, or plain PRINT.
_UPRINTWIDTH returns the width of text that is going to be printed to the screen using _UPRINTSCREEN.

^ That is the basic -- and most important -- difference in the two commands.  If you're used to using _PrintWidth, then there should be zero issue with you swapping over to _UPrintWidth  -- with a few syntax changes which I'll go over below.



For starters, let me share the relevant wiki page for each command:

https://qb64phoenix.com/qb64wiki/index.php/UPRINTWIDTH
https://qb64phoenix.com/qb64wiki/index.php/PRINTWIDTH

And their syntax:
pixelWidth& = _UPRINTWIDTH(text$[, utfEncoding&][, fontHandle&])
pixelWidth% = _PRINTWIDTH(textToPrint$[, destinationHandle&])

Now, as you can see, the REQUIRED portions of the commands are both the same, in their simplest form:

width = _command(text$)    <whereas command is whichever of those two commands you want to substitute in there>

But, there ARE a few differences in the optional parameters, which I'll cover below:

_PRINSTSTRING has only one optional parameter -- destinationHandle&.  Basically, you can point it to the SCREEN that you want to get the width for, and it'll return the size for any text that you'd print to that screen.

_UPRINTSTRING has two optional parameters:

1) utfEncoding& ---  this is a parameter which you can use to tell it what encoding you're using with the chosen font.  Are you wanting the width for ASCII/ANSI formatted text?  UTF-8 formatted text?  UTF-16?  UTF-32?  Like I mentioned yesterday, *MOST* folks can basically just skip this parameter completely.  Unless you're working with UniCode text strings (which UPrintString does, but PrintString can't), then you can just skip messing with this parameter completely.

fontHandle& -- and here you can specify the FONT HANDLE that you want, when you're getting the width of that text to the screen.

Note that this is NOT the same as the destinationHandle&, that _PrintString uses.  Don't let that old habit catch you unaware and cause issues for you.

_PrintString returns the width for whatever font is currently loaded on the screen you specify.

_UPrintString returns the width for whatever font you specify.  It doesn't have to be loaded on the screen whatsoever, for it to work for you. 

This difference can save you from having to write code such as:

Code: (Select All)
F = _FONT 'get the old font
_FONT newfonthandle 'set the new fonthandle to the screen in question
pw = _PrintWidth("Hello World") 'get the width, in the chosen font
_FONT F  'restore the old font

Instead, you can just do something as simple as:

Code: (Select All)
upw = _UPrintWidth("Hello World", ,newfonthandle) 'get the uprintwidth of the text in the chosen font.



The most important thing is just to remember:

When using _UPRINTSTRING, then use _UPrintWidth with it

If you're using _PrintString or just PRINT, then use _PrintWidth with those commands.

There's a few slight differences in things here, between _PrintWidth and _UPrintWidth, but they're subtle enough that I don't think anyone will have any trouble adjusting to them once they're aware of them.

And since you guys all read this post, you're all aware of those minute differences now, and shouldn't have any issues whatsoever making using of _UPrintWidth properly.

Right? 

Big Grin

Print this item

  $RESIZE questions
Posted by: TerryRitchie - 06-06-2024, 09:09 PM - Forum: Help Me! - Replies (8)

With $RESIZE:ON I've noticed that _WIDTH and _HEIGHT will not update when the screen is resized (which I assume is correct behavior).

_RESIZEWIDTH and _RESIZEHEIGHT do however as detailed in the Wiki.

Without $RESIZE:ON in the code I've noticed that _RESIZEWIDTH and _RESIZEHEIGHT report the same as _WIDTH and _HEIGHT. According to the Wiki the RESIZE command set should not be available without $RESIZE:ON.

Is _RESIZEWIDTH and _RESIZEHEIGHT reporting values without $RESIZE:ON a bug or is this expected behavior?

If this is not expected behavior and will get fixed (a bug) how can I detect when a program is allowed to resize? I would need to know to use _WIDTH and _HEIGHT when a window has a fixed size or use _RESIZEWIDTH and _RESIZEHEIGHT when a window is allowed to resize. I need to be able to incorporate this detection into libraries.

If this is expected behavior then why use _WIDTH and _HEIGHT at all? _RESIZEWIDTH and _RESIZEHEIGHT will always report the correct client _WIDTH and _HEIGHT whether $RESIZE:ON is present or not.

Any insights?

Print this item

  _WINDOWHANDLE
Posted by: TerryRitchie - 06-05-2024, 09:57 PM - Forum: Help Me! - Replies (8)

Just a head's up for everyone. I've just spent an hour cursing at my code until I figured out what was going on.

SCREEN _NEWIMAGE(640, 480, 32)
hWnd&& = _WINDOWHANDLE

The above code will not return the correct window handle.

SCREEN _NEWIMAGE(640, 480, 32)
_DELAY .25
hWnd&& = _WINDOWHANDLE

This code above will. Very frustrating.

Print this item

  Lesson's 10 Exercise (Partial solution)
Posted by: marbac74 - 06-05-2024, 02:03 PM - Forum: Terry Ritchie's Tutorial - Replies (4)

Hello everyone,
I'm working on Lesson's 10 assignment...it's definitely more complicated than the previous ones  Sick I'm not finished with it yet, but I wanted to post the intermediate result, because there are a couple of things worth noticing: the exercise is full of tricks so make use of the wiki information...for example at line 49 in the code below...you need to use a semicolon otherwise some of your print statements will disappear from screen and you'll be left wondering why..."they were there ten minutes ago and now they don't show up anymore...but I didn't change anything so how can it be?". If you reach the end of screen you must add a semicolon to the last print statement to prevent...I don't remember the name but in order that everything shows up as it is written. Today I worked on the DrawSymbol subroutine and I'm quite happy with it, it works as expected, but I don't know if there is a more efficient way to code it... Here is the partial solution to the exercise:

Code: (Select All)

SCREEN _NEWIMAGE(340, 340, 32)
_TITLE "Slot Machine"

CONST RED = _RGB32(255, 0, 0)
CONST GREEN = _RGB32(0, 255, 0)
CONST BLUE = _RGB32(0, 0, 255)
CONST PURPLE = _RGB32(255, 0, 255)
CONST YELLOW = _RGB32(255, 255, 0)
CONST CYAN = _RGB32(0, 255, 255)
CONST BLACK = _RGB32(0)
CONST GREY = _RGB32(70)

DIM Score%

Score% = 0

PAINT (170, 170), GREY
_PRINTMODE _KEEPBACKGROUND
LOCATE 1, 16
COLOR YELLOW: PRINT "SLOT MACHINE"

LINE (10, 20)-(110, 120), BLACK, BF
DrawSymbol "DIAMOND", 1
LINE (120, 20)-(220, 120), BLACK, BF
DrawSymbol "DIAMOND", 2
LINE (230, 20)-(330, 120), BLACK, BF
DrawSymbol "DIAMOND", 3

LOCATE 9, 2
COLOR YELLOW: PRINT "ENTER to spin"; SPC(7); Score%; SPC(7); "ESC to exit"
LOCATE 11, 18
PRINT "PAYOUTS"
LOCATE 13, 10
COLOR YELLOW: PRINT "3 Double Circles - 500"
LOCATE 14, 10
COLOR YELLOW: PRINT "3 Squares        -  25"
LOCATE 15, 10
COLOR YELLOW: PRINT "3 Triangles      -  25"
LOCATE 16, 10
COLOR YELLOW: PRINT "3 Circles        -  25"
LOCATE 17, 10
COLOR YELLOW: PRINT "2 Circles        -  10"
LOCATE 18, 10
COLOR YELLOW: PRINT "3 Diamonds      -  10"
LOCATE 19, 10
COLOR YELLOW: PRINT "2 Diamonds      -  5"
LOCATE 20, 10
COLOR YELLOW: PRINT "1 Diamond        -  1";
SLEEP

SUB DrawSymbol (Figure$, Box%)
    IF Figure$ = "SQUARE" AND Box% = 1 THEN
        LINE (20, 30)-(100, 110), BLUE, BF
    ELSEIF Figure$ = "SQUARE" AND Box% = 2 THEN
        LINE (130, 30)-(210, 110), BLUE, BF
    ELSEIF Figure$ = "SQUARE" AND Box% = 3 THEN
        LINE (240, 30)-(320, 110), BLUE, BF
    ELSEIF Figure$ = "CIRCLE" AND Box% = 1 THEN
        CIRCLE (60, 70), 40, RED
        PAINT (60, 70), RED, RED
    ELSEIF Figure$ = "CIRCLE" AND Box% = 2 THEN
        CIRCLE (170, 70), 40, RED
        PAINT (170, 70), RED, RED
    ELSEIF Figure$ = "CIRCLE" AND Box% = 3 THEN
        CIRCLE (280, 70), 40, RED
        PAINT (280, 70), RED, RED
    ELSEIF Figure$ = "SPECIAL" AND Box% = 1 THEN
        CIRCLE (60, 70), 40, CYAN
        PAINT (60, 70), CYAN, CYAN
        CIRCLE (60, 70), 20, BLUE
        PAINT (60, 70), BLUE, BLUE
    ELSEIF Figure$ = "SPECIAL" AND Box% = 2 THEN
        CIRCLE (170, 70), 40, CYAN
        PAINT (170, 70), CYAN, CYAN
        CIRCLE (170, 70), 20, BLUE
        PAINT (170, 70), BLUE, BLUE
    ELSEIF Figure$ = "SPECIAL" AND Box% = 3 THEN
        CIRCLE (280, 70), 40, CYAN
        PAINT (280, 70), CYAN, CYAN
        CIRCLE (280, 70), 20, BLUE
        PAINT (280, 70), BLUE, BLUE
    ELSEIF Figure$ = "UPTRIANGLE" AND Box% = 1 THEN
        LINE (20, 110)-(100, 110), YELLOW
        LINE -(60, 30), YELLOW
        LINE -(20, 110), YELLOW
        PAINT (60, 70), YELLOW, YELLOW
    ELSEIF Figure$ = "UPTRIANGLE" AND Box% = 2 THEN
        LINE (130, 110)-(210, 110), YELLOW
        LINE -(170, 30), YELLOW
        LINE -(130, 110), YELLOW
        PAINT (170, 70), YELLOW, YELLOW
    ELSEIF Figure$ = "UPTRIANGLE" AND Box% = 3 THEN
        LINE (240, 110)-(320, 110), YELLOW
        LINE -(280, 30), YELLOW
        LINE -(240, 110), YELLOW
        PAINT (280, 70), YELLOW, YELLOW
    ELSEIF Figure$ = "DOWNTRIANGLE" AND Box% = 1 THEN
        LINE (20, 30)-(100, 30), PURPLE
        LINE -(60, 110), PURPLE
        LINE -(20, 30), PURPLE
        PAINT (60, 70), PURPLE, PURPLE
    ELSEIF Figure$ = "DOWNTRIANGLE" AND Box% = 2 THEN
        LINE (130, 30)-(210, 30), PURPLE
        LINE -(170, 110), PURPLE
        LINE -(130, 30), PURPLE
        PAINT (170, 70), PURPLE, PURPLE
    ELSEIF Figure$ = "DOWNTRIANGLE" AND Box% = 3 THEN
        LINE (240, 30)-(320, 30), PURPLE
        LINE -(280, 110), PURPLE
        LINE -(240, 30), PURPLE
        PAINT (280, 70), PURPLE, PURPLE
    ELSEIF Figure$ = "DIAMOND" AND Box% = 1 THEN
        LINE (60, 110)-(100, 70), GREEN
        LINE -(60, 30), GREEN
        LINE -(20, 70), GREEN
        LINE -(60, 110), GREEN
        PAINT (60, 70), GREEN, GREEN
    ELSEIF Figure$ = "DIAMOND" AND Box% = 2 THEN
        LINE (170, 110)-(210, 70), GREEN
        LINE -(170, 30), GREEN
        LINE -(130, 70), GREEN
        LINE -(170, 110), GREEN
        PAINT (170, 70), GREEN, GREEN
    ELSEIF Figure$ = "DIAMOND" AND Box% = 3 THEN
        LINE (280, 110)-(320, 70), GREEN
        LINE -(280, 30), GREEN
        LINE -(240, 70), GREEN
        LINE -(280, 110), GREEN
        PAINT (280, 70), GREEN, GREEN
    END IF
END SUB

Print this item