Last active
October 26, 2019 03:23
-
-
Save ne1uno/a5d79c0b7a8f9dac65f4737834b900b4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
http://news.e-scribe.com/193 | |
To move, you tell the computer how many numbers (counting from the left) to reverse. | |
For example, if the current list is 2 3 4 5 1 6 7 8 9 and you reverse 4, | |
the result will be 5 4 3 2 1 6 7 8 9. Now if you reverse 5, you win. | |
• Comment from Pascal | |
Funny game, here is a REBOL version of this game. An interesting thing is its readability. | |
numbers: random ordered: [1 2 3 4 5 6 7 8 9] | |
count: 0 | |
while [numbers <> ordered][ | |
reverse/part probe numbers to-integer ask "Reverse how many? " | |
count: count + 1 | |
] | |
print reform ["Done! That took you" count "steps."] | |
<> Or you can also use this: while [not-equal? numbers ordered] | |
I got the idea from reverse.exu jeremy euqt ~2010 or so and this | |
http://openeuphoria.org/wiki/view/ReverseGame.wc | |
[0 1 2 3 4 5 6 7 9 8] move (0 to quit)? 10 | |
[8 9 7 6 5 4 3 2 1 0] move (0 to quit)? 2 | |
[9 8 7 6 5 4 3 2 1 0] move (0 to quit)? 10 | |
You've won in only 3 moves! | |
very difficult to imagine good search terms to find prior art | |
https://www.bing.com/search?q=reverse++button+swap+demo | |
the game works slightly different than I remember | |
added tabs for swapper or reverser versions | |
Red [ | |
title "reverse swap game demo example conversion to redlang" | |
auth: "ne1" | |
date: "2019/10" | |
icon: %red-3D.ico | |
Needs: 'View | |
version: 0.0.0.00 ; | |
rights: "MIT or whatever you like" | |
productname: "reverse from jeremy euqt example and pascal" | |
red-strict-check?: no | |
] | |
random/seed now/precise | |
bfont: make font! [ ;game buttons | |
name: "Consolas" ; | |
size: 16 | |
color: gray | |
style: 'bold | |
align: 'left | |
] | |
tfont: make font! [ ;status text | |
name: "Consolas" ; | |
size: 11 | |
color: gray | |
;style: 'bold | |
align: 'left ; | |
] | |
ifont: make font! [ ;ui buttons | |
name: "arial" ; how to specify fallback 2nd typeface? need validate font exists | |
size: 12 | |
color: black | |
align: 'left ;center | |
] | |
;; _: 0 | |
;; steps: -1 | |
gboard: [1 2 3 4 5 6 7 8 9] ;this may be pointers to images or simply integers | |
board: random copy gboard ;shuffle | |
n: 9 | |
nxy: 40x50 ;horribly hardwired | |
;room for panel and timer and debug area assumes tfont and swapper 1..9 buttons | |
wxy: as-pair (nxy/x + 14 * n) nxy/y * 6 | |
txy: as-pair (nxy/x + 12 * n) nxy/y * 3 ;panel, room for game buttons, assumes bfont | |
; | |
;; swapper still too hardwired, status & timer code | |
status: [alert "message" ] ;temp workaround status not defined till gui runs | |
now': does [now/time/precise] | |
;never quite got eraser fade working | |
init-stats: function [ "add eraser or whatever to this face" | |
face "area/text to push message" | |
][ | |
face/extra: make object! [ | |
eraser: no | |
eraser: func [ "reduce message till it's gone" | |
seconds | |
][ | |
;; either face/extra/eraser [ | |
;; face/text: rejoin [face/text: copy/part face/text (3 - length? face/text)] | |
;; face/rate/time: seconds | |
;; ][ | |
;; eraser: yes | |
;; ] | |
] | |
] | |
] | |
update-stats: function [ "add message to area" | |
face "area/text to push message" | |
msg | |
/timeout sec "do I even know how? add reactor to erase message in sec seconds" | |
/line "single line insert" | |
;need to replace or insert refinement, newline not always good | |
][ | |
either line [ | |
face/text: rejoin [msg space copy/part face/text 500] | |
][ | |
face/text: rejoin [msg newline copy/part face/text 3500] | |
] | |
if timeout [face/extra/erase sec] ;needs to be accessable for other processes to cancel it | |
] | |
half-life: 60 | |
; | |
; from @hiiamboris retris.red as used in setsgame. copy from 'status: above to 'start below | |
; should rename Cards, decks, Score to more generic names and alias to fit usage better | |
; | |
rea': copy rea: make deep-reactor! [ | |
elapsed: 0:0:0 score: 0 deckc: 0 pause: no t0: is [elapsed pause now'] ;deckc: length? deck | |
interval: is [(atan (to-float elapsed) / half-life) / (pi / -2) + 1.0] | |
hint-status: none | |
;scores: [] scores: is [head clear skip sort/skip/reverse scores 2 20] | |
] | |
; do start or restart as required, may want pause? | |
restart: does [start rea/score: 0] | |
start: does [set rea rea' rea/t0: now'] | |
start | |
;example use, there are a few moving parts | |
; | |
;rea/hint-status/text: "" ;place anywhere update needs to happen | |
;and/or | |
;update-stats status " find sets ", debug area for more output if open window more | |
; create timer in layout | |
;; group-box 500x38 font (cfg/dfont) color-bg "" [ ;adds extra line for some reason | |
;; pad 5x-8 | |
;; text "Scores: 00 etcs Cards remain" font (cfg/cfont) | |
;; react [face/data: reduce/into [ | |
;; "Found:" rejoin [rea/score ordinal-suffix rea/score] "Set" | |
;; rea/deckc "Cards remain" | |
;; ] clear []] | |
;; pad -8x0 | |
;; text 125x22 "T" font (cfg/cfont) | |
;; react [face/data: reduce/into [ | |
;; "Time:" round rea/elapsed | |
;; ] clear []] | |
;; rate 0:0:1 on-time [ | |
;; unless rea/pause [ | |
;; ;advance 0x1 | |
;; rea/elapsed: rea/elapsed + modulo now' - rea/t0 24:0:0 | |
;; face/rate: rea/interval * 0:0:1 | |
;; ] | |
;; ] | |
;; ] ;g | |
;; pad 0x5 | |
;; return | |
;; rea/deckc: length? deck ; | |
;; rea/hint-status/text: rejoin ["replaced " form g ordinal-suffix g] | |
;; status: area color-bg 450x130 font cfg/bfont "" ;white/ivory works cfg/color-bg fails? | |
;; gstatus: 'text 'font (cfg/cfont) 290x24 "-------- Hintinfo --------" | |
;; 'on-created [rea/hint-status: face init-stats face] ;push face to reactor for hint & info. | |
; init after gui drawn | |
;; ; >. 17=<<200x w/cfont | |
;; gstatus: 'text 'font (cfg/cfont) 290x24 "-------- Hintinfo --------" | |
;; 'on-created [rea/hint-status: face init-stats face] ;push face to reactor for hint & info. | |
;; status: area color-bg 450x130 font cfg/bfont "" ; | |
; in use examples | |
;rea/score: rea/score + 1 | |
; do rich-text counter & timer | |
;; rich-text "Hello Red World!" draw [pen gold box 40x50 90x80] | |
;; with [data: [1x17 0.0.255 italic 7x3 255.0.0 bold 24 underline]] | |
;should clip save | |
;how is this or a generator or an itterator not in a lib and used before? | |
;reset needs to take name and n so can have default or named counters maintained | |
_counter: 0 | |
next_counter: function ["generic generator, returns next higher number, incrementing _counter. /reset n returns n" | |
/reset n "set to n" | |
/extern _counter | |
][ ; | |
either reset [_counter: n][ | |
_counter: 1 + _counter | |
] | |
_counter ;redundent? | |
] | |
;need something for init new game like reverser | |
b: copy board | |
next_b: function ["next button text from board" /extern b][ ; | |
;print [b "-"] | |
x: first b | |
b: next b | |
x | |
] | |
;; print [b " +" next_b] | |
;; print [b " +" next_b] | |
clicked: none | |
swap_b: function ["push text on first button clicked, 2nd clicked swap their text" face /extern clicked /local x][ ; | |
either clicked [ | |
x: face/text | |
face/text: clicked/text | |
clicked/text: x | |
clicked: none | |
rea/hint-status/text: "" ; | |
rea/score: rea/score + 1 | |
update-stats status rejoin [" swapped " form x " " form face/text] | |
][ | |
clicked: face | |
rea/hint-status/text: rejoin [form clicked/text " pick another"] ; | |
] | |
] | |
buttons: clear [] ;only intended to be used for one set of buttons, reverser uses swapper doesn't | |
;sequential in created order here but could be map and store face, count, text and other incedentals | |
Init-Buttons-Reverse: function [{classic generic push face into button array to access later} | |
face | |
/extern buttons | |
][ | |
print [" +" length? buttons] | |
;create b"n" tag? | |
append buttons face ;[face] | |
] | |
Update-Board: function [{reverser game update board & buttons on clicked} | |
count [integer!] | |
/extern board | |
][ | |
;prin [count " " board] | |
; board = reverse(board, 1, count) | |
board: reverse/part board count | |
;; for i = 1 to count do | |
;; q:propset(buttons[i], "text", sprintf("%d", board[i])) | |
;; end for | |
forall buttons [ | |
;prin [buttons/1/text "-"] | |
buttons/1/text: form board/1 | |
board: next board | |
] | |
;; steps += 1 | |
;; q:propset(moveCounter, "text", sprintf("Move #%d", steps)) | |
rea/score: 1 + rea/score ;reactive | |
board: head board | |
;print [ " reversed " board] | |
if equal? gboard board [ | |
print ["Won!"] | |
update-stats status rejoin [" won in " form rea/score " moves"] | |
;; --how to add custom test to button? | |
;; _ = q:information(win, "Winner", | |
;; sprintf("You've won in %d moves!\n\nNew Game?", steps), | |
;; or_all({QMessageBox_Yes, QMessageBox_No}) | |
;; ) | |
;; if _ then | |
;; ?1 | |
;; abort(0) | |
;; else | |
;; --newgame eventually | |
;; ?0 | |
;; abort(0) | |
;; end if | |
] | |
] | |
;text label | |
tlabel: 0 ;later may need to change when do image slices | |
s-title: " Swaps" ;this may need to change per tab eventually make cfg | |
gview: layout [ ;compose/deep | |
title "reverse button " | |
size wxy ;750x300 | |
backdrop ivory | |
;for swapper from rcalc | |
style mb: base nxy bold font bfont extra context [c: wheat] ;none red, should't need to hardwire | |
[print [form face/text]] ;seems to be ignored if set at use? | |
on-create [ | |
face/extra: make face/extra clear [] | |
face/extra/c: face/color | |
face/text: form next_b | |
] | |
on-over [ | |
face/color: either event/away? [face/extra/c][white] ;face/color / 2] | |
] | |
style bs: mb wheat [swap_b face] ;on-create [face/text: form next_b] | |
style bt: mb wheat [] | |
style bh: text 43x15 ivory font-size 9 font tfont [] on-create [tlabel: (1 + tlabel) face/text: rejoin [" " form tlabel]] | |
;for reverser | |
style mb-r: base nxy bold font bfont extra context [c: wheat i: 0] ;none red, should't need to hardwire | |
;need to bg-color & cfg defaults | |
style bs-r: mb-r wheat | |
on-create [ | |
face/extra: make face/extra clear [] ;why am I making extra blank after making a context c i there? | |
face/extra/c: face/color | |
;not sure why didn't work in layout on-create | |
face/extra/i: next_counter ;have to /reset 0 instead of 1 when next_counter used in style. | |
Init-Buttons-Reverse face | |
;need set key shortcut 1..9 | |
] | |
on-over [ | |
face/color: either event/away? [face/extra/c][white] ;face/color / 2] | |
] | |
style bt-r: mb-r wheat | |
on-create [ | |
face/extra: make face/extra clear [] | |
face/extra/c: face/color | |
] | |
on-over [ | |
face/color: either event/away? [face/extra/c][white] ;face/color / 2] | |
] | |
style bh-r: text 43x15 ivory font-size 9 font tfont ;[] | |
on-create [ | |
tlabel: 1 + tlabel | |
face/text: rejoin [" " form tlabel] | |
] | |
tp: tab-panel txy [ | |
"Reverser Game" [ | |
;row of hints above | |
text 1x1 on-create [tlabel: 0] ;backdoor init, careful if rearrange tabs | |
bh-r bh-r bh-r bh-r bh-r bh-r bh-r bh-r bh-r | |
return | |
text 1x1 on-create [tlabel: 0 next_counter/reset 0] ;backdoor init, careful if rearrange tabs | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
bs-r | |
[ | |
update-board face/extra/i | |
] | |
;last one needs additional init and next_counter from style is ignored for some reason | |
bs-r | |
[ | |
update-board face/extra/i | |
;print [form face/text mold face/extra board] | |
] | |
text 1x1 on-create [ | |
print ["last reverser button created"] | |
update-board n | |
restart | |
update-stats status rejoin [board " " form rea/score] | |
] ;backdoor done w/creating buttons | |
return | |
bt-r 178x25 "new game" font ifont silver [ ;need a new_game/reverser to enable init from multiple places | |
board: random copy gboard print ["randomized" board] | |
Update-Board n | |
restart | |
update-stats status rejoin [board " " form rea/score] | |
] | |
] "Swapper Game" [ | |
;; ;row of hints above | |
;; text 1x1 on-create [ tlabel: 0] ;backdoor init | |
;; bh bh bh bh bh bh bh bh bh | |
;; return | |
;; bs bs bs bs bs bs bs bs bs | |
;; return | |
;; | |
;; check "P/L" font ifont silver [print ["pl"]] ;H/V and other posibilities | |
;; bt 178x25 "new game" font ifont silver [ ;possibly lighup when buttons aligned. need flexible validator | |
;; ;add details what was swapped should be in any init, not after done first time | |
;; board: random copy gboard print ["random" board] | |
;; update-stats status rejoin [board " " form rea/score] | |
;; | |
;; ;; need init or update buttons like reverse | |
;; restart | |
;; ] | |
]];e tp | |
return | |
;count & timer | |
group-box 500x38 font tfont white "" [ ;adds extra line for some reason | |
pad 5x-8 | |
;needs to be no wrap | |
tcount: text "Swaps: 00 " font tfont ;Swaps remaining 00 when do solver | |
react [face/data: reduce/into [ | |
"" rejoin [rea/score s-title] ;ordinal-suffix rea/score | |
; rea/deckc "Swaps remain" | |
] clear []] | |
pad -8x0 | |
text 125x22 "T" font tfont | |
react [face/data: reduce/into [ | |
"" round rea/elapsed | |
] clear []] | |
rate 0:0:1 on-time [ | |
unless rea/pause [ | |
;advance 0x1 | |
rea/elapsed: rea/elapsed + modulo now' - rea/t0 24:0:0 | |
face/rate: rea/interval * 0:0:1 | |
] | |
] | |
] ;g | |
pad 0x5 | |
return | |
;status & debug info | |
gstatus: text font tfont 250x24 "" ;-------- Hintinfo -------- | |
on-created [rea/hint-status: face init-stats face] ;push face to reactor for hint & info updates. | |
return | |
return | |
status: area white 250x80 font tfont "" ; | |
] | |
insert-event-func [ | |
if all [event/window = gview event/type = 'resize] [ | |
;print ["size-pos " event/window/size status/offset tp/offset] | |
tp/size/x: event/window/size/x - 5 - tp/offset/x | |
;; | |
;; ; | |
;; status/size/x: event/window/size/x - 18 - status/offset/x | |
;; tcount/size/x: event/window/size/x - 14 - tcount/offset/x ;reactor protected? | |
;'done | |
] | |
] | |
;remove no-wait when -r/-c compiled, fails -e encaped and console | |
; | |
;; either system/state/interpreted? [ | |
;; view/no-wait/flags/options gview ['resize][offset: 80x20] | |
;; ][ | |
;; ;when compiled, can't no-wait | |
;; view/flags/options gview ['resize][offset: 80x20] | |
;; ] | |
;works interpreted or compiled | |
view/flags/options gview ['resize][offset: 80x20] | |
comment { | |
t11927p01:49 last edited euphoria version | |
f2019A18a12 cvert to red | |
looked up the rerverse web pages, seems I forgot how the game was intended to work. | |
left unfinished swap button version, may do other spinoffs, image slices, order of images game | |
comment out either interpreted?, fails console and -e otherwise. | |
no simple workaround? add console and -e to not exit? | |
consolidate init and context for board for each tab using basically the same setup | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment