Slot Machine

Lesson 4: Slot Machine Project using Fl_Pack

Source code to slot machine from video. Notice, the use of Fl_Pack for widget layout.

Correction:

pack.type(FL_HORIZONTAL) is wrong. That’s only for Fl_Valuators. Fl_Pack type should be Fl_Pack.VERTICAL or Fl_Pack.HORIZONTAL

from fltk import *
import random

def pull_cb(wid):
    shown=[]
    for x in range(3):
        i=random.randrange(len(I))
        B[x].image(I[i])
        shown.append(i) #checking indices not images
        win.redraw() #usually B[x].redraw() but images are transparent
    if len(set(shown)) == 1: #remember sets are unique
        fl_message('You win!')

fnames=['cherry.png','lemon.png','watermelon.png','bell.png','seven.png','grapes.png']
I=[]
for name in fnames:
    I.append(Fl_PNG_Image(name).copy(200,300))
win=Fl_Window(650,300)
B=[]
win.begin()

pack = Fl_Pack(0,0,win.w(),win.h())
pack.begin()
for x in range(3):
    B.append(Fl_Box(0, 0, 200,0))
    B[-1].box(FL_SHADOW_BOX)
    B[-1].color(207)
pull = Fl_Return_Button(0,0,50,0,'Pull')
pull.tooltip('Hit enter to play again')
pull.callback(pull_cb)
pack.end()
pack.type(Fl_Pack.HORIZONTAL)

win.end()
Fl.scheme('plastic')
win.show()
Fl.run()

Output:

slotmachine.png

For fun try adding the following lines after the callback line

pull.label('\nP\nU\nL\nL')
pull.labelsize(24)
pull.align(FL_ALIGN_TOP|FL_ALIGN_INSIDE)

Notes on Fl_Pack

Notice that when I added the Fl_Box’s to the Fl_Pack

B.append(Fl_Box(0, 0, 200,0))

the initializer arguments are x,y,w,h. But I only specified the width as 200. This is because inside a horizontal Fl_Pack only the width of the widgets matters, all the other args are ignored. So I simply supply 0 for the other args. Similarly, if I had set pack.type(FL_VERTICAL) then only the height would be required. Also, if I wanted 10 pixels of spacing between widgets inside an Fl_Pack then I could use pack.spacing(10).

Example to dynamically create widgets inside callbacks

#
# "$Id: pack.py 495 2013-03-30 09:39:45Z andreasheld $"
# Modified by Robert Arkiletian 2021-07-09

# Pack test program for pyFLTK the Python bindings
# for the Fast Light Tool Kit (FLTK).
#
# FLTK copyright 1998-1999 by Bill Spitzak and others.
# pyFLTK copyright 2003 by Andreas Held and others.
#
# This library is free software you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA.
#
# Please report all bugs and problems to "pyfltk-user@lists.sourceforge.net".
#

from fltk import *
import sys


def type_cbH(ptr):
    type_cb(Fl_Pack.HORIZONTAL)

def type_cbV(ptr):
    type_cb(Fl_Pack.VERTICAL)

def type_cb(v):
    for i in range(0,pack.children(),1):
        pack.child(i).resize(0,0,25,25)
    pack.resize(scroll.x(), scroll.y(), scroll.w(), scroll.h())
    p = pack.parent()
    p.redraw()
    pack.type(v)
    pack.redraw()

def spacing_cb(ptr):
    pack.spacing(int(s.value()))
    scroll.redraw()

def addbutton(wid):
    size=len(buttons)-3
    pack.begin()
    buttons.append(Fl_Button( size*10+35, size*10+35, 25,25, 'b'+str(size+1)))
    buttons[-1].callback(addbutton)
    pack.end()
    Fl.check()
    pack.redraw()

w = Fl_Window(100, 100, 365, 525)

scroll = Fl_Scroll(10,10,345,285)

pack = Fl_Pack(10, 10, 345, 285)
pack.box(FL_DOWN_FRAME)

buttons=[]
for x in range(6):
    buttons.append( Fl_Button( x*10+35, x*10+35, 25,25, 'b'+str(x+1)))
    buttons[-1].callback(addbutton)
pack.end()
w.resizable(pack)

scroll.end()
v = ( Fl_Light_Button(10, 325, 175, 25, "VERTICAL"))
buttons.append(v)
v.type(FL_RADIO_BUTTON)
v.callback(type_cbH)

h = ( Fl_Light_Button(10, 350, 175, 25, "HORIZONTAL"))
buttons.append( h )
h.type(FL_RADIO_BUTTON)
h.value(1)
h.callback(type_cbV)

s = ( Fl_Value_Slider(50,375, 295,25,"spacing:"))
buttons.append( s )
s.align(FL_ALIGN_LEFT)
s.type(FL_HORIZONTAL)
s.range(0,30)
s.step(1)
s.callback(spacing_cb)

w.end()
w.show(len(sys.argv), sys.argv)
Fl.run()