-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path2048.red
208 lines (193 loc) · 4.71 KB
/
2048.red
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
Red [
Title: {2048}
File: %2048.red
Author: {WayneTsui}
Description: {
Inspired by https://github.com/mydzor/bash2048
}
]
game: context [
pipe: '|
bar: append/dup copy [] quote '- 19
content: append/dup copy [] " " 19
content/5: content/10: content/15: quote pipe
score: 0
directions: charset {HhLlKkJjAaDdWwSsQq}
generate: function [ values [block!] return: [block!]][
position: first random parse values [
collect [
any [
ahead none! s: keep (index? s) skip | skip
]
]
]
head replace at values position none first random copy [2 4]
]
fill-content: function [ values [block!] return: [block!]][
board: copy []
repeat i 4 [
temp: copy content
repeat j 4 [
value: values/((i - 1) * 4 + j)
unless none? value [
temp/(j * 5 - 1): value
case [
value < 10 [ ]
value < 100 [ temp/(j * 5 - 2): reduce [space space]]
value < 1000 [temp/(j * 5 - 2): "" ]
true [temp/(j * 5 - 2): "" temp/(j * 5 - 3): reduce [space space]]
]
]
]
append board compose [bar lf (content) lf (temp) lf (content) lf ]
]
append board bar
board
]
move: function [ direction [char!] values [block!] return: [block!]][
move-hori: function [ value [block!] action [block!] return: [block!]][
result: copy []
repeat i 4 [
numbers: copy []
nones: copy []
parse reduce bind value 'i [
collect into numbers [
any [
set s integer! keep (s) | set t none! (append nones t)
]
]
]
do bind action 'result
]
result
]
move-vert: function [ value [block!] action [block!] return: [block!]][
;result: make block! 16
result: append/dup copy [] none 16
repeat i 4 [
numbers: copy []
nones: copy []
parse reduce bind value 'i [
collect into numbers [
any [
set s integer! keep (s) | set t none! (append nones t)
]
]
]
do bind action 'result
result/(i): temp/1
result/(i + 4): temp/2
result/(i + 8): temp/3
result/(i + 12): temp/4
]
result
]
merge: function [ blk [block!] return: [block!]][
result: copy []
parse blk [
collect into result [
any [
set a integer! set b integer!
if(equal? a b) (append blk none game/score: game/score + a + b)
keep (a + b)
|
set a integer! keep (a)
|
set a none! keep (a)
]
]
]
head result
]
switch direction [
#"h" #"H" #"a" #"A" [ ;Left
blk: [ values/(i * 4 - 3) values/(i * 4 - 2) values/(i * 4 - 1) values/(i * 4)]
action: [append result merge append head numbers nones]
result: move-hori blk action
]
#"l" #"L" #"d" #"D" [ ;Right
blk: [ values/(i * 4 - 3) values/(i * 4 - 2) values/(i * 4 - 1) values/(i * 4)]
action: [append result reverse merge reverse append nones head numbers]
result: move-hori blk action
]
#"k" #"K" #"w" #"W" [ ;Up
blk: [ values/(i) values/(i + 4) values/(i + 8) values/(i + 12)]
action: [
temp: copy []
append temp merge append head numbers nones
]
result: move-vert blk action
]
#"j" #"J" #"s" #"S" [ ;Down
blk: [ values/(i) values/(i + 4) values/(i + 8) values/(i + 12)]
action: [
temp: copy []
append temp reverse merge reverse append nones head numbers
]
result: move-vert blk action
]
#"q" #"Q" [ quit ]
]
result
]
win?: function [ values [block!] return: [logic!]][
either find values 2048 [
print "Congratulations! You win!"
true
][
false
]
]
lose?: function [ values [block!] return: [logic!]][
find-adjacent: function[ blk [block!] return: [ logic ]][
parse blk [
some [
set a integer! set b integer! if ( equal? a b) (return true)
|
skip
]
]
false
]
either find values none [
false
][
repeat i 4 [
if find-adjacent reduce [ values/(i * 4 - 3) values/(i * 4 - 2) values/(i * 4 - 1) values/(i * 4)][
return false
]
if find-adjacent reduce [ values/(i) values/(i + 4) values/(i + 8) values/(i + 12) ][
return false
]
]
print "What a pity!"
true
]
]
start: does [
values: append/dup copy [] none 16
values: generate values
print ["Score: " game/score]
print fill-content values
command: none
until[
until [
command: ask "[H] left, [L] right, [K] up, [J] down or [Q]uit?"
all [ not none? first command find game/directions first command]
]
;probe values
privious: copy values
command: first command
values: move command values
unless equal? privious values [
values: generate values
]
;probe values
print ["Score: " game/score]
print fill-content values
any [ win? values lose? values]
]
if find [#"y" #"Y"] first ask "Play again? [Y/N]" [ start ]
]
]
game/start