forked from pasky/pachi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
move.h
116 lines (94 loc) · 2.71 KB
/
move.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef PACHI_MOVE_H
#define PACHI_MOVE_H
#include <ctype.h>
#include <stdint.h>
#include <string.h>
#include "util.h"
#include "stone.h"
typedef int coord_t;
#define coord_xy(board, x, y) ((x) + (y) * board_size(board))
#define coord_x(c, b) ((b)->coord[c][0])
#define coord_y(c, b) ((b)->coord[c][1])
/* TODO: Smarter way to do this? */
#define coord_dx(c1, c2, b) (coord_x(c1, b) - coord_x(c2, b))
#define coord_dy(c1, c2, b) (coord_y(c1, b) - coord_y(c2, b))
static coord_t pass = -1;
static coord_t resign = -2;
#define is_pass(c) (c == pass)
#define is_resign(c) (c == resign)
#define coord_is_adjecent(c1, c2, b) (abs(c1 - c2) == 1 || abs(c1 - c2) == board_size(b))
#define coord_is_8adjecent(c1, c2, b) (abs(c1 - c2) == 1 || abs(abs(c1 - c2) - board_size(b)) < 2)
/* Quadrants:
* 0 1
* 2 3 (vertically reversed from board_print output, of course!)
* Middle coordinates are included in lower-valued quadrants. */
#define coord_quadrant(c, b) ((coord_x(c, b) > board_size(b) / 2) + 2 * (coord_y(c, b) > board_size(b) / 2))
/* dyn allocated */
static coord_t *coord_init(int x, int y, int size);
static coord_t *coord_copy(coord_t c);
static coord_t *coord_pass(void);
static coord_t *coord_resign(void);
static void coord_done(coord_t *c);
struct board;
char *coord2bstr(char *buf, coord_t c, struct board *board);
/* Return coordinate string in a dynamically allocated buffer. Thread-safe. */
char *coord2str(coord_t c, struct board *b);
/* Return coordinate string in a static buffer; multiple buffers are shuffled
* to enable use for multiple printf() parameters, but it is NOT safe for
* anything but debugging - in particular, it is NOT thread-safe! */
char *coord2sstr(coord_t c, struct board *b);
coord_t *str2coord(char *str, int board_size);
struct move {
coord_t coord;
enum stone color;
};
static inline coord_t *
coord_init(int x, int y, int size)
{
coord_t *c = (coord_t*)calloc2(1, sizeof(coord_t));
*c = x + y * size;
return c;
}
static inline coord_t *
coord_copy(coord_t c)
{
coord_t *c2 = (coord_t*)calloc2(1, sizeof(coord_t));
memcpy(c2, &c, sizeof(c));
return c2;
}
static inline coord_t *
coord_pass()
{
return coord_copy(pass);
}
static inline coord_t *
coord_resign()
{
return coord_copy(resign);
}
/* No sanity checking */
static inline coord_t
str2scoord(char *str, int size)
{
if (!strcasecmp(str, "pass")) {
return pass;
} else if (!strcasecmp(str, "resign")) {
return resign;
} else {
char xc = tolower(str[0]);
return xc - 'a' - (xc > 'i') + 1 + atoi(str + 1) * size;
}
}
static inline void
coord_done(coord_t *c)
{
free(c);
}
static inline int
move_cmp(struct move *m1, struct move *m2)
{
if (m1->color != m2->color)
return m1->color - m2->color;
return m1->coord - m2->coord;
}
#endif