Welcome, Guest |
You have to register before you can post on our site.
|
Forum Statistics |
» Members: 483
» Latest member: aplus
» Forum threads: 2,804
» Forum posts: 26,432
Full Statistics
|
|
|
QB64 GPT now available |
Posted by: SpriggsySpriggs - 05-17-2024, 05:08 PM - Forum: General Discussion
- Replies (5)
|
|
I am working on a QB64 GPT. I have been training it on the Wiki as well as some sample programs. Doesn't always produce ready-to-use code, especially when it comes to OpenGL or Windows API. Otherwise, most things it makes should be good. If anyone is willing to concatenate all their samples or libraries into single files, I'd be happy to use them as training data for the GPT. It also has InForm as training data, though I can't say it does too well. I plan on making another GPT that is strictly for helping with making changes to the IDE/compiler.
https://chatgpt.com/g/g-Cufiyami0-qb64-gpt
|
|
|
Orbit Demo SIN and COS |
Posted by: bplus - 05-17-2024, 03:59 PM - Forum: bplus
- Replies (3)
|
|
Orbit sub calculates points about a point cx, cy at a given angle in degrees and radius using trig functions COS and SIN ratios according to degrees.
Code: (Select All) Option _Explicit
_Title "orbit demo" 'b+ 2024-05-10
'============================== Main
Const Xmax = 1000, Ymax = 700
Const Thick = 2
Const Arc_Radius = 100
Const Sin_color = _RGB32(0, 0, 255)
Const Cos_color = _RGB32(0, 128, 0)
Const Radius_color = _RGB32(255, 0, 0)
Const Ang_color = _RGB32(255, 255, 0)
Const White = _RGB32(255, 255, 255)
Const Origin_color = _RGB32(255, 128, 0)
Dim cx, cy, mx, my, stepX, stepY, Radius, dAng, xOut, yOut, x, y
cx = Xmax / 2: cy = Ymax / 2
Screen _NewImage(Xmax, Ymax, 32)
_ScreenMove 60, 0
_PrintMode _KeepBackground
_MouseMove cx + 100, cy + 100 ' get ball rolling
While 1
Cls
Color White
Locate 2, 18
Print "Move your mouse clockwise starting at 0 due East to see Basics Angle in Degrees increase."
Locate 5, 68
Print "Orbit ";
Color Origin_color
Print "X_Origin, Y_Origin,";
Color Ang_color
Print " Degrees,";
Color Radius_color
Print " Radius,";
Color White
Print " xOut, yOut"
'draw horizontal through center of screen
Line (70, cy)-(Xmax - 70, cy), Cos_color
' draw vertical line through center of screen
Line (cx, 70)-(cx, Ymax - 70), Sin_color
'poll mouse
While _MouseInput: Wend ' updates all mouse stuff except wheel
mx = _MouseX: my = _MouseY 'get mouse location
'draw our Color Coded Trig Triangle
ThickLine cx, cy, mx, cy, 1, Cos_color
ThickLine mx, cy, mx, my, 1, Sin_color
ThickLine cx, cy, mx, my, Thick, Radius_color
stepX = mx - cx: stepY = my - cy
Radius = (stepX ^ 2 + stepY ^ 2) ^ .5
'to draw angle need to do some math
'dAng = mouse angle to 0 Degrees due East
dAng = _R2D(_Atan2(my - cy, mx - cx))
If dAng < 0 Then dAng = dAng + 360
Color Ang_color
ThickArc cx, cy, Radius, 0, dAng, Thick
'report all numbers color coded
Color Ang_color
Locate 5, 3: Print "Yellow Angle (in Degrees) ~ "; dAng \ 1
Color Radius_color
Locate 7, 7: Print " Length red Radius ~ "; Radius \ 1
Color Sin_color
Locate 9, 7: Print " Length blue Opp side ~ "; Abs(stepY) \ 1
Color Cos_color
Locate 8, 7: Print "Length green Adj side ~ "; Abs(stepX) \ 1
Color White
Locate 11, 1: Print " Ratios: (if no division by 0)"
If Radius <> 0 Then
Color Cos_color
Locate 12, 8: Print "COS = Adj ";
Color Radius_color
Print "/ Radius ";
Color White
Print "~ "; Left$(Str$(stepX / Radius), 6) '; Cos(_D2R(dAng)) ' double check
Color Sin_color
Locate 13, 8: Print "SIN = Opp ";
Color Radius_color
Print "/ Radius ";
Color White
Print "~ "; Left$(Str$(stepY / Radius), 6) '; Sin(_D2R(dAng)) ' double check
End If
Color White
orbit cx, cy, dAng, Radius, xOut, yOut ' mouse here
orbit cx, cy, dAng, Radius + 50, x, y ' set label here
label x, y, "(xOut, yOut) = (" + _Trim$(Str$(xOut \ 1)) + "," + Str$(yOut \ 1) + ")"
Color Origin_color
label cx, cy - 10, "(X_Origin, Y_Origin) = (" + _Trim$(Str$(cx)) + "," + Str$(cy) + ")"
_Display
_Limit 60
Wend
' !!!!!! featuring the use of this SUB routine !!!!
Sub orbit (X_Origin, Y_Origin, Degrees, Radius, xOut, yOut) ' all default single should be ok
xOut = X_Origin + Radius * Cos(_D2R(Degrees))
yOut = Y_Origin + Radius * Sin(_D2R(Degrees))
End Sub
Sub label (xc, yc, text$)
Dim th2, pw2
th2 = _FontHeight / 2
pw2 = _PrintWidth(text$) / 2
_PrintString (xc - pw2 + 1.25, yc - th2 + .5), text$
End Sub
Sub ThickArc (xCenter, yCenter, arcRadius, dAngleStart, dAngleEnd, rThick)
Dim rAngle, rAngleStart, rAngleEnd, x1, y1, Stepper
'draws an Arc with center at xCenter, yCenter, Radius from center is arcRadius
'for SmallBASIC angle 0 Degrees is due East and angle increases clockwise towards South
'THIS SUB IS SETUP TO DRAW AN ARC IN CLOCKWISE DIRECTION
'dAngleStart is where to start Angle in Degrees
' so make the dAngleStart the first ray clockwise from 0 Degrees that starts angle drawing clockwise
'dAngleEnd is where the arc ends going clockwise with positive Degrees
' so if the arc end goes past 0 Degrees clockwise from dAngleStart
' express the end angle as 360 + angle
'rThick is the Radius of the many,many tiny circles this will draw to make the arc thick
' so if rThick = 2 the circles will have a Radius of 2 pixels and arc will be 4 pixels thick
If arcRadius < 1 Then PSet (xCenter, yCenter): Exit Sub
rAngleStart = _D2R(dAngleStart): rAngleEnd = _D2R(dAngleEnd)
If Int(rThick) = 0 Then Stepper = 1 / (arcRadius * _Pi) Else Stepper = rThick / (arcRadius * _Pi / 2)
For rAngle = rAngleStart To rAngleEnd Step Stepper
x1 = arcRadius * Cos(rAngle): y1 = arcRadius * Sin(rAngle)
If Int(rThick) < 1 Then
PSet (xCenter + x1, yCenter + y1)
Else
fcirc xCenter + x1, yCenter + y1, rThick, Ang_color
End If
Next
End Sub
Sub ThickLine (x1, y1, x2, y2, rThick, K As _Unsigned Long)
Dim length, stepx, stepy, dx, dy, i
'x1,y1 is one endpoint of line
'x2,y2 is the other endpoint of the line
'rThick is the Radius of the tiny circles that will be drawn
' from one end point to the other to create the thick line
'Yes, the line will then extend beyond the endpoints with circular ends.
stepx = x2 - x1
stepy = y2 - y1
length = (stepx ^ 2 + stepy ^ 2) ^ .5
If length Then
dx = stepx / length: dy = stepy / length
For i = 0 To length
fcirc x1 + dx * i, y1 + dy * i, rThick, K
Next
End If
End Sub
Sub fcirc (CX As Long, CY As Long, R As Long, C As _Unsigned Long)
Dim Radius As Long, RadiusError As Long
Dim X As Long, Y As Long
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
edit: to show when sin and cos go negative. abs() should only be applied to lengths.
Notice 0 Degrees is due East and as the angle in degrees increases the the arc goes CLOCK-WISE about cx, cy from EAST to SOUTH to WEST to NORTH and returns to due EAST at 360 degrees, one complete turn.
|
|
|
For..Next |
Posted by: Dimster - 05-17-2024, 03:27 PM - Forum: GitHub Discussion
- Replies (6)
|
|
I don't think there is present option whereby the NEXT (as in the FOR..NEXT) will automatically display the control variable after Next?? When a For is typed you get an automatic warning that you need the NEXT but if the For already has a control variable then could the warning also include the control variable? For x = 1 to 10 "Warning missing NEXT x"
I do appreciate there is a lot less typing if the control variable is not needed to complete the For .. Next but sometimes when I have a lot of nested IF statements with a lot of For..Next loops it is always a missing End If that is somewhere in that mess of code which creates a Program Flow error. Following which For goes to which Next can be a little challenging. So I was thinking is the Flow Error highlighted Next x as the loop where I can find the missing End If (as opposed to the Next y or Next Num etc in the same mess of coding) it could help.
|
|
|
New Alchemy |
Posted by: PhilOfPerth - 05-17-2024, 05:09 AM - Forum: Games
- Replies (5)
|
|
Alchemy.7z (Size: 355.16 KB / Downloads: 99)
I've re-written the word-game Alchemy with several new innovations, which I think make it more enjoyable.
It has 3 sets of 20 word-pairs, roughly sorted in order of difficulty from easy to hard. All pairs are
proven to be solvable, with the current best results stored as three Previous best files. These automatically
update when the records are beaten, but can be removed and re-started at will.
It allows re-starting a word-pair, or re-picking the set of words. A random-access word file is included which
makes the word-checking function much faster.
My thanks to Steve and bplus for their help.
Code: (Select All) Common Shared Ln$, SetNum$, Filename$, LineNum, CPL, WordPos, bad$, ok$, a$, Set$()
Common Shared Pairnum, Prev$, First$(), Last$(), Best$(), Name$(), Chain$(), Target$(), Target$, Name$
Common Shared ThisChain$, TryVert, Try$, Tries, MaxTries, Result
Randomize Timer
WWidth = 1275: WHeight = 820
Screen _NewImage(WWidth, WHeight, 32)
SetFont: f& = _LoadFont("C:\WINDOWS\fonts\courbd.ttf", 24, "monospace")
_Font f& ' install monospace font size 24, giving 32 usable text rows of 66 cols
dw = _DesktopWidth: dh = _DesktopHeight
CPL = WWidth / _PrintWidth("X") ' characters per line - used for centring and wiping
lhs = (dw - WWidth) / 2: top = 100 ' window left and top locations
_ScreenMove lhs, top
ok$ = "o3l32ceg": bad$ = "o2l16gec" ' centre display on target screen
Set1Data:
Data "BADGE","MEDAL","HORSE","SHEEP","SHED","HOUSE","CAR","TRUCK","MAJOR","MINOR"
Data "PASS","FAIL","STEAK","EGGS","SUN","MOON","BIRD","FISH","TOWN","CITY"
Data "COLD","HOT","LOCK","WATCH","CUP","PLATE","PARK","GARDEN","RIPE","ROTTEN"
Data "SHORT","TALL","WAR","PEACE","BIG","SMALL","DRAIN","SEWER","DRESS","SUIT"
Set2Data:
Data "MILK","HONEY","CREAM","CUSTARD","SPICE","SUGAR","RAKE","SHOVEL","WOOL","COTTON"
Data "WEED","FLOWER","EASTER","EGG","LOOK","LISTEN","FOX","HOUND","DANGER","SAFETY"
Data "COPPER","BRASS","LION","TIGER","BOX","CARTON","BOOK","PAPER","GREEN","BROWN"
Data "CHILD","ADULT","DESERT","OASIS","QUERY","RESULT","DUNCE","GENIUS","FATHER","SON"
Set3Data:
Data "PAPER","PENCIL","PRETTY","UGLY","RAISE","LOWER","ROAD","STREET","BLUNT","SHARP"
Data "BLACK","WHITE","MARS","SATURN","COVER","EXPOSE","FORWARD","REVERSE","MODEST","PROUD"
Data "MARRY","DIVORCE","CIRCLE","SQUARE","ANVIL","HAMMER","PATTERN","MODEL","FRINGE","PLAIT"
Data "DARK","LIGHT","RUBY","DIAMOND","BEDROOM","KITCHEN","ANTIQUE","VINTAGE","DUCKLING","SWAN"
Dim Set$(3, 20, 5) ' First, Last, Best, Name and Chain for 3 sets of 20 pairs
CheckFiles: ' check 3 Set files; if not found create with defaults
For a = 1 To 3
Filename$ = "Set" + LTrim$(Str$(a))
txt$ = "Checking " + Filename$
Centre txt$, 15: _Delay .5
If Not _FileExists(Filename$) Then
If a = 1 Then
Restore Set1Data
ElseIf a = 2 Then
Restore Set2Data
ElseIf a = 3 Then
Restore Set3Data
End If
Open Filename$ For Output As #1
For b = 1 To 20
Read first$, last$
Write #1, first$, last$, "21", "NOT SET", "UNSOLVED"
Next
Print "created "; Filename$: Sleep 1
Close: Cls: Run
End If
Next
Description
Chooseset:
Centre "Choose from Set 1 to Set 3 (9 TO EXIT)", 15
SetNum$ = ""
While SetNum$ <> "9" And (SetNum$ < "1" Or SetNum$ > "3")
SetNum$ = InKey$
Wend
If SetNum$ = "9" Then System
Cls
ReDim First$(20), Last$(20), Best$(20), Name$(20), Chain$(20)
ShowPairs
MaxTries = 20: WordPos = 36
InviteChoosePair: ' choose a pair of words to attempt
Yellow: Centre "Choose a pair, from A to T", 29
Centre "Z to re-choose set number", 30 ' choose pair Z to change set number
Centre " * to reset this pair's history", 31
Centre "(ESC to quit)", 32 ' Esc quits the game
_KeyClear: k = 0
While k < 1
_Limit 30
k = _KeyHit
Wend
Cls
Select Case k
Case Is = 42, 56 ' press * to reset this pair history
Wipe "303132"
Centre "Do you really want to remove the history for this set (y/n)?", 30
_KeyClear
k$ = ""
While k$ = ""
k$ = InKey$: Wend
If UCase$(k$) <> "Y" Then
GoTo Chooseset
Else
If SetNum$ = "1" Then
Restore Set1Data ' start reading pairs at Set1Data
ElseIf SetNum$ = "2" Then
Restore Set2Data ' start reading pairs at Set1Data
ElseIf SetNum$ = "3" Then
Restore Set3Data ' start reading pairs at Set1Data
End If
Filename$ = "Set" + SetNum$
Open Filename$ For Output As #1 ' re-create the Set file with this data
For a = 1 To 20
Read first$, last$ ' get the word-pair from data
Write #1, first$, last$, "21", "NOT SET", "UNSOLVED" ' write First, Last, Best, Name, and Chain to file
Next
Close
Cls: msg$ = Filename$ + " reset"
Centre msg$, 15
Sleep 1
GoTo Chooseset
End If
Case Is = 27 ' Esc to quit
System
Case Is = 90, 122 ' Z or z to re-choose set
GoTo Chooseset
Case 65 To 84 ' selected A to T
Pairnum = k - 64 ' convert to number 1 to 20 uppercase
Case 97 To 116 ' a to t
Pairnum = k - 96 ' convert to number 1 to 20 lower-case
Case Else ' if it's none of these, try again
Play bad$
GoTo Chooseset
End Select
FirstLook:
Cls: ThisChain$ = "" ' empty the chain for this pair
Prev$ = First$(Pairnum) ' put start word at front of chain
TryVert = 6: remain = 21: Tries = 0
target = Val(Best$(Pairnum)): Name$ = Name$(Pairnum)
msg$ = "Target:" + Str$(target)
Centre msg$, 4 ' show target details for this pair
Yellow: Centre First$(Pairnum), 5 ' show the first word
For a = TryVert To MaxTries + 5
Print Using "##"; Tab(28); a - 5;
Centre String$(9, "."), a
Next ' show 9 dots for each try
Yellow: Centre Last$(Pairnum), 26 ' show the target word
_KeyClear
CheckNumTries:
If Tries = MaxTries Then ' check if all tries used yet
Play bad$
Wipe "30"
Red: Centre "You've Used up all of your tries, sorry!", 30
Wipe "24": White: Sleep 1
GoTo Chooseset ' if all tries used, advise and restart the same pair
End If
GetTry:
Centre String$(9, "."), TryVert
Yellow:
Wipe "30"
txt$ = "You have" + Str$(20 - Tries) + " tries remaining"
Centre txt$, 30
Yellow
Locate 5, 50: Print "Added"; Tab(60); "Removed"
Sleep 1
'For a = 0 To 2: Locate 5 + a, 5: Print Space$(21):Next
Locate 5, 2: Print "Enter your word"
Locate 6, 2: Print "Space to restart from top"
Locate 7, 2: Print "Esc to quit"
White
Locate TryVert, WordPos - 5: Print Space$(12) ' clear the Try space
Locate TryVert, WordPos - 2
Input "", Try$ ' place cursor outside try-line
Try$ = UCase$(Try$)
Select Case Try$
Case Is = Chr$(27) ' pressed Esc to quit
System
Case Is = Chr$(32) ' pressed space to restart from try 1
GoTo FirstLook
Case "A" To "Z", "a" To "z" '
GoTo Letters
Case Else
GoTo GetTry
End Select
Letters:
If Len(Try$) < 2 Or Len(Try$) > 9 Then ' check length is 2 to 9 letters
Play bad$
Red: Centre "Words from 2 to 9 letters only allowed", 29
Sleep 1: Wipe "29": White
Locate TryVert, WordPos
Print Space$(15) ' if length is wrong, erase,
GoTo GetTry ' and start this try again
End If
Tries = Tries + 1
Locate TryVert, WordPos: Print Space$(12)
Centre Space$(9), TryVert
Centre Try$, TryVert
CheckWord ' Call Sub to Check the Player's Word
TryVert = TryVert + 1
GoTo CheckNumTries
' ------------------------------------------------------------------- subs below -------------------------------------------------------------------
Sub ShowPairs
Filename$ = "Set" + SetNum$
Open Filename$ For Input As #1
For a = 1 To 20
Input #1, First$(a), Last$(a), Best$(a), Name$(a), Chain$(a)
Next
Close
txt$ = Filename$ + " Word Pairs "
Yellow: Centre txt$, 5 ' show pair details, but don't show chains
Print: Print Tab(18); "Pair"; Tab(26); "From"; Tab(37); "To"; Tab(44); "Best"; Tab(52); "By"
White
For a = 1 To 20
Print Tab(19); Chr$(a + 64); Tab(26); First$(a); Tab(36); Last$(a); Tab(45); Best$(a); Tab(50); Name$(a)
Next
Close
Play ok$
End Sub
Sub CheckWord ' check this word - number of changes ok? valid word?
Added = 0: Added$ = "": Removed = 0: Removed$ = "": Result = 0
CountAddedLetters: ' Find letters in Try$ that were not in Prev$ (so they are added)
temp$ = Prev$ ' keep prev$ intact while checking
For a = 1 To Len(Try$) '
l$ = Mid$(Try$, a, 1) ' get a letter from try$,
po = InStr(temp$, l$) ' find its position in temp$, if any
If po = 0 Then ' if not in temp$, it was added, if not found...
Added = Added + 1: Added$ = Added$ + l$ ' so add to Added$ and increment Added count
Else ' if in temp$, replace with a space (stops double-find)
temp$ = Left$(temp$, po - 1) + " " + Right$(temp$, Len(temp$) - po)
End If
Next
CountRemovedLetters: ' Find letters in prev$ that are not in try$ (removed)
temp$ = Try$ ' backup try$ before checking
For a = 1 To Len(Prev$)
l$ = Mid$(Prev$, a, 1) ' get a letter from prev$
po = InStr(temp$, l$) ' find its position in try$, if any
If po = 0 Then ' if not in temp$ it has been removed,
Removed = Removed + 1: Removed$ = Removed$ + l$ ' so add to Removed$ and increment the Removed count
Else ' if in temp$, replace with a space to (stops double-find)
temp$ = Left$(temp$, po - 1) + " " + Right$(temp$, Len(temp$) - po)
End If
Next
Locate TryVert, 50: Print Added$; Tab(60); Removed$
ResultOfCount: ' check number of added and removed letters
If Added > 1 Or Removed > 1 Then
Wipe "30"
Red: Centre "Too many changes!", 30
Play bad$
Sleep 1
Result = 1 ' flag too many changes with Result = 1
White
GoTo ChecksFinished ' bad result, no more checking needed
End If
DictionaryCheck: ' number of changes was ok, result is zero
Close
Open "RA9" For Random As #1 Len = 13 ' random access file with longest word 9 letters
fl = LOF(1) \ 13 + 1 ' get number of words in dictionary
bot = 0: top = fl
While Abs(top - bot) > 1
srch = Int((top + bot) / 2) ' set section of dictionary to searchrch ' set search point
Get #1, srch, a$ ' get a word from dictionary at srch point
a$ = UCase$(a$)
Select Case a$
Case Is < Try$ ' try$ is greater than dictionary word
bot = srch ' move search forward
Case Is > Try$ ' try$ is less than dictionary word
top = srch ' move search back
End Select
If Try$ = Last$(Pairnum) Then
msg$ = "Solved in " + LTrim$(Str$(Tries)) + " tries!"
Result = 2 ' solved
Yellow: Centre msg$, 31
Centre Try$, TryVert
' ThisChain$ = First$(Pairnum) + " - " + ThisChain$ ' + Try$ ' complete the chain
Exit While
ElseIf Try$ = a$ Then
Result = 3 ' valid word but not Last$
Centre Try$, TryVert
Exit While
End If
Wend
Close
InvalidWord: ' fall through to here if Try$ not Last$ and not valid
If Result < 2 Then
Wipe "30"
Red: Centre "Invalid word!", 30
Red: Centre Try$, TryVert
Sleep 1
ThisChain$ = ThisChain$ + " " + String$(Len(Try$), "*") + " - "
End If
Wipe "30" ' if we got here it's an invalid word, result still zero
White
ChecksFinished: '
Select Case Result
Case Is = 0, 1 ' word failed - too many changes or invalid word
Red: Centre Try$, TryVert
ThisChain$ = ThisChain$ + " " + String$(Len(Try$), "*") + " - "
Play bad$
Case Is = 2 ' word ok and last word is found
msg$ = "Solved in " + LTrim$(Str$(Tries)) + " tries!"
Yellow: Centre msg$, 31
Centre Try$, TryVert
ThisChain$ = First$(Pairnum) + " - " + ThisChain$ + Try$ ' complete the chain
If Len(ThisChain$) > CPL - 8 Then ThisChain$ = ThisChain$ + Chr$(13)
Case Is = 3 ' word ok but is not Last$
Centre Try$, TryVert
ThisChain$ = ThisChain$ + Try$ + " - "
Play ok$
Prev$ = Try$
End Select
If Result = 2 Then FinishedPair
Sleep 1: Wipe "3031"
End Sub
Sub FinishedPair
Play ok$: Play ok$: Cls: Yellow
msg$ = "You did it in " + LTrim$(Str$(Tries)) + " changes"
Centre msg$, 15
If Tries < Val(Best$(Pairnum)) Then ' if this beats the Best for the current round,
Centre "New record! Enter your name (or <ENTER> for anonymous) ", 16
Locate 16, 60: Input winname$ ' get the player's name,
If Len(winname$) < 2 Then winname$ = "(ANON)" ' if no name is given, player is ANON
Name$(Pairnum) = UCase$(winname$) ' place Name of best player for this pair in array
Best$(Pairnum) = LTrim$(Str$(Tries)) ' place Best score for this pair in array
Chain$(Pairnum) = ThisChain$ ' this beats previous best so update chain$ for this pair,
Filename$ = "Set" + SetNum$ '
Open Filename$ For Output As #1
Cls
For a = 1 To 20 '
Write #1, First$(a), Last$(a), Best$(a), Name$(a), Chain$(a) ' and re-write the history file for this set
Next
Close
End If
Cls
Yellow
msg$ = "Best for this pair: " + Best$(Pairnum) + " by " + Name$(Pairnum)
Centre msg$, 15
White: Locate 17, 1: Print ThisChain$
Play ok$
Yellow: Centre "Press a key", 19
Sleep
Run
End Sub
Sub Description
AlchemyDescription:
Yellow: Centre "ALCHEMY", 2: White: Print
Print " Alchemy (al/ke/mi) is the process of changing items into something"
Print " different in a mystical way, such as changing ";: Green
Print "STONE";: White: Print " into ";: Green: Print "GOLD.": White
Print " This game calls upon your skills in this art, to change a word into"
Print " a totally different one, with the least number of changes.": Print
Print " In the usual word-swap game, you repeatedly change one letter of a"
Print " word for a different one, creating a new word, until the final word"
Print " is produced.": Print
Print " But in Alchemy you have another tool available to you for the task."
Print " You can also ";: Green: Print "add";: White: Print " or ";: Green
Print "remove";: White: Print " a letter, before ";: Green
Print "re-arranging";: White: Print " them, so"
Print " the length of the word may vary as you progress (to max 9 letters)."
Print " As an example, we can change STONE into GOLD with just 4 changes:"
Green: Centre "STONE - TONE - GONE - LONG - GOLD", 18: White: Print
Print " There are three sets of word-pairs provided, ranging from easy to";: Print
Print " difficult, and you are allowed up to 20 changes for each pair. A"
Print " record is kept of the best score for each pair, and if you beat"
Print " one of these, your record will replace it (you can restart these"
Print " records from new at any time).": Print
Print " By the way, an ";: Green: Print "Easter Egg";: White: Print " with ";
Print "the best recorded solutions for all"
Print " of the word-pairs is hidden somewhere (hint: you may have to visit"
Print " Tibet to find it)!"
Yellow: Centre "Press a key to continue", 29
Sleep: Play ok$: Cls
End Sub
Sub Wipe (ln$) ' ln$ is 2-digit line nums eg "0122" is lines 1 and 22)
For a = 1 To Len(ln$) - 1 Step 2 ' get 2 digits for wipe-line,
wl = Val(Mid$(ln$, a, 2)) ' and wipe that line
Locate wl, 1: Print Space$(CPL);
Next
End Sub
Sub Centre (txt$, linenum) ' centres text on selected line
ctr = Int(CPL / 2 - Len(txt$) / 2) + 1 ' centre is half of chars per line minus half string-length
Locate linenum, ctr
Print txt$
End Sub
Sub Red
Color _RGB(255, 0, 0)
End Sub
Sub Yellow
Color _RGB(255, 255, 0)
End Sub
Sub White
Color _RGB(255, 255, 255)
End Sub
Sub Green
Color _RGB(0, 255, 0)
End Sub
STEVE FREINDLY EDIT -- Grab the download from here as well, if you need it:
Alchemy.7z (Size: 355.16 KB / Downloads: 99)
(Most folks are used to finding these attachments at the bottom of posts, so I just edited it down here as well as leaving it up top as originally posted. )
|
|
|
Fast Primes |
Posted by: SMcNeill - 05-16-2024, 08:13 AM - Forum: Utilities
- Replies (18)
|
|
A quick little method to get prime numbers from 2 to a little over 1,000,000.
Code: (Select All)
Screen _NewImage(1280, 900, 32)
_ScreenMove _Middle
For i = 1 To 999999 'I didn't stop at 1,000,000 just cause I didn't want that last SLEEP/CLS to erase the last page.
If IsPrime(i) Then Print i;
If i Mod 12000 = 0 Then Sleep: Cls
Next
Beep 'an audible warning so folks can take their finger off whatever key they're using to spam past the SLEEP statements.
_Delay 2 'and time for them to let go of that key
_KeyClear 'so if they're using ENTER as the "Get on with it damn ya!" key, it won't blow past the manual test.
Print
Print
Print "Feel free to do some independent tesing to see if my response is speedy enough for you:"
Do
Input "Give me a number from 0 to 1,016,064 and I'll tell you if it's prime or not. (Zero quits.) =>"; num
If IsPrime(num) Then
Print num; "is, indeed, a prime number!"
Else
Print "Nope!"; num; "is not prime!"
End If
Loop Until num = 0
System
Function IsPrime (num)
'to check for any given number less than 1,016,064, we only have to do a maximum of 170 comparisons
'as the max value we ever have to check against is the SQR of our number.
'for example, no value higher than 10 could ever be a factor in 100 and be prime!
'so for numbers less than 1,000,000, all we need do is compare them against factors less than 1,000.
'and there's not that many of them, as you can see below!
If num < 2 _Orelse num > 1016064 Then Exit Function
Restore prime_factors
IsPrime = -1
For j = 1 To 10 'broken down to give 10 quick exit points so we don't check every value for an answer.
Read count
For i = 1 To count
Read factor
If num <= factor Then
Exit Function
Else
If num Mod factor = 0 Then IsPrime = 0: Exit Function
End If
Next
If num < factor * factor Then Exit Function
Next
Exit Function
prime_factors: 'for a list of prime factors for numbers from 1 to 1,000,000
Data 25: 'for numbers from 1 to 100
Data 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97: 'factors up to 10,000 (100 ^ 2)
Data 21: 'for numbers from 101 to 200
Data 101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199: 'up to 44,100 (210 ^ 2)
Data 16
Data 211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293: 'up to 93,636 (306 ^ 2)
Data 16
Data 307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397: 'up to 160,000 (400 ^ 2)
Data 17
Data 401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499: 'up to 252,004 (502 ^ 2)
Data 14
Data 503,509,521,523,541,547,557,563,569,571,577,587,593,599: 'up to 360,000 (600 ^ 2)
Data 16
Data 601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691: 'up to 490,000 (700 ^ 2)
Data 14
Data 701,709,719,727,733,739,743,751,757,761,769,773,787,797: 'up to 652,864 (808 ^ 2)
Data 15
Data 809,811,821,823,827,829,839,853,857,859,863,877,881,883,887: 'up to 820,836 (906 ^ 2)
Data 14
Data 907,911,919,929,937,941,947,953,967,971,977,983,991,997: 'up to 1,01,064 (1008 ^ 2)
End Function
Note that this saves no tables, no values. Uses almost no memory. It's just direct elimination in the most efficient manner possible, for values from 2 to a little over 1,000,000. If someone wanted, they could continue this to go further, but it's all I need at the moment for my personal purposes, so I'll just post it as is and leave it for others to work on and enjoy if they ever want to.
|
|
|
Best way to update PE |
Posted by: PhilOfPerth - 05-16-2024, 12:04 AM - Forum: Help Me!
- Replies (9)
|
|
I'm sure I'm doing it wrong! To update, I currently download the new file (into my Downloads folder), then extract the files to my QB64PE folder (which is directly on the C: drive).
I then go to this new folder in PE, and copy all the files to the PE folder itself. I'm prompted to write over old files found or to skip the copy.
Is there a quicker/simpler way to update (maybe skipping files that are not changed)?
|
|
|
Extended KotD #7: $INCLUDEONCE |
Posted by: SMcNeill - 05-15-2024, 07:17 AM - Forum: Keyword of the Day!
- Replies (7)
|
|
Thanks to @RhoSigma , this wonderful keyword was added into the language a few versions back. I'm honestly surprised we haven't had more people talk about it, use it, or at least ask about it! This is one of those commands that I consider to be a *MUST HAVE* for anyone who does any serious library creation.
What is $INCLUDEONCE? And what's it do for us that's so nifty?
$INCLUDEONCE is a metacommand that you place inside any of your library files, and no matter how many $INCLUDE statements they show up in, they're only included ONCE in your code.
For example, let's say I write various libraries and I have a Truth.BI file which I make excessive use of:
Truth.BI Code: (Select All) CONST True = -1
CONST False = 0
Now, I write a little program which saves files for me to the disk as *.SSF (Steve Special Format) files. This save file library is going to $INCLUDE:'Truth.BI.
And I also write a little program which loads files for me from the disk, if they're *.SFF files. This is seperate from the save library as folks may just need one of the routines and not both in their code. This file would also have in it somewhere the need for $INCLUDE:'Truth.BI'
Now, for my own use, I want to use *both* of the routines in my program -- I want to both save and load files. So, I write my code for the main program to look something like the following:
Code: (Select All) $INCLUDE:'SaveSSF.BI'
$INCLUDE:'LoadSSF.BI'
... more code
And, in the IDE, I get warnings and errors and dancing bears growling and trying to eat me as I'm now trying to include Truth.BI twice in my code and that means I'm trying to define the same CONSTs multiple times. QB64PE doesn't like that type of behavior!!
So what's the simple fix??
Let's go back and change Truth.Bi just a little:
Code: (Select All) $INCLUDEONCE
CONST True = -1
CONST False = 0
Now, even though that library "Truth.BI" is included in multiple other libraries, and thus included in my code at multiple points, IT'S ONLY ADDED ONCE!!
The first time a file with $INCLUDEONCE in it is $INCLUDEd into your code, it's added to the code. At each and EVERY point after that, that code is just skipped as you've already included it into your code earlier!!
$INCLUDEONCE, when placed inside a bas/bi/bm file, makes certain that the code in that file is only included one time, no matter how many $INCLUDE statements try to reference that file.
And that's a game changer right there, for anyone who writes and creates library files!
For everyone else, if you don't use $INCLUDE, you can basically just save the brain cells and forget this command even exists. It ONLY affects $INCLUDE behavior, and does absolutely nothing in any other type code.
|
|
|
Getting vectors using a lookup table |
Posted by: TerryRitchie - 05-14-2024, 08:00 PM - Forum: Programs
- Replies (2)
|
|
More playing around today. I created a few functions to quickly get vector quantities from a SIN lookup table.
The SIN/COSINE table returns standard results while the conversion functions negate the COSINE value so 0 degrees and 0Pi are north/up.
Code: (Select All) '+-------------------------------------------------------+
'| Radian to Vector and Degree to Vector subroutines |
'| by |
'| Terry Ritchie |
'| 05/14/24 |
'| |
'| Convert radians or degrees to vector pairs using a |
'| pre-calculated lookup table or real-time calculation. |
'| Documentation contained in subs. |
'| |
'| R2VX!(radian, mode) - return radian x vector |
'| R2VY!(radian, mode) - return radian y vector |
'| D2VX!(degree, mode) - return degree x vector |
'| D2VY!(degree, mode) - return degree y vector |
'| SINE!(Index) - return SINE from lookup table |
'| COSINE!(Index) - return COSINE from lookup table |
'| |
'| R2VX!, R2VY!, D2VX!, and D2VY! return vector values |
'| based on the following input values: |
'| |
'| 0 = North 90 = East 180 = South 270 = West |
'| 0Pi = North .5Pi = East Pi = South 1.5Pi = West |
'| |
'| Degrees based on 0 to 359, radians from 0 to 2Pi. |
'+-------------------------------------------------------+
'+--------------------+
'| Begin demo program |
'+--------------------+
CONST MODE% = 0 ' (0 to use lookup table, 1 to calculate in real time)
DIM d AS SINGLE ' counter
SCREEN _NEWIMAGE(640, 480, 32)
' Draw line from center point using degree values passed in
FOR d = 0 TO 359
LINE (319, 239)-(319 + D2XV(d, MODE) * 200, 239 + D2YV(d, MODE) * 200)
_DELAY .005
NEXT d
SLEEP
CLS
' Draw line from center point using radian values passed in
FOR d = 0 TO 2 * _PI STEP 2 * _PI / 360
LINE (319, 239)-(319 + R2XV(d, MODE) * 200, 239 + R2YV(d, MODE) * 200)
_DELAY .005
NEXT d
'+------------------+
'| End demo program |
'+------------------+
'------------------------------------------------------------------------------------------------------------
FUNCTION R2XV! (rad AS SINGLE, mode AS INTEGER) ' radian to x vector
'+---------------------------------------------------------------------------+
'| Converts a radian value passed in to the corresponding x vector value. |
'| 0Pi = North/Up, .5Pi = East/Right, Pi = South/Down, 1.5Pi = West/Left. |
'| |
'| rad - the radian value to convert to x vector |
'| mode - 0 return value from lookup table, not 0 return calculated value |
'| |
'| Note: To use the lookup table the radian value needs to be converted to a |
'| degree value. The lookup table only contains the values for integer |
'| degrees ranging from 0 to 359. If you need a more precise |
'| calculation set mode above to a non xero integer value. |
'+---------------------------------------------------------------------------+
IF mode THEN ' calculate vector?
R2XV! = SIN(rad) ' yes, return calculated SINE value
ELSE ' no, use lookup table
R2XV! = SINE!(_R2D(rad)) ' return SINE value from table
END IF
END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION R2YV! (rad AS SINGLE, mode AS INTEGER) ' radian to y vector
'+---------------------------------------------------------------------------+
'| Converts a radian value passed in to the corresponding y vector value. |
'| 0Pi = North/Up, .5Pi = East/Right, Pi = South/Down, 1.5Pi = West/Left. |
'| |
'| rad - the radian value to convert to y vector |
'| mode - 0 return value from lookup table, not 0 return calculated value |
'| |
'| Note: To use the lookup table the radian value needs to be converted to a |
'| degree value. The lookup table only contains the values for integer |
'| degrees ranging from 0 to 359. If you need a more precise |
'| calculation set mode above to a non xero integer value. |
'+---------------------------------------------------------------------------+
IF mode THEN ' calculate vector?
R2YV! = -COS(rad) ' yes, return calculated COSINE value (negate so 0 = north)
ELSE ' no, use lookup table
R2YV! = -COSINE!(_R2D(rad)) ' return COSINE value from table (negate so 0 = north)
END IF
END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION D2XV! (deg AS SINGLE, mode AS INTEGER) ' degree to x vector
'+---------------------------------------------------------------------------+
'| Converts a degree value passed in to the corresponding x vector value. |
'| 0 = North / Up, 90 = East / Right, 180 = South / Down, 270 = West / Left. |
'| |
'| deg - the degree value to convert to x vector |
'| mode - 0 return value from lookup table, not 0 return calculated value |
'| |
'| Note: The lookup table only contains SIN/COS values for integer degrees |
'| ranging from 0 to 359. If you need a more precise calculation set |
'| mode above to a non zero integer value. |
'+---------------------------------------------------------------------------+
IF mode THEN ' calculate vector?
D2XV! = SIN(_D2R(deg)) ' yes, return calculated SINE value
ELSE ' no, use lookup table
D2XV! = SINE!(deg) ' return SINE value from table
END IF
END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION D2YV! (deg AS SINGLE, mode AS INTEGER) ' degree to y vector
'+---------------------------------------------------------------------------+
'| Converts a degree value passed in to the corresponding y vector value. |
'| 0 = North / Up, 90 = East / Right, 180 = South / Down, 270 = West / Left. |
'| |
'| deg - the degree value to convert to y vector |
'| mode - 0 return value from lookup table, not 0 return calculated value |
'| |
'| Note: The lookup table only contains SIN/COS values for integer degrees |
'| ranging from 0 to 359. If you need a more precise calculation set |
'| mode above to a non zero integer value. |
'+---------------------------------------------------------------------------+
IF mode THEN ' calculate vector?
D2YV! = -COS(_D2R(deg)) ' yes, return calculated COSINE value (negate so 0 = north)
ELSE ' no, use lookup table
D2YV! = -COSINE!(deg) ' return COSINE value from table (negate so 0 = north)
END IF
END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION SINE! (Index AS INTEGER) ' SINE lookup table
'+--------------------------------------------------+
'| Returns a SINE value from the SINE lookup table. |
'| |
'| Index - 0 to 359 |
'+--------------------------------------------------+
STATIC x(360) AS SINGLE ' SINE lookup table persistent values
DIM d AS INTEGER ' data counter
'+-----------------------------------------------------------------+
'| Build the SINE lookup table the first time subroutine is called |
'+-----------------------------------------------------------------+
IF x(90) = 0 THEN ' has the lookup table been built?
DO ' no, begin data read loop
READ x(d) ' SINE 0 through 90
x(180 - d) = x(d) ' SINE 90 through 180
x(180 + d) = -x(d) ' SINE 180 through 270
x(360 - d) = -x(d) ' SINE 270 through 360
d = d + 1 ' increment degree counter
LOOP UNTIL d = 91 ' leave when all data values read
END IF
SINE! = x(Index) ' return SINE
'+------------------------------------------------------------------------------------------------------+
'| The values for SINE 0 to 0.5PI (0 to 90 degrees) |
'| |
'| I know what you're thinking, "Why not just calculate these and then place the values into the array |
'| table?" I was getting strange anomolies in the returned values. For instance, sometimes .49999999 or |
'| .50000001 would show up for .5 and other times numbers like this would appear .58778552520000001. |
'| Creating and using this data set ensures consistent values. |
'+------------------------------------------------------------------------------------------------------+
DATA 0
DATA .017452406,.034899496,.052335956,.069756473,.087155742,.104528463,.121869343,.139173100,.156434465
DATA .173648177,.190808995,.207911690,.224951054,.241921895,.258819045,.275637355,.292371704,.309016994
DATA .325568154,.342020143,.358367949,.374606593,.390731128,.406736643,.422618261,.438371146,.453990499
DATA .469471562,.484809620,.500000000,.515038074,.529919264,.544639035,.559192903,.573576436,.587785252
DATA .601815023,.615661475,.629320391,.642787609,.656059028,.669130606,.681998360,.694658370,.707106781
DATA .719339800,.731353701,.743144825,.754709580,.766044443,.777145961,.788010753,.798635510,.809016994
DATA .819152044,.829037572,.838670567,.848048096,.857167300,.866025403,.874619707,.882947592,.891006524
DATA .898794046,.906307787,.913545457,.920504853,.927183854,.933580426,.939692620,.945518575,.951056516
DATA .956304755,.961261695,.965925826,.970295726,.974370064,.978147600,.981627183,.984807753,.987688340
DATA .990268068,.992546151,.994521895,.996194698,.997564050,.998629534,.999390827,.999847695,1.00000000
END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION COSINE! (Index AS INTEGER) ' COSINE lookup table
'+---------------------------------------------------+
'| Returns a COSINE value from the SIN lookup table. |
'| |
'| Index - 0 to 359 |
'+---------------------------------------------------+
SELECT CASE Index ' which array index to return?
CASE 0 TO 89 ' quadrant 1
COSINE! = SINE!(90 - Index) ' return equivalent from SINE table
CASE 90 TO 179 ' quadrant 2
COSINE! = -SINE!(Index - 90) ' return equivalent from SINE table
CASE 180 TO 269 ' quadrant 3
COSINE! = -SINE!(270 - Index) ' return equivalent from SINE table
CASE 270 TO 359 ' quadrant 4
COSINE! = SINE!(Index - 270) ' return equivalent from SINE table
END SELECT
END FUNCTION
|
|
|
Vintage programming |
Posted by: BigPete - 05-14-2024, 11:53 AM - Forum: General Discussion
- Replies (4)
|
|
Greetings all.
100% New here.
I normally program for windows, but i miss the good old days where stuff were so much simpler.
I also realize how much I have forgotten about Qbasic and the stuff I enjoyed.
My request is not really serious, but rather curious as to certain processes that I saw in VBDOS that were carried over into windows.
It is easy to use pre-existing controls in visual designers, but how on earth did Microsoft create those basic controls for VB dos??
Like: On a dos screen in QB64 I set width to 140, 50 which looks much like the old DOS screens.
Drawing boxes with Ascii codes using commands SUBs is pretty fun, but it is just lines and text.
How would one try and create a basic FORM in Screen 0 that looks like VBDOS (the draw is easy) that you could MOVE and open another?
It has to be some image clipping of sorts and event trapping?
I am having loads of fun, but i also realize how much i have become dependent on other people's designers without understanding the core processes that runs it.
Some ideas would be much appreciated.
Regards, Pete
|
|
|
|