1 /* 2 * puzzles.h: header file for my puzzle collection 3 */ 4 5 #ifndef PUZZLES_PUZZLES_H 6 #define PUZZLES_PUZZLES_H 7 8 #include <stdio.h> /* for FILE */ 9 #include <stdlib.h> /* for size_t */ 10 #include <limits.h> /* for UINT_MAX */ 11 #include <stdbool.h> 12 13 #define PI 3.141592653589793238462643383279502884197169399 14 #define ROOT2 1.414213562373095048801688724209698078569672 15 16 #define lenof(array) ( sizeof(array) / sizeof(*(array)) ) 17 18 #define STR_INT(x) #x 19 #define STR(x) STR_INT(x) 20 21 /* NB not perfect because they evaluate arguments multiple times. */ 22 #ifndef max 23 #define max(x,y) ( (x)>(y) ? (x) : (y) ) 24 #endif /* max */ 25 #ifndef min 26 #define min(x,y) ( (x)<(y) ? (x) : (y) ) 27 #endif /* min */ 28 29 enum { 30 LEFT_BUTTON = 0x0200, 31 MIDDLE_BUTTON, 32 RIGHT_BUTTON, 33 LEFT_DRAG, 34 MIDDLE_DRAG, 35 RIGHT_DRAG, 36 LEFT_RELEASE, 37 MIDDLE_RELEASE, 38 RIGHT_RELEASE, 39 CURSOR_UP, 40 CURSOR_DOWN, 41 CURSOR_LEFT, 42 CURSOR_RIGHT, 43 CURSOR_SELECT, 44 CURSOR_SELECT2, 45 /* UI_* are special keystrokes generated by front ends in response 46 * to menu actions, never passed to back ends */ 47 UI_LOWER_BOUND, 48 UI_QUIT, 49 UI_NEWGAME, 50 UI_SOLVE, 51 UI_UNDO, 52 UI_REDO, 53 UI_UPPER_BOUND, 54 55 /* made smaller because of 'limited range of datatype' errors. */ 56 MOD_CTRL = 0x1000, 57 MOD_SHFT = 0x2000, 58 MOD_NUM_KEYPAD = 0x4000, 59 MOD_MASK = 0x7000 /* mask for all modifiers */ 60 }; 61 62 #define IS_MOUSE_DOWN(m) ( (unsigned)((m) - LEFT_BUTTON) <= \ 63 (unsigned)(RIGHT_BUTTON - LEFT_BUTTON)) 64 #define IS_MOUSE_DRAG(m) ( (unsigned)((m) - LEFT_DRAG) <= \ 65 (unsigned)(RIGHT_DRAG - LEFT_DRAG)) 66 #define IS_MOUSE_RELEASE(m) ( (unsigned)((m) - LEFT_RELEASE) <= \ 67 (unsigned)(RIGHT_RELEASE - LEFT_RELEASE)) 68 #define IS_CURSOR_MOVE(m) ( (m) == CURSOR_UP || (m) == CURSOR_DOWN || \ 69 (m) == CURSOR_RIGHT || (m) == CURSOR_LEFT ) 70 #define IS_CURSOR_SELECT(m) ( (m) == CURSOR_SELECT || (m) == CURSOR_SELECT2) 71 #define IS_UI_FAKE_KEY(m) ( (m) > UI_LOWER_BOUND && (m) < UI_UPPER_BOUND ) 72 73 /* 74 * Flags in the back end's `flags' word. 75 */ 76 /* Bit flags indicating mouse button priorities */ 77 #define BUTTON_BEATS(x,y) ( 1 << (((x)-LEFT_BUTTON)*3+(y)-LEFT_BUTTON) ) 78 /* Flag indicating that Solve operations should be animated */ 79 #define SOLVE_ANIMATES ( 1 << 9 ) 80 /* Pocket PC: Game requires right mouse button emulation */ 81 #define REQUIRE_RBUTTON ( 1 << 10 ) 82 /* Pocket PC: Game requires numeric input */ 83 #define REQUIRE_NUMPAD ( 1 << 11 ) 84 /* end of `flags' word definitions */ 85 86 #define IGNOREARG(x) ( (x) = (x) ) 87 88 typedef struct frontend frontend; 89 typedef struct config_item config_item; 90 typedef struct midend midend; 91 typedef struct random_state random_state; 92 typedef struct game_params game_params; 93 typedef struct game_state game_state; 94 typedef struct game_ui game_ui; 95 typedef struct game_drawstate game_drawstate; 96 typedef struct game game; 97 typedef struct blitter blitter; 98 typedef struct document document; 99 typedef struct drawing_api drawing_api; 100 typedef struct drawing drawing; 101 typedef struct psdata psdata; 102 103 #define ALIGN_VNORMAL 0x000 104 #define ALIGN_VCENTRE 0x100 105 106 #define ALIGN_HLEFT 0x000 107 #define ALIGN_HCENTRE 0x001 108 #define ALIGN_HRIGHT 0x002 109 110 #define FONT_FIXED 0 111 #define FONT_VARIABLE 1 112 113 /* For printing colours */ 114 #define HATCH_SLASH 1 115 #define HATCH_BACKSLASH 2 116 #define HATCH_HORIZ 3 117 #define HATCH_VERT 4 118 #define HATCH_PLUS 5 119 #define HATCH_X 6 120 121 /* 122 * Structure used to pass configuration data between frontend and 123 * game 124 */ 125 enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END }; 126 struct config_item { 127 /* Not dynamically allocated */ 128 const char *name; 129 /* Value from the above C_* enum */ 130 int type; 131 union { 132 struct { /* if type == C_STRING */ 133 /* Always dynamically allocated and non-NULL */ 134 char *sval; 135 } string; 136 struct { /* if type == C_CHOICES */ 137 /* 138 * choicenames is non-NULL, not dynamically allocated, and 139 * contains a set of option strings separated by a 140 * delimiter. The delimiter is also the first character in 141 * the string, so for example ":Foo:Bar:Baz" gives three 142 * options `Foo', `Bar' and `Baz'. 143 */ 144 const char *choicenames; 145 /* 146 * Indicates the chosen index from the options in 147 * choicenames. In the above example, 0==Foo, 1==Bar and 148 * 2==Baz. 149 */ 150 int selected; 151 } choices; 152 struct { 153 bool bval; 154 } boolean; 155 } u; 156 }; 157 158 /* 159 * Structure used to communicate the presets menu from midend to 160 * frontend. In principle, it's also used to pass the same information 161 * from game to midend, though games that don't specify a menu 162 * hierarchy (i.e. most of them) will use the simpler fetch_preset() 163 * function to return an unstructured list. 164 * 165 * A tree of these structures always belongs to the midend, and only 166 * the midend should ever need to free it. The front end should treat 167 * them as read-only. 168 */ 169 struct preset_menu_entry { 170 char *title; 171 /* Exactly one of the next two fields is NULL, depending on 172 * whether this entry is a submenu title or an actual preset */ 173 game_params *params; 174 struct preset_menu *submenu; 175 /* Every preset menu entry has a number allocated by the mid-end, 176 * so that midend_which_preset() can return a value that 177 * identifies an entry anywhere in the menu hierarchy. The values 178 * will be allocated reasonably densely from 1 upwards (so it's 179 * reasonable for the front end to use them as array indices if it 180 * needs to store GUI state per menu entry), but no other 181 * guarantee is given about their ordering. 182 * 183 * Entries containing submenus have ids too - not only the actual 184 * presets are numbered. */ 185 int id; 186 }; 187 struct preset_menu { 188 int n_entries; /* number of entries actually in use */ 189 int entries_size; /* space currently allocated in this array */ 190 struct preset_menu_entry *entries; 191 }; 192 /* For games which do want to directly return a tree of these, here 193 * are convenience routines (in midend.c) for constructing one. These 194 * assume that 'title' and 'encoded_params' are already dynamically 195 * allocated by the caller; the resulting preset_menu tree takes 196 * ownership of them. */ 197 struct preset_menu *preset_menu_new(void); 198 struct preset_menu *preset_menu_add_submenu(struct preset_menu *parent, 199 char *title); 200 void preset_menu_add_preset(struct preset_menu *menu, 201 char *title, game_params *params); 202 /* Helper routine front ends can use for one of the ways they might 203 * want to organise their preset menu usage */ 204 game_params *preset_menu_lookup_by_id(struct preset_menu *menu, int id); 205 206 /* 207 * Small structure specifying a UI button in a keyboardless front 208 * end. The button will have the text of "label" written on it, and 209 * pressing it causes the value "button" to be passed to 210 * midend_process_key() as if typed at the keyboard. 211 * 212 * If `label' is NULL (which it likely will be), a generic label can 213 * be generated with the button2label() function. 214 */ 215 typedef struct key_label { 216 /* What should be displayed to the user by the frontend. Backends 217 * can set this field to NULL and have it filled in by the midend 218 * with a generic label. Dynamically allocated, but frontends 219 * should probably use free_keys() to free instead. */ 220 char *label; 221 int button; /* passed to midend_process_key when button is pressed */ 222 } key_label; 223 224 /* 225 * Platform routines 226 */ 227 228 /* We can't use #ifdef DEBUG, because Cygwin defines it by default. */ 229 #ifdef DEBUGGING 230 #define debug(x) (debug_printf x) 231 void debug_printf(const char *fmt, ...); 232 #else 233 #define debug(x) 234 #endif 235 236 void fatal(const char *fmt, ...); 237 void frontend_default_colour(frontend *fe, float *output); 238 void deactivate_timer(frontend *fe); 239 void activate_timer(frontend *fe); 240 void get_random_seed(void **randseed, int *randseedsize); 241 242 /* 243 * drawing.c 244 */ 245 drawing *drawing_new(const drawing_api *api, midend *me, void *handle); 246 void drawing_free(drawing *dr); 247 void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize, 248 int align, int colour, const char *text); 249 void draw_rect(drawing *dr, int x, int y, int w, int h, int colour); 250 void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour); 251 void draw_polygon(drawing *dr, const int *coords, int npoints, 252 int fillcolour, int outlinecolour); 253 void draw_circle(drawing *dr, int cx, int cy, int radius, 254 int fillcolour, int outlinecolour); 255 void draw_thick_line(drawing *dr, float thickness, 256 float x1, float y1, float x2, float y2, int colour); 257 void clip(drawing *dr, int x, int y, int w, int h); 258 void unclip(drawing *dr); 259 void start_draw(drawing *dr); 260 void draw_update(drawing *dr, int x, int y, int w, int h); 261 void end_draw(drawing *dr); 262 char *text_fallback(drawing *dr, const char *const *strings, int nstrings); 263 void status_bar(drawing *dr, const char *text); 264 blitter *blitter_new(drawing *dr, int w, int h); 265 void blitter_free(drawing *dr, blitter *bl); 266 /* save puts the portion of the current display with top-left corner 267 * (x,y) to the blitter. load puts it back again to the specified 268 * coords, or else wherever it was saved from 269 * (if x = y = BLITTER_FROMSAVED). */ 270 void blitter_save(drawing *dr, blitter *bl, int x, int y); 271 #define BLITTER_FROMSAVED (-1) 272 void blitter_load(drawing *dr, blitter *bl, int x, int y); 273 void print_begin_doc(drawing *dr, int pages); 274 void print_begin_page(drawing *dr, int number); 275 void print_begin_puzzle(drawing *dr, float xm, float xc, 276 float ym, float yc, int pw, int ph, float wmm, 277 float scale); 278 void print_end_puzzle(drawing *dr); 279 void print_end_page(drawing *dr, int number); 280 void print_end_doc(drawing *dr); 281 void print_get_colour(drawing *dr, int colour, bool printing_in_colour, 282 int *hatch, float *r, float *g, float *b); 283 int print_mono_colour(drawing *dr, int grey); /* 0==black, 1==white */ 284 int print_grey_colour(drawing *dr, float grey); 285 int print_hatched_colour(drawing *dr, int hatch); 286 int print_rgb_mono_colour(drawing *dr, float r, float g, float b, int mono); 287 int print_rgb_grey_colour(drawing *dr, float r, float g, float b, float grey); 288 int print_rgb_hatched_colour(drawing *dr, float r, float g, float b, 289 int hatch); 290 void print_line_width(drawing *dr, int width); 291 void print_line_dotted(drawing *dr, bool dotted); 292 293 /* 294 * midend.c 295 */ 296 midend *midend_new(frontend *fe, const game *ourgame, 297 const drawing_api *drapi, void *drhandle); 298 void midend_free(midend *me); 299 const game *midend_which_game(midend *me); 300 void midend_set_params(midend *me, game_params *params); 301 game_params *midend_get_params(midend *me); 302 void midend_size(midend *me, int *x, int *y, bool user_size); 303 void midend_reset_tilesize(midend *me); 304 void midend_new_game(midend *me); 305 void midend_restart_game(midend *me); 306 void midend_stop_anim(midend *me); 307 bool midend_process_key(midend *me, int x, int y, int button); 308 key_label *midend_request_keys(midend *me, int *nkeys); 309 void midend_force_redraw(midend *me); 310 void midend_redraw(midend *me); 311 float *midend_colours(midend *me, int *ncolours); 312 void midend_freeze_timer(midend *me, float tprop); 313 void midend_timer(midend *me, float tplus); 314 struct preset_menu *midend_get_presets(midend *me, int *id_limit); 315 int midend_which_preset(midend *me); 316 bool midend_wants_statusbar(midend *me); 317 enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_FRONTEND_SPECIFIC }; 318 config_item *midend_get_config(midend *me, int which, char **wintitle); 319 const char *midend_set_config(midend *me, int which, config_item *cfg); 320 const char *midend_game_id(midend *me, const char *id); 321 char *midend_get_game_id(midend *me); 322 char *midend_get_random_seed(midend *me); 323 bool midend_can_format_as_text_now(midend *me); 324 char *midend_text_format(midend *me); 325 const char *midend_solve(midend *me); 326 int midend_status(midend *me); 327 bool midend_can_undo(midend *me); 328 bool midend_can_redo(midend *me); 329 void midend_supersede_game_desc(midend *me, const char *desc, 330 const char *privdesc); 331 char *midend_rewrite_statusbar(midend *me, const char *text); 332 void midend_serialise(midend *me, 333 void (*write)(void *ctx, const void *buf, int len), 334 void *wctx); 335 const char *midend_deserialise(midend *me, 336 bool (*read)(void *ctx, void *buf, int len), 337 void *rctx); 338 const char *identify_game(char **name, 339 bool (*read)(void *ctx, void *buf, int len), 340 void *rctx); 341 void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx); 342 bool midend_get_cursor_location(midend *me, int *x, int *y, int *w, int *h); 343 344 /* Printing functions supplied by the mid-end */ 345 const char *midend_print_puzzle(midend *me, document *doc, bool with_soln); 346 int midend_tilesize(midend *me); 347 348 /* 349 * malloc.c 350 */ 351 void *smalloc(size_t size); 352 void *srealloc(void *p, size_t size); 353 void sfree(void *p); 354 char *dupstr(const char *s); 355 #define snew(type) \ 356 ( (type *) smalloc (sizeof (type)) ) 357 #define snewn(number, type) \ 358 ( (type *) smalloc ((number) * sizeof (type)) ) 359 #define sresize(array, number, type) \ 360 ( (type *) srealloc ((array), (number) * sizeof (type)) ) 361 362 /* 363 * misc.c 364 */ 365 void free_cfg(config_item *cfg); 366 void free_keys(key_label *keys, int nkeys); 367 void obfuscate_bitmap(unsigned char *bmp, int bits, bool decode); 368 char *fgetline(FILE *fp); 369 370 /* allocates output each time. len is always in bytes of binary data. 371 * May assert (or just go wrong) if lengths are unchecked. */ 372 char *bin2hex(const unsigned char *in, int inlen); 373 unsigned char *hex2bin(const char *in, int outlen); 374 375 /* Sets (and possibly dims) background from frontend default colour, 376 * and auto-generates highlight and lowlight colours too. */ 377 void game_mkhighlight(frontend *fe, float *ret, 378 int background, int highlight, int lowlight); 379 /* As above, but starts from a provided background colour rather 380 * than the frontend default. */ 381 void game_mkhighlight_specific(frontend *fe, float *ret, 382 int background, int highlight, int lowlight); 383 384 /* Randomly shuffles an array of items. */ 385 void shuffle(void *array, int nelts, int eltsize, random_state *rs); 386 387 /* Draw a rectangle outline, using the drawing API's draw_line. */ 388 void draw_rect_outline(drawing *dr, int x, int y, int w, int h, 389 int colour); 390 391 /* Draw a set of rectangle corners (e.g. for a cursor display). */ 392 void draw_rect_corners(drawing *dr, int cx, int cy, int r, int col); 393 394 void move_cursor(int button, int *x, int *y, int maxw, int maxh, bool wrap); 395 396 /* Used in netslide.c and sixteen.c for cursor movement around edge. */ 397 int c2pos(int w, int h, int cx, int cy); 398 int c2diff(int w, int h, int cx, int cy, int button); 399 void pos2c(int w, int h, int pos, int *cx, int *cy); 400 401 /* Draws text with an 'outline' formed by offsetting the text 402 * by one pixel; useful for highlighting. Outline is omitted if -1. */ 403 void draw_text_outline(drawing *dr, int x, int y, int fonttype, 404 int fontsize, int align, 405 int text_colour, int outline_colour, const char *text); 406 407 /* Copies text left-justified with spaces. Length of string must be 408 * less than buffer size. */ 409 void copy_left_justified(char *buf, size_t sz, const char *str); 410 411 /* Returns a generic label based on the value of `button.' To be used 412 whenever a `label' field returned by the request_keys() game 413 function is NULL. Dynamically allocated, to be freed by caller. */ 414 char *button2label(int button); 415 416 /* 417 * dsf.c 418 */ 419 int *snew_dsf(int size); 420 421 void print_dsf(int *dsf, int size); 422 423 /* Return the canonical element of the equivalence class containing element 424 * val. If 'inverse' is non-NULL, this function will put into it a flag 425 * indicating whether the canonical element is inverse to val. */ 426 int edsf_canonify(int *dsf, int val, bool *inverse); 427 int dsf_canonify(int *dsf, int val); 428 int dsf_size(int *dsf, int val); 429 430 /* Allow the caller to specify that two elements should be in the same 431 * equivalence class. If 'inverse' is true, the elements are actually opposite 432 * to one another in some sense. This function will fail an assertion if the 433 * caller gives it self-contradictory data, ie if two elements are claimed to 434 * be both opposite and non-opposite. */ 435 void edsf_merge(int *dsf, int v1, int v2, bool inverse); 436 void dsf_merge(int *dsf, int v1, int v2); 437 void dsf_init(int *dsf, int len); 438 439 /* 440 * tdq.c 441 */ 442 443 /* 444 * Data structure implementing a 'to-do queue', a simple 445 * de-duplicating to-do list mechanism. 446 * 447 * Specification: a tdq is a queue which can hold integers from 0 to 448 * n-1, where n was some constant specified at tdq creation time. No 449 * integer may appear in the queue's current contents more than once; 450 * an attempt to add an already-present integer again will do nothing, 451 * so that that integer is removed from the queue at the position 452 * where it was _first_ inserted. The add and remove operations take 453 * constant time. 454 * 455 * The idea is that you might use this in applications like solvers: 456 * keep a tdq listing the indices of grid squares that you currently 457 * need to process in some way. Whenever you modify a square in a way 458 * that will require you to re-scan its neighbours, add them to the 459 * list with tdq_add; meanwhile you're constantly taking elements off 460 * the list when you need another square to process. In solvers where 461 * deductions are mostly localised, this should prevent repeated 462 * O(N^2) loops over the whole grid looking for something to do. (But 463 * if only _most_ of the deductions are localised, then you should 464 * respond to an empty to-do list by re-adding everything using 465 * tdq_fill, so _then_ you rescan the whole grid looking for newly 466 * enabled non-local deductions. Only if you've done that and emptied 467 * the list again finding nothing new to do are you actually done.) 468 */ 469 typedef struct tdq tdq; 470 tdq *tdq_new(int n); 471 void tdq_free(tdq *tdq); 472 void tdq_add(tdq *tdq, int k); 473 int tdq_remove(tdq *tdq); /* returns -1 if nothing available */ 474 void tdq_fill(tdq *tdq); /* add everything to the tdq at once */ 475 476 /* 477 * laydomino.c 478 */ 479 int *domino_layout(int w, int h, random_state *rs); 480 void domino_layout_prealloc(int w, int h, random_state *rs, 481 int *grid, int *grid2, int *list); 482 /* 483 * version.c 484 */ 485 extern char ver[]; 486 487 /* 488 * random.c 489 */ 490 random_state *random_new(const char *seed, int len); 491 random_state *random_copy(random_state *tocopy); 492 unsigned long random_bits(random_state *state, int bits); 493 unsigned long random_upto(random_state *state, unsigned long limit); 494 void random_free(random_state *state); 495 char *random_state_encode(random_state *state); 496 random_state *random_state_decode(const char *input); 497 /* random.c also exports SHA, which occasionally comes in useful. */ 498 #if __STDC_VERSION__ >= 199901L 499 #include <stdint.h> 500 typedef uint32_t uint32; 501 #elif UINT_MAX >= 4294967295L 502 typedef unsigned int uint32; 503 #else 504 typedef unsigned long uint32; 505 #endif 506 typedef struct { 507 uint32 h[5]; 508 unsigned char block[64]; 509 int blkused; 510 uint32 lenhi, lenlo; 511 } SHA_State; 512 void SHA_Init(SHA_State *s); 513 void SHA_Bytes(SHA_State *s, const void *p, int len); 514 void SHA_Final(SHA_State *s, unsigned char *output); 515 void SHA_Simple(const void *p, int len, unsigned char *output); 516 517 /* 518 * printing.c 519 */ 520 document *document_new(int pw, int ph, float userscale); 521 void document_free(document *doc); 522 void document_add_puzzle(document *doc, const game *game, game_params *par, 523 game_state *st, game_state *st2); 524 int document_npages(const document *doc); 525 void document_begin(const document *doc, drawing *dr); 526 void document_end(const document *doc, drawing *dr); 527 void document_print_page(const document *doc, drawing *dr, int page_nr); 528 void document_print(const document *doc, drawing *dr); 529 530 /* 531 * ps.c 532 */ 533 psdata *ps_init(FILE *outfile, bool colour); 534 void ps_free(psdata *ps); 535 drawing *ps_drawing_api(psdata *ps); 536 537 /* 538 * combi.c: provides a structure and functions for iterating over 539 * combinations (i.e. choosing r things out of n). 540 */ 541 typedef struct _combi_ctx { 542 int r, n, nleft, total; 543 int *a; 544 } combi_ctx; 545 546 combi_ctx *new_combi(int r, int n); 547 void reset_combi(combi_ctx *combi); 548 combi_ctx *next_combi(combi_ctx *combi); /* returns NULL for end */ 549 void free_combi(combi_ctx *combi); 550 551 /* 552 * divvy.c 553 */ 554 /* divides w*h rectangle into pieces of size k. Returns w*h dsf. */ 555 int *divvy_rectangle(int w, int h, int k, random_state *rs); 556 557 /* 558 * findloop.c 559 */ 560 struct findloopstate; 561 struct findloopstate *findloop_new_state(int nvertices); 562 void findloop_free_state(struct findloopstate *); 563 /* 564 * Callback provided by the client code to enumerate the graph 565 * vertices joined directly to a given vertex. 566 * 567 * Semantics: if vertex >= 0, return one of its neighbours; if vertex 568 * < 0, return a previously unmentioned neighbour of whatever vertex 569 * was last passed as input. Write to 'ctx' as necessary to store 570 * state. In either case, return < 0 if no such vertex can be found. 571 */ 572 typedef int (*neighbour_fn_t)(int vertex, void *ctx); 573 /* 574 * Actual function to find loops. 'ctx' will be passed unchanged to 575 * the 'neighbour' function to query graph edges. Returns false if no 576 * loop was found, or true if one was. 577 */ 578 bool findloop_run(struct findloopstate *state, int nvertices, 579 neighbour_fn_t neighbour, void *ctx); 580 /* 581 * Query whether an edge is part of a loop, in the output of 582 * find_loops. 583 * 584 * Due to the internal storage format, if you pass u,v which are not 585 * connected at all, the output will be true. (The algorithm actually 586 * stores an exhaustive list of *non*-loop edges, because there are 587 * fewer of those, so really it's querying whether the edge is on that 588 * list.) 589 */ 590 bool findloop_is_loop_edge(struct findloopstate *state, int u, int v); 591 592 /* 593 * Alternative query function, which returns true if the u-v edge is a 594 * _bridge_, i.e. a non-loop edge, i.e. an edge whose removal would 595 * disconnect a currently connected component of the graph. 596 * 597 * If the return value is true, then the numbers of vertices that 598 * would be in the new components containing u and v are written into 599 * u_vertices and v_vertices respectively. 600 */ 601 bool findloop_is_bridge( 602 struct findloopstate *pv, int u, int v, int *u_vertices, int *v_vertices); 603 604 /* 605 * Helper function to sort an array. Differs from standard qsort in 606 * that it takes a context parameter that is passed to the compare 607 * function. 608 * 609 * I wrap it in a macro so that you only need to give the element 610 * count of the array. The element size is determined by sizeof. 611 */ 612 typedef int (*arraysort_cmpfn_t)(const void *av, const void *bv, void *ctx); 613 void arraysort_fn(void *array, size_t nmemb, size_t size, 614 arraysort_cmpfn_t cmp, void *ctx); 615 #define arraysort(array, nmemb, cmp, ctx) \ 616 arraysort_fn(array, nmemb, sizeof(*(array)), cmp, ctx) 617 618 /* 619 * Data structure containing the function calls and data specific 620 * to a particular game. This is enclosed in a data structure so 621 * that a particular platform can choose, if it wishes, to compile 622 * all the games into a single combined executable rather than 623 * having lots of little ones. 624 */ 625 struct game { 626 const char *name; 627 const char *winhelp_topic, *htmlhelp_topic; 628 game_params *(*default_params)(void); 629 bool (*fetch_preset)(int i, char **name, game_params **params); 630 struct preset_menu *(*preset_menu)(void); 631 void (*decode_params)(game_params *, char const *string); 632 char *(*encode_params)(const game_params *, bool full); 633 void (*free_params)(game_params *params); 634 game_params *(*dup_params)(const game_params *params); 635 bool can_configure; 636 config_item *(*configure)(const game_params *params); 637 game_params *(*custom_params)(const config_item *cfg); 638 const char *(*validate_params)(const game_params *params, bool full); 639 char *(*new_desc)(const game_params *params, random_state *rs, 640 char **aux, bool interactive); 641 const char *(*validate_desc)(const game_params *params, const char *desc); 642 game_state *(*new_game)(midend *me, const game_params *params, 643 const char *desc); 644 game_state *(*dup_game)(const game_state *state); 645 void (*free_game)(game_state *state); 646 bool can_solve; 647 char *(*solve)(const game_state *orig, const game_state *curr, 648 const char *aux, const char **error); 649 bool can_format_as_text_ever; 650 bool (*can_format_as_text_now)(const game_params *params); 651 char *(*text_format)(const game_state *state); 652 game_ui *(*new_ui)(const game_state *state); 653 void (*free_ui)(game_ui *ui); 654 char *(*encode_ui)(const game_ui *ui); 655 void (*decode_ui)(game_ui *ui, const char *encoding); 656 key_label *(*request_keys)(const game_params *params, int *nkeys); 657 void (*changed_state)(game_ui *ui, const game_state *oldstate, 658 const game_state *newstate); 659 char *(*interpret_move)(const game_state *state, game_ui *ui, 660 const game_drawstate *ds, int x, int y, int button); 661 game_state *(*execute_move)(const game_state *state, const char *move); 662 int preferred_tilesize; 663 void (*compute_size)(const game_params *params, int tilesize, 664 int *x, int *y); 665 void (*set_size)(drawing *dr, game_drawstate *ds, 666 const game_params *params, int tilesize); 667 float *(*colours)(frontend *fe, int *ncolours); 668 game_drawstate *(*new_drawstate)(drawing *dr, const game_state *state); 669 void (*free_drawstate)(drawing *dr, game_drawstate *ds); 670 void (*redraw)(drawing *dr, game_drawstate *ds, const game_state *oldstate, 671 const game_state *newstate, int dir, const game_ui *ui, 672 float anim_time, float flash_time); 673 float (*anim_length)(const game_state *oldstate, 674 const game_state *newstate, int dir, game_ui *ui); 675 float (*flash_length)(const game_state *oldstate, 676 const game_state *newstate, int dir, game_ui *ui); 677 void (*get_cursor_location)(const game_ui *ui, 678 const game_drawstate *ds, 679 const game_state *state, 680 const game_params *params, 681 int *x, int *y, int *w, int *h); 682 int (*status)(const game_state *state); 683 bool can_print, can_print_in_colour; 684 void (*print_size)(const game_params *params, float *x, float *y); 685 void (*print)(drawing *dr, const game_state *state, int tilesize); 686 bool wants_statusbar; 687 bool is_timed; 688 bool (*timing_state)(const game_state *state, game_ui *ui); 689 int flags; 690 }; 691 692 /* 693 * Data structure containing the drawing API implemented by the 694 * front end and also by cross-platform printing modules such as 695 * PostScript. 696 */ 697 struct drawing_api { 698 void (*draw_text)(void *handle, int x, int y, int fonttype, int fontsize, 699 int align, int colour, const char *text); 700 void (*draw_rect)(void *handle, int x, int y, int w, int h, int colour); 701 void (*draw_line)(void *handle, int x1, int y1, int x2, int y2, 702 int colour); 703 void (*draw_polygon)(void *handle, const int *coords, int npoints, 704 int fillcolour, int outlinecolour); 705 void (*draw_circle)(void *handle, int cx, int cy, int radius, 706 int fillcolour, int outlinecolour); 707 void (*draw_update)(void *handle, int x, int y, int w, int h); 708 void (*clip)(void *handle, int x, int y, int w, int h); 709 void (*unclip)(void *handle); 710 void (*start_draw)(void *handle); 711 void (*end_draw)(void *handle); 712 void (*status_bar)(void *handle, const char *text); 713 blitter *(*blitter_new)(void *handle, int w, int h); 714 void (*blitter_free)(void *handle, blitter *bl); 715 void (*blitter_save)(void *handle, blitter *bl, int x, int y); 716 void (*blitter_load)(void *handle, blitter *bl, int x, int y); 717 void (*begin_doc)(void *handle, int pages); 718 void (*begin_page)(void *handle, int number); 719 void (*begin_puzzle)(void *handle, float xm, float xc, 720 float ym, float yc, int pw, int ph, float wmm); 721 void (*end_puzzle)(void *handle); 722 void (*end_page)(void *handle, int number); 723 void (*end_doc)(void *handle); 724 void (*line_width)(void *handle, float width); 725 void (*line_dotted)(void *handle, bool dotted); 726 char *(*text_fallback)(void *handle, const char *const *strings, 727 int nstrings); 728 void (*draw_thick_line)(void *handle, float thickness, 729 float x1, float y1, float x2, float y2, 730 int colour); 731 }; 732 733 /* 734 * For one-game-at-a-time platforms, there's a single structure 735 * like the above, under a fixed name. For all-at-once platforms, 736 * there's a list of all available puzzles in array form. 737 */ 738 #ifdef COMBINED 739 extern const game *gamelist[]; 740 extern const int gamecount; 741 #else 742 extern const game thegame; 743 #endif 744 745 /* 746 * Special string value to return from interpret_move in the case 747 * where the game UI has been updated but no actual move is being 748 * appended to the undo chain. Must be declared as a non-const char, 749 * but should never actually be modified by anyone. 750 */ 751 extern char UI_UPDATE[]; 752 753 /* A little bit of help to lazy developers */ 754 #define DEFAULT_STATUSBAR_TEXT "Use status_bar() to fill this in." 755 756 #endif /* PUZZLES_PUZZLES_H */ 757