iAmNewbe

AutoIT Slot Machine Game Project

3 posts in this topic

#AutoIt3Wrapper_UseX64=y
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.2
    Author:   Ported By IAmNewbe
                  Inspired by the book Programming for the Absolute Beginner Second Edition
                  Author:  Jerry Lee Ford, Jr.
                  Chapter 9, Vegas Style Slot Machine written in JustBasic
                  Ported and coded from scratch using AutoIT version 3.3.14.2

                New Images were created for this AutoIT version and no resources from the book are included.
                The program performs as close to the JustBasic script as possible with minor GUI differences.

    Date:   Port Date: 10/24/2016
                Book Published: February 1, 2015

    Script Function:
            Slot Machine Game
            Objective is to play and not go broke, when no money is left the application will try to exit
            though the user can over ride that and continue. That aspect needs work the continueing from
            possible shut down.

    Version:
        ver 1.02
        Rewrote code to eliminate redundancy and unneccesary switches and loops.
        Optimized and commented best could. Kept close as possible to original script functionality and operation.

        This is a very basic Slot Machine Game that is rather boring after awhile
        Here is an example of a Casino Style Slot Machine that some day this could become.
                http://www.vegas-slots.com/double-diamond.html

#ce ----------------------------------------------------------------------------


;~   TO DO:   RESET AFTER GAME OVER allowing player to continue on instead of quiting application
;~              need to reset counters and labels, textboxes if continueing.


#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>


    Global $title = "AutoIt Slots" ; used to populate title in various places in GUI
    Global $spinCount, $money, $roundsPlayed, $imageArray[3]  = [ "Images\cherries.jpg",  "Images\bar.jpg", "Images\bar2.jpg" ] ;  Cherries == $imageArray[0], Bar == $imageArray[1],  Bar2 == $imageArray[2]
    Global $shuffleImageArray = $imageArray ; Setup a copy of images array to use as sorting array, original used for calculating wins and loses
    HotKeySet("{ESC}", "appClose")

    GameReset()
    StartGame()

Func StartGame()
    Dim $title, $money, $roundsPlayed, $imageArray
    Global $slotMachine = GUICreate($title, 500, 500, (@DesktopWidth - 500) / 2,  123)  ; Width, Height, Horizontal, Vertical
    ; (@DesktopWidth - 500) / 2  == Centers GUI in middle of main monitor 500 is width of GUI if divide first get wrong position == GUI not centered
    GUISetIcon("Images\cherries.ico")  ; Sets Icon in Title Bar and on Taskbar

    $guiDimensions = WinGetClientSize($slotMachine)  ; Gets width and height of GUI for centering components as needed returns array [0] = Width and [1] = Height

    Global $TitleTextLabel = GUICtrlCreateLabel($title, ($guiDimensions[0] - 315) / 2, 20,  315, 60); Left, Top, Width, Height
    GUICtrlSetFont(-1, 42, 900, 0, "Arial", 3) ; -1 means set font of last created control OR can put the variable of label control like $TitleTextLabel which contains HWND of this Label Control

    Global $img1 = GUICtrlCreatePic($imageArray[0], 50, 115, 93, 93)
    Global $img2 = GUICtrlCreatePic($imageArray[1], 200, 115, 93, 93)
    Global $img3 = GUICtrlCreatePic($imageArray[2], 350, 115, 93, 93)

    Global $slotInfoText = GUICtrlCreateLabel("Lets Play!", 130, 240, 220, 30, $SS_CENTER+$SS_SUNKEN) ; can use bitOR($SS_CENTER, $SS_SUNKEN)
    GUICtrlSetBkColor ( -1, 0xFFFFFF )
    GUICtrlSetFont(-1, 18, 900, 0, "Arial", 3)
    Global $button = GUICtrlCreateButton("Spin", 200, 300, 100, 30)
    GUICtrlSetState($button, $GUI_FOCUS)

    Global $statsGroup = GUICtrlCreateGroup("Stats:", 60, 350, 380, 100) ; Starts A Group
        GUICtrlCreateLabel("Rounds Played:", 90, 372, 105, 20) ; not doing anything with this so no need for variable
        Global $roundsPlayedLabel = GUICtrlCreateLabel("", 90, 395, 100, 20, $SS_SUNKEN)
        GUICtrlSetBkColor ( -1, 0xFFFFFF )
        GUICtrlCreateLabel("Money:", 290, 372, 50, 20) ; Static Text which won't change, no need for variable
        Global $moneyLabel = GUICtrlCreateLabel("", 290, 395, 100, 20, $SS_SUNKEN)
        GUICtrlSetBkColor ( -1, 0xFFFFFF )
        GUICtrlSetData($moneyLabel, $money)
        GUICtrlSetData($roundsPlayedLabel, $roundsPlayed)
    GUICtrlCreateGroup("", -99, -99, 1, 1) ; Closes The Group
    GUISetState(@SW_SHOW)
