Computer Chess Club Archives


Search

Terms

Messages

Subject: Question about the KnightCap find_pins function

Author: Matthew White

Date: 21:56:12 07/13/03


Hi all,

I was browsing through the code in KnightCap, and I noticed the following
function. Doesn't this seem like an incorrect definition of a pinned piece? I
thought that a pinned piece was when a lower valued piece was blocking the
attack on a higher valued piece (or the king). Any ideas?

Matt

static etype find_pins(Position *b)
{
	int i, j, k;
	uint32 pinner_mask;

	/* to find pins we loop over all pieces, looking for pieces
	   that are under attack by sliding pieces (but not if they
	   themselves are sliding pieces of the same type!). Then we
	   check to see if the sliding piece would attack another
	   piece, making it hung, if moved.

	   This is a expensive procedure!  */

	b->pinned_mask = 0;

	if (b->stage == MATING)
		return 0;

	for (i=2;i<16;i++) {
		if (!b->pieces[i].p) continue;

		pinner_mask = b->topieces[b->pieces[i].pos] &
			b->sliding_mask & BLACK_MASK;

		while (pinner_mask) {
			j = ff_one(pinner_mask);
			pinner_mask &= ~(1<<j);

			/* If the pinned piece is attacking the pinner then
			   it isn't a pin! It might be a skewer tho.
			   */
			if (b->topieces[b->pieces[j].pos] & (1<<i))
				continue;

			/* look for a piece that this bit is pinned against */
			for (k=0;k<8;k++) {
				if (!b->pieces[k].p) continue;
				if (k == i) continue;
				if (!same_line(b->pieces[j].pos, b->pieces[i].pos,
					       b->pieces[k].pos)) continue;
				if (!empty_line(b, b->pieces[i].pos,
						b->pieces[k].pos))
				    continue;

				/* we have a likely pin. Now we need
				   to confirm that if the pinner could attack
				   the pinnedto piece then that piece
				   would be hung */
				if (get_control(b,
						b->topieces[b->pieces[k].pos] | (1<<j),
						b->pieces[k].p,
					        b->pieces[k].pos) < 0) {
					b->pinned_mask |= (1<<i);
					if (debug)
						lprintf(0,"w pinned %s -> %s -> %s\n",
							posstr(b->pieces[j].pos),
							posstr(b->pieces[i].pos),
							posstr(b->pieces[k].pos)
							);
				}
			}
		}
	}


	for (i=18;i<32;i++) {
		if (!b->pieces[i].p) continue;

		pinner_mask = b->topieces[b->pieces[i].pos] &
			b->sliding_mask & WHITE_MASK;

		while (pinner_mask) {
			j = ff_one(pinner_mask);
			pinner_mask &= ~(1<<j);

			/* If the pinned piece is attacking the pinner then
			   it isn't a pin! It might be a skewer tho.
			   */
			if (b->topieces[b->pieces[j].pos] & (1<<i))
				continue;

			/* look for a piece that this bit is pinned against */
			for (k=16;k<24;k++) {
				if (!b->pieces[k].p) continue;
				if (k == i) continue;
				if (!same_line(b->pieces[j].pos, b->pieces[i].pos,
					       b->pieces[k].pos)) continue;
				if (!empty_line(b, b->pieces[i].pos,
						b->pieces[k].pos))
				    continue;

				/* we have a likely pin. Now we need
				   to confirm that if the pinner could attack
				   the pinnedto piece then that piece
				   would be hung */
				if (get_control(b,
						b->topieces[b->pieces[k].pos] | (1<<j),
						b->pieces[k].p,
						b->pieces[k].pos) > 0) {
					b->pinned_mask |= (1<<i);
					if (debug)
						lprintf(0,"b pinned %s -> %s -> %s\n",
							posstr(b->pieces[j].pos),
							posstr(b->pieces[i].pos),
							posstr(b->pieces[k].pos)
							);
				}
			}
		}
	}

	return 0;
}




This page took 0.06 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.