-
Notifications
You must be signed in to change notification settings - Fork 116
/
Copy pathboard_undo.h
90 lines (77 loc) · 2.89 KB
/
board_undo.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
#ifndef PACHI_BOARD_UNDO_H
#define PACHI_BOARD_UNDO_H
typedef struct {
group_t group;
coord_t last;
group_info_t info;
} undo_merge_t;
typedef struct {
group_t group;
group_info_t info;
coord_t *stones;
} undo_enemy_t;
typedef struct board_undo {
move_t last_move2;
move_t ko;
move_t last_ko;
int last_ko_age;
coord_t next_at;
coord_t inserted;
undo_merge_t merged[4];
int nmerged;
int nmerged_tmp;
int nenemies;
int ncaptures;
coord_t *captures_end;
undo_enemy_t enemies[4];
coord_t captures[BOARD_MAX_COORDS];
} board_undo_t;
/* Quick play/undo to try out a move.
* WARNING Only core board data structures are maintained !
* Code in between can't rely on anything else.
*
* Currently this means these can't be used:
* - incremental patterns (pat3)
* - hashes, superko_violation (spathash, hash, qhash, history_hash)
* - list of free positions (f / flen)
* - list of capturable groups (c / clen)
*
* #define QUICK_BOARD_CODE at the top of your file to get compile-time
* error if you try to access a forbidden field.
*
* Invalid quick_play()/quick_undo() combinations (missing undo for example)
* are caught at next board_play() if BOARD_UNDO_CHECKS is defined.
*/
int board_quick_play(board_t *board, move_t *m, board_undo_t *u);
void board_quick_undo(board_t *b, move_t *m, board_undo_t *u);
/* quick_play() + quick_undo() combo.
* Body is executed only if move is valid (silently ignored otherwise).
* Can break out in body, but definitely *NOT* return / jump around !
* (caught at run time if BOARD_UNDO_CHECKS defined). Can use
* with_move_return(val) to return value for non-nested with_move()'s
* though. */
#define with_move(board_, coord_, color_, body_) \
do { \
board_t *board__ = (board_); /* For with_move_return() */ \
move_t m_ = move((coord_), (color_)); \
board_undo_t u_; \
if (board_quick_play(board__, &m_, &u_) >= 0) { \
do { body_ } while(0); \
board_quick_undo(board__, &m_, &u_); \
} \
} while (0)
/* Return value from within with_move() statement.
* Valid for non-nested with_move() *ONLY* */
#define with_move_return(val_) \
do { typeof(val_) val__ = (val_); board_quick_undo(board__, &m_, &u_); return val__; } while (0)
/* Same as with_move() but assert out in case of invalid move. */
#define with_move_strict(board_, coord_, color_, body_) \
do { \
board_t *board__ = (board_); /* For with_move_return() */ \
move_t m_ = move((coord_), (color_)); \
board_undo_t u_; \
assert (board_quick_play(board__, &m_, &u_) >= 0); \
do { body_ } while(0); \
board_quick_undo(board__, &m_, &u_); \
} while (0)
#endif /* PACHI_BOARD_UNDO_H */