EndFunc

Func AnimateSlotSpin()
    ; Resets text to default settings when button pressed
    Dim $slotInfoText, $button
    GUICtrlSetData($slotInfoText, "")
    GUICtrlSetData($button, "Spin")
    ; Loop through the images 6 times to give illusion of spinning wheels.
    For $i = 1 to 6 step 1
        spinSlots()
        sleep(80) ; Adjusts speed of image spin -  higher is slower, lower is faster
    Next
EndFunc

Func spinSlots()
    Dim $spinCount, $shuffleImageArray, $img1, $img2, $img3
    $spinCount = $spinCount + 1
    _ArrayShuffle($shuffleImageArray)
    If($spinCount < 6) Then
        GUICtrlSetImage($img1, $shuffleImageArray[0])
        GUICtrlSetImage($img2, $shuffleImageArray[1])
        GUICtrlSetImage($img3 , $shuffleImageArray[2])
    ; Play Noise on each spin, leave it to you to figure out if you want it or not
    Else
        $spinCount = 0
        getRoundResult()
    EndIf
EndFunc

Func getRandomNumber()
    ; Returns a number between 1 and 3 used to select image at random. IF have more images need adjust max range
    return Random(1,3,1) ; 1 at end tells to return an integer
EndFunc

Func getRoundResult()
    Dim $roundsPlayed, $img1, $img2, $img3, $money, $slotInfoText, $imageArray
    Local $imageNum1, $imageNum2, $imageNum3,  $result
    $result = 0
    $imageNum1 = getRandomNumber()
    GUICtrlSetImage($img1, $imageArray[$imageNum1 - 1]) ; subtract one because array is zero based else would be one off
    $result = $result + $imageNum1  ; adds image number to result

    $imageNum2 = getRandomNumber()
    GUICtrlSetImage($img2, $imageArray[$imageNum2 - 1])
    $result = $result + $imageNum2  ; adds image number to result

    $imageNum3 = getRandomNumber()
    GUICtrlSetImage($img3, $imageArray[$imageNum3 - 1])
    $result = $result + $imageNum3  ; adds image number to result

    ; Play sound for slots spin here

    If($result == 3 OR $result == 9) Then
        GUICtrlSetData($slotInfoText, "Jackpot!")
        $money = $money + 3 ; Adds 3 dollars to players account
    EndIf

    If($result == 6) Then
        If($imageNum1 == $imageNum2) Then
            GUICtrlSetData($slotInfoText, "Jackpot!")
            $money = $money + 3 ; Adds 3 dollars to players account
        Else
            GUICtrlSetData($slotInfoText, "You Lose!")
            $money = $money - 5
        EndIf
    EndIf

    If($result <> 3 AND $result <> 6 AND $result <> 9) Then
        GUICtrlSetData($slotInfoText, "Two Of A Kind!")
        $money = $money + 1
    EndIF

    If($money < 1) Then
        ; Player ran out of money, Game Over!
         $money = 0
        GUICtrlSetData($slotInfoText, "Game Over!")
