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