Terrapin Resources

3-Card Monte

by Stan Munson

3-Card Monte is game of chance. The object of the game is to locate the Queen of Hearts. It may look easy, but sometimes you get fooled by the movements.

3-CardMonte.lgo

TO RANDOM.BETWEEN :A :B
	LOCAL "TEMP
	IF :A > :B [
		MAKE "TEMP :A
		MAKE "A :B
		MAKE "B :TEMP
	]
	OUTPUT (:A - 1) + RANDOM (:B - :A + 1)
END

TO RANDOM0 :N
	OUTPUT (RANDOM :N) - 1
END

TO CHOOSE :INPUT.CHOICES
	IF EMPTY? THING :INPUT.CHOICES OUTPUT THING :INPUT.CHOICES
	LOCAL "CHOICE
	MAKE "CHOICE PICK THING :INPUT.CHOICES
	MAKE :INPUT.CHOICES BUTMEMBER :CHOICE THING :INPUT.CHOICES
	OUTPUT :CHOICE
END

TO RUNIT
	DRAW
	HT
	CLEARTEXT
	SETBG "LIGHTGREEN
	PPROP "LOGO.ENV "LAYOUT "PURE
	FULLSCREEN
	PPROPS "PREFS [HINTS FALSE DRAGGABLE.OBJECTS FALSE]
	ERASE [SJ HQ CK SJBACK HQBACK CKBACK]
	SETUP
	PLAY.GAME
END

TO SETUP

; locations for the table spaces

	MAKE "LEFTXY [-100 0]
	MAKE "MIDDLEXY [0 0]
	MAKE "RIGHTXY [100 0]

; initial positions of the cards

	MAKE "SJXY :LEFTXY
	MAKE "HQXY :MIDDLEXY
	MAKE "CKXY :RIGHTXY

; Locations for the hands at midpoints above and between the card locations

	MAKE "LXY [-50 100]
	MAKE "RXY [50 100]

; global definitions

	MAKE "SHOW.DELAY 1000
	MAKE "CARDS [SJ HQ CK]

; delay value for movement of cards

	MAKE "DL 21	; related to 73 by 7x3

; initial setup 
; the cards are either in a table space or in a hand
; to start, each space has a card and the hands are empty

	MAKE "TS.LEFT "SJ
	MAKE "TS.MIDDLE "HQ
	MAKE "TS.RIGHT "CK
	MAKE "LEFT.HAND "||
	MAKE "RIGHT.HAND "||

; the available cards are in the non-empty positions

	MAKE "AVAILABLE.CARDS [LEFT MIDDLE RIGHT]

; the available spaces are the empty ones

	MAKE "AVAILABLE.SPACES []
END

TO PLAY.GAME
	CREATE.CARDS
	CREATE.CONTROLS
	FOREACH :CARDS [
		PPROP "? "POSITION THING WORD "? "XY
		PPROP WORD "? "BACK "POSITION THING WORD "? "XY
	]
	SHOW.CARDS
	START.PLAY
END

