Esempio n. 1
0
void
pattern_get(struct pattern_config *pc, struct pattern *p, struct board *b, struct move *m)
{
	p->n = 0;
	struct feature *f = &p->f[0];

	/* TODO: We should match pretty much all of these features
	 * incrementally. */

	/* FEAT_SPATIAL */
	/* TODO */
	assert(!pc->spat_max);

	/* FEAT_PASS */
	if (is_pass(m->coord)) {
		f->id = FEAT_PASS; f->payload = 0;
		f->payload |= (b->moves > 0 && is_pass(b->last_move.coord)) << PF_PASS_LASTPASS;
		p->n++;
		return;
	}

	/* FEAT_CAPTURE */
	{
		foreach_neighbor(b, m->coord, {
			if (board_at(b, c) != stone_other(m->color))
				continue;
			group_t g = group_at(b, c);
			if (!g || board_group_info(b, g).libs != 1)
				continue;

			/* Capture! */
			f->id = FEAT_CAPTURE; f->payload = 0;

			f->payload |= is_ladder(b, m->coord, g, true, true) << PF_CAPTURE_LADDER;
			/* TODO: is_ladder() is too conservative in some
			 * very obvious situations, look at complete.gtp. */

			/* TODO: PF_CAPTURE_RECAPTURE */

			foreach_in_group(b, g) {
				foreach_neighbor(b, c, {
					assert(board_at(b, c) != S_NONE || c == m->coord);
					if (board_at(b, c) != m->color)
						continue;
					group_t g = group_at(b, c);
					if (!g || board_group_info(b, g).libs != 1)
						continue;
					/* A neighboring group of ours is in atari. */
					f->payload |= 1 << PF_CAPTURE_ATARIDEF;
				});
			} foreach_in_group_end;

			if (group_is_onestone(b, g)
			    && neighbor_count_at(b, m->coord, stone_other(m->color))
			       + neighbor_count_at(b, m->coord, S_OFFBOARD) == 4)
				f->payload |= 1 << PF_CAPTURE_KO;

			(f++, p->n++);
		});
Esempio n. 2
0
bool
is_middle_ladder(Board *b, Coord coord, group_t laddered, Stone lcolor)
{
	/* TODO: Remove the redundant parameters. */
	assert(group_at(b, laddered)->liberties == 1);

  Coord last_lib = get_nlibs_of_group(b, laddered, 1, NULL);
	assert(last_lib == coord);
	assert(group_at(b, laddered)->color == lcolor);

	/* If we can move into empty space or do not have enough space
	 * to escape, this is obviously not a ladder. */
	if (immediate_liberty_count(b, coord) != 2) {
    /*
		if (DEBUGL(5))
			fprintf(stderr, "no ladder, wrong free space\n");
    */
		return false;
	}

	/* A fair chance for a ladder. Group in atari, with some but limited
	 * space to escape. Time for the expensive stuff - set up a temporary
	 * board and start selective 2-liberty search. */

	Board *bset = (Board *)malloc(BOARD_MAX_SIZE * 2 * sizeof(Board));

	struct move_queue ccq = { .moves = 0 };
	if (can_countercapture(b, lcolor, laddered, lcolor, &ccq, 0)) {
		/* We could escape by countercapturing a group.
		 * Investigate. */
		assert(ccq.moves > 0);
		for (unsigned int i = 0; i < ccq.moves; i++) {
			Board b2;
			CopyBoard(&b2, b);
			bool is_ladder = middle_ladder_walk(&b2, bset, laddered, ccq.move[i], lcolor);
			// board_done_noalloc(&b2);
			if (!is_ladder) {
				free(bset);
				return false;
			}
		}
	}

	Board b2;
  CopyBoard(&b2, b);
  Coord last_lib2 = get_nlibs_of_group(&b2, laddered, 1, NULL);

	bool is_ladder = middle_ladder_walk(&b2, bset, laddered, last_lib2, lcolor);
	// board_done_noalloc(&b2);
	free(bset);
	return is_ladder;
}

bool
wouldbe_ladder(Board *b, group_t group, Coord escapelib, Coord chaselib, Stone lcolor)
{
	assert(b->_groups[group].liberties == 2);
	assert(b->_groups[group].color == lcolor);

  /*
	if (DEBUGL(6))
		fprintf(stderr, "would-be ladder check - does %s %s play out chasing move %s?\n",
			stone2str(lcolor), coord2sstr(escapelib, b), coord2sstr(chaselib, b));
  */

	if (!NEIGHBOR8(escapelib, chaselib)) {
    /*
		if (DEBUGL(5))
			fprintf(stderr, "cannot determine ladder for remote simulated stone\n");
    */
		return false;
	}

	if (neighbor_count_at(b, chaselib, lcolor) != 1 || immediate_liberty_count(b, chaselib) != 2) {
    /*
		if (DEBUGL(5))
			fprintf(stderr, "overly trivial for a ladder\n");
    */
		return false;
	}

	bool is_ladder = false;
	Board *bset = (Board *)malloc(BOARD_MAX_SIZE * 2 * sizeof(Board));
	Board b2;
	CopyBoard(&b2, b);

  GroupId4 ids;
  if (TryPlay(&b2, X(chaselib), Y(chaselib), OPPONENT(lcolor), &ids)) {
    Play(&b2, &ids);
    Coord last_lib2 = get_nlibs_of_group(&b2, group, 1, NULL);
		is_ladder = middle_ladder_walk(&b2, bset, group, last_lib2, lcolor);
  }

	// board_done_noalloc(&b2);
	free(bset);
	return is_ladder;
}