Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
zmx0142857
GitHub Repository: zmx0142857/mini-games
Path: blob/master/c/rubik-cube/rubik-cube.cpp
363 views
1
#include <cstdio>
2
#include <stack>
3
using namespace std;
4
5
class Cube {
6
typedef unsigned char Color;
7
static const Color WHITE=0, BLUE=1, RED=2, YELLOW=3, GREEN=4,
8
MAGENTA=5, COLORS=6;
9
static const int DIM = 9;
10
Color data[COLORS][DIM];
11
typedef unsigned char Move;
12
stack<Move> undo, redo;
13
14
public:
15
Cube()
16
{
17
for (Color color = WHITE; color != COLORS; ++color)
18
for (int i = 0; i != DIM; ++i)
19
data[color][i] = color;
20
}
21
22
void cycle(Color &a, Color &b, Color &c, Color &d, bool clockwise)
23
{
24
Color tmp = a;
25
if (clockwise) {
26
a = b; b = c; c = d; d = tmp;
27
} else {
28
a = d; d = c; c = b; b = tmp;
29
}
30
}
31
32
void face_rotate(int face, bool clockwise)
33
{
34
35
cycle(data[face][7], data[face][5], data[face][3], data[face][1], clockwise);
36
cycle(data[face][8], data[face][6], data[face][4], data[face][2], clockwise);
37
}
38
39
void rotate(Move group, bool clockwise)
40
{
41
/* group:
42
* 1 = up, 2 = mid, 3 = bottom,
43
* 4 = left, 5 = mid, 6 = right,
44
* 7 = front, 8 = mid, 9 = rear.
45
*/
46
switch (group) {
47
case 1: face_rotate(0, clockwise);
48
cycle(data[1][2], data[2][4], data[4][8], data[5][6], clockwise);
49
cycle(data[1][3], data[2][5], data[4][1], data[5][7], clockwise);
50
cycle(data[1][4], data[2][6], data[4][2], data[5][8], clockwise); break;
51
case 3: face_rotate(3, clockwise);
52
cycle(data[5][2], data[4][4], data[2][8], data[1][6], clockwise);
53
cycle(data[5][3], data[4][5], data[2][1], data[1][7], clockwise);
54
cycle(data[5][4], data[4][6], data[2][2], data[1][8], clockwise); break;
55
case 4: face_rotate(5, clockwise);
56
cycle(data[4][2], data[3][4], data[1][8], data[0][6], clockwise);
57
cycle(data[4][3], data[3][5], data[1][1], data[0][7], clockwise);
58
cycle(data[4][4], data[3][6], data[1][2], data[0][8], clockwise); break;
59
case 6: face_rotate(2, clockwise);
60
cycle(data[0][2], data[1][4], data[3][8], data[4][6], clockwise);
61
cycle(data[0][3], data[1][5], data[3][1], data[4][7], clockwise);
62
cycle(data[0][4], data[1][6], data[3][2], data[4][8], clockwise); break;
63
case 7: face_rotate(1, clockwise);
64
cycle(data[2][2], data[0][4], data[5][8], data[3][6], clockwise);
65
cycle(data[2][3], data[0][5], data[5][1], data[3][7], clockwise);
66
cycle(data[2][4], data[0][6], data[5][2], data[3][8], clockwise); break;
67
case 9: face_rotate(4, clockwise);
68
cycle(data[3][2], data[5][4], data[0][8], data[2][6], clockwise);
69
cycle(data[3][3], data[5][5], data[0][1], data[2][7], clockwise);
70
cycle(data[3][4], data[5][6], data[0][2], data[2][8], clockwise); break;
71
case 2: cycle(data[1][1], data[2][3], data[4][7], data[5][5], clockwise);
72
cycle(data[1][0], data[2][0], data[4][0], data[5][0], clockwise);
73
cycle(data[1][5], data[2][7], data[4][3], data[5][1], clockwise); break;
74
case 5: cycle(data[0][1], data[1][3], data[3][7], data[4][5], clockwise);
75
cycle(data[0][0], data[1][0], data[3][0], data[4][0], clockwise);
76
cycle(data[0][5], data[1][7], data[3][3], data[4][1], clockwise); break;
77
case 8: cycle(data[2][1], data[0][3], data[5][7], data[3][5], clockwise);
78
cycle(data[2][0], data[0][0], data[5][0], data[3][0], clockwise);
79
cycle(data[2][5], data[0][7], data[5][3], data[3][1], clockwise); break;
80
}
81
}
82
83
void print() const
84
{
85
/*
86
____________ ____________
87
/ 8 / 1 / 2 /\ /\ 2 \ 1 \ 8 \
88
/___/___/___/6 \ /6 \___\___\___\
89
/ 7 /(0)/ 3 /\ /\ /\ /\ 3 \(4)\ 7 \
90
/___/___/___/5 \/7 \ /7 \/5 \___\___\___\
91
/ 6 / 5 / 4 /\ /\ /\ /\ /\ /\ 4 \ 5 \ 6 \
92
/___/___/___/4 \/2)\/8 \ /8 \/5)\/4 \___\___\___\
93
\ 2 \ 3 \ 4 \ /\ /\ / \ /\ /\ / 4 / 3 / 2 /
94
\___\___\___\/3 \/1 \/ \/1 \/3 \/___/___/___/
95
\ 1 \(1)\ 5 \ /\ / \ /\ / 5 /(3)/ 1 /
96
\___\___\___\/2 \/ \/2 \/___/___/___/
97
\ 8 \ 7 \ 6 \ / \ / 6 / 7 / 8 /
98
\___\___\___\/ \/___/___/___/
99
100
printf(
101
" ____________\n"
102
" / / / /\\\n"
103
" /___/___/___/ \\\n"
104
" / / / /\\ /\\\n"
105
" /___/___/___/ \\/ \\\n"
106
" / / / /\\ /\\ /\\\n"
107
"/___/___/___/ \\/ \\/ \\\n"
108
"\\ \\ \\ \\ /\\ /\\ /\n"
109
" \\___\\___\\___\\/ \\/ \\/\n"
110
" \\ \\ \\ \\ /\\ /\n"
111
" \\___\\___\\___\\/ \\/\n"
112
" \\ \\ \\ \\ /\n"
113
" \\___\\___\\___\\/\n");
114
*/
115
static const char *ones[] = {
116
"\033[47m \033[0m", // white
117
"\033[44m \033[0m", // blue
118
"\033[41m \033[0m", // red
119
"\033[43m \033[0m", // yellow
120
"\033[42m \033[0m", // green
121
"\033[45m \033[0m" // magenta
122
};
123
static const char *threes[] = {
124
"\033[47m \033[0m",
125
"\033[44m \033[0m",
126
"\033[41m \033[0m",
127
"\033[43m \033[0m",
128
"\033[42m \033[0m",
129
"\033[45m \033[0m"
130
};
131
printf("\033[0;0H"); // go to 0,0
132
#define QQQ(i,j) threes[data[i][j]]
133
#define Q(i,j) ones[data[i][j]]
134
printf(" %s %s %s \n"
135
" %s %s %s %s \n"
136
" %s %s %s %s \n"
137
" %s %s %s %s %s %s \n"
138
" %s %s %s %s %s \n"
139
" %s %s %s %s %s %s %s %s \n"
140
" %s %s %s %s %s %s\n"
141
"e %s %s %s %s %s %s %s %s o\n"
142
" %s %s %s %s %s\n"
143
" d %s %s %s %s %s %s k\n"
144
" %s %s %s %s\n"
145
" c %s %s %s %s m\n"
146
" v b n\n\n"
147
, QQQ(0,8), QQQ(0,1), QQQ(0,2)
148
, QQQ(0,8), QQQ(0,1), QQQ(0,2), Q(2,6)
149
, QQQ(0,7), QQQ(0,0), QQQ(0,3), QQQ(2,6)
150
, QQQ(0,7), QQQ(0,0), QQQ(0,3), Q(2,5), Q(2,6), Q(2,7)
151
, QQQ(0,6), QQQ(0,5), QQQ(0,4), QQQ(2,5), QQQ(2,7)
152
, QQQ(0,6), QQQ(0,5), QQQ(0,4), Q(2,4), Q(2,5), Q(2,0), Q(2,7), Q(2,8)
153
, QQQ(1,2), QQQ(1,3), QQQ(1,4), QQQ(2,4), QQQ(2,0), QQQ(2,8)
154
, QQQ(1,2), QQQ(1,3), QQQ(1,4), Q(2,4), Q(2,3), Q(2,0), Q(2,1), Q(2,8)
155
, QQQ(1,1), QQQ(1,0), QQQ(1,5), QQQ(2,3) , QQQ(2,1)
156
, QQQ(1,1), QQQ(1,0), QQQ(1,5), Q(2,3), Q(2,2), Q(2,1)
157
, QQQ(1,8), QQQ(1,7), QQQ(1,6), QQQ(2,2)
158
, QQQ(1,8), QQQ(1,7), QQQ(1,6), Q(2,2));
159
#undef QQQ
160
#undef Q
161
}
162
163
void play()
164
{
165
printf("\033[2J"); // clear screen
166
char c = 0;
167
Move m;
168
print();
169
printf("\033[1A"); // move up cursor
170
while ((c = getchar()) != EOF) {
171
switch (c) {
172
case 'e': rotate(1, true); undo.push(~1); break;
173
case 'd': rotate(2, true); undo.push(~2); break;
174
case 'c': rotate(3, false); undo.push(3); break;
175
case 'v': rotate(4, true); undo.push(~4); break;
176
case 'b': rotate(5, false); undo.push(5); break;
177
case 'n': rotate(6, false); undo.push(6); break;
178
case 'm': rotate(7, true); undo.push(~7); break;
179
case 'k': rotate(8, true); undo.push(~8); break;
180
case 'o': rotate(9, false); undo.push(9); break;
181
182
case 'E': rotate(1, false); undo.push(1); break;
183
case 'D': rotate(2, false); undo.push(2); break;
184
case 'C': rotate(3, true); undo.push(~3); break;
185
case 'V': rotate(4, false); undo.push(4); break;
186
case 'B': rotate(5, true); undo.push(~5); break;
187
case 'N': rotate(6, true); undo.push(~6); break;
188
case 'M': rotate(7, false); undo.push(7); break;
189
case 'K': rotate(8, false); undo.push(8); break;
190
case 'O': rotate(9, true); undo.push(~9); break;
191
case '\n':
192
// move up cursor
193
printf("\033[1A");
194
printf("\033[K");
195
continue;
196
case 'u':
197
if (!undo.empty()) {
198
m = undo.top();
199
undo.pop();
200
redo.push(m);
201
if (1 <= m && m <= 9)
202
rotate(m, true);
203
else
204
rotate(~m, false);
205
break;
206
} else {
207
continue;
208
}
209
case 'r':
210
if (!redo.empty()) {
211
m = redo.top();
212
redo.pop();
213
if (1 <= m && m <= 9)
214
rotate(m, false);
215
else
216
rotate(~m, true);
217
break;
218
} else {
219
continue;
220
}
221
default:
222
continue;
223
}
224
print();
225
}
226
}
227
};
228
229
int main()
230
{
231
Cube cube;
232
cube.play();
233
return 0;
234
}
235
236