TO CREATE.CARDS
	MAKE "CARDBACK WORD "BACK RANDOM 8
	FOREACH :CARDS [
		DECLARE "TURTLE "?
		ASK "? [PU LOADSHAPE (WORD "~HOME/TOOLBOX/CARDS/ "?)]
		ASK "? [LOCKSHAPE]
		PPROP "? "TOOLTIP "||
		DECLARE "TURTLE WORD "? "BACK
		ASK WORD "? "BACK [PU LOADSHAPE (WORD "~HOME/TOOLBOX/CARDS/ :CARDBACK)]
		ASK WORD "? "BACK [LOCKSHAPE]
		PPROP WORD "? "BACK "TOOLTIP "||
	]
	FOREACH :AVAILABLE.CARDS [
		ASK WORD (THING WORD "TS. "?) "BACK [SETXY THING WORD "? "XY SHOWTURTLE]
	]
END

TO SHOW.CARDS
	FOREACH :CARDS [
		PPROP WORD "? "BACK "VISIBLE FALSE
		PPROP "? "VISIBLE TRUE
	]
	WAIT :SHOW.DELAY
END

TO SHOW.BACKS
	FOREACH :CARDS [
		PPROP WORD "? "BACK "VISIBLE TRUE
		PPROP "? "VISIBLE FALSE
	]
END

TO START.PLAY
	SHOW.BACKS
	MOVE.CARDS BETWEEN 6 10
	GET.PICK
END

TO MOVE.CARDS :MOVE.COUNT
	DO.INITIAL.MOVE
	REPEAT :MOVE.COUNT [
		MOVE.LEFTHAND
		MOVE.RIGHTHAND
	]
	DO.FINAL.MOVE
END

TO DO.INITIAL.MOVE
	MAKE "CARD "RIGHT
	MAKE "AVAILABLE.CARDS BUTMEMBER "RIGHT :AVAILABLE.CARDS
	MAKE "LEFT.HAND THING WORD "TS. :CARD
	MAKE "AVAILABLE.SPACES FPUT :CARD :AVAILABLE.SPACES
	PPROP WORD :LEFT.HAND "BACK "Z.ORDER 9999
	(WEB.MOVE WORD :LEFT.HAND "BACK LIST THING WORD :CARD "XY :LXY FALSE :DL)

;	TABLE.TO.R
	MAKE "CARD "LEFT
	MAKE "AVAILABLE.CARDS BUTMEMBER "LEFT :AVAILABLE.CARDS
	MAKE "RIGHT.HAND THING WORD "TS. :CARD
	MAKE "AVAILABLE.SPACES FPUT :CARD :AVAILABLE.SPACES
	PPROP WORD :RIGHT.HAND "BACK "Z.ORDER 9999
	(WEB.MOVE WORD :RIGHT.HAND "BACK LIST THING WORD :CARD "XY :RXY FALSE :DL)

; temporarily set the table xy's to be closer
; together to make it harder to follow

	MAKE "LEFTXY [-25 0]
	MAKE "RIGHTXY [25 0]
END

TO MOVE.LEFTHAND
	L.TO.TABLE
	TABLE.TO.L
END

TO MOVE.RIGHTHAND
	R.TO.TABLE
	TABLE.TO.R
END

TO DO.FINAL.MOVE
	L.TO.TABLE
	R.TO.TABLE

; reset the table xy's to be normal

	MAKE "LEFTXY [-100 0]
	MAKE "RIGHTXY [100 0]

; make sure the backs are aligned to the normal table positions

	FOREACH :AVAILABLE.CARDS [
		PPROP WORD (THING WORD "TS. "?) "BACK "POSITION THING WORD "? "XY
	]

	FOREACH :CARDS [
		ASK "? [SETXY ASK WORD "? "BACK [GETXY]]
	]

	FOREACH [LEFT MIDDLE RIGHT] [
		PPROP WORD (THING WORD "TS. "?) "BACK "RUN (LIST "PICKED QUOTE "?)
	]
END

TO TABLE.TO.L
	MAKE "CARD CHOOSE "AVAILABLE.CARDS
	MAKE "LEFT.HAND THING WORD "TS. :CARD
	MAKE "AVAILABLE.SPACES FPUT :CARD :AVAILABLE.SPACES
	PPROP WORD :LEFT.HAND "BACK "Z.ORDER 9999
	(WEB.MOVE WORD :LEFT.HAND "BACK LIST THING WORD :CARD "XY :LXY FALSE :DL)
END

TO TABLE.TO.R
	MAKE "CARD CHOOSE "AVAILABLE.CARDS
	MAKE "RIGHT.HAND THING WORD "TS. :CARD
	MAKE "AVAILABLE.SPACES FPUT :CARD :AVAILABLE.SPACES
	PPROP WORD :RIGHT.HAND "BACK "Z.ORDER 9999
	(WEB.MOVE WORD :RIGHT.HAND "BACK LIST THING WORD :CARD "XY :RXY FALSE :DL)
END

TO L.TO.TABLE
	MAKE "SPACE CHOOSE "AVAILABLE.SPACES
	MAKE WORD "TS. :SPACE :LEFT.HAND
	PPROP WORD :LEFT.HAND "BACK "Z.ORDER 9999
	(WEB.MOVE WORD :LEFT.HAND "BACK LIST :LXY THING WORD :SPACE "XY FALSE :DL)
	MAKE "AVAILABLE.CARDS FPUT :SPACE :AVAILABLE.CARDS
	MAKE "LEFT.HAND "||
END

TO R.TO.TABLE
	MAKE "SPACE CHOOSE "AVAILABLE.SPACES
	MAKE WORD "TS. :SPACE :RIGHT.HAND
	PPROP WORD :RIGHT.HAND "BACK "Z.ORDER 9999
	(WEB.MOVE WORD :RIGHT.HAND "BACK LIST :RXY THING WORD :SPACE "XY FALSE :DL)
	MAKE "AVAILABLE.CARDS FPUT :SPACE :AVAILABLE.CARDS
	MAKE "RIGHT.HAND "||
END

TO ANY.MOVING?
	FOREACH :CARDS [
		IF MOVING? WORD "BACK "? [OUTPUT TRUE]
	]
	OUTPUT FALSE
END

TO GET.PICK
	PPROP "INSTRUCT "VISIBLE TRUE
END

TO PICKED :CHOICE
	PPROP "INSTRUCT "VISIBLE FALSE
	PPROP THING WORD "TS. :CHOICE "VISIBLE TRUE
	PPROP WORD THING WORD "TS. :CHOICE "BACK "VISIBLE FALSE

	IF EQUAL? "HQ THING WORD "TS. :CHOICE [
		PPROP "PLAYORQUIT "TEXT "|You win! Were you just lucky?|
	] [
		PPROP "PLAYORQUIT "TEXT "|Too bad. Better luck next time.|
	]

	PPROP "PLAYBUTTON "STATE FALSE

	FOREACH [PLAYORQUIT PLAYBUTTON] [
		PPROP "? "VISIBLE TRUE
	]
END

TO PLAY.AGAIN
	FOREACH [PLAYORQUIT PLAYBUTTON] [
		PPROP "? "VISIBLE FALSE
	]
	SHOW.CARDS
	WAIT :SHOW.DELAY
	START.PLAY
END

TO CREATE.CONTROLS

	ERASE [INSTRUCT PLAYORQUIT PLAYBUTTON]
	DECLARE "STATICTEXT "INSTRUCT
	PPROPS "INSTRUCT [
		SIZE [200 60]
		POSITION [0 -100]
		TEXT |Where's the Queen of Hearts now? Click a card to see if you're a winner.|
		VISIBLE FALSE
	]

	PPROP "INSTRUCT "FONT SENTENCE BL GPROP "INSTRUCT "FONT 1

	DECLARE "STATICTEXT "PLAYORQUIT
	PPROPS "PLAYORQUIT [
		SIZE [130 40]
		POSITION [0 -84]
		VISIBLE FALSE
	]

	PPROP "PLAYORQUIT "FONT SENTENCE BL GPROP "PLAYORQUIT "FONT 1

	DECLARE "BUTTON "PLAYBUTTON
	PPROPS "PLAYBUTTON [
		SIZE [130 40]
		POSITION [0 -128]
		TEXT |Play again|
		VISIBLE FALSE
		RUN [PLAY.AGAIN]
	]

END

TO ABOUT
	(LOCAL "LF "PP "SAMPLE.TEXT "P1 "P2 "P3 "P4 "P5 "P6 "P7 "P8 "P9 "P10)
	MAKE "LF CHAR 10
	MAKE "PP WORD :LF :LF
	MAKE "P1 "|3-Card Monte is game of chance. The object of the game |
	MAKE "P2 "|is to locate the Queen of Hearts. It may look easy, but |
	MAKE "P3 "|sometimes you get fooled by the movements. |
	MAKE "SAMPLE.TEXT (WORD :P1 :P2 :P3)
	IGNORE ALERT :SAMPLE.TEXT
END

TO WEB.MOVE :OBJECT :PATH :FOREVER? [:DELAY 50] 3
	(LINEAR.MOVE :OBJECT FIRST :PATH LAST :PATH 10 :DELAY)
END

TO LINEAR.MOVE :OBJECT :A :B :N [:DELAY 50] 4
	ASK :OBJECT [SETXY :A SETH TOWARDS :B]
	LOCAL "INC
	ASK :OBJECT [MAKE "INC INT ( (DISTANCE :B) / :N)]
	REPEAT :N [ASK :OBJECT [FD :INC WAIT :DELAY]]
	ASK :OBJECT [SETXY :B]
END

TO RANDOM.BETWEEN :A :B
	LOCAL "TEMP
	IF :A > :B [
		MAKE "TEMP :A
		MAKE "A :B
		MAKE "B :TEMP
	]
	OUTPUT (:A - 1) + RANDOM (:B - :A + 1)
END

TO RANDOM.BETWEEN :A :B
	LOCAL "TEMP
	IF :A > :B [
		MAKE "TEMP :A
		MAKE "A :B
		MAKE "B :TEMP
	]
	OUTPUT (:A - 1) + RANDOM (:B - :A + 1)
END

TO MAIN
	RUNIT
END

; Aliases
ALIAS "RANDOM.BETWEEN "RANDOMAB
ALIAS "RANDOM.BETWEEN "BETWEEN

MAIN

Procedure MAIN
Description A game of chance to locate the Queen of Hearts.
Level Intermediate
Tags Game