2 Functions for board scoring that take komi and dynamic komi into consideration.
4 Remember that in Matilda, scores and komi are always doubled to become integer.
13 #include "cfg_board.h"
16 #include "state_changes.h"
25 Produces a textual representation of a Go match score., ex: B+3.5, 0
32 snprintf(dst
, MAX_PAGE_SIZ
, "0");
33 } else if ((score
& 1) == 1) {
35 snprintf(dst
, MAX_PAGE_SIZ
, "B+%d.5", score
/ 2);
37 snprintf(dst
, MAX_PAGE_SIZ
, "W+%d.5", (-score
) / 2);
41 snprintf(dst
, MAX_PAGE_SIZ
, "B+%d", score
/ 2);
43 snprintf(dst
, MAX_PAGE_SIZ
, "W+%d", (-score
) / 2);
49 Produces a textual representation of a komidashi value.
56 snprintf(dst
, MAX_PAGE_SIZ
, "0");
57 } else if ((komi
& 1) == 1) {
59 snprintf(dst
, MAX_PAGE_SIZ
, "%d.5", komi
/ 2);
61 snprintf(dst
, MAX_PAGE_SIZ
, "-%d.5", (-komi
) / 2);
65 snprintf(dst
, MAX_PAGE_SIZ
, "%d", komi
/ 2);
67 snprintf(dst
, MAX_PAGE_SIZ
, "-%d", (-komi
) / 2);
73 Scoring by counting stones on the board only.
74 RETURNS positive score for a black win; negative for a white win; 0 for a draw
76 d16
score_stones_only(
77 const u8 p
[static TOTAL_BOARD_SIZ
]
81 for (move m
= 0; m
< TOTAL_BOARD_SIZ
; ++m
) {
96 Scoring by counting stones and eyes on the board only.
97 RETURNS positive score for a black win; negative for a white win; 0 for a draw
99 d16
score_stones_and_eyes2(
105 for (move m
= 0; m
< TOTAL_BOARD_SIZ
; ++m
) {
114 if (is_4pt_eye(cb
, true, m
, &_ignored
)) {
119 if (is_4pt_eye(cb
, false, m
, &_ignored
)) {
124 if (is_2pt_eye(cb
, true, m
, &_ignored
)) {
128 if (is_2pt_eye(cb
, false, m
, &_ignored
)) {
132 if (is_eye(cb
, true, m
)) {
136 if (is_eye(cb
, false, m
)) {
147 Scoring by counting stones and eyes on the board only.
148 RETURNS positive score for a black win; negative for a white win; 0 for a draw
150 d16
score_stones_and_eyes(
154 cfg_from_board(&cb
, b
);
155 d16 ret
= score_stones_and_eyes2(&cb
);
162 const u8 p
[static TOTAL_BOARD_SIZ
],
164 bool explored
[static TOTAL_BOARD_SIZ
],
165 bool * restrict black
,
166 bool * restrict white
170 move_to_coord(m
, &x
, &y
);
173 if (p
[m
+ LEFT
] == BLACK_STONE
) {
175 } else if (p
[m
+ LEFT
] == WHITE_STONE
) {
177 } else if (explored
[m
+ LEFT
] == false) {
178 explored
[m
+ LEFT
] = true;
179 _search(p
, m
+ LEFT
, explored
, black
, white
);
183 if (x
< BOARD_SIZ
- 1) {
184 if (p
[m
+ RIGHT
] == BLACK_STONE
) {
186 } else if (p
[m
+ RIGHT
] == WHITE_STONE
) {
188 } else if (explored
[m
+ RIGHT
] == false) {
189 explored
[m
+ RIGHT
] = true;
190 _search(p
, m
+ RIGHT
, explored
, black
, white
);
195 if (p
[m
+ TOP
] == BLACK_STONE
) {
197 } else if (p
[m
+ TOP
] == WHITE_STONE
) {
199 } else if (explored
[m
+ TOP
] == false) {
200 explored
[m
+ TOP
] = true;
201 _search(p
, m
+ TOP
, explored
, black
, white
);
205 if (y
< BOARD_SIZ
- 1) {
206 if (p
[m
+ BOTTOM
] == BLACK_STONE
) {
208 } else if (p
[m
+ BOTTOM
] == WHITE_STONE
) {
210 } else if (explored
[m
+ BOTTOM
] == false) {
211 explored
[m
+ BOTTOM
] = true;
212 _search(p
, m
+ BOTTOM
, explored
, black
, white
);
218 u8 p
[static TOTAL_BOARD_SIZ
],
224 move_to_coord(m
, &x
, &y
);
226 if (x
> 0 && p
[m
+ LEFT
] == EMPTY
) {
228 _apply(p
, m
+ LEFT
, val
);
231 if (x
< BOARD_SIZ
- 1 && p
[m
+ RIGHT
] == EMPTY
) {
233 _apply(p
, m
+ RIGHT
, val
);
236 if (y
> 0 && p
[m
+ TOP
] == EMPTY
) {
238 _apply(p
, m
+ TOP
, val
);
241 if (y
< BOARD_SIZ
- 1 && p
[m
+ BOTTOM
] == EMPTY
) {
243 _apply(p
, m
+ BOTTOM
, val
);
248 Scoring by counting stones and surrounded area. Also known as area scoring. Does
249 not remove dead stones.
250 RETURNS positive score for a black win; negative for a white win; 0 for a draw
252 d16
score_stones_and_area(
253 const u8 p
[static TOTAL_BOARD_SIZ
]
255 /* explored intersections array is only used for empty intersections */
256 bool explored
[TOTAL_BOARD_SIZ
];
257 memset(explored
, false, TOTAL_BOARD_SIZ
* sizeof(bool));
259 u8 bak
[TOTAL_BOARD_SIZ
];
260 memcpy(bak
, p
, TOTAL_BOARD_SIZ
);
262 for (move m
= 0; m
< TOTAL_BOARD_SIZ
; ++m
) {
263 if (p
[m
] == EMPTY
&& !explored
[m
]) { /* Find owner of empty intersection */
264 bool found_black
= false;
265 bool found_white
= false;
267 _search(p
, m
, explored
, &found_black
, &found_white
);
269 if (found_black
!= found_white
) { /* established intersection */
271 bak
[m
] = BLACK_STONE
;
272 _apply(bak
, m
, BLACK_STONE
);
274 bak
[m
] = WHITE_STONE
;
275 _apply(bak
, m
, WHITE_STONE
);
282 for (move m
= 0; m
< TOTAL_BOARD_SIZ
; ++m
) {
283 if (bak
[m
] == BLACK_STONE
) {
285 } else if (bak
[m
] == WHITE_STONE
) {