;~      GUICtrlSetData($button, "Play Again?")  ; changes button text
        appClose()
    EndIf

    $roundsPlayed = $roundsPlayed + 1
    GUICtrlSetData($roundsPlayedLabel,  $roundsPlayed)
    GUICtrlSetData($moneyLabel,  $money)
EndFunc

Func gameReset()
    ; Resets Game Elements
    Dim $spinCount, $money, $roundsPlayed
    $spinCount = 0
    $money = 30
    $roundsPlayed = 0
EndFunc

Func appClose()
    Dim $title
    If WinActive($title) Then
        Local $exitCode = MsgBox(68,'',"Are you sure you want to quit?")
        If($exitCode == 6) Then Exit
    EndIF
EndFunc

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            appClose()
        Case $button
            AnimateSlotSpin()
    EndSwitch
WEnd

 

The above is a port of a JustBasic program from the book "Programming for the Absolute Beginner Second Edition"
This Slot Machine game has custom images created for this version, none of the resources from the book are included.
Attached to this post is the 7z archive file containing all the files necessary to compile from within AutoIT.
 

There are a few issues I noticed, the wheels are not always different so getting the same result in a row happens often, same images in same order.
I eliminated redundant and unnecessary logic and looping structures and condensed the code compared to the book version.

The spinning of the wheels are done via a timer in the book I could not get that to work in AutoIT so I used a for loop instead.
Here an an online slot machine example of what this could become if you wanted to try to upgrade the code and of course images.
http://www.vegas-slots.com/double-diamond.html

Would be fun to add multi-line support, options for betting amounts and other features of a real casino slot machine.
Also get the spins to look more realistic than the currently do. This is a very basic version used entirely for educational purposes
only for learning how to program and in this case better understand AutoIT and GUI design.

Have fun and please share your updates, feel free to completely gut and rewrite this as you want, this is a learning project for us all so have fun with it.

 

--
 

AutoITSlotMachine.7z

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Update to use a timer instead of a FOR Loop to spin the slot wheels.

 

#AutoIt3Wrapper_UseX64=y

;~   TO DO:   RESET AFTER GAME OVER allowing player to continue on instead of quiting application
;~              need to reset counters and labels, textboxes if continueing.


#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <Timers.au3>

    Global $title = "AutoIt Slots" ; used to populate title in various places in GUI
    Global $spinCount, $money, $roundsPlayed, $imageArray[3]  = [ "Images\cherries.jpg",  "Images\bar.jpg", "Images\bar2.jpg" ] ;  Cherries == $imageArray[0], Bar == $imageArray[1],  Bar2 == $imageArray[2]
    Global $shuffleImageArray = $imageArray ; Setup a copy of images array to use as sorting array, original used for calculating wins and loses
    Global $stopTimer = False ; sets Timer toggle to not activate at startup since timer doesn't exist yet
    HotKeySet("{ESC}", "appClose")

    GameReset()
    StartGame()



