[REBOL] Re: A Rebol Challenge. The Monty Hall Puzzle IN 0 BY TES
From: sunandadh:aol at: 19-Dec-2001 20:34
Hi Mario,
> Hallo Sunanda, Rebolers all,
> it looks like you are having a lot of fun with this
> kind of puzzles.
> Maybe this site will interest you:
Thanks for the references.
> I am also fairly
> > confident that I
> > can do a full GUI implementation in under 1K
>
> Uhm, sounds interesting!
> A small interactive math puzzles with animated man and
> sliding doors...
>
Well, it's not under 250, and it isn't very animated. But it is only a first
draft ... more of a proof of concept. See what you think.
You'll have to save this code as a file (e.g. VidDOORS.R) and then Do it ...
The square brackets aren't up to the Console's expectations, so you can't
just cut and paste it into the console
Here's an interesting feature of this code (in my eyes any way) .... In any
other language I expect I would have used a state table: when a door is
clicked the code could check what that click means (First selection; illegal
attempt to pick Monty's door; final selection etc). And--even in Rebol--that
would be an elegant approach. But I've done it different. I change the VID
action facets instead.
Another perhaps interesting feature shows a drawback of VID. VID is
inherently multi-threaded. I'm using WAITs to control some pathetic
graphics
. But that means you could click the other boxes while I'm doing
that. So I have to prevent further input--hence the Disable-doors function.
Sunanda.
Rebol []
;; =========================================
;; Monty Hall Challenge: First draft of code
;; =========================================
;; Reset the display for a new round
;; =================================
ResetDoors: func [/local door-cols]
[
door-cols: random copy reduce [Red blue green]
foreach door view-doors
[
Door/text: copy ""
Door/color: first door-cols
remove door-cols door/color
Door/action: func [face] [I-Pick face]
Door/edge/Effect: 'ibevel
Door/edge/Size: 4x2
Door/edge/color: Door/color / 3
Show Door
] ; for
;; Set which one wins
;; ------------------
Car-Behind: first random view-doors
MSG/Text: "Click a door to play!"
Show Msg
]
;; Disable doors
;; ==============
;;
;; Wait and Vid go together like "Oh no" and "this needs fixing".
;;
;; So we disable all action facets while we are doing our
;; waits
Disable-Doors: func []
[
foreach Door View-doors [Door/Action: none]
]
;; Function when player clicks on any door
;; =======================================
i-Pick: func [face /local unpicked]
[
Disable-doors
Face/text: "You picked this one"
Show face
UnpickedDoors: copy []
foreach Door view-doors
[either door <> face
[append UnpickedDoors Door
Door/Action: func [f] [I-Decide "swap" f]
]
[Door/action: func [f] [I-Decide "Keep" f]
]
] ; for
;; randomise the two doors left, so (if neither of them
;; has no car), Monty isn't always showing the first
UnpickedDoors: random UnpickedDoors
;; Pick an empty door for Monty to show
;; ====================================
Monty: either UnPickedDoors/1 = Car-Behind [UnpickedDoors/2] [UnpickedDoors/1]
;; And show it
;; ===========
Wait (0.1 * random 5)
Monty/Text: "Monty opens this one..."
Monty/Action: func [] []
Show Monty
loop 6 [Monty/color: 255.255.255 - monty/color
show monty
wait 0.2
]
Wait (0.1 * random 5)
Monty/Text: "... It's empty!! No car here^/Now make your final choice"
show monty
Msg/text: "Keep your door, or click the other one ... Good luck!"
show Msg
return true
] ; func
;; Function when player has clicked again to
;; keep the same or select the other door
;; =========================================
;;
;; Action is a string "Swap" or "keep". It is used to
;; reference the Swap and keep globals
i-Decide: func [Action [string!] face /local Results]
[
Disable-doors
;; Create a bit of drama
;; =====================
Msg/Text: "We're checking behind that door... please wait"
Show Msg
Wait (0.75 + 0.1 * random 4)
;; Update the number of plays
Results: get to-word Action
Results/1: Results/1 + 1
;; Check if win or lose
;; ====================
either face = Car-Behind
[face/text: "YOU WIN A CAR!"
loop 12 [Face/color: 255.255.255 - face/color
show face
wait 0.1
]
Results/2: results/2 + 1
]
[
face/text: "Oh No: You lose!"
face/color: 0.0.0
]
show face
;; Update progress bar
;; ===================
Set in get to-word last Results 'data Results/2 / Results/1
show get to-word last Results
MSG/Text: "Click any door to play again"
Show MSG
;; Change all actions back to "play again"
foreach Door View-Doors
[Door/Action: func [] [ResetDoors]]
] ; func
;; ================
;; Start of program
;; ================
;; Global variables
;; ================
;; results blocks [Total Wins Bar-to-update]
;; -----------------------------------------
Keep: copy [0 0 Bar1]
Swap: copy [0 0 Bar2]
Random/seed now
;; Screen metrics
;; --------------
HPixels: system/view/screen-face/size/1
VPixels: system/view/screen-face/size/2
DoorSize: (to-pair reduce [HPixels VPixels]) * 0.2
ProgBarSize: to-integer (Hpixels * 0.60)
;; Array for the doors
View-doors: copy []
;; View the layout
Unview/all
View/New layout
[backdrop effect [gradient 0x1 (white) ]
across
Banner "Monty Challenge!!"
return
ADoor: box DoorSize
do (append View-Doors ADoor)
ADoor: box DoorSize
do (append View-Doors ADoor)
ADoor: box DoorSize
do (append View-Doors ADoor)
return
bar1: progress ProgBarSize 255.255.255 - random 50.50.50
orange + random 50.50.50
text "%wins when sticking" font-size 15
return
Bar2: progress ProgBarSize 255.255.255 - random 75.75.75
orange - random 50.50.50
text "%wins when swapping" font-size 15
Return
MSG: field ProgbarSize black Font-color white font-size 18
]
;; set all defaults before ...
ResetDoors
;; activating the layout
do-events