Solution to Lesson 12
( This code can be found at .\tutorial\Lesson12\SoundSlots.bas )
'* Simple Slot Machine V1.1
'* by Terry Ritchie
'* 08/15/22 - made for QB64 tutorial Lesson 10
'* 06/11/24 - Sound added for tutorial Lesson 12
'* Open source code - freely modify
'* Original author's name must remain intact
OPTION _EXPLICIT ' all variables must be declared
CONST FALSE = 0, TRUE = NOT FALSE
CONST SQUARE = 1, CIRC = 2, DIAMOND = 3, TRIANGLE1 = 4, TRIANGLE2 = 5, SPECIAL = 6
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 GRAY = _RGB32(63, 63, 63)
TYPE ICONS ' icon definition
icon AS INTEGER ' shape of icon
value1 AS INTEGER ' value if one shown
value2 AS INTEGER ' value if two shown
value3 AS INTEGER ' value if three shown
END TYPE
TYPE SOUNDS ' game sound effects
Ambient AS LONG ' ambient casino background sound
InsertCoin AS LONG ' coin being inserted into slot machine
PullHandle AS LONG ' handle being pulled
BeginWheelSpin AS LONG ' sound of wheels getting spun up
WheelSpin AS LONG ' wheels spinning
WheelStop AS LONG ' a wheel stopping
Winner AS LONG ' regular winning sound
Jackpot AS LONG ' jackpot winning sound
JackpotCoins AS LONG ' jackpot coins dropping
END TYPE
DIM Icon(6) AS ICONS ' array of the 6 icons available
DIM Wheel(3, 16) AS ICONS ' array of 3 wheels each containing 16 icons
DIM IWind%(3) ' icon window x coordinate locations
DIM CoinDrop&(10) ' 10 different sounds of coins dropping
DIM SND AS SOUNDS ' slot machine sound effects
DIM Count% ' general purpose counter / value holder
DIM Score& ' player score (LONG INT in case player wins big)
DIM Winner% ' TRUE when player wins, FALSE otherwise
DIM KeyPress$ ' player keyboard inputs
DIM i% ' counter
DIM j% ' counter
LoadSounds ' load the game sounds
Icon(1).icon = SQUARE ' each wheel contains 3
Icon(1).value3 = 25 ' 3 squares point
Icon(2).icon = CIRC ' each wheel contains 3
Icon(2).value2 = 10 ' 2 circles points
Icon(2).value3 = 25 ' 3 circles points
Icon(3).icon = DIAMOND ' each wheel contains 3
Icon(3).value1 = 1 ' 1 diamond points
Icon(3).value2 = 5 ' 2 diamonds points
Icon(3).value3 = 10 ' 3 diamonds points
Icon(4).icon = TRIANGLE1 ' each wheel contain 3
Icon(4).value3 = 25 ' 3 up triangles points
Icon(5).icon = TRIANGLE2 ' each wheel contains 3
Icon(5).value3 = 25 ' 3 down triangles points
Icon(6).icon = SPECIAL ' each wheel contains 1
Icon(6).value3 = 500 ' 3 specials points
FOR i% = 1 TO 3 ' cycle through the 3 wheels
IWind%(i%) = (i% - 1) * 110 + 10 ' record x coordinate of icon window
Count% = 0 ' reset icon counter
FOR j% = 1 TO 15 ' cycle through 15 icons on the wheel
Count% = Count% + 1 ' increment icon counter
IF Count% = 6 THEN Count% = 1 ' reset icon counter when needed
Wheel(i%, j%) = Icon(Count%) ' place icon at this position on wheel
NEXT j%
Wheel(i%, 16) = Icon(6) ' last position on wheel contains big payout icon
NEXT i%
Wheel(1, 0).value2 = 16 ' These variables are used to indicate which icon
Wheel(2, 0).value2 = 16 ' on each wheel is currently showing. since
Wheel(3, 0).value2 = 16 ' (x,0).value2 not used it has been repurposed.
SCREEN _NEWIMAGE(340, 340, 32) ' create game window
CLS , GRAY ' clear window with gray background
_TITLE "Slot Machine" ' give window a title
_SCREENMOVE _MIDDLE ' move window to center of screen
_DELAY .2 ' give it some time to get there
DrawIcon IWind%(1), SPECIAL ' draw special icon in all three icon windows
DrawIcon IWind%(2), SPECIAL
DrawIcon IWind%(3), SPECIAL
COLOR YELLOW, GRAY ' yellow text on gray background
PRINT " SLOT MACHINE"
LOCATE 9, 1: PRINT " ENTER to spin ESC to exit"
LOCATE 11, 1: PRINT " PAYOUTS"
PRINT
PRINT " 3 Double Circles - 500"
PRINT " 3 Squares - 25"
PRINT " 3 Triangles - 25"
PRINT " 3 Circles - 25"
PRINT " 2 Circles - 10"
PRINT " 3 Diamonds - 10"
PRINT " 2 Diamonds - 5"
PRINT " 1 Diamond - 1";
_SNDLOOP SND.Ambient
DO ' ** begin main game loop **
Count% = 0 ' reset general purpose variable
LOCATE 9, 20 ' position the text cursor
PRINT USING "#####"; Score& ' print player's current score
DO ' begin player input loop
_LIMIT 5 ' check for input 5 times per second
KeyPress$ = INKEY$ ' grab any key player may press
IF KeyPress$ = CHR$(27) THEN ExitGame ' leave if player pressed escape key
IF Winner% THEN ' was last spin a winner?
Count% = Count% + 1 ' yes, increment text flash counter
IF Count% = 11 THEN Count% = 1 ' reset text flash counter if needed
LOCATE 1, 17 ' position the text cursor
IF Count% < 6 THEN ' is text flash counter < 6?
PRINT " WINNER!! "; ' yes, show winner text
ELSE ' no, it's > 5
PRINT " "; ' print nothing instead
END IF
END IF
LOOP UNTIL KeyPress$ = CHR$(13) ' leave input loop when ENTER pressed
_SNDSTOP SND.JackpotCoins ' stop jackpot coins if looping
_SNDPLAY SND.InsertCoin ' coin being inserted into machine
_DELAY 1 ' wait for it to drop
_SNDPLAY SND.PullHandle ' pull handle sound
_DELAY .7 ' wait a bit while its being pulled
_SNDPLAY SND.BeginWheelSpin ' spring release sound to start spinning
Winner% = FALSE ' reset winner flag
LOCATE 1, 17 ' position the text cursor
PRINT "SLOT MACHINE"; ' reset top text
Score& = Score& - 1 ' player used 1 point to play
Count% = SpinWheels% ' spin the wheels and get the result
IF Count% > 0 THEN ' did player win?
Winner% = TRUE ' yes, set the winner flag
Score& = Score& + Count% ' add the winnings to the score
IF Count% = 500 THEN ' jackpot?
_SNDPLAY SND.Jackpot ' yes, play jackpot bell
_SNDLOOP SND.JackpotCoins ' start dropping massive coins
ELSE ' no, other than jackpot
_SNDPLAY SND.Winner ' play normal winner bell
RANDOMIZE TIMER ' seed random number generator
FOR i% = 1 TO Count% ' count the number of coins won
_SNDPLAY CoinDrop&(INT(RND * 10) + 1) ' drop a coin sound
_DELAY .25 ' 4 coin drops per second
NEXT i%
END IF
END IF
LOOP ' ** end main game loop **
'-------------------------------------------------------------------------------------------
FUNCTION SpinWheels% () ' spins the 3 icon wheels returning payout result
SHARED Wheel() AS ICONS ' array of 3 wheels
SHARED IWind() AS INTEGER ' array of icon window positions
SHARED SND AS SOUNDS ' slot machine sound effects
DIM icon1%, icon2%, icon3% ' the icons showing after spin complete
DIM total% ' the total of the icons showing
DIM i% ' general purpose counter
_SNDLOOP SND.WheelSpin ' start wheel spin sound
RANDOMIZE TIMER ' seed RND generator
Wheel(1, 0).value1 = 16 + INT(RND * 16) ' # of frames wheel 1 spins
Wheel(2, 0).value1 = Wheel(1, 0).value1 + 16 + INT(RND * 16) ' # of frames wheel 2 spins
Wheel(3, 0).value1 = Wheel(2, 0).value1 + 16 + INT(RND * 16) ' # of frames wheel 3 spins
DO ' spin the wheels
_LIMIT 32 ' 32 frames per second
FOR i% = 1 TO 3 ' cycle through the wheels
IF Wheel(i%, 0).value1 > 0 THEN ' is wheel still spinning?
Wheel(i%, 0).value2 = Wheel(i%, 0).value2 + 1 ' go to next icon
IF Wheel(i%, 0).value2 = 17 THEN Wheel(i%, 0).value2 = 1 ' reset icon
Wheel(i%, 0).value1 = Wheel(i%, 0).value1 - 1 ' count down frames
IF Wheel(i%, 0).value1 = 10 THEN _SNDPLAYCOPY SND.WheelStop ' play kerchunk
DrawIcon IWind(i%), Wheel(i%, Wheel(i%, 0).value2).icon ' draw the icon
END IF
NEXT i%
_DISPLAY ' only show icon when done drawing
LOOP UNTIL Wheel(3, 0).value1 = 0 ' leave when wheels have stopped
_SNDSTOP SND.WheelSpin ' stop wheel gears clicking sound
_AUTODISPLAY ' display screen updates right away
icon1% = Wheel(1, Wheel(1, 0).value2).icon ' record the three icons showing
icon2% = Wheel(2, Wheel(2, 0).value2).icon
icon3% = Wheel(3, Wheel(3, 0).value2).icon
total% = Wheel(1, Wheel(1, 0).value2).value1 ' get value of icon 1
IF icon1% = icon2% THEN ' does 2nd icon match 1st?
total% = Wheel(2, Wheel(2, 0).value2).value2 ' yes, get value of icon 2
END IF
IF icon1% = icon2% AND icon2% = icon3% THEN ' are all 3 icons the same?
total% = Wheel(3, Wheel(3, 0).value2).value3 ' yes, get value of icon 3
END IF
SpinWheels% = total% ' return the payout value
END FUNCTION
'-------------------------------------------------------------------------------------------
SUB DrawIcon (x%, icon%) ' draws a given icon within the given icon window x coordinate
DIM y% ' the y coordinate position of the icon windows
y% = 20 ' 20 pixels down from top
LINE (x%, y%)-(x% + 100, y% + 100), _RGB32(0, 0, 0), BF ' draw the icon window
SELECT CASE icon% ' which icon to draw?
CASE SQUARE ' the blue square
LINE (x% + 10, y% + 10)-(x% + 90, y% + 90), BLUE, BF ' draw the icon in window
CASE CIRC ' the red circle
CIRCLE (x% + 50, y% + 50), 40, RED ' draw the icon
PAINT (x% + 50, y% + 50), RED, RED
CASE DIAMOND ' the green diamond
LINE (x% + 50, y% + 10)-(x% + 90, y% + 50), GREEN ' draw the icon
LINE -(x% + 50, y% + 90), GREEN
LINE -(x% + 10, y% + 50), GREEN
LINE -(x% + 50, y% + 10), GREEN
PAINT (x% + 50, y% + 50), GREEN, GREEN
CASE TRIANGLE1 ' the yellow triangle
LINE (x% + 50, y% + 10)-(x% + 90, y% + 90), YELLOW ' draw the icon
LINE -(x% + 10, y% + 90), YELLOW
LINE -(x% + 49, y% + 10), YELLOW
PAINT (x% + 49, y% + 50), YELLOW, YELLOW
CASE TRIANGLE2 ' the purple triangle
LINE (x% + 10, y% + 10)-(x% + 90, y% + 10), PURPLE ' draw the icon
LINE -(x% + 50, y% + 90), PURPLE
LINE -(x% + 10, y% + 10), PURPLE
PAINT (x% + 50, y% + 50), PURPLE, PURPLE
CASE SPECIAL ' the big payout icon
CIRCLE (x% + 50, y% + 50), 40, CYAN ' draw the icon
PAINT (x% + 50, y% + 50), CYAN, CYAN
CIRCLE (x% + 50, y% + 50), 20, BLUE
PAINT (x% + 50, y% + 50), BLUE, BLUE
END SELECT
END SUB
'-------------------------------------------------------------------------------------------
SUB LoadSounds () ' loads the game's sounds
SHARED CoinDrop&() ' 10 different sounds of coins dropping
SHARED SND AS SOUNDS ' slot machine sound effects
DIM s% ' counter
DIM FilePath$ ' path to sound files
FilePath$ = ".\tutorial\Lesson12\slots\" ' path to sound files
SND.Ambient = _SNDOPEN(FilePath$ + "casinoambient.ogg")
SND.InsertCoin = _SNDOPEN(FilePath$ + "coininsert.ogg")
SND.PullHandle = _SNDOPEN(FilePath$ + "pullhandle.ogg")
SND.BeginWheelSpin = _SNDOPEN(FilePath$ + "wheelspinbegin.ogg")
SND.WheelSpin = _SNDOPEN(FilePath$ + "wheelspin.ogg")
SND.WheelStop = _SNDOPEN(FilePath$ + "wheelstop.ogg")
SND.Winner = _SNDOPEN(FilePath$ + "winner.ogg")
SND.Jackpot = _SNDOPEN(FilePath$ + "winnerwinner.ogg")
SND.JackpotCoins = _SNDOPEN(FilePath$ + "coindropwinner.ogg")
FOR s% = 1 TO 10
CoinDrop&(s%) = _SNDOPEN(FilePath$ + "coindrop" + _TRIM$(STR$(s%)) + ".ogg")
NEXT s%
END SUB
'-------------------------------------------------------------------------------------------
SUB ExitGame () ' remove assets from RAM then exit program
SHARED CoinDrop&() ' 10 different sounds of coins dropping
SHARED SND AS SOUNDS ' slot machine sound effects
DIM s% ' counter
_SNDCLOSE SND.Ambient ' remove all sounds from RAM
_SNDCLOSE SND.InsertCoin ' (always clean up after yourself before exiting)
_SNDCLOSE SND.PullHandle
_SNDCLOSE SND.BeginWheelSpin
_SNDCLOSE SND.WheelSpin
_SNDCLOSE SND.WheelStop
_SNDCLOSE SND.Winner
_SNDCLOSE SND.Jackpot
_SNDCLOSE SND.JackpotCoins
FOR s% = 1 TO 10
_SNDCLOSE CoinDrop&(s%)
NEXT s%
SYSTEM ' return to operating system
END SUB
'-------------------------------------------------------------------------------------------