Func StartGame()
    Dim $title, $money, $roundsPlayed, $imageArray
    Global $slotMachine = GUICreate($title, 500, 500, (@DesktopWidth - 500) / 2,  123)  ; Width, Height, Horizontal, Vertical
    ; (@DesktopWidth - 500) / 2  == Centers GUI in middle of main monitor 500 is width of GUI if divide first get wrong position == GUI not centered
    GUISetIcon("Images\cherries.ico")  ; Sets Icon in Title Bar and on Taskbar

    $guiDimensions = WinGetClientSize($slotMachine)  ; Gets width and height of GUI for centering components as needed returns array [0] = Width and [1] = Height

    Global $TitleTextLabel = GUICtrlCreateLabel($title, ($guiDimensions[0] - 315) / 2, 20,  315, 60); Left, Top, Width, Height
    GUICtrlSetFont(-1, 42, 900, 0, "Arial", 3) ; -1 means set font of last created control OR can put the variable of label control like $TitleTextLabel which contains HWND of this Label Control

    Global $img1 = GUICtrlCreatePic($imageArray[0], 50, 115, 93, 93)
    Global $img2 = GUICtrlCreatePic($imageArray[1], 200, 115, 93, 93)
    Global $img3 = GUICtrlCreatePic($imageArray[2], 350, 115, 93, 93)

    Global $slotInfoText = GUICtrlCreateLabel("Lets Play!", 130, 240, 220, 30, $SS_CENTER+$SS_SUNKEN) ; can use bitOR($SS_CENTER, $SS_SUNKEN)
    GUICtrlSetBkColor ( -1, 0xFFFFFF )
    GUICtrlSetFont(-1, 18, 900, 0, "Arial", 3)
    Global $button = GUICtrlCreateButton("Spin", 200, 300, 100, 30)
    GUICtrlSetState($button, $GUI_FOCUS)

    Global $statsGroup = GUICtrlCreateGroup("Stats:", 60, 350, 380, 100) ; Starts A Group
        GUICtrlCreateLabel("Rounds Played:", 90, 372, 105, 20) ; not doing anything with this so no need for variable
        Global $roundsPlayedLabel = GUICtrlCreateLabel("", 90, 395, 100, 20, $SS_SUNKEN)
        GUICtrlSetBkColor ( -1, 0xFFFFFF )
        GUICtrlCreateLabel("Money:", 290, 372, 50, 20) ; Static Text which won't change, no need for variable
        Global $moneyLabel = GUICtrlCreateLabel("", 290, 395, 100, 20, $SS_SUNKEN)
        GUICtrlSetBkColor ( -1, 0xFFFFFF )
        GUICtrlSetData($moneyLabel, $money)
        GUICtrlSetData($roundsPlayedLabel, $roundsPlayed)
    GUICtrlCreateGroup("", -99, -99, 1, 1) ; Closes The Group
    GUISetState(@SW_SHOW)
EndFunc

Func spinSlots($hWnd, $iMsg, $iIDTimer, $iTime)
    Dim $slotMachine, $stopTimer, $spinCount, $shuffleImageArray, $img1, $img2, $img3
    $spinCount = $spinCount + 1
    _ArrayShuffle($shuffleImageArray)
    If($spinCount < 6) Then
        GUICtrlSetImage($img1, $shuffleImageArray[0])
        GUICtrlSetImage($img2, $shuffleImageArray[1])
        GUICtrlSetImage($img3 , $shuffleImageArray[2])
    ; Play Noise on each spin, leave it to you to figure out if you want it or not
    Else
        $stopTimer = True; Timer needs to be shutoff or it will keep calling function
        $spinCount = 0
        getRoundResult()
    EndIf
EndFunc

Func getRandomNumber()
    ; Returns a number between 1 and 3 used to select image at random. IF have more images need adjust max range
    return Random(1,3,1) ; 1 at end tells to return an integer
EndFunc

Func getRoundResult()
    Dim $roundsPlayed, $img1, $img2, $img3, $money, $slotInfoText, $imageArray
    Local $imageNum1, $imageNum2, $imageNum3,  $result
    $result = 0
    $imageNum1 = getRandomNumber()
    GUICtrlSetImage($img1, $imageArray[$imageNum1 - 1]) ; subtract one because array is zero based else would be one off
    $result = $result + $imageNum1  ; adds image number to result

    $imageNum2 = getRandomNumber()
    GUICtrlSetImage($img2, $imageArray[$imageNum2 - 1])
    $result = $result + $imageNum2  ; adds image number to result

    $imageNum3 = getRandomNumber()
    GUICtrlSetImage($img3, $imageArray[$imageNum3 - 1])
    $result = $result + $imageNum3  ; adds image number to result

    ; Play sound for slots spin here

    If($result == 3 OR $result == 9) Then
        GUICtrlSetData($slotInfoText, "Jackpot!")
        $money = $money + 3 ; Adds 3 dollars to players account
    EndIf

    If($result == 6) Then
        If($imageNum1 == $imageNum2) Then
            GUICtrlSetData($slotInfoText, "Jackpot!")
            $money = $money + 3 ; Adds 3 dollars to players account
        Else
            GUICtrlSetData($slotInfoText, "You Lose!")
            $money = $money - 5
        EndIf
    EndIf

    If($result <> 3 AND $result <> 6 AND $result <> 9) Then
        GUICtrlSetData($slotInfoText, "Two Of A Kind!")
        $money = $money + 1
    EndIF

    If($money < 1) Then
        ; Player ran out of money, Game Over!
         $money = 0
        GUICtrlSetData($slotInfoText, "Game Over!")
