Module Name: src Committed By: rillig Date: Sat May 28 19:47:24 UTC 2022
Modified Files: src/games/gomoku: bdinit.c Log Message: gomoku: clean up initialization of overlap information Fix variable names 'ia' and 'ib', which I forgot in the previous commit. Move the documentation in the right places. Split off another part of init_overlap, to make each function fit on a single screen. Reducing the number of nested 'for' loops allows the indentation to follow the NetBSD style. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/games/gomoku/bdinit.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/games/gomoku/bdinit.c diff -u src/games/gomoku/bdinit.c:1.26 src/games/gomoku/bdinit.c:1.27 --- src/games/gomoku/bdinit.c:1.26 Sat May 28 18:55:16 2022 +++ src/games/gomoku/bdinit.c Sat May 28 19:47:24 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: bdinit.c,v 1.26 2022/05/28 18:55:16 rillig Exp $ */ +/* $NetBSD: bdinit.c,v 1.27 2022/05/28 19:47:24 rillig Exp $ */ /* * Copyright (c) 1994 @@ -34,7 +34,7 @@ #include <sys/cdefs.h> /* from: @(#)bdinit.c 8.2 (Berkeley) 5/3/95 */ -__RCSID("$NetBSD: bdinit.c,v 1.26 2022/05/28 18:55:16 rillig Exp $"); +__RCSID("$NetBSD: bdinit.c,v 1.27 2022/05/28 19:47:24 rillig Exp $"); #include <string.h> #include "gomoku.h" @@ -160,43 +160,65 @@ init_board(void) init_overlap(); } -/*- - * ra direction of frame A - * ia index of the spot in frame A (0 to 5) - * rb direction of frame B - * ib index of the spot in frame B (0 to 5) +/* + * Variable names for frames A and B: + * + * fi index of the frame in the global 'frames' + * r direction: 0 = right, 1 = down right, 2 = down, 3 = down left + * d direction delta, difference between adjacent spot indexes + * si index of the spot in the frame, 0 to 5 + */ + +/* + * Each entry in the overlap array is a bit mask with eight bits corresponding + * to whether frame B overlaps frame A (as indexed by overlap[A * FAREA + B]). + * + * The eight bits correspond to whether A and B are open-ended (length 6) or + * closed (length 5). + * + * 0 A closed and B closed + * 1 A closed and B open + * 2 A open and B closed + * 3 A open and B open + * 4 A closed and B closed and overlaps in more than one spot + * 5 A closed and B open and overlaps in more than one spot + * 6 A open and B closed and overlaps in more than one spot + * 7 A open and B open and overlaps in more than one spot + * + * As pieces are played during the game, frames that no longer share an empty + * spot will be removed from the overlap array by setting the entry to 0. */ static u_char -adjust_overlap(u_char ov, int ra, int ia, int rb, int ib, int mask) +adjust_overlap(u_char ov, int ra, int sia, int rb, int sib, int mask) { - ov |= (ib == 5) ? mask & 0xA : mask; + ov |= (sib == 5) ? mask & 0xA : mask; if (rb != ra) return ov; /* compute the multiple spot overlap values */ - switch (ia) { + switch (sia) { case 0: - if (ib == 4) + if (sib == 4) ov |= 0xA0; - else if (ib != 5) + else if (sib != 5) ov |= 0xF0; break; case 1: - if (ib == 5) + if (sib == 5) ov |= 0xA0; else ov |= 0xF0; break; case 4: - if (ib == 0) + if (sib == 0) ov |= 0xC0; else ov |= 0xF0; break; case 5: - if (ib == 1) + if (sib == 1) ov |= 0xC0; - else if (ib != 0) + else if (sib != 0) ov |= 0xF0; break; default: @@ -207,73 +229,56 @@ adjust_overlap(u_char ov, int ra, int ia } /* - * Initialize the overlap array. - * Each entry in the array is a bit mask with eight bits corresponding - * to whether frame B overlaps frame A (as indexed by overlap[A * FAREA + B]). - * The eight bits correspond to whether A and B are open-ended (length 6) or - * closed (length 5). - * 0 A closed and B closed - * 1 A closed and B open - * 2 A open and B closed - * 3 A open and B open - * 4 A closed and B closed and overlaps in more than one spot - * 5 A closed and B open and overlaps in more than one spot - * 6 A open and B closed and overlaps in more than one spot - * 7 A open and B open and overlaps in more than one spot - * As pieces are played, it can make frames not overlap if there are no - * common open spaces shared between the two frames. + * Given a single spot 's' of frame A, update the overlap information for + * each frame B that overlaps frame A in that spot. */ static void +init_overlap_frame(int fia, int ra, int sia, int s, int mask) +{ + + for (int rb = 4; --rb >= 0;) { + int db = dd[rb]; + + for (int sib = 0; sib < 6; sib++) { + /* spb0 is the spot where frame B starts. */ + const struct spotstr *spb0 = &board[s - sib * db]; + if (spb0->s_occ == BORDER) + break; + if ((spb0->s_flags & BFLAG << rb) != 0) + continue; + + int fib = (int)(spb0->s_frame[rb] - frames); + intersect[fia * FAREA + fib] = (short)s; + u_char *op = &overlap[fia * FAREA + fib]; + *op = adjust_overlap(*op, ra, sia, rb, sib, mask); + } + } +} + +static void init_overlap(void) { memset(overlap, 0, sizeof(overlap)); memset(intersect, 0, sizeof(intersect)); - /*- - * Variables for frames A and B: - * - * fi index of the frame in the global 'frames' - * r direction: 0 = right, 1 = down right, 2 = down, 3 = down left - * d direction delta, difference between adjacent spot indexes - * si index of the spot in the frame, 0 to 5 - * sp data of the spot at index i - */ - - for (unsigned fia = FAREA; fia-- > 0; ) { - struct combostr *fa = &frames[fia]; - int vertex = fa->c_vertex; - struct spotstr *spa = &board[vertex]; - u_char ra = fa->c_dir; - int da = dd[ra]; - - /* - * len = 5 if closed, 6 if open. - * At this point, Black and White have the same values. - */ - int len = 5 + spa->s_fval[BLACK][ra].cv_win; - - for (int sia = 0; sia < len; sia++, spa += da, vertex += da) { - /* the sixth spot in frame A only overlaps if it is open */ - int mask = (sia == 5) ? 0xC : 0xF; - - for (int rb = 4; --rb >= 0; ) { - struct spotstr *spb = spa; - int db = dd[rb]; - - /* for each frame that intersects at spot spa */ - for (int sib = 0; sib < 6; sib++, spb -= db) { - if (spb->s_occ == BORDER) - break; - if ((spb->s_flags & BFLAG << rb) != 0) - continue; + for (int fia = FAREA; fia-- > 0;) { + const struct combostr *fa = &frames[fia]; + int s = fa->c_vertex; + u_char ra = fa->c_dir; + int da = dd[ra]; + + /* + * len = 5 if closed, 6 if open. At this early stage, Black + * and White have the same value for cv_win. + */ + int len = 5 + board[s].s_fval[BLACK][ra].cv_win; + + for (int sia = 0; sia < len; sia++) { + /* spot[5] in frame A only overlaps if it is open */ + int mask = (sia == 5) ? 0xC : 0xF; - int fib = (int)(spb->s_frame[rb] - frames); - intersect[fia * FAREA + fib] = (short)vertex; - u_char *op = &overlap[fia * FAREA + fib]; - *op = adjust_overlap(*op, ra, sia, rb, sib, mask); - } + init_overlap_frame(fia, ra, sia, s + sia * da, mask); } - } } }