forked from girst/solvitaire-mirror-of-git.gir.st
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sol.h
267 lines (255 loc) · 6.16 KB
/
sol.h
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#ifndef __SOL_H__
#define __SOL_H__
// enums and constants {{{
#define DECK_SIZE 52
#ifdef KLONDIKE
#define NUM_PILES 7
#define MAX_HIDDEN 6 /*how many cards are turned over at most in a tableu pile*/
#define MAX_STOCK 24 /*how many cards can be in the stock at most (=@start)*/
#define NUM_DECKS 1
#define PILE_SIZE MAX_HIDDEN+NUM_RANKS
#elif defined SPIDER
#define MAX_HIDDEN 5
#define NUM_PILES 10
#define MAX_STOCK 50 /*how many cards can be dealt onto the piles*/
#define NUM_DECKS 2
#define PILE_SIZE DECK_SIZE*NUM_DECKS /* no maximum stack size in spider :/ */
#endif
enum cards {
NO_CARD,
CLU_A, DIA_A, HEA_A, SPA_A,
CLU_2, DIA_2, HEA_2, SPA_2,
CLU_3, DIA_3, HEA_3, SPA_3,
CLU_4, DIA_4, HEA_4, SPA_4,
CLU_5, DIA_5, HEA_5, SPA_5,
CLU_6, DIA_6, HEA_6, SPA_6,
CLU_7, DIA_7, HEA_7, SPA_7,
CLU_8, DIA_8, HEA_8, SPA_8,
CLU_9, DIA_9, HEA_9, SPA_9,
CLU_X, DIA_X, HEA_X, SPA_X,
CLU_J, DIA_J, HEA_J, SPA_J,
CLU_Q, DIA_Q, HEA_Q, SPA_Q,
CLU_K, DIA_K, HEA_K, SPA_K,
_NUM_CARDS_internal
};
enum colors {
BLK,
RED,
NUM_COLORS
};
enum suits {
CLUBS,
DIAMONDS,
HEARTS,
SPADES,
NUM_SUITS
};
enum ranks {
RANK_A,
RANK_2,
RANK_3,
RANK_4,
RANK_5,
RANK_6,
RANK_7,
RANK_8,
RANK_9,
RANK_X,
RANK_J,
RANK_Q,
RANK_K,
NUM_RANKS
};
enum action_return {
OK, /*move successful*/
ERR, /*invalid move*/
WON, /*game won*/
};
enum game_states {
GAME_NEW,
GAME_WON,
GAME_QUIT,
};
/* WARN: stock must always follow immediately after `TAB_*`! */
#define TAB_MAX (STOCK-1)
enum field_places {
TAB_1,
TAB_2,
TAB_3,
TAB_4,
TAB_5,
TAB_6,
TAB_7,
#ifdef SPIDER
TAB_8,
TAB_9,
TAB_10,
STOCK,
#define WASTE 0 /* for action[][10] (must be valid index) */
#define TABLEU STOCK+1 /* for undo{.t} (value never read) */
#define FOUNDATION STOCK+2 /* for undo{.t} (must be unique) */
#elif defined KLONDIKE
STOCK,
WASTE,
FOUNDATION,
#endif
NUM_PLACES,
};
enum special_cmds {
CMD_MOVE,
CMD_INVAL,
CMD_NONE,
CMD_QUIT,
CMD_NEW,
CMD_AGAIN,
CMD_HINT,
CMD_JOIN,
CMD_UNDO,
CMD_HELP,
};
enum event {
/* for getctrlseq() */
KEY_NULL = 0,
KEY_EOF = -1,
KEY_INVAL = -2,
MOUSE_ANY = -3,
/* for getch() */
MOUSE_LEFT = -4,
MOUSE_MIDDLE = -5,
MOUSE_RIGHT = -6,
MOUSE_DRAG = -7,
KEY_LEFT = -8,
KEY_DOWN = -9,
KEY_UP = -10,
KEY_RIGHT = -11,
KEY_HOME = -12,
KEY_END = -13,
KEY_INS = -14,
KEY_PGUP = -15,
KEY_PGDN = -16,
};
enum difficulty {
NORMAL,
MEDIUM,
EASY,
};
//}}}
typedef signed char card_t;
struct playfield {
int z; /* stock size */
int w; /* waste; index into stock (occupied foundations in spider) */
card_t s[MAX_STOCK]; /* stock */
card_t f[NUM_DECKS*NUM_SUITS][PILE_SIZE]; /* foundation */
card_t t[NUM_PILES][PILE_SIZE]; /* tableu piles */
struct undo {
int f; /* pile cards were taken from */
int t; /* pile cards were moved to */
int n; /* if tableu: number of cards moved */
/* else: index into stock/foundation */
int o; /* turn_over() fired? */
struct undo* prev;
struct undo* next;
}* u;
};
struct opts {
#ifdef SPIDER
int m; /* difficulty mode */
#endif
unsigned short w[2]; /* terminal window rows/columns */
const struct scheme* s;
int h; /* show active highlight? (disabled when mouse used) */
int v; /* (simulated) visbell enabled? */
};
struct cursor {
int pile;
int opt; /* klondike: foundation id; spider: move nth movable card */
};
const struct cursor no_hi = {-1, -1};
#define NO_HI &no_hi
struct undo undo_sentinel;
// help texts {{{
#define SHORTHELP "%s [OPTIONS]\n"
#ifdef KLONDIKE
#define LONGHELP_SPECIFIC ""
#define DIRECT_ADDR_KEYHELP \
" 1 .. 7: directly address tableu\n" \
" 8,9,0 : directly address stock/waste/foundation\n"
#elif defined SPIDER
#define LONGHELP_SPECIFIC \
" -s(uits) <1, 2 or 4>\n"
#define DIRECT_ADDR_KEYHELP \
" 1 .. 0: directly address tableu\n"
#endif
#define LONGHELP \
"OPTIONS:\n" \
LONGHELP_SPECIFIC \
" -b(land colorscheme)\n" \
" -c(olorful colorscheme)\n" \
" -m(iniature colorscheme, monochrome)\n" \
" -M(iniature colorscheme, colorful)\n" \
" -V(isual bell disable; experimental)\n" \
" -h(elp)\n" \
"\n"
#define KEYHELP \
"Keybindings:\n" \
" hjkl : move cursor (or cursor keys)\n" \
" H,M,L : move cursor to first/centre/last tableu pile (or home/ins/end)\n" \
" J : join to here (or right mouse click)\n" \
/*" K : show hint\n" */\
" space : select at cursor (or left mouse click)\n" \
" return: draw from stock\n" \
" :n : new game\n" \
" :r : restart game\n" \
" :h : show keyboard help\n" \
" :q : quit\n" \
DIRECT_ADDR_KEYHELP
//}}}
int sol(void);
void quit(void);
int find_top(card_t* pile);
int first_movable(card_t* pile);
int turn_over(card_t* pile);
int check_won(void);
int rank_next (card_t a, card_t b);
int is_consecutive (card_t* pile, int pos);
int is_movable(card_t* pile, int n);
#ifdef KLONDIKE
card_t stack_take(void);
int t2f(int from, int to, int opt);
int w2f(int from, int to, int opt);
int s2w(int from, int to, int opt);
int w2s(int from, int to, int opt);
int f2t(int from, int to, int opt);
int w2t(int from, int to, int opt);
int t2t(int from, int to, int opt);
#elif defined SPIDER
int remove_if_complete (int pileno);
int t2t(int from, int to, int opt);
int s2t(int from, int to, int opt);
int t2f(int from, int to, int opt);
#endif
int join(int to);
int nop(int from, int to, int opt);
void cursor_left (struct cursor* cursor);
void cursor_down (struct cursor* cursor);
void cursor_up (struct cursor* cursor);
void cursor_right (struct cursor* cursor);
void cursor_to (struct cursor* cursor, int pile);
int get_cmd (int* from, int* to, int* opt);
int getctrlseq(unsigned char* buf);
int term2pile(unsigned char *mouse);
int wait_mouse_up(unsigned char* mouse);
int getch(unsigned char* buf);
void deal(long seed);
void print_hi(int invert, int grey_bg, int bold, char* str);
void print_table(const struct cursor* active, const struct cursor* inactive);
void visbell (void);
void win_anim(void);
void undo_push (int f, int t, int n, int o);
void undo_pop (struct undo* u);
void free_undo (struct undo* u);
void screen_setup (int enable);
void raw_mode(int enable);
void signal_handler (int signum);
void signal_setup(void);
#endif