1 /*
2  * Copyright © 2007 Christian Persch
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef AISLERIOT_GAME_H
19 #define AISLERIOT_GAME_H
20 
21 #include <gdk/gdk.h>
22 
23 #include "ar-card.h"
24 
25 G_BEGIN_DECLS
26 
27 /* A slot */
28 
29 typedef enum {
30   AR_SLOT_UNKNOWN,
31   AR_SLOT_CHOOSER,
32   AR_SLOT_FOUNDATION,
33   AR_SLOT_RESERVE,
34   AR_SLOT_STOCK,
35   AR_SLOT_TABLEAU,
36   AR_SLOT_WASTE
37 } ArSlotType;
38 
39 typedef struct {
40   int id;
41   ArSlotType type;
42 
43   GByteArray *cards;
44 
45   /* the topmost |exposed| cards are shown on the pile */
46   guint exposed;
47   int expansion_depth;
48 
49   /* The location in slot co-ordinates. Filled in by the game code. */
50   double x;
51   double y;
52 
53   /* In-slot card spacing */
54   union {
55     double dx;
56     double dy;
57   } expansion;
58 
59   int pixeldx;
60   int pixeldy;
61 
62   /* The location in pixel units. Filled in by the scaling code. */
63   GdkRectangle rect;
64 
65   /* GdkPixbuf* or GdkPixmap*, no reference owned */
66   GPtrArray *card_images;
67 
68   guint expanded_right : 1;
69   guint expanded_down : 1;
70   guint dx_set : 1;
71   guint dy_set : 1;
72   guint needs_update : 1;
73 } ArSlot;
74 
75 #define SLOT_CARDS_N_PREALLOC (32)
76 
77 ArSlotType ar_slot_get_slot_type (ArSlot *slot);
78 
79 const char *ar_slot_get_type_string (ArSlot *slot);
80 
81 char *ar_slot_get_hint_string (ArSlot *slot,
82                                int cardid);
83 
84 /* The game */
85 
86 #define AISLERIOT_TYPE_GAME         (aisleriot_game_get_type ())
87 #define AISLERIOT_GAME(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), AISLERIOT_TYPE_GAME, AisleriotGame))
88 #define AISLERIOT_GAME_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), AISLERIOT_TYPE_GAME, AisleriotGameClass))
89 #define AISLERIOT_IS_GAME(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), AISLERIOT_TYPE_GAME))
90 #define AISLERIOT_IS_GAME_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), AISLERIOT_TYPE_GAME))
91 #define AISLERIOT_GAME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), AISLERIOT_TYPE_GAME, AisleriotGameClass))
92 
93 #define DEFAULT_VARIATION  "klondike"
94 #define FREECELL_VARIATION "freecell"
95 
96 #define AISLERIOT_GAME_ERROR  (aisleriot_game_error_quark ())
97 
98 #define AISLERIOT_GAME_OPTIONS_MAX (0x7FFFFFFF) /* 31 bits, since we're using int not guint */
99 
100 typedef struct _AisleriotGame AisleriotGame;
101 typedef struct _AisleriotGameClass AisleriotGameClass;
102 
103 enum {
104   GAME_ERROR_EXCEPTION = 0,
105   GAME_ERROR_GENERIC   = 1
106 };
107 
108 typedef enum {
109   FEATURE_DROPPABLE     = 1 << 0,
110   FEATURE_SCORE_HIDDEN  = 1 << 1,
111   FEATURE_DEALABLE      = 1 << 2,
112   ALL_FEATURES          = 0x7
113 } AisleriotGameFeatures;
114 
115 typedef enum {
116   GAME_UNINITIALISED,
117   GAME_LOADED,
118   GAME_BEGIN,
119   GAME_RUNNING,
120   GAME_OVER,
121   GAME_WON,
122   LAST_GAME_STATE
123 } AisleriotGameState;
124 
125 typedef enum {
126   AISLERIOT_GAME_OPTION_CHECK,
127   AISLERIOT_GAME_OPTION_RADIO
128 } AisleriotGameOptionType;
129 
130 typedef struct {
131   char *display_name;
132   AisleriotGameOptionType type;
133   guint32 value; /* exactly 1 bit set */
134   gboolean set;
135 } AisleriotGameOption;
136 
137 GQuark aisleriot_game_error_quark (void);
138 
139 void aisleriot_game_option_free (AisleriotGameOption *option);
140 
141 GType aisleriot_game_get_type (void);
142 
143 AisleriotGame *aisleriot_game_new (void);
144 
145 GPtrArray *aisleriot_game_get_slots (AisleriotGame * game);
146 
147 void aisleriot_game_slot_add_cards (AisleriotGame * game,
148                                     ArSlot * slot,
149                                     guint8 * cards, guint n_cards);
150 
151 guint aisleriot_game_get_state (AisleriotGame * game);
152 
153 guint aisleriot_game_get_features (AisleriotGame *game);
154 
155 void aisleriot_game_start (AisleriotGame * game);
156 
157 void aisleriot_game_set_paused (AisleriotGame * game, gboolean paused);
158 
159 void aisleriot_game_get_geometry (AisleriotGame * game,
160                                   double *width, double *height);
161 
162 void aisleriot_game_undo_move (AisleriotGame * game);
163 
164 void aisleriot_game_redo_move (AisleriotGame * game);
165 
166 gboolean aisleriot_game_load_game (AisleriotGame * game,
167                                    const char *filename, GError ** error);
168 
169 void aisleriot_game_new_game (AisleriotGame *game);
170 
171 void aisleriot_game_new_game_with_rand (AisleriotGame *game,
172                                         GRand *rand);
173 
174 void aisleriot_game_restart_game (AisleriotGame * game);
175 
176 const char *aisleriot_game_get_game_module (AisleriotGame * game);
177 
178 char *aisleriot_game_get_name (AisleriotGame * game);
179 
180 gboolean aisleriot_game_drag_valid (AisleriotGame * game,
181                                     int slot_id,
182                                     guint8 * cards, guint n_cards);
183 
184 gboolean aisleriot_game_drop_valid (AisleriotGame * game,
185                                     int start_slot,
186                                     int end_slot,
187                                     guint8 * cards, guint n_cards);
188 
189 gboolean aisleriot_game_drop_cards (AisleriotGame * game,
190                                     int start_slot,
191                                     int end_slot,
192                                     guint8 * cards, guint n_cards);
193 
194 gboolean aisleriot_game_button_clicked_lambda (AisleriotGame * game,
195                                                int slot_id);
196 
197 gboolean aisleriot_game_button_double_clicked_lambda (AisleriotGame * game,
198                                                       int slot_id);
199 
200 char *aisleriot_game_get_hint (AisleriotGame *game);
201 
202 GList *aisleriot_game_get_options (AisleriotGame * game);
203 
204 guint32 aisleriot_game_change_options (AisleriotGame *game,
205                                        guint32 changed_mask,
206                                        guint32 changed_value);
207 
208 gboolean aisleriot_game_timeout_lambda (AisleriotGame * game);
209 
210 void aisleriot_game_record_move (AisleriotGame * game,
211                                  int slot_id, guint8 * cards, guint n_cards);
212 
213 void aisleriot_game_end_move (AisleriotGame * game);
214 
215 void aisleriot_game_discard_move (AisleriotGame * game);
216 
217 void aisleriot_game_set_click_to_move (AisleriotGame * game,
218                                        gboolean enabled);
219 
220 void aisleriot_game_test_end_of_game (AisleriotGame * game);
221 
222 void aisleriot_game_generate_exception (AisleriotGame * game);
223 
224 void aisleriot_game_deal_cards (AisleriotGame *game);
225 
226 void aisleriot_game_get_card_offset (ArSlot *slot,
227                                      guint card_num,
228                                      gboolean old_cards,
229                                      gint *xoff, gint *yoff);
230 
231 void aisleriot_game_reset_old_cards (ArSlot *slot);
232 
233 const char *aisleriot_game_get_score (AisleriotGame *game);
234 
235 char **ar_get_game_modules (void);
236 
237 G_END_DECLS
238 
239 #endif /* !AISLERIOT_GAME_H */
240