1 #ifndef GAME_HH
2 #define GAME_HH
3 #include <lcdf/vector.hh>
4 #include <lcdf/inttypes.h>
5 #include <stdio.h>
6 class Tile;
7 class Tileset;
8 class Game;
9
10 /* must have TILE_ROWS even */
11 #define TILE_ROWS 24
12 #define TILE_COLS 38
13 #define TILE_LEVS 12
14
15 struct Move {
16
17 Tile *m1;
18 Tile *m2;
19
MoveMove20 Move() { }
MoveMove21 Move(Tile *t1, Tile *t2) : m1(t1), m2(t2) { }
22
23 };
24
25
26 class GameHooks {
27
28 public:
29
~GameHooks()30 virtual ~GameHooks() { }
31
layout_hook(Game *)32 virtual void layout_hook(Game *) { }
start_hook(Game *)33 virtual void start_hook(Game *) { }
add_tile_hook(Game *,Tile *)34 virtual void add_tile_hook(Game *, Tile *) { }
remove_tile_hook(Game *,Tile *)35 virtual void remove_tile_hook(Game *, Tile *) { }
move_made_hook(Game *)36 virtual void move_made_hook(Game *) { }
37
38 };
39
40
41 class Game {
42
43 Tileset *_tileset;
44 short _nmatches;
45
46 Vector<Tile *> _tiles;
47
48 uint32_t _board_number;
49 short _taken;
50 short _left;
51 short _possible_moves;
52
53 Vector<Move> _moves;
54 Vector<short> _user_moves;
55 int _user_move_pos;
56
57 Vector<Move> _solution;
58
59 Vector<GameHooks *> _hooks;
60
61 Tile **_grid;
62
63 bool _bad_free_count;
64 int *_free_count;
65
66 int *_left_count;
67
68 bool init_grid();
69 void init_blockage();
70
71 void assign(uint32_t);
72 void assign_solvable(uint32_t);
73
74 void clear_layout();
75 bool place_tile(int, int, int);
76 void check_level_blockage(int, int, int) const;
77
78 void wipe_info();
79 void make_free_count();
80 void count_possible_moves();
81
82 bool layout_young_file(FILE *);
83 bool layout_kyodai_file(FILE *);
84 bool layout_kmahjongg_file(FILE *);
85
86 static Tile the_null_tile;
87
88 public:
89
90 Game(Tileset *);
91 ~Game();
92
add_hook(GameHooks * gh)93 void add_hook(GameHooks *gh) { _hooks.push_back(gh); }
94 void remove_hook(GameHooks *gh);
95
ntiles() const96 int ntiles() const { return _tiles.size(); }
tile(int i) const97 Tile *tile(int i) const { return _tiles[i]; }
tiles() const98 const Vector<Tile *> &tiles() const { return _tiles; }
99
100 Tile *&grid(short r, short c, short l) const;
null_tile() const101 Tile *null_tile() const { return &the_null_tile; }
102
tileset() const103 Tileset *tileset() const { return _tileset; }
board_number() const104 uint32_t board_number() const { return _board_number; }
105
106 void layout_default();
107 int layout_file(const char *);
108 void relayout();
109
110 void start(uint32_t, bool);
111 void start_specific(uint32_t);
112
nmatches() const113 short nmatches() const { return _nmatches; }
nremaining() const114 short nremaining() const { return _left; }
115 int free_count(int);
116 int left_count(int) const;
117 int possible_moves();
solution() const118 const Vector<Move> &solution() const { return _solution; }
119
120 void add(Tile *);
121 void remove(Tile *);
122
123 void move(Tile *, Tile *, bool was_user = true);
124 void mark_user_move();
125 bool undo();
126 bool redo();
127
128 static uint32_t seed_to_board_number(uint32_t, bool);
129 static void board_number_to_seed(uint32_t, uint32_t &, bool &);
130
131 };
132
133 extern void zrand_seed(uint32_t);
134 extern uint32_t zrand();
135
136
137 inline Tile *&
grid(short r,short c,short l) const138 Game::grid(short r, short c, short l) const
139 {
140 assert(r>=0 && r<TILE_ROWS && c>=0 && c<TILE_COLS && l>=0 && l<TILE_LEVS);
141 return _grid[ (r * TILE_LEVS + l) * TILE_COLS + c ];
142 }
143
144 inline int
free_count(int i)145 Game::free_count(int i)
146 {
147 assert(i >= 0 && i < nmatches());
148 if (_bad_free_count) make_free_count();
149 return _free_count[i];
150 }
151
152 inline int
left_count(int i) const153 Game::left_count(int i) const
154 {
155 assert(i >= 0 && i < nmatches());
156 return _left_count[i];
157 }
158
159 inline int
possible_moves()160 Game::possible_moves()
161 {
162 if (_possible_moves < 0) count_possible_moves();
163 return _possible_moves;
164 }
165
166 extern void fatal_error(const char *, ...);
167 extern void error(const char *, ...);
168 extern void warning(const char *, ...);
169
170 #endif
171