;~      GUICtrlSetData($button, "Play Again?")  ; changes button text
        appClose()
    EndIf

    $roundsPlayed = $roundsPlayed + 1
    GUICtrlSetData($roundsPlayedLabel,  $roundsPlayed)
    GUICtrlSetData($moneyLabel,  $money)
EndFunc

Func gameReset()
    ; Resets Game Elements
    Dim $spinCount, $money, $roundsPlayed
    $spinCount = 0
    $money = 30
    $roundsPlayed = 0
EndFunc

Func appClose()
    Dim $title
    If WinActive($title) Then
        Local $exitCode = MsgBox(68,'',"Are you sure you want to quit?")
        If($exitCode == 6) Then Exit
    EndIF
EndFunc

While 1
   if($stopTimer == True) Then  _Timer_KillAllTimers($slotMachine) ; Stops timer by killing it.
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _Timer_KillAllTimers($slotMachine)
            appClose()
        Case $button
            $stopTimer = False ; sets timer toggle to NOT activate timer since it is now being activated.
            _Timer_SetTimer($slotMachine, 150, "spinSlots") ; Creates AND Activates timer AND Spins the Slot Wheels
    EndSwitch
WEnd

 

 

I don't know how to hilight changed sections in the code so will just put the new lines below.


 

#include <Timers.au3>
    
    
    Global $stopTimer = False ; sets Timer toggle to not activate at startup since timer doesn't exist yet
    
    
 Func spinSlots($hWnd, $iMsg, $iIDTimer, $iTime)
    Dim $slotMachine, $stopTimer, $spinCount, $shuffleImageArray, $img1, $img2, $img3
    $spinCount = $spinCount + 1
    _ArrayShuffle($shuffleImageArray)
    If($spinCount < 6) Then
        GUICtrlSetImage($img1, $shuffleImageArray[0])
        GUICtrlSetImage($img2, $shuffleImageArray[1])
        GUICtrlSetImage($img3 , $shuffleImageArray[2])
    ; Play Noise on each spin, leave it to you to figure out if you want it or not
    Else
    
NEW LINE -->  $stopTimer = True; Timer needs to be shutoff or it will keep calling function
    
        $spinCount = 0
        getRoundResult()
    EndIf
EndFunc


While 1
NEW LINE -->   if($stopTimer == True) Then  _Timer_KillAllTimers($slotMachine) ; Stops timer by killing it.
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
NEW LINE -->  _Timer_KillAllTimers($slotMachine)
            appClose()
        Case $button
NEW LINE -->  $stopTimer = False ; sets timer toggle to NOT activate timer since it is now being activated.
NEW LINE --> _Timer_SetTimer($slotMachine, 150, "spinSlots") ; Creates AND Activates timer AND Spins the Slot Wheels
    EndSwitch
WEnd

 

The Animate Slot Spin function is no longer needed so I removed it in the new version.  There probably is some code that is redundant now, I only focused on adding the Timer since I figured out how to to do that. The original code from Basic used a Timer running at 300th of a second or 300 milliseconds..   Which I think is 0.300 which is WAY too fast so I originally set it to 300 which was too slow so I played with it and ended up at 150 which on my computer is ok.   

 

1000  ==  One Second.

 

 



 

Edited by iAmNewbe

Share this post


Link to post
Share on other sites

I realize the above code is redundant in areas but I am not really putting that much effort into it other than to make sure it works and it seems to.

 

Would be great to see your additions, updates or rewrites to this.  We can all learn from each other that way.

Hope you are having fun  with the project.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now