Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Lesson 10: Slot Machine
#1
So, I saw the other post for the slot machine, and thought I'd take a quick shot at seeing how I'd come up with something like you suggested.  Wink

Code: (Select All)
SCREEN _NEWIMAGE(340, 340, 32)
_TITLE "Slot Machine!"
RANDOMIZE TIMER
$COLOR:32
COLOR White, 0
Money = 300
DIM AS _FLOAT spin1, spin2, spin3
DO
CLS , DarkGray
CenterText 10, "ENTER TO SPIN! (You have $" + STR$(Money) + ")"
CenterText 140, "PAYOUTS"
CenterText 160, "Three Double Circles -- 500"
CenterText 180, "Three Squares -- 25"
CenterText 200, "Three Triangles -- 25"
CenterText 220, "Three Circles -- 25"
CenterText 240, "Two Circles -- 10"
CenterText 260, "Three Diamonds -- 10"
CenterText 280, "Two Diamonds -- 5"
CenterText 300, "One Diamond -- 1"
DO: a$ = INPUT$(1): LOOP UNTIL a$ = CHR$(13) OR a$ = CHR$(27)
IF a$ = CHR$(27) THEN SYSTEM
LINE (0, 0)-(340, 340), DarkGray, BF
spin1 = TIMER + RND * 2 + 1: spin2 = RND * 2 + 1 + spin1: spin3 = RND * 2 + 1 + spin2
DO
finished = -1
IF spin1 > TIMER THEN slot1 = Slot(INT(RND * 32)): DrawSlot 0, slot1
IF spin2 > TIMER THEN slot2 = Slot(INT(RND * 32)): DrawSlot 1, slot2
IF spin3 > TIMER THEN slot3 = Slot(INT(RND * 32)): DrawSlot 2, slot3: finished = 0
_LIMIT 10
_DISPLAY
LOOP UNTIL finished
_AUTODISPLAY
win = -10 'the "ante" of $10 to spin.
IF slot1 = slot2 AND slot2 = slot3 THEN 'three of a kind!
SELECT CASE slot1
CASE 1: win = 250 '3 circles
CASE 2: win = 250 '3 triangles
CASE 3: win = 100 '3 diamonds
CASE 4: win = 5000 '3 double circles
CASE 5: win = 250 '3 squares
END SELECT
END IF
diamond = 0: circles = 0
IF slot1 = 3 THEN diamond = diamond + 1 ELSE IF slot1 = 1 THEN circles = circles + 1
IF slot2 = 3 THEN diamond = diamond + 1 ELSE IF slot2 = 1 THEN circles = circles + 1
IF slot3 = 3 THEN diamond = diamond + 1 ELSE IF slot2 = 1 THEN circles = circles + 1
IF diamond = 1 THEN win = 10 ELSE IF diamond = 2 THEN win = 50 '1 diamond or 2 diamond
IF circles = 2 THEN win = 100 '2 circles
IF win < 0 THEN CenterText 250, "Sorry. No Match. You lose." ELSE CenterText 250, "Congrats! You win!"
Money = Money + win
_KEYCLEAR: SLEEP: _DELAY .5: _KEYCLEAR
LOOP

SUB DrawSlot (where, what)
LINE (10 + 110 * where, 50)-STEP(100, 100), Black, BF
w = 110 * where
SELECT CASE what
CASE 1: CircleFill 60 + w, 100, 50, Blue 'circle
CASE 2: FillTriangle 60 + w, 50, 10 + w, 150, 110 + w, 150, Yellow 'triangle
CASE 3: FillQuad 60 + w, 50, 10 + w, 100, 60 + w, 150, 110 + w, 100, Green 'diamond
CASE 4: CircleFill 60 + w, 100, 50, Red: CircleFill 60 + w, 100, 25, Yellow 'double circle
CASE 5: LINE (20 + 110 * where, 60)-STEP(80, 80), Gold, BF: 'square
END SELECT
END SUB

FUNCTION Slot (roll AS INTEGER)
SELECT CASE roll
CASE 0 TO 1: Slot = 1
CASE 1 TO 3: Slot = 2
CASE 3 TO 7: Slot = 5
CASE 7 TO 15: Slot = 4
CASE ELSE: Slot = 3
END SELECT
END FUNCTION

SUB CenterText (y, text$)
l = _PRINTWIDTH(text$)
w = _WIDTH
x = (w - l) \ 2
_PRINTSTRING (x, y), text$
END SUB

SUB FillTriangle (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
STATIC a&, m AS _MEM
IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32): m = _MEMIMAGE(a&)
_MEMPUT m, m.OFFSET, K
_MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
END SUB
SUB FillQuad (x1, y1, x2, y2, x3, y3, x4, y4, K AS _UNSIGNED LONG)
FillTriangle x1, y1, x2, y2, x3, y3, K
FillTriangle x3, y3, x4, y4, x1, y1, K
END SUB

SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
DIM Radius AS INTEGER, RadiusError AS INTEGER
DIM X AS INTEGER, Y AS INTEGER
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

About 120ish lines of code, and I don't think I missed anything out of the instructions. Did I?

I haven't looked to see how anyone else has tackled this task yet, as I wanted to give it a go all on my own, so I'm hoping I didn't hit too far off the mark. Wink
Reply
#2
Close, the visuals need just a bit of work. But damn, 120 lines of code, 60 less than mine.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#3
(06-09-2024, 12:39 AM)TerryRitchie Wrote: Close, the visuals need just a bit of work. But damn, 120 lines of code, 60 less than mine.

Less than 100 lines if I swap the  CircleFill out for just a CIRCLE and PAINT routine, I think.  Smile

I'll have to go back and see what instructions I missed on the visuals.
Reply
#4
Try #2: I think this matches the color scheme fairly well, and it replaces the missing reverse triangle which I'd overlooked.  (One color doesn't seem to match 100%, and that's the Purple.  I'm using the HTML purple, but the shade seems off from whatever you used for your own purple.  Without looking at your source, I don't think I'll be able to get the _RGB32 values to match perfectly.)

Code: (Select All)
SCREEN _NEWIMAGE(340, 340, 32)
_TITLE "Slot Machine!"
RANDOMIZE TIMER
$COLOR:32
COLOR White, 0
Money = 300
DIM AS _FLOAT spin1, spin2, spin3
DO
CLS , DarkGray
CenterText 10, "ENTER TO SPIN! (You have $" + STR$(Money) + ")"
CenterText 140, "PAYOUTS"
CenterText 160, "Three Double Circles -- 500"
CenterText 180, "Three Squares -- 25"
CenterText 200, "Three Triangles -- 25"
CenterText 220, "Three Circles -- 25"
CenterText 240, "Two Circles -- 10"
CenterText 260, "Three Diamonds -- 10"
CenterText 280, "Two Diamonds -- 5"
CenterText 300, "One Diamond -- 1"
DO: a$ = INPUT$(1): LOOP UNTIL a$ = CHR$(13) OR a$ = CHR$(27)
IF a$ = CHR$(27) THEN SYSTEM
LINE (0, 0)-(340, 340), DarkGray, BF
spin1 = TIMER + RND * 2 + 1: spin2 = RND * 2 + 1 + spin1: spin3 = RND * 2 + 1 + spin2
DO
finished = -1
IF spin1 > TIMER THEN slot1 = Slot(INT(RND * 16)): DrawSlot 0, slot1
IF spin2 > TIMER THEN slot2 = Slot(INT(RND * 16)): DrawSlot 1, slot2
IF spin3 > TIMER THEN slot3 = Slot(INT(RND * 16)): DrawSlot 2, slot3: finished = 0
_LIMIT 10
_DISPLAY
LOOP UNTIL finished
_AUTODISPLAY
win = -10 'the "ante" of $10 to spin.
IF slot1 = slot2 AND slot2 = slot3 THEN 'three of a kind!
SELECT CASE slot1
CASE 1: win = 250 '3 circles
CASE 2: win = 250 '3 triangles
CASE 3: win = 100 '3 diamonds
CASE 4: win = 100 '3 reverse triangles
CASE 5: win = 250 '3 squares
CASE 6: win = 5000 '3 double circles
END SELECT
END IF
diamond = 0: circles = 0
IF slot1 = 3 THEN diamond = diamond + 1 ELSE IF slot1 = 1 THEN circles = circles + 1
IF slot2 = 3 THEN diamond = diamond + 1 ELSE IF slot2 = 1 THEN circles = circles + 1
IF slot3 = 3 THEN diamond = diamond + 1 ELSE IF slot3 = 1 THEN circles = circles + 1
IF diamond = 1 THEN win = 10 ELSE IF diamond = 2 THEN win = 50 '1 diamond or 2 diamond
IF circles = 2 THEN win = 100 '2 circles
IF win < 0 THEN CenterText 250, "Sorry. No Match. You lose." ELSE CenterText 250, "Congrats! You win!"
Money = Money + win
_KEYCLEAR: SLEEP: _DELAY .5: _KEYCLEAR
LOOP

