Welcome, Guest |
You have to register before you can post on our site.
|
Forum Statistics |
» Members: 490
» Latest member: Dr.Creek
» Forum threads: 2,826
» Forum posts: 26,485
Full Statistics
|
Latest Threads |
ANSIPrint
Forum: a740g
Last Post: grymmjack
2 hours ago
» Replies: 1
» Views: 43
|
Rock Jockey 2.0 is ready ...
Forum: Games
Last Post: madscijr
3 hours ago
» Replies: 13
» Views: 439
|
decfloat -- again
Forum: Programs
Last Post: Jack
4 hours ago
» Replies: 41
» Views: 2,896
|
games or graphics for 3-D...
Forum: General Discussion
Last Post: madscijr
Today, 04:39 AM
» Replies: 28
» Views: 1,069
|
Button rack or hotkey fun...
Forum: Utilities
Last Post: eoredson
Today, 12:00 AM
» Replies: 5
» Views: 358
|
trouble building ansiprin...
Forum: Help Me!
Last Post: a740g
Yesterday, 11:39 PM
» Replies: 1
» Views: 29
|
DRAW to generate the poin...
Forum: QBJS, BAM, and Other BASICs
Last Post: CharlieJV
Yesterday, 07:15 PM
» Replies: 0
» Views: 37
|
Next small EQ step - EQ D...
Forum: Petr
Last Post: Petr
Yesterday, 06:08 PM
» Replies: 9
» Views: 466
|
What do you guys like to ...
Forum: General Discussion
Last Post: OldMoses
Yesterday, 03:35 PM
» Replies: 32
» Views: 913
|
Happy Birthday Terry Ritc...
Forum: General Discussion
Last Post: madscijr
Yesterday, 07:29 AM
» Replies: 21
» Views: 821
|
|
|
ASCII Animations |
Posted by: SpriggsySpriggs - 10-21-2023, 07:15 AM - Forum: Programs
- Replies (6)
|
|
Inspired by the thread started by mnrvovrfc (https://qb64phoenix.com/forum/showthread.php?tid=2112), I converted the whole Rick Astley - Never Gonna Give You Up music video to an ASCII animation.
And the code:
Code: (Select All)
Option Explicit
$NoPrefix
Screen NewImage(80, 25)
'You know the rules and so do I
Sleep
Open "B", 1, "rickroll.txt"
Dim As Long x
Dim As String pic, buf
Dim As Long s: s = SndOpen("02 - Rick Astley - Never Gonna Give You Up.flac", "STREAM")
If s Then SndPlay (s)
While Not EOF(1)
For x = 0 To 24
If EOF(1) = 0 Then
Line Input #1, buf
pic = pic + buf
End If
Next
Cls
Print Mid$(pic, 2)
Limit 60
pic = ""
If EOF(1) Then Exit While
Wend
Close
Converted the video like this:
1) Download a GIF or video with plain background, preferably white. In my case, I had to get the green screen version of the music video and then use Kdenlive to make it white.
2) Use ffmpeg to convert the video/GIF into a JPEG image sequence
Code: (Select All) ffmpeg -i rickroll.mkv -vsync 0 rickroll/rickroll_%d.jpg
3) Use a Python script
img2ascii.txt (Size: 3.15 KB / Downloads: 49)
(save as img2ascii.py) in a bash loop to iterate over each frame and convert them into ASCII text files
Code: (Select All) #!/bin/bash
for filename in rickroll/*.jpg; do
sem -j+0 python img2ascii.py --file "$filename" --out rickroll/$(basename "$filename".txt)
done
#you might have to kill this sem call to proceed
sem --wait
cat $(find rickroll/ -name "rickroll_*.jpg.txt" | sort -V) >> rickroll.txt
rm rickroll/rickroll_*.jpg.txt
echo "DONE"
4) Monitor the output of the script. It will tell you how many columns and rows the images are. Set your QB64 up for that many columns and rows for a perfect output!
5) ???
6) Profit
If you don't want to go through all that and just want to run it:
Linux -
rickroll_lnx.zip (Size: 30.2 MB / Downloads: 78)
Windows -
rickroll_win.zip (Size: 30.51 MB / Downloads: 81)
|
|
|
Integer (math) Single = Single |
Posted by: SMcNeill - 10-20-2023, 12:16 AM - Forum: General Discussion
- No Replies
|
|
So here's something that was glitching the heck out of one of my programs earlier, that you guys might not be aware of:
Code: (Select All)
$Console:Only
Dim f As _Float, i As _Integer64
f = 1: i = 1: g = 1
For x = 1 To 10
Print x, f,
Locate , 30: Print i
f = f * 10 + x
i = i * 10 + x
Next
Now, if you run that, you end up with the following results: Code: (Select All) 1 1 1
2 11 11
3 112 112
4 1123 1123
5 11234 11234
6 112345 112345
7 1123456 1123456
8 11234567 11234567
9 112345678 112345680
10 1123456789 1123456768
If you see our math here, we basically take the previous number, multiply it by 10, and then add the previous pass value. (times 10 + 1)
But take a close look at what happens to our integer value once we get up past 7 digits -- it screws up!!
The reason??
Single precision values are limited to 8 digits and then they swap over to scientific notation.
The math here does the integer part correctly. 11234567 * 10 = 112345670
But the math with the SINGLE variable x gives us a SINGLE value as a return: 112345670 + 8 = 1.12345678E8
Which we then assign to our integer64 variable so it now becomes 1123456780.
If you want to avoid this glitch, change X from being a SINGLE variable to becoming a DOUBLE (or _FLOAT), which can hold enough digits to do the proper math without giving scientific notation results (which result in rounding).
Just one more thing to tuck under your hat and be aware of when programming and working with numbers larger than you can easily count on your fingers and toes.
|
|
|
How many parameters are too many parameters? |
Posted by: SMcNeill - 10-19-2023, 02:16 AM - Forum: General Discussion
- Replies (5)
|
|
Another of my Steve's Overengineered Routines:
Code: (Select All)
Option _Explicit
Screen _NewImage(1280, 720, 32)
$Color:32
'Box (Mode As Integer, X1 As Integer, Y1 As Integer, X2 As Integer, Y2 As Integer, Caption As String, _
' FontColor As _Unsigned Long, FontBackground As _Unsigned Long, BoxColor As _Unsigned Long, _
' BoxHighLight As _Unsigned Long, XOffset As Integer, YOffset As Integer
'Mode 0 (or any unsupported number) will tell the box to size itself from X1,Y1 to X2,Y2
'Mode 1 will tell the box to autosize itself according to whatever text is placed within it.
'Mode 2 will tell the box to use X2 and Y2 as relative coordinates and not absolute coordinates. (Width and Height of box.)
'Mode 3 will tell the box to autocenter text with X2, Y2 being absolute coordinates.
'Mode 4 will tell the box to autocenter text with X2, Y2 being relative coordinates. (Width and Height of box.)
'X1/Y1 carries the X/Y location of where we want to place our box on the screen.
'X2/Y2 is the X/Y boundry of our box on the screen, depending on our mode.
'Caption is the text that we want our box to contain.
'FontColor is our font color for our caption and FontBackground is the font background color for our caption
'BoxColor is our box color and BoxHighlight is our box highligh colors
'XOffset/YOFFSET is used to offset our text # pixels from the X1/Y1 position.
Dim i As Long
For i = 0 To 4
Print "Showcasing diffferent modes for Box. This is mode #"; i
Box i, 100, 100, 200, 200, "Hello World", Red, Blue, Gold, Silver, 0, 0
Sleep
Cls
Next
Sub Box (Mode As Integer, X1 As Integer, Y1 As Integer, X2 As Integer, Y2 As Integer, Caption As String, FontColor As _Unsigned Long, FontBackground As _Unsigned Long, BoxColor As _Unsigned Long, BoxHighLight As _Unsigned Long, XOffset As Integer, YOffset As Integer)
'This is an upgrade version of my original Button routine.
'It's more versitile (but complex) than the original.
'Mode 0 (or any unsupported number) will tell the box to size itself from X1,Y1 to X2,Y2
'Mode 1 will tell the box to autosize itself according to whatever text is placed within it.
'Mode 2 will tell the box to use X2 and Y2 as relative coordinates and not absolute coordinates.
'Mode 3 will tell the box to autocenter text with X2, Y2 being absolute coordinates.
'Mode 4 will tell the box to autocenter text with X2, Y2 being relative coordinates.
'Mode otherwise is unused, but available for expanded functionality.
'X1 carries the X location of where we want to place our box on the screen.
'Y2 carries the Y location of where we want to place our box on the screen.
'X2 is the X boundry of our box on the screen, depending on our mode.
'Y2 is the Y boundry of our box on the screen, depending on our mode.
'Caption is the text that we want our box to contain.
'FontColor is our font color for our caption
'FontBackground is the font background color for our caption
'NOTE: IF FONTCOLOR OR FONTBACKGROUND IS SET TO ZERO, THEY WILL **NOT** AFFECT THE COLOR BEHIND THEM.
'This can be used to mimic the function of _KEEPBACKGROUND, _FILLBACKGROUND, or _ONLYBACKGROUND
'BoxColor is our box color
'BoxHighlight is our box highligh colors
'NOTE: SAME WITH BOXCOLOR AND BOXHIGHLIGHT. IF SET TO ZERO, THEY WILL HAVE **NO** COLOR AT ALL TO THEM, AND WILL NOT AFFECT THE BACKGROUND OF ANYTHING BEHIND THEM.
'XOffset is used to offset our text # pixels from the X1 top.
'YOffset is used to offset our text # pixels from the Y1 top.
'These can be used to place our text wherever we want on our box.
'But remember, if Mode = 3 or 4, the box will autocenter the text and ignore these parameters completely.
Dim BoxBlack As _Unsigned Long
Dim As Long dc, bg, cw, ch
dc& = _DefaultColor: bg& = _BackgroundColor
BoxBlack = _RGB32(0, 0, 0)
cw = _PrintWidth(Caption): ch = _FontHeight
Select Case Mode
Case 0
'We use the X2, Y2 coordinates provided as absolute coordinates
Case 1
X2 = X1 + cw + 8
Y2 = Y1 + ch + 8
XOffset = 5: YOffset = 5
Case 2
X2 = X1 + X2
Y2 = Y1 + Y2
Case 3
XOffset = (X2 - X1 - cw) \ 2
YOffset = (Y2 - Y1 - ch) \ 2
Case 4
X2 = X1 + X2
Y2 = Y1 + Y2
XOffset = (X2 - X1 - cw) \ 2
YOffset = (Y2 - Y1 - ch) \ 2
End Select
Line (X1, Y1)-(X2, Y2), BoxBlack, BF
Line (X1 + 1, Y1 + 1)-(X2 - 1, Y2 - 1), BoxHighLight, B
Line (X1 + 2, Y1 + 2)-(X2 - 2, Y2 - 2), BoxHighLight, B
Line (X1 + 3, Y1 + 3)-(X2 - 3, Y2 - 3), BoxBlack, B
Line (X1, Y1)-(X1 + 3, Y1 + 3), BoxBlack
Line (X2, Y1)-(X2 - 3, Y1 + 3), BoxBlack
Line (X1, Y2)-(X1 + 3, Y2 - 3), BoxBlack
Line (X2, Y2)-(X2 - 3, Y2 - 3), BoxBlack
Line (X1 + 3, Y1 + 3)-(X2 - 3, Y2 - 3), BoxColor, BF
Color FontColor, FontBackground
_PrintString (X1 + XOffset, Y1 + YOffset), Caption$
Color dc&, bg&
End Sub
Function BoxImage& (Mode As Integer, X As Integer, Y As Integer, Caption As String, FontColor As _Unsigned Long, FontBackground As _Unsigned Long, BoxColor As _Unsigned Long, BoxHighLight As _Unsigned Long, XOffset As Integer, YOffset As Integer)
'This creates our box as an image so we can manipulate it however we wish before placing it on the screen.
'Mode 0 will tell the box to draw itself X,Y size, and autocenter the text.
'Mode 1 will tell the box to autosize itself according to whatever text is placed within it.
'Mode 2 will tell the box to draw itself X,Y size, and place the text at the offsets.
'Mode otherwise is unused, but available for expanded functionality.
'Caption is the text that we want our box to contain.
'FontColor is our font color for our caption
'FontBackground is the font background color for our caption
'NOTE: IF FONTCOLOR OR FONTBACKGROUND IS SET TO ZERO, THEY WILL **NOT** AFFECT THE COLOR BEHIND THEM.
'This can be used to mimic the function of _KEEPBACKGROUND, _FILLBACKGROUND, or _ONLYBACKGROUND
'BoxColor is our box color
'BoxHighlight is our box highligh colors
'NOTE: SAME WITH BOXCOLOR AND BOXHIGHLIGHT. IF SET TO ZERO, THEY WILL HAVE **NO** COLOR AT ALL TO THEM, AND WILL NOT AFFECT THE BACKGROUND OF ANYTHING BEHIND THEM.
'XOffset is used to offset our text # pixels from the X1 top.
'YOffset is used to offset our text # pixels from the Y1 top.
'These can be used to place our text wherever we want on our box.
'But remember, if Mode = 3 or 4, the box will autocenter the text and ignore these parameters completely.
Dim BoxBlack As _Unsigned Long
Dim As Long dc, bg, cw, ch
Dim As Long X1, Y1, X2, Y2, tempBoxImage
dc& = _DefaultColor: bg& = _BackgroundColor
BoxBlack = _RGB32(0, 0, 0)
cw = _PrintWidth(Caption): ch = _FontHeight
X1 = 0: Y1 = 0
X2 = X: Y2 = Y
Select Case Mode
Case 0
X2 = X1 + cw + 8
Y2 = Y1 + ch + 8
XOffset = 5: YOffset = 5
Case 2
XOffset = (X2 - cw) \ 2
YOffset = (Y2 - ch) \ 2
End Select
tempBoxImage& = _NewImage(X, Y, 32)
_Dest tempBoxImage&
Line (X1, Y1)-(X2, Y2), BoxBlack, BF
Line (X1 + 1, Y1 + 1)-(X2 - 1, Y2 - 1), BoxHighLight, B
Line (X1 + 2, Y1 + 2)-(X2 - 2, Y2 - 2), BoxHighLight, B
Line (X1 + 3, Y1 + 3)-(X2 - 3, Y2 - 3), BoxBlack, B
Line (X1, Y1)-(X1 + 3, Y1 + 3), BoxBlack
Line (X2, Y1)-(X2 - 3, Y1 + 3), BoxBlack
Line (X1, Y2)-(X1 + 3, Y2 - 3), BoxBlack
Line (X2, Y2)-(X2 - 3, Y2 - 3), BoxBlack
Line (X1 + 3, Y1 + 3)-(X2 - 3, Y2 - 3), BoxColor, BF
Color FontColor, FontBackground
_PrintString (X1 + XOffset, Y1 + YOffset), Caption$
Color dc&, bg&
_Dest 0
BoxImage = tempBoxImage
End Function
Function TextScreenToImage256& (image&)
Dim As Long d, s, i, f, fw, fh, w, h, l
Dim As Long tempScreen, Screen0to256
Dim m As _MEM, b As _Unsigned _Byte, t As String * 1
Dim o As _Offset
d& = _Dest: s& = _Source
Dim Plt(15) As Long
_Source image&: _Dest image&
For i = 0 To 15: Plt(i) = _PaletteColor(i, image&): Next
f& = _Font(image&)
_Font f&
fw& = _FontWidth
fh& = _FontHeight
w& = _Width * _FontWidth
h& = _Height * _FontHeight '+ _HEIGHT
l& = (_Width * _Height) * 2 'The screen is width * height in pixels. (80X25) = 2000 X 2 bytes each = 4000 total bytes to hold a page of screen 0 text and color
tempScreen& = _NewImage(w&, h& + _Height, 256)
Screen0to256& = _NewImage(w&, h&, 256)
m = _MemImage(image&)
o = m.OFFSET
_Dest (tempScreen&)
For i = 0 To 15: _PaletteColor i, Plt(i): Next
_Font f&
For i = 0 To l& - 2 Step 2
_MemGet m, m.OFFSET + i, t
_MemGet m, m.OFFSET + i + 1, b
If b > 127 Then b = b - 128
Color b Mod 16, b \ 16
Print t;
Next
_PutImage , tempScreen&, Screen0to256&, (0, 0)-(w&, h&)
_FreeImage tempScreen&
_Dest d&: _Source s&
_MemFree m
TextScreenToImage256 = Screen0to256&
End Function
Function TextScreenToImage32& (image&)
Dim As Long d, s, i, f, fw, fh, w, h, l, fgc, bgc
Dim As Long tempScreen, Screen0To32
d& = _Dest: s& = _Source
Dim Plt(15) As Long
_Source image&
For i = 0 To 15: Plt(i) = _PaletteColor(i, image&): Next
f& = _Font(image&)
_Font f&
fw& = _FontWidth
fh& = _FontHeight
w& = _Width * _FontWidth
h& = _Height * _FontHeight '+ _HEIGHT
l& = (_Width * _Height) * 2 'The screen is width * height in pixels. (80X25) = 2000 X 2 bytes each = 4000 total bytes to hold a page of screen 0 text and color
tempScreen& = _NewImage(w&, h& + _Height, 32)
Screen0To32& = _NewImage(w&, h&, 32)
_Dest tempScreen&
Dim m As _MEM, b As _Unsigned _Byte, t As String * 1
Dim o As _Offset
m = _MemImage(image&)
o = m.OFFSET
_Font f&
For i = 0 To l& - 2 Step 2
_MemGet m, m.OFFSET + i, t
_MemGet m, m.OFFSET + i + 1, b
If b > 127 Then b = b - 128
fgc = b Mod 16: bgc = b \ 16
Color _RGB32(_Red(fgc, image&), _Green(fgc, image&), _Blue(fgc, image&)), _RGB32(_Red(bgc, image&), _Green(bgc, image&), _Blue(bgc, image&))
Print t;
Next
_PutImage , tempScreen&, Screen0To32&, (0, 0)-(w&, h&)
_FreeImage tempScreen&
_Dest d&: _Source s&
_MemFree m
TextScreenToImage32 = Screen0To32&
End Function
Function BinaryStringSearch (search$, Array() As String)
'These routines work with actual indexes, so we can search from Array(-10 to 10), if we want to.
'When the search string is found, it'll return a value = to the index proper.
'When it's not found, it'll return a value LESS THAN the LBOUND limit of the array,
'And the point where the string WOULD'VE appeared, if it existed, is after the shared variable LastIndex
BinaryStringSearch = BinaryStringSearchSome(search$, Array(), LBound(Array), UBound(Array))
End Function
Function BinaryStringSearchSome (search$, Array() As String, StartIndex As Long, EndIndex As Long)
'These routines work with actual indexes, so we can search from Array(-10 to 10), if we want to.
'When the search string is found, it'll return a value = to the index proper.
'When it's not found, it'll return a value LESS THAN the LBOUND limit of the array,
'And the point where the string WOULD'VE appeared, if it existed, is after the shared variable LastIndex
Dim As Long min, max, compare, LastIndex, found
Dim As _Float gap
min = StartIndex
max = EndIndex
Do
gap = (max + min) \ 2
compare = _StrCmp(search$, Array(gap))
If compare > 0 Then
min = gap + 1
ElseIf compare < 0 Then
max = gap - 1
Else
BinaryStringSearchSome = gap
Exit Function
End If
If max - min < 1 Then
If search$ = Array(min) Then
BinaryStringSearchSome = min
Else
BinaryStringSearchSome = LBound(Array) - 1
If search$ < Array(min) Then
LastIndex = min - 1
Else
LastIndex = min
End If
End If
found = -1
End If
Loop Until found
End Function
Sub StringSortSome (Array() As String, StartIndex As Long, EndIndex As Long)
Dim As Long min, max, i, swapped
Dim As _Float gap
min = StartIndex
max = EndIndex
gap = EndIndex - StartIndex + 1
Do
gap = 10 * gap \ 13
If gap < 1 Then gap = 1
i = StartIndex
swapped = 0
Do
If _StrCmp(Array(i), Array(i + gap)) > 0 Then
Swap Array(i), Array(i + gap)
swapped = -1
End If
i = i + 1
Loop Until i + gap > EndIndex
Loop Until swapped = 0 And gap = 1
End Sub
Sub StringSort (Array() As String)
StringSortSome Array(), LBound(Array), UBound(Array)
End Sub
Only 12 parameters in this one. (The one that turns the box into an image is even more!)
So my question is: How many parameters are TOO MANY parameters? Little routines like this one can be expanded in sooo many different ways. (A parameter for the width of the border/highlight. One for if we want shading, and one for what shade of shading, and which direction it should shade in. One for a rotation, or a scale factor, or if we allow blending or not...)
Do you guys have some hard and fast limit that you tend to use for how many parameters you attach to a sub or function? I'm just curious about what other folks opinions are for this type of ultra-versatile routine.
|
|
|
Best Practice for Library Building and Toolboxes |
Posted by: bplus - 10-18-2023, 12:10 PM - Forum: General Discussion
- Replies (21)
|
|
@SMcNeill, @RhoSigma and @TerryRitchie
I don't remember seeing this discussion for Libraries and would very much like to review the results you agreed upon (if you did) actually the thinking and reasoning behind the guidelines would be best for review.
A review might aid Terry's tutorial as well.
I do have some ideas for guidelines in building Toolboxes.
1. Have code that tests each sub and function perhaps against other methods. I have a folder called Test just for that purpose each file is a routine or related few. Make notes why you did this and that. If something goes wrong using the routine go back to this test file and update the routine. Rule of thumb question: "Can you ever test enough?"
2. All the best subs and function are pasted into 000Handy at the top of my QB64 Work Folder for easy access and helps see if they can coexist ie no name conflicts.
3. If the routine needs another sub or function be sure to make note of it.
4. Avoiding dependence of constants from Main program but list inside sub if you are using a UDT or constant or anything that needs inclusion in main code so routine works.
That's a few from the top of my head for toolboxes, I am big fan of copy / paste from toolbox to get just the routines I need into the app I am working so no extra library files needed. But I don't write giant programs either except GUI, oh Interpreter and FVal$ is getting there specially when finish adding String Math and Astring Functions.
Toolbox Advantage: after pasted into app, you can modify as needed for app without screwing up the toolbox code. That is pretty hard to do with Library Code, I found out over and over with GUI stuff.
|
|
|
Cube Game from scratch |
Posted by: bplus - 10-18-2023, 02:12 AM - Forum: Programs
- Replies (2)
|
|
Before I saw the correct version of Cube from Morristown I thought the game would benefit from a mapping display for "You are here." But the way input was setup with Morristown code it was clear where you've been and where you could go next. Anyway here is my version made from scratch.
Oh a couple of mods to game:
1. to make input as easy and simple as possible you only enter one letter for your move
2. that one letter increases player one step on x, y or z plane
3. Wager is out but when you succeed to 3,3,3 you earn 1000 first time and are offered the opportunity to play again to double your money or lose it all and end game.
Code: (Select All) Option _Explicit ' best practice
DefLng A-Z ' all numbers are integers
Randomize Timer ' for different mining at start
_Title "Cube From Scratch" ' bplus 2023-10-17
' a demo of developing code from a commented text of code specs
' try standard demo screen for QB64
Const Xmax = 800, Ymax = 600 ' screen width and height
Screen _NewImage(Xmax, Ymax, 12) ' 12 is 16 color old QB system
_ScreenMove 240, 80
' Define all Shared variables here with caps
' So to do this game called Cube from scratch you need a Cube array (x, y, z)
' where each x, y, or z is a number from 1 to 3
Dim Shared Cube(1 To 3, 1 To 3, 1 To 3)
Dim Shared Px, Py, Pz ' players position
Dim Shared MoneyUnits ' points from success(es?)
Dim Shared GameOver ' player stepped on Mine flag
Dim Shared GameWin ' player made it to 3,3,3
Intro
Do ' how many times can you make it to 3,3,3 and double your money?
InitGame
Do ' game round
DisplayCube 0 ' display cube but not the mines
HandleRound ' <<< game ends in here
If GameWin Then Exit Do
_Limit 30
Loop
Loop
Sub DisplayCube (showMines) ' flags both GameOver and GameWin
Dim x, y, z, zz, yy, xx, rn
Cls
' 3 grids one for each z level
' x ascends going right
' y ascends going down
' z ascends going right
_PrintString (179, 170), "z = 1"
drawGrid 150, 50, 50, 50, 2, 2
_PrintString (379, 170), "z = 2"
drawGrid 350, 50, 50, 50, 2, 2
_PrintString (579, 170), "z = 3"
drawGrid 550, 50, 50, 50, 2, 2
For z = 1 To 3
zz = 150 + 200 * (z - 1)
For y = 1 To 3
yy = 50 + 50 * (y - 1)
For x = 1 To 3
xx = zz + 50 * (x - 1)
If Px = x And Py = y And Pz = z Then ' draw player
For rn = 0 To 6
Circle (xx, yy), rn, 9
Next
If Px = 3 And Py = 3 And Pz = 3 Then GameWin = -1 'celebrate!
End If
If Cube(x, y, z) Then ' a mine is here
If showMines Then
For rn = 1 To 10 Step 2
Circle (xx, yy), rn, 12
Next
End If
If Px = x And Py = y And Pz = z Then GameOver = -1 'doomed
End If
Next
Next
Next
End Sub
Sub HandleRound
Dim ok$, plane$
If GameOver Then ' Round ender
DisplayCube -1 ' show where mines were
Beep
Color 14
yCP 23, "BOOM!"
yCP 25, "Player you stepped on a mine."
yCP 27, "Game Over!"
Sleep
End
ElseIf GameWin Then ' Round ender
' made it! award 1000 or double money and offer to double it
DisplayCube -1 ' show where mines were
If MoneyUnits Then MoneyUnits = 2 * MoneyUnits Else MoneyUnits = 1000
yCP 12, "You have earned" + Str$(MoneyUnits)
yCP 14, "Do you want to play again for chance to double your money?"
yCP 16, "Just press y + enter or just enter for yes, any other + enter = quit."
Locate 23, 50: Input ok$
If ok$ = "" Or ok$ = "y" Then Else End
Else ' still going round get next move, get player move
Locate 20, 32
Input "Enter x, y, or z for the next step "; plane$
plane$ = LCase$(plane$)
If Px < 3 And plane$ = "x" Then
Px = Px + 1
ElseIf Py < 3 And plane$ = "y" Then
Py = Py + 1
ElseIf Pz < 3 And plane$ = "z" Then
Pz = Pz + 1
End If
End If
End Sub
Sub Intro ' Start with clear description of the Game as Intro:
Dim ok$
yCP 5, "*** Cube from scratch ***"
yCP 6, "bplus 2023-10-17"
yCP 10, "You, the player, are starting at position 1,1,1 on wire frame cube 3x3x3"
yCP 11, "and your objective is to reach 3,3,3 in single step moves."
yCP 12, "You move on x, y, or z planes by 1 step forward no side or back stepping."
yCP 14, "A Miner has preceeded you from 1,1,1 to 3,3,3 and laid mines down his path."
yCP 16, "If you step on a mine, BOOM Game Over, so sorry this is a stupid game of pure luck!"
yCP 18, "If you make it to 3,3,3 you will be awarded 1000 money units PLUS"
yCP 19, "you will be offered opportunity to double your money units and play again."
yCP 22, "Press enter to play, any other + enter quits..."
Locate 30, 50: Input ; ok$
If ok$ <> "" Then System
End Sub
Sub InitGame ' Reset variables and mine cube
Dim mx, my, mz ' Minor's position
Dim rn ' random number
Erase Cube
Px = 1: Py = 1: Pz = 1
mx = 1: my = 1: mz = 1
GameWin = 0
' Mine the cube by making one path from start to goal
' So where cube(x,y,z) = 0 it is safe for player to go ie move into.
While mx <> 3 Or my <> 3 Or mz <> 3
rn = rndI&(1, 3)
If rn = 1 Then
If mx < 3 Then
mx = mx + 1
ElseIf my < 3 Then
my = my + 1
Else
mz = mz + 1
End If
ElseIf rn = 2 Then
If my < 3 Then
my = my + 1
ElseIf mz < 3 Then
mz = mz + 1
Else
mx = mx + 1
End If
Else
If mz < 3 Then
mz = mz + 1
ElseIf mx < 3 Then
mx = mx + 1
Else
my = my + 1
End If
End If
If mx = 3 And my = 3 And mz = 3 Then Else Cube(mx, my, mz) = 1 ' mined
Wend
End Sub
Sub yCP (RowNum&, s$) ' for graphics screen Center Print rowNum * 20 per row = y
_PrintString ((_Width - _PrintWidth(s$)) / 2, RowNum& * 20), s$
End Sub
Function rndI& (n1 As Long, n2 As Long) 'return an integer between 2 numbers
Dim As Long l, h
If n1 > n2 Then l = n2: h = n1 Else l = n1: h = n2
rndI& = Int(Rnd * (h - l + 1)) + l
End Function
Sub drawGrid (x, y, xs, ys, xn, yn) ' top left x, y, x side, y side, number of x, nmber of y
Dim As Long i, dx, dy
dx = xs * xn: dy = ys * yn
For i = 0 To xn
_PrintString (x + xs * i - 4, y - 24), _Trim$(Str$(i + 1))
Line (x + xs * i, y)-(x + xs * i, y + dy)
Next
For i = 0 To yn
_PrintString (x - 20, y + ys * i - 8), _Trim$(Str$(i + 1))
Line (x, y + ys * i)-(x + dx, y + ys * i)
Next
End Sub
|
|
|
Ascii ClipDoodle (text screen art) |
Posted by: James D Jarvis - 10-16-2023, 09:40 PM - Forum: Works in Progress
- Replies (10)
|
|
A multi-window program to draw ASCII-art.
The program consists of the main program and 2 other programs that must also be compiled for this to function properly.
sorry V0.2 for Windows only due to the clipboard use. V0.3 doesn't use the clipboard commands
Thanks to SMcNeil for the excellent text screen saving routines.
EDIT: V0.3 entries for all 3 programs are in a later post to this thread. Hopefully it will work on other systems.
Code: (Select All)
'Ascii Clipdoodle V 0.2
'an ascii doodle pad that opens control panel apps in other windows
'
'sorry windows only
'
'loadtextimage and savetextimage from SMcNeil at https://qb64phoenix.com/forum/showthread.php?tid=2022
'
'pickclip.exe and colorpick16.exe must be compiled before this program will function properly
Dim Shared reflag
reflag = -1
Dim Shared helpscreen As Long
Dim Shared twd, tht
twd = 80: tht = 25
helpscreen = _NewImage(twd, tht, 0)
Dim Shared mainscreen As Long
mainscreen = _NewImage(80, 25, 0) 'default size text screen. feel free to change it.
Screen mainscreen
_Title "Ascii ClipDoodle"
Cls
_Clipboard$ = "ClipDoodleOn" ' "clears" clipboard for use
Shell _DontWait "pickclip.exe" ' Open the pickclip control panel
Shell _DontWait "colorpick16.exe" ' Open the colorpick16 control panel
_ControlChr Off
AK = 42
Do
_Limit 100
Do While _MouseInput 'mouse status changes only
_Limit 2000
x = _MouseX
y = _MouseY
px = _MouseX: py = _MouseY
If _MouseButton(1) Then
_PrintString (x, y), brush$
End If
Loop
kk$ = InKey$
Select Case kk$
Case "t", "T" 'type on current line with current color characteristics
_KeyClear
Do
Do
_Limit 60
tk$ = InKey$
Loop Until tk$ <> ""
If tk$ = Chr$(8) Then
tk$ = ""
px = px - 1
End If
If tk$ <> Chr$(13) And tk$ <> "" Then
_PrintString (px, py), tk$
px = px + 1
If px > _Width Then tk$ = Chr$(13) 'exit type input if attempting to type outside screen
End If
Loop Until tk$ = Chr$(13)
Case "S" 'save text screen
filef = 0
file$ = _SaveFileDialog$("Save File", "", "*.SAV", "SAved text screen")
If file$ <> "" Then
filef = 1
_MessageBox "Information", "File will be saved to " + file$
End If
If filef = 1 Then
SaveTextImage 0, file$
_MessageBox "Image SAved", "Text Images SAVED to " + file$
End If
filef = 0
Case "L", "O" 'load text screen
file$ = _OpenFileDialog$("Open File", "", "*.SAV", "SAVed text screen", -1)
If file$ <> "" Then
_MessageBox "Information", "You selected " + file$
'mainscreen = LoadTextImage(file$)
Screen LoadTextImage(file$)
tht = _Height
twid = _Width
End If
Case "C" 'clear screen
cc = _MessageBox("CLEAR SCREEN", "Are you sure you want to clear the screen? The image will be lost if it has not been saved. ", "yesnocancel", "warning", 0)
If cc = 1 Then Cls
Case Chr$(27)
cc = _MessageBox("QUIT !", "Are you sure you wish to QUIT? The image will be lost if it has not been saved. ", "yesnocancel", "warning", 0)
If cc = 1 Then Else kk$ = ""
Case "R"
do_resize
Case "?" 'help
do_help
End Select
ik$ = _Clipboard$
If Left$(ik$, 2) = "AC" Then AK = Val(Right$(ik$, Len(ik$) - 2))
If Left$(ik$, 2) = "CK" Then
ff$ = " "
n = 2
Do
n = n + 1
A$ = Mid$(ik$, n, 1)
If A$ <> "/" Then ff$ = ff$ + A$
Loop Until A$ = "/"
bb$ = ""
Do
A$ = Mid$(ik$, n, 1)
If A$ <> "/" Then bb$ = bb$ + A$
n = n + 1
Loop Until n > Len(ik$)
FG = Val(ff$): BG = Val(bb$)
Color FG, BG
End If
brush$ = Chr$(AK)
Loop Until kk$ = Chr$(27)
_Clipboard$ = "QUITCOLORPICK16"
Sleep 1
_Clipboard$ = "QUITCLIPPICK"
System
Sub do_help
ls& = _Dest
Screen helpscreen
Cls
Print "HELP"
Print "------------------"
Print "use mouse to draw with ascii characters"
Print "select character to draw and colors from control panels"
Print " "
Print "<ESC> to quit program"
Print "t,T - To type a line of text in colors picked"
Print
Print "S - To Save Screen"
Print "L,O - to Load Saved Screen"
Print "C - to clear screen"
print "R - to Resize Screen (WARNING : DESTRUCTIVE)"
Print
Print "press any key to continue"
Sleep
Screen ls&
End Sub
Sub do_resize
ls& = _Dest
Screen helpscreen
Cls
Print "Resize"
Print "------------------"
Print "Current size "
Print "width "; twd, "Height "; tht
Print "Enter new coordinates"
Input "Width "; twd
Input "Height"; tht
_FreeImage ls&
Screen _NewImage(twd, tht, 0)
End Sub
Function LoadTextImage& (SaveFile As String) 'create and load to a new Screen 0 screen with our saved image
Dim As Integer Wide, Tall, Flag: Wide = 80: Tall = 25: Flag = 0
Dim As String ImageData
Dim As _MEM M
f = FreeFile
Open SaveFile For Binary As #f
compress$ = Space$(LOF(f))
Get #f, 1, compress$
Close #f
temp$ = _Inflate$(compress$)
Flag = Asc(temp$, 1): p = 2
If Flag And 1 Then Wide = CVI(Mid$(temp$, p, 2)): p = p + 2
If Flag And 2 Then Tall = CVI(Mid$(temp$, p, 2)): p = p + 2
If Flag And 4 Then _Blink On Else _Blink Off
If Flag And 8 Then _Font Asc(temp$, p): p = p + 1
ImageData = Mid$(temp$, p)
TempImage = _NewImage(Wide, Tall, 0)
M = _MemImage(TempImage): _MemPut M, M.OFFSET, ImageData: _MemFree M
LoadTextImage = TempImage
End Function
Sub SaveTextImage (ImageHandle As Long, SaveFile As String)
Dim As Integer Wide, Tall, Flag
Dim As Long ImageSize
Dim As String ImageData
Dim As _MEM M
If _PixelSize(ImageHandle) <> 0 Then Error 5: Exit Sub 'only text images for this routine
M = _MemImage(ImageHandle)
Wide = _Width(ImageHandle): Tall = _Height(ImageHandle)
temp$ = "0" 'placeholder for our finalized image flag which holds custom information
If Wide <> 80 Then Flag = Flag + 1: temp$ = temp$ + MKI$(Wide)
If Tall <> 25 Then Flag = Flag + 2: temp$ = temp$ + MKI$(Tall)
If _Blink Then Flag = Flag + 4 'Set a flag saying that this image uses _Blink
Select Case _Font(ImageHandle)
Case 8: Flag = Flag + 8: temp$ = temp$ + Chr$(8)
Case 9: Flag = Flag + 8: temp$ = temp$ + Chr$(9)
Case 14: Flag = Flag + 8: temp$ = temp$ + Chr$(14)
Case 15: Flag = Flag + 8: temp$ = temp$ + Chr$(15)
Case 16 '16 needs no flag as it's the default for screen 0
Case 17: Flag = Flag + 8: temp$ = temp$ + Chr$(17)
Case Else
'To be added once we get a _MemFont to retrieve custom font data back from QB64PE
End Select
ImageSize = Wide * Tall * 2
ImageData = Space$(ImageSize): _MemGet M, M.OFFSET, ImageData: _MemFree M
temp$ = temp$ + ImageData
Mid$(temp$, 1) = Chr$(Flag) 'replace our placeholder with the proper value of the custom flag
compress$ = _Deflate$(temp$)
f = FreeFile
Open SaveFile For Output As #f: Close #f
Open SaveFile For Binary As #f: Put #f, 1, compress$: Close #f
End Sub
The color picker
Code: (Select All)
'colorpick16 0.2
'
'a color picker for mode 0 screens.
'compile as colorpick16.exe
'
Screen _NewImage(32, 8, 0)
_ScreenMove 600, 400
_Title "colorpick16"
blinkflag = -1
hflag = -1
FB = 0
BB = 0
print_picker FB, BB
Do
_Limit 100
Do While _MouseInput 'mouse status changes only
x = _MouseX
y = _MouseY
If _MouseButton(1) Then
If y >= 1 And y <= 2 Then
fk = (y - 1) * 8 + Int(x / 4) + FB
End If
Color fk, 0
If fk = 0 Then Color fk, 8
_PrintString (12, 4), " "
_PrintString (12, 4), Str$(fk)
If y = 7 Then
bk = Int(x / 4) + BB
End If
Color fk, bk
_PrintString (12, 5), " "
_PrintString (12, 5), Str$(bk)
_Clipboard$ = "CK" + _Trim$(Str$(fk)) + "/" + _Trim$(Str$(bk))
If x = 31 And y = 4 Then
blinkflag = blinkflag * -1
Select Case blinkflag
Case -1
FB = 0
BB = 0
print_picker FB, BB
Case 1
FB = 16
BB = 8
print_picker FB, BB
End Select
End If
End If
Loop
kk$ = InKey$
Select Case kk$
Case "B"
FB = 16
BB = 8
print_picker FB, BB
Case "b"
FB = 0
BB = 0
print_picker FB, BB
Case Chr$(27)
cc = _MessageBox("QUIT !", "Are you sure you wish to QUIT? The program will lose functionality. ", "yesnocancel", "warning", 0)
If cc = 1 Then cc = 1 Else kk$ = ""
End Select
ccheck$ = _Clipboard$
If ccheck$ = "QUITCOLORPICK16" Then kk$ = "QUITCOLORPICK16"
Loop Until kk$ = Chr$(27) Or kk$ = "QUITCOLORPICK16"
_Clipboard$ = "pickcolor quit"
System
Sub print_picker (f, b)
For y = 0 To 1
For x = 0 To 7
fk = y * 8 + x + f
p$ = "[ ]"
a$ = _Trim$(Str$(fk))
If Len(a$) = 1 Then
Mid$(p$, 3, 1) = a$
Else
Mid$(p$, 2, 2) = a$
End If
Color fk, 0
If fk = 0 Then Color 0, 7
_PrintString ((x + 1) * 4 - 3, y + 1), p$
Next
Next
_PrintString (31, 4), "B"
_PrintString (1, 4), "Foreground"
_PrintString (1, 5), "Background"
For x = 0 To 7
bk = x + b
p$ = "[ ]"
a$ = _Trim$(Str$(bk))
If bk < 8 Then Mid$(p$, 3, 1) = a$ Else Mid$(p$, 2, 2) = a$
Color 0, bk
If bk = 0 Then Color 15, 0
_PrintString ((x + 1) * 4 - 3, 7), p$
Next
fk = 15: bk = 0
End Sub
The ascii character picker.
Code: (Select All)
'colorpick16 0.2
'
'a color picker for mode 0 screens.
'compile as colorpick16.exe
'
Screen _NewImage(32, 8, 0)
_ScreenMove 600, 400
_Title "colorpick16"
blinkflag = -1
hflag = -1
FB = 0
BB = 0
print_picker FB, BB
Do
_Limit 100
Do While _MouseInput 'mouse status changes only
x = _MouseX
y = _MouseY
If _MouseButton(1) Then
If y >= 1 And y <= 2 Then
fk = (y - 1) * 8 + Int(x / 4) + FB
End If
Color fk, 0
If fk = 0 Then Color fk, 8
_PrintString (12, 4), " "
_PrintString (12, 4), Str$(fk)
If y = 7 Then
bk = Int(x / 4) + BB
End If
Color fk, bk
_PrintString (12, 5), " "
_PrintString (12, 5), Str$(bk)
_Clipboard$ = "CK" + _Trim$(Str$(fk)) + "/" + _Trim$(Str$(bk))
If x = 31 And y = 4 Then
blinkflag = blinkflag * -1
Select Case blinkflag
Case -1
FB = 0
BB = 0
print_picker FB, BB
Case 1
FB = 16
BB = 8
print_picker FB, BB
End Select
End If
End If
Loop
kk$ = InKey$
Select Case kk$
Case "B"
FB = 16
BB = 8
print_picker FB, BB
Case "b"
FB = 0
BB = 0
print_picker FB, BB
Case Chr$(27)
cc = _MessageBox("QUIT !", "Are you sure you wish to QUIT? The program will lose functionality. ", "yesnocancel", "warning", 0)
If cc = 1 Then cc = 1 Else kk$ = ""
End Select
ccheck$ = _Clipboard$
If ccheck$ = "QUITCOLORPICK16" Then kk$ = "QUITCOLORPICK16"
Loop Until kk$ = Chr$(27) Or kk$ = "QUITCOLORPICK16"
_Clipboard$ = "pickcolor quit"
System
Sub print_picker (f, b)
For y = 0 To 1
For x = 0 To 7
fk = y * 8 + x + f
p$ = "[ ]"
a$ = _Trim$(Str$(fk))
If Len(a$) = 1 Then
Mid$(p$, 3, 1) = a$
Else
Mid$(p$, 2, 2) = a$
End If
Color fk, 0
If fk = 0 Then Color 0, 7
_PrintString ((x + 1) * 4 - 3, y + 1), p$
Next
Next
_PrintString (31, 4), "B"
_PrintString (1, 4), "Foreground"
_PrintString (1, 5), "Background"
For x = 0 To 7
bk = x + b
p$ = "[ ]"
a$ = _Trim$(Str$(bk))
If bk < 8 Then Mid$(p$, 3, 1) = a$ Else Mid$(p$, 2, 2) = a$
Color 0, bk
If bk = 0 Then Color 15, 0
_PrintString ((x + 1) * 4 - 3, 7), p$
Next
fk = 15: bk = 0
End Sub
|
|
|
Cube Game Question |
Posted by: bplus - 10-16-2023, 01:06 PM - Forum: General Discussion
- Replies (19)
|
|
From game by D.Ahl BASIC COMPUTER GAMES
Can someone explain this game to me? I've seen Davids Morristown version (Before QB) and now MG's QB64 update, I don't get what's going on.
I'd share QB64 code from another forum but might upset mnr's cohorts so I better not ;-))
I just wanna have fun!
|
|
|
Everything Date |
Posted by: SMcNeill - 10-16-2023, 04:41 AM - Forum: SMcNeill
- Replies (3)
|
|
I thought a few of you guys might have use for some of these inside your own works. (Note that these are all going into my toolbox project as well. I just thought I'd share them independent here for a preview of sorts for folks to enjoy.)
Code: (Select All)
Print "Is the date in proper format? The skies say "; CheckDayFormat(Date$)
Print "The Date = "; Date$
Print "Weekday = "; GetWeekDayName(Date$); ", which is day number"; GetWeekDay(Date$); "of the week."
Print "Day ="; GetDay(Date$)
Print "Month ="; GetMonth(Date$)
Print "Year ="; GetYear(Date$)
Print
Print "And to reverse the process we take those values and make them a date with :"; MakeDate(GetMonth(Date$), GetDay(Date$), GetYear(Date$))
Print
Print
Print
Print "And we can always fancify our date to universal formats: "
Print UniDate$("mm/dd/yyyy", Date$)
Print UniDate$("w, MM dd, YYYY", Date$)
Print UniDate$("W, MM DD, YYYY", Date$)
Print UniDate$("dd/mm/yyyy", Date$)
Print UniDate$("W, E D, YYYY", Date$)
Print UniDate$("mm-dd-yy", Date$)
Function CheckDayFormat (Day As String) 'use MM/DD/YYYY format
Dim As String DD, MM, YYYY, TD, TM, TY
If Len(Day$) <> 10 Then Glitch = -1
DD = Left$(Day, 2)
MM = Mid$(Day, 4, 2)
YYYY = Right$(Day, 4)
TD = Right$("00" + _Trim$(Str$(Val(DD))), 2)
TM = Right$("00" + _Trim$(Str$(Val(MM))), 2)
TY = Right$("0000" + _Trim$(Str$(Val(YYYY))), 4)
If TD <> DD Then Glitch = -1
If TM <> MM Then Glitch = -1
If TY <> YYYY Then Glitch = -1
If Glitch = 0 Then CheckDayFormat = -1
End Function
Function GetDay& (Day As String) 'use MM/DD/YYYY format
If CheckDayFormat(Day$) = 0 Then GetDay = 0: Exit Function
GetDay = Val(Mid$(Day, 4, 2))
End Function
Function GetMonth& (Day As String) 'use MM/DD/YYYY format
If CheckDayFormat(Day$) = 0 Then GetMonth = 0: Exit Function
GetMonth = Val(Left$(Day, 2))
End Function
Function GetYear& (Day As String) 'use MM/DD/YYYY format
If CheckDayFormat(Day$) = 0 Then GetYear = 0: Exit Function
GetYear = Val(Right$(Day, 4))
End Function
Function GetWeekDay& (Day$) 'use MM/DD/YYYY format
'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
If CheckDayFormat(Day$) = 0 Then GetWeekDay = 0: Exit Function
Dim As Long century, zerocentury, result
Dim As Long MM, DD, YYYY
MM = GetMonth(Day$): DD = GetDay(Day$): YYYY = GetYear(Day$)
If MM < 3 Then MM = MM + 12: YYYY = YYYY - 1
century = YYYY Mod 100
zerocentury = YYYY \ 100
result = (DD + Int(13 * (MM + 1) / 5) + century + Int(century / 4) + Int(zerocentury / 4) + 5 * zerocentury) Mod 7
If result = 0 Then result = 7
GetWeekDay& = result 'results are 1 to 7, from Sunday to Saturday
End Function
Function GetWeekDayName$ (Day$) 'use MM/DD/YYYY format
Dim result As Long
result = GetWeekDay(Day$)
Select Case result
Case 1: GetWeekDayName = "Sunday"
Case 2: GetWeekDayName = "Monday"
Case 3: GetWeekDayName = "Tuesday"
Case 4: GetWeekDayName = "Wednesday"
Case 5: GetWeekDayName = "Thursday"
Case 6: GetWeekDayName = "Friday"
Case 7: GetWeekDayName = "Saturday"
End Select
End Function
Function MakeDate$ (MM As _Unsigned Long, DD As _Unsigned Long, YYYY As _Unsigned Long)
Dim As String TD, TM, TY
TM = Right$("00" + _Trim$(Str$(MM)), 2)
TD = Right$("00" + _Trim$(Str$(DD)), 2)
TY = Right$("0000" + _Trim$(Str$(YYYY)), 4)
MakeDate = TM + "-" + TD + "-" + TY
End Function
Function UniDate$ (format$, userdate$)
'some basic documentation for formatting:
'dates sent via userdate$ should be in the standardized QB64 DATE$ format -- MM/DD/YYYY
'To customize your return date format, use the following syntax
'w = short weekday names. (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
'W = long weekday names. (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
'E = Extended month names. (January, February, March....)
'M = long month names. (Jan, Feb, Mar...)
'm = short month names. (01, 02, 03...)
'D = long day names. (01st, 02nd, 03rd...)
'd = short day names. (01, 02, 03...)
'Y or y (case insensitive) = year. Number of Yy present determines the number of digits we return.
' YY = 2-digit year
' YYYY = 4 digit year
' Y with any additional number of y's = 4 digit year by default, so a typo of YYYYY is the same as YYYY.
'Any other character is simply considered part of the desired output and faithfully carried over into the proper spot.
' For example, "mm/dd/yyyy" gives us "02/10/2023" for Feb 10th, 2023.
' Second example, "dd.mm.yyyy" gives us "10.02.2023" for the same date.
' Third example, "dd EE YYYY" gives us "02 February 2023" for that same date.
'Note: Extra digits of most of these codes are simply ignored for error proofing purposes, with only the initial code being accepted.
' For example "mM YYYY" is actually processed as a simple "m YYYY". The process won't mix short, long, or extended results.
' Also for example, "m YY" is the *exact* same as "mm YY".
' Feel free to use extra digits as you desire to help you keep track of positional spacing in your format string.
' Even though "M D, yyyy" may process the same as "MMM DDDD, YYYY", the second may work better for you if you're trying to track
' position of formatted objects. (The output would be "Feb 10th, 2023", and those extra characters help hold that
' positioning for us easily.)
'And, I think that's it. Enjoy, guys!
Dim As String temp, m, d, y, firstchar, Day
Dim out$
Dim As Long MonthSet, DaySet, WeekdaySet, result, YearSet, mm, dd, yyyy, century, zerocentury
temp$ = userdate$
If temp$ = "" Then temp$ = Date$
m$ = Left$(temp$, 2)
d$ = Mid$(temp$, 4, 2)
y$ = Right$(temp$, 4)
temp$ = format$
Do
firstchar$ = Left$(temp$, 1)
Select Case firstchar$
Case "E" 'extended month
temp$ = Mid$(temp$, 2)
If Not MonthSet Then
MonthSet = -1
Select Case Val(m$)
Case 1: out$ = out$ + "January"
Case 2: out$ = out$ + "February"
Case 3: out$ = out$ + "March"
Case 4: out$ = out$ + "April"
Case 5: out$ = out$ + "May"
Case 6: out$ = out$ + "June"
Case 7: out$ = out$ + "July"
Case 8: out$ = out$ + "August"
Case 9: out$ = out$ + "September"
Case 10: out$ = out$ + "October"
Case 11: out$ = out$ + "November"
Case 12: out$ = out$ + "December"
End Select
End If
Case "M" 'long month
temp$ = Mid$(temp$, 2)
If Not MonthSet Then
MonthSet = -1
Select Case Val(m$)
Case 1: out$ = out$ + "Jan"
Case 2: out$ = out$ + "Feb"
Case 3: out$ = out$ + "Mar"
Case 4: out$ = out$ + "Apr"
Case 5: out$ = out$ + "May"
Case 6: out$ = out$ + "Jun"
Case 7: out$ = out$ + "Jul"
Case 8: out$ = out$ + "Aug"
Case 9: out$ = out$ + "Sep"
Case 10: out$ = out$ + "Oct"
Case 11: out$ = out$ + "Nov"
Case 12: out$ = out$ + "Dec"
End Select
End If
Case "m" 'short month
temp$ = Mid$(temp$, 2)
If Not MonthSet Then
MonthSet = -1
Select Case Val(m$)
Case 1: out$ = out$ + "01"
Case 2: out$ = out$ + "02"
Case 3: out$ = out$ + "03"
Case 4: out$ = out$ + "04"
Case 5: out$ = out$ + "05"
Case 6: out$ = out$ + "06"
Case 7: out$ = out$ + "07"
Case 8: out$ = out$ + "08"
Case 9: out$ = out$ + "09"
Case 10: out$ = out$ + "10"
Case 11: out$ = out$ + "11"
Case 12: out$ = out$ + "12"
End Select
End If
Case "D" 'long day
temp$ = Mid$(temp$, 2)
If Not DaySet Then
DaySet = -1
out$ = out$ + Right$("00" + _Trim$(d$), 2)
Select Case Val(d$)
Case 1, 11, 21, 31: out$ = out$ + "st"
Case 2, 22: out$ = out$ + "nd"
Case 3, 23: out$ = out$ + "rd"
Case Else: out$ = out$ + "th"
End Select
End If
Case "d" 'short day
temp$ = Mid$(temp$, 2)
If Not DaySet Then
DaySet = -1
out$ = out$ + Right$("00" + _Trim$(d$), 2)
End If
Case "W" 'long weekday
temp$ = Mid$(temp$, 2)
If Not WeekdaySet Then
GoSub getday
Select Case result
Case 0: Day$ = "Saturday"
Case 1: Day$ = "Sunday"
Case 2: Day$ = "Monday"
Case 3: Day$ = "Tuesday"
Case 4: Day$ = "Wednesday"
Case 5: Day$ = "Thursday"
Case 6: Day$ = "Friday"
End Select
out$ = out$ + Day$
End If
Case "w" 'short weekday
temp$ = Mid$(temp$, 2)
If Not WeekdaySet Then
GoSub getday
Select Case result
Case 0: Day$ = "Sat"
Case 1: Day$ = "Sun"
Case 2: Day$ = "Mon"
Case 3: Day$ = "Tue"
Case 4: Day$ = "Wed"
Case 5: Day$ = "Thr"
Case 6: Day$ = "Fri"
End Select
out$ = out$ + Day$
End If
Case "Y", "y" 'year
If Not YearSet Then
YearSet = -1
If Left$(UCase$(temp$), 4) = "YYYY" Then
temp$ = Mid$(temp$, 5)
out$ = out$ + y$
ElseIf Left$(UCase$(temp$), 2) = "YY" Then
temp$ = Mid$(temp$, 3)
out$ = out$ + Right$(y$, 2)
Else
temp$ = Mid$(temp$, 2)
out$ = out$ + y$
End If
Else
temp$ = Mid$(temp$, 2)
End If
Case Else 'seperator
temp$ = Mid$(temp$, 2)
out$ = out$ + firstchar$
End Select
Loop Until temp$ = ""
UniDate$ = out$
Exit Function
getday:
WeekdaySet = -1
'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
mm = Val(m$): dd = Val(d$): yyyy = Val(y$)
If mm < 3 Then mm = mm + 12: yyyy = yyyy - 1
century = yyyy Mod 100
zerocentury = yyyy \ 100
result = (dd + Int(13 * (mm + 1) / 5) + century + Int(century / 4) + Int(zerocentury / 4) + 5 * zerocentury) Mod 7
Return
End Function
|
|
|
|