From d5999adad80a4adde0bab73e3df64108e7ddb4b8 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sun, 9 Jan 2011 16:22:06 +0100 Subject: [PATCH] Tactics nakade_point(): Simple eye-piercing tool --- tactics/Makefile | 2 +- tactics/nakade.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tactics/nakade.h | 14 ++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tactics/nakade.c create mode 100644 tactics/nakade.h diff --git a/tactics/Makefile b/tactics/Makefile index 82762db..344dde3 100644 --- a/tactics/Makefile +++ b/tactics/Makefile @@ -1,5 +1,5 @@ INCLUDES=-I.. -OBJS=1lib.o 2lib.o nlib.o ladder.o selfatari.o util.o +OBJS=1lib.o 2lib.o nlib.o ladder.o nakade.o selfatari.o util.o all: tactics.a tactics.a: $(OBJS) diff --git a/tactics/nakade.c b/tactics/nakade.c new file mode 100644 index 0000000..257dc49 --- /dev/null +++ b/tactics/nakade.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#define DEBUG +#include "board.h" +#include "debug.h" +#include "move.h" +#include "tactics/nakade.h" + + +coord_t +nakade_point(struct board *b, coord_t around, enum stone color) +{ + /* First, examine the nakade area. For sure, it must be at most + * six points. And it must be within color group(s). */ +#define NAKADE_MAX 6 + coord_t area[NAKADE_MAX]; int area_n = 0; + + area[area_n++] = around; + + for (int i = 0; i < area_n; i++) { + foreach_neighbor(b, area[i], { + if (board_at(b, c) == stone_other(color)) + return pass; + if (board_at(b, c) == S_NONE) { + bool dup = false; + for (int j = 0; j < area_n; j++) + if (c == area[j]) { + dup = true; + break; + } + if (dup) continue; + + if (area_n >= NAKADE_MAX) { + /* Too large nakade area. */ + return pass; + } + area[area_n++] = c; + } + }); + } + + /* We also collect adjecency information - how many neighbors + * we have for each area point, and histogram of this. This helps + * us verify the appropriate bulkiness of the shape. */ + int neighbors[area_n]; int ptbynei[9] = {area_n, 0}; + memset(neighbors, 0, sizeof(neighbors)); + for (int i = 0; i < area_n; i++) { + for (int j = i + 1; j < area_n; j++) + if (coord_is_adjecent(area[i], area[j], b)) { + ptbynei[neighbors[i]]--; + neighbors[i]++; + ptbynei[neighbors[i]]++; + ptbynei[neighbors[j]]--; + neighbors[j]++; + ptbynei[neighbors[j]]++; + } + } + + /* For each given neighbor count, arbitrary one coordinate + * featuring that. */ + coord_t coordbynei[9]; + for (int i = 0; i < area_n; i++) + coordbynei[neighbors[i]] = area[i]; + + switch (area_n) { + case 1: return pass; + case 2: return pass; + case 3: assert(ptbynei[2] == 1); + return coordbynei[2]; // middle point + case 4: if (ptbynei[3] != 1) return pass; // long line + return coordbynei[3]; // tetris four + case 5: if (ptbynei[3] == 1 && ptbynei[1] == 1) return coordbynei[3]; // bulky five + if (ptbynei[4] == 1) return coordbynei[4]; // cross five + return pass; // long line + case 6: if (ptbynei[4] == 1 && ptbynei[2] == 3) + return coordbynei[4]; // rabbity six + return pass; // anything else + default: assert(0); + } +} diff --git a/tactics/nakade.h b/tactics/nakade.h new file mode 100644 index 0000000..0960f25 --- /dev/null +++ b/tactics/nakade.h @@ -0,0 +1,14 @@ +#ifndef ZZGO_TACTICS_NAKADE_H +#define ZZGO_TACTICS_NAKADE_H + +/* Piercing eyes. */ + +#include "board.h" +#include "debug.h" + +/* Find an eye-piercing point within the @around area of empty board + * internal to group of color @color. + * Returns pass if the area is not a nakade shape or not internal. */ +coord_t nakade_point(struct board *b, coord_t around, enum stone color); + +#endif -- 2.11.4.GIT