SUB DrawSlot (where, what)
LINE (10 + 110 * where, 50)-STEP(100, 100), Black, BF
w = 110 * where
SELECT CASE what
CASE 1: CircleFill 60 + w, 100, 50, Red 'circle
CASE 2: FillTriangle 60 + w, 50, 10 + w, 150, 110 + w, 150, Yellow 'up triangle
CASE 3: FillQuad 60 + w, 50, 10 + w, 100, 60 + w, 150, 110 + w, 100, Green 'diamond
CASE 4: FillTriangle 60 + w, 150, 10 + w, 50, 110 + w, 50, Purple 'down triangle
CASE 5: LINE (20 + 110 * where, 60)-STEP(80, 80), Blue, BF: 'square
CASE 6: CircleFill 60 + w, 100, 50, Cyan: CircleFill 60 + w, 100, 25, Blue 'double circle
END SELECT
END SUB

FUNCTION Slot (roll AS INTEGER)
SELECT CASE roll
CASE 0 TO 2: Slot = 1
CASE 3 TO 5: Slot = 2
CASE 6 TO 8: Slot = 3
CASE 9 TO 11: Slot = 4
CASE 13 TO 15: Slot = 5
CASE ELSE: Slot = 6
END SELECT
END FUNCTION

SUB CenterText (y, text$)
l = _PRINTWIDTH(text$)
w = _WIDTH
x = (w - l) \ 2
_PRINTSTRING (x, y), text$
END SUB

SUB FillTriangle (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
STATIC a&, m AS _MEM
IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32): m = _MEMIMAGE(a&)
_MEMPUT m, m.OFFSET, K
_MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
END SUB
SUB FillQuad (x1, y1, x2, y2, x3, y3, x4, y4, K AS _UNSIGNED LONG)
FillTriangle x1, y1, x2, y2, x3, y3, K
FillTriangle x3, y3, x4, y4, x1, y1, K
END SUB

SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
CIRCLE (CX, CY), R, C
PAINT (CX, CY), C
END SUB

As I mentioned, taking all the fancy math out of CircleFill here reduced this down to now being 100-line program -- and that's even after adding in the logic for the missing reverse triangle. Smile

Also read the instructions a little better. This now should also follow the same odds as what your game had -- 3 in 16 chance for 5 pieces to show up, 1 in 16 chance for that last double circle to appear.
Reply
#5
100 lines of code, very impressive.

However, to be fair, you are using some very advanced techniques. I had to keep the example solution to statements introduced from lessons 1 through 10. But even then I'm sure I would struggle to get the code to 100 lines.

Something like this sounds like a fun challenge. "Create code from this game example with as little lines as possible."
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#6
(06-09-2024, 02:29 PM)TerryRitchie Wrote: 100 lines of code, very impressive.

However, to be fair, you are using some very advanced techniques. I had to keep the example solution to statements introduced from lessons 1 through 10. But even then I'm sure I would struggle to get the code to 100 lines.

Something like this sounds like a fun challenge. "Create code from this game example with as little lines as possible."

"However, to be fair, you are using some very advanced techniques"

I agree. I found that this assignment was definitely a clear leap up both in terms of complexity and of program design so to say (from the perspective of a beginner of course). His variant is super concise and simple, but for sure too advanced for me Smile What this Slot Machine program really lacks is sound...but that is covered in Lesson 12 I think...
Reply
#7
@marbac74 See if this is a little easier to understand.  I don't think there's any advanced commands in it anymore. 

Code: (Select All)
SCREEN _NEWIMAGE(340, 340, 32)
_TITLE "Slot Machine!"
RANDOMIZE TIMER
$COLOR:32
COLOR White, 0
Money = 300
DIM AS _FLOAT spin1, spin2, spin3
DO
    CLS , DarkGray
    CenterText 2, "ENTER TO SPIN!  (You have $" + STR$(Money) + ")"
    CenterText 10, "PAYOUTS"
    CenterText 11, "Three Double Circles -- 500"
    CenterText 12, "Three Squares        --  25"
    CenterText 13, "Three Triangles      --  25"
    CenterText 14, "Three Circles        --  25"
    CenterText 15, "Two Circles          --  10"
    CenterText 16, "Three Diamonds      --  10"
    CenterText 17, "Two Diamonds        --  5"
    CenterText 18, "One Diamond          --  1"
    DO: a$ = INPUT$(1): LOOP UNTIL a$ = CHR$(13) OR a$ = CHR$(27)
    IF a$ = CHR$(27) THEN SYSTEM
    LINE (0, 0)-(340, 340), DarkGray, BF
    spin1 = TIMER + RND * 2 + 1: spin2 = RND * 2 + 1 + spin1: spin3 = RND * 2 + 1 + spin2
    DO
        finished = -1
        IF spin1 > TIMER THEN slot1 = INT(RND * 16 / 3) + 1: DrawSlot 0, slot1
        IF spin2 > TIMER THEN slot2 = INT(RND * 16 / 3) + 1: DrawSlot 1, slot2
        IF spin3 > TIMER THEN slot3 = INT(RND * 16 / 3) + 1: DrawSlot 2, slot3: finished = 0
        _LIMIT 10
        _DISPLAY
    LOOP UNTIL finished
    _AUTODISPLAY
    win = -10: diamond = 0: circles = 0 'the "ante" of $10 to spin.  Reset values
    IF slot1 = slot2 AND slot2 = slot3 THEN 'three of a kind!
        SELECT CASE slot1
            CASE 1, 2, 4, 5: win = 250 '3 circles/triangles/reverse triangles/squares
            CASE 3: win = 100 '3 diamonds
            CASE 6: win = 5000 '3 double circles
        END SELECT
    END IF
    IF slot1 = 3 THEN diamond = diamond + 1 ELSE IF slot1 = 1 THEN circles = circles + 1
    IF slot2 = 3 THEN diamond = diamond + 1 ELSE IF slot2 = 1 THEN circles = circles + 1
    IF slot3 = 3 THEN diamond = diamond + 1 ELSE IF slot3 = 1 THEN circles = circles + 1
    IF diamond = 1 THEN win = 10 ELSE IF diamond = 2 THEN win = 50 '1 diamond or 2 diamond
    IF circles = 2 THEN win = 100 '2 circles
    IF win < 0 THEN CenterText 15, "Sorry.  No Match.  You lose." ELSE CenterText 15, "Congrats!  You win!"
    Money = Money + win
    _KEYCLEAR: SLEEP: _DELAY .5: _KEYCLEAR
LOOP
SUB DrawSlot (where, what)
    w = 110 * where
    LINE (10 + w, 50)-STEP(100, 100), Black, BF
    SELECT CASE what
        CASE 1: MakeCircle 60 + w, 100, 50, Red 'circle
        CASE 2: MakeTriangle 60 + w, 50, 10 + w, 150, 110 + w, 150, Yellow 'up triangle
        CASE 3: MakeDiamond 60 + w, 50, 10 + w, 100, 60 + w, 150, 110 + w, 100, Green 'diamond
        CASE 4: MakeTriangle 60 + w, 150, 10 + w, 50, 110 + w, 50, Purple 'down triangle
        CASE 5: LINE (20 + 110 * where, 60)-STEP(80, 80), Blue, BF: 'square
        CASE 6: MakeCircle 60 + w, 100, 50, Cyan: MakeCircle 60 + w, 100, 25, Blue 'double circle
    END SELECT
END SUB
SUB CenterText (y, text$)
    LOCATE y, (42 - LEN(text$)) / 2: PRINT text$;
END SUB
SUB MakeTriangle (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
    LINE (x1, y1)-(x2, y2), K: LINE -(x3, y3), K: LINE -(x1, y1), K
    PAINT (x1, 100), K
END SUB
SUB MakeDiamond (x1, y1, x2, y2, x3, y3, x4, y4, K AS _UNSIGNED LONG)
    LINE (x1, y1)-(x2, y2), K: LINE -(x3, y3), K: LINE -(x4, y4), K: LINE -(x1, y1), K
    PAINT (x1, 100), K
END SUB
SUB MakeCircle (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
    CIRCLE (CX, CY), R, C
    PAINT (CX, CY), C
END SUB

Most of the advanced stuff, was really just quick little plug-ins from code that I've wrote in the past and optomized for speed.  It looks fancy, and runs fast, but it's no more valid than something as simple as the above, for little games and demos like this.  Smile

If you have any questions of what I've did here, at any point in the code, just ask.  I'm always available to answer questions.  Wink



(And you also have to keep in mind, I'm not quite classified as a "beginner" anymore.  I suppose I can still claim the tag of "developer" for the language -- though I'm often too lazy, or two busy with other stuff to do any real developing.  I tend to leave that to the younger, smarter, but less amazing guys!  Big Grin )
Reply
#8
(06-09-2024, 03:43 PM)marbac74 Wrote:
(06-09-2024, 02:29 PM)TerryRitchie Wrote: 100 lines of code, very impressive.

However, to be fair, you are using some very advanced techniques. I had to keep the example solution to statements introduced from lessons 1 through 10. But even then I'm sure I would struggle to get the code to 100 lines.

Something like this sounds like a fun challenge. "Create code from this game example with as little lines as possible."

"However, to be fair, you are using some very advanced techniques"

I agree. I found that this assignment was definitely a clear leap up both in terms of complexity and of program design so to say (from the perspective of a beginner of course). His variant is super concise and simple, but for sure too advanced for me Smile What this Slot Machine program really lacks is sound...but that is covered in Lesson 12 I think...
I'm looking forward to the sounds you add to the slot machine Smile

Heck, that sounds like an excellent "your turn" section for Lesson 12 as I don't have one yet. I'll add that in a bit.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply




Users browsing this thread: 5 Guest(s)