
#include "RobboLito_def.h"
#include "RobboTripleBase.h"
#include <string.h>
#include "RobboTotalBase.h"

#include "IH-board.h"
typedef struct { uint32 move; } typeMoveList;
boolean CapturesByWhite (uint64*, uint8*, typeMoveList*, typeMoveList**, int);
boolean CapturesByBlack (uint64*, uint8*, typeMoveList*, typeMoveList**, int);
void TripleMake (uint32, Type_PiSq*, uint64*, uint8*);
void TripleUndo (uint32, Type_PiSq*, uint64*, uint8*);

#define RANK8 0xff00000000000000
#define RANK1 0x00000000000000ff
#define FILEh 0x8080808080808080
#define FILEa 0x0101010101010101

/* to 0-5, from 6-11, cap 12-19, mov 20-27, 28 ep, 29 prom+cap, 30 prom */

#define Serial(T, sq) \
  { while (T) \
      { to = BSF (T); c = Board[to]; if (c == bEnumK) return TRUE; \
	(L++)->move = (Board[sq] << 20) | (c << 12) | (sq << 6) | to; \
        BitClear (to, T); } }

#define FlagEP (1 << 28)
#define FlagPromote (1 << 30)

boolean CapturesByWhite
(uint64* BitBoard, uint8* Board, typeMoveList* L, typeMoveList** l, int ep)
{
  uint64 T, U, O = BitBoard[bEnumOcc], OCC = O | BitBoard[wEnumOcc];
  int sq, to;
  uint8 c;
  for (U = BitBoard[wEnumN]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttN[sq] & O;
      Serial (T, sq);
    }
  for (U = BitBoard[wEnumB]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttB (sq, OCC) & O;
      Serial (T, sq);
    }
  for (U = BitBoard[wEnumR]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttR (sq, OCC) & O;
      Serial (T, sq);
    }
  for (U = BitBoard[wEnumQ]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttQ (sq, OCC) & O;
      Serial (T, sq);
    }
  for (U = BitBoard[wEnumK]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttK [sq] & O & ~AttK[BSF (BitBoard[bEnumK])];
      Serial (T, sq);
    }
  for (U = ((BitBoard[wEnumP] & ~FILEa) << 7) & O; U; BitClear (sq, U))
    {
      to = BSF (U);
      c = Board[to];
      if (c == bEnumK)
	return TRUE;
      (L++)->move = ((to >= 070) << 29) |
	(Board[to - 7] << 20) | (c << 12) | ((to - 7) << 6) | to;
    }
  for (U = ((BitBoard[wEnumP] & ~FILEh) << 9) & O; U; BitClear (sq, U))
    {
      to = BSF (U);
      c = Board[to];
      if (c == bEnumK)
	return TRUE;
      (L++)->move = ((to >= 070) << 29) |
	(Board[to - 9] << 20) | (c << 12) | ((to - 9) << 6) | to;
    }
  for (U = (BitBoard[wEnumP] << 8) & (RANK8 & ~OCC); U; BitClear (sq, U))
    {
      to = BSF (U); /* promote */
      (L++)->move = FlagPromote | (Board[to - 8] << 20) | ((to - 8) << 6) | to;
    }
  if (ep & 077)
    {
      if (BitBoard[wEnumP] & ~FILEa & (1ULL << (ep - 7)))
	(L++)->move = FlagEP |
	  (Board[ep - 7] << 20) | (Board[ep - 8] << 12) | ((ep - 7) << 6) | ep;
      if (BitBoard[wEnumP] & ~FILEh & (1ULL << (ep - 9)))
	(L++)->move = FlagEP |
	  (Board[ep - 9] << 20) | (Board[ep - 8] << 12) | ((ep - 9) << 6) | ep;
    }
  *l = L;
  return FALSE;
}

#undef Serial /* un define */
#define Serial(T, sq) \
  { while (T) \
      { to = BSF (T); c = Board[to]; if (c == wEnumK) return TRUE; \
	(L++)->move = (Board[sq] << 20) | (c << 12) | (sq << 6) | to; \
        BitClear (to, T); } }

boolean CapturesByBlack
(uint64* BitBoard, uint8* Board, typeMoveList* L, typeMoveList** l, int ep)
{
  uint64 T, U, O = BitBoard[wEnumOcc], OCC = O | BitBoard[bEnumOcc];
  int sq, to;
  uint8 c;
  for (U = BitBoard[bEnumN]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttN[sq] & O;
      Serial (T, sq);
    }
  for (U = BitBoard[bEnumB]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttB (sq, OCC) & O;
      Serial (T, sq);
    }
  for (U = BitBoard[bEnumR]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttR (sq, OCC) & O;
      Serial (T, sq);
    }
  for (U = BitBoard[bEnumQ]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttQ (sq, OCC) & O;
      Serial (T, sq);
    }
  for (U = BitBoard[bEnumK]; U; BitClear (sq, U))
    {
      sq = BSF (U);
      T = AttK [sq] & O & ~AttK[BSF (BitBoard[wEnumK])];
      Serial (T, sq);
    }
  for (U = ((BitBoard[bEnumP] & ~FILEh) >> 7) & O; U; BitClear (sq, U))
    {
      to = BSF (U);
      c = Board[to];
      if (c == wEnumK)
	return TRUE;
      (L++)->move = ((to < 010) << 29) |
	(Board[to + 7] << 20) | (c << 12) | ((to + 7) << 6) | to;
    }
  for (U = ((BitBoard[bEnumP] & ~FILEa) >> 9) & O; U; BitClear (sq, U))
    {
      to = BSF (U);
      c = Board[to];
      if (c == wEnumK)
	return TRUE;
      (L++)->move = ((to < 010) << 29) |
	(Board[to + 9] << 20) | (c << 12) | ((to + 9) << 6) | to;
    }
  for (U = (BitBoard[bEnumP] >> 8) & (RANK1 & ~OCC); U; BitClear (sq, U))
    {
      to = BSF (U); /* promote */
      (L++)->move = FlagPromote | (Board[to + 8] << 20) | ((to + 8) << 6) | to;
    }
  if (ep & 077)
    {
      if (BitBoard[bEnumP] & ~FILEh & (1ULL << (ep + 7)))
	(L++)->move = FlagEP |
	  (Board[ep + 7] << 20) | (Board[ep + 8] << 12) | ((ep + 7) << 6) | ep;
      if (BitBoard[bEnumP] & ~FILEa & (1ULL << (ep + 9)))
	(L++)->move = FlagEP |
	  (Board[ep + 9] << 20) | (Board[ep + 8] << 12) | ((ep + 9) << 6) | ep;
    }
  *l = L;
  return FALSE;
}

/* to 0-5, from 6-11, cap 12-19, mov 20-27, 28 ep, 29 promcap, 30 prom */

void UnDoEP (uint32 move, Type_PiSq* PiSq, uint64* BitBoard, uint8* Board);
void MakeEP (uint32 move, Type_PiSq* PiSq, uint64* BitBoard, uint8* Board);

void TripleMake (uint32 move, Type_PiSq* PiSq, uint64* BitBoard, uint8* Board)
{
  int to, from, cap, pi, w, k;
  PiSq->nodes++;
  if (move & (1 << 28))
    {
      MakeEP (move, PiSq, BitBoard, Board);
      return;
    }
  if (move & (1 << 30))
    {
      to = move & 077;
      from = (move >> 6) & 077;
      pi = (move >> 20) & 0xff;
      w = (pi >> 4) & 0x3;
      PiSq->sq[w] = to;
      BitBoard[PiSq->pi[w]] ^= (1ULL << from);
      PiSq->pi[w] += wEnumQ - wEnumP; /* HACK */
      BitBoard[PiSq->pi[w]] ^= (1ULL << to);
      Board[to] = (PiSq->pi[w]) | (w << 4);
      BitBoard[pi & 010] ^= (1ULL << to) | (1ULL << from);
      goto FIN_ISH;
    }

  to = move & 077;
  from = (move >> 6) & 077;
  cap = (move >> 12) & 0xff;
  pi = (move >> 20) & 0xff;
  BitBoard[cap & 0x0f] ^= (1ULL << to);
  BitBoard[pi & 0x0f] ^= (1ULL << to) | (1ULL << from);
  BitBoard[cap & 010] ^= (1ULL << to);
  BitBoard[pi & 010] ^= (1ULL << to) | (1ULL << from);
  w = (pi >> 4) & 0x3;
  k = (cap >> 4) & 0x3;

  if (pi & 0x40) /* White Blocked Pawn */
    {
      PiSq->pi[w] = wEnumP;
      PiSq->sq[w] = to;
      PiSq->pi[k] = bEnumP;
      PiSq->sq[k] = from + 8;
      Board[to] = wEnumP | (w << 4);
      Board[from + 8] = bEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (pi & 0x80) /* Black Blocked Pawn */
    {
      PiSq->pi[w] = bEnumP;
      PiSq->sq[w] = to;
      PiSq->pi[k] = wEnumP;
      PiSq->sq[k] = from - 8;
      Board[to] = bEnumP | (w << 4);
      Board[from - 8] = wEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (cap & 0x40)
    {
      PiSq->pi[k] = bEnumP;
      PiSq->sq[k] = to + 8;
      if (pi == bEnumK)
	PiSq->bK = to;
      else
	PiSq->sq[w] = to;
      Board[to + 8] = bEnumP | (k << 4);
      Board[to] = Board[from];
      goto FIN_ISH;
    }
  if (cap & 0x80)
    {
      PiSq->pi[k] = wEnumP;
      PiSq->sq[k] = to - 8;
      if (pi == wEnumK)
	PiSq->wK = to;
      else
	PiSq->sq[w] = to;
      Board[to - 8] = wEnumP | (k << 4);
      Board[to] = Board[from];
      goto FIN_ISH;
    }
  if (pi == wEnumK)
    {
      PiSq->wK = to;
      Board[to] = pi;
    }
  else if (pi == bEnumK)
    {
      PiSq->bK = to;
      Board[to] = pi;
    }
  else
    { 
      PiSq->sq[w] = to;
      Board[to] = pi | (w << 4);
    }
  if (move & (1 << 29))
    {
      BitBoard[PiSq->pi[w]] ^= (1ULL << to);
      PiSq->pi[w] += wEnumQ - wEnumP; /* HACK */
      BitBoard[PiSq->pi[w]] ^= (1ULL << to);
      Board[to] = (PiSq->pi[w]) | (w << 4);
    }
  PiSq->pi[k] = PiSq->pi[PiSq->n - 1];
  PiSq->sq[k] = PiSq->sq[PiSq->n - 1];
  PiSq->pi[PiSq->n - 1] = 0;
  PiSq->sq[PiSq->n - 1] = 0;
  if (k != PiSq->n - 1)
    {
      if (PiSq->pi[k] == BlockedPawn)
	{
	  Board[PiSq->sq[k]] = wEnumP | (k << 4) | 0x40;
	  Board[PiSq->sq[k] + 8] = bEnumP | (k << 4) | 0x80;
	}
      else
	Board[PiSq->sq[k]] = PiSq->pi[k] | (k << 4);
    }
  PiSq->n--;

 FIN_ISH:
  Board[from] = 0; /* incur */
  PiSq->ep = 0;  
  PiSq->wtm ^= 1;
  PiSq->pedone = BitBoard[wEnumP] || BitBoard[bEnumP];
}

void TripleUndo (uint32 move, Type_PiSq* PiSq, uint64* BitBoard, uint8* Board)
{
  int to, from, cap, pi, w, k, u;
  if (move & (1 << 28))
    {
      UnDoEP (move, PiSq, BitBoard, Board);
      return;
    }
  if (move & (1 << 30))
    {
      to = move & 077;
      from = (move >> 6) & 077;
      pi = (move >> 20) & 0xff;
      w = (pi >> 4) & 0x3;
      PiSq->sq[w] = from;
      BitBoard[PiSq->pi[w]] ^= (1ULL << to);
      PiSq->pi[w] -= wEnumQ - wEnumP; /* HACK */
      BitBoard[PiSq->pi[w]] ^= (1ULL << from);
      Board[to] = 0;
      Board[from] = (PiSq->pi[w]) | (w << 4);
      BitBoard[pi & 010] ^= (1ULL << to) | (1ULL << from);
      goto FIN_ISH;
    }

  to = move & 077;
  from = (move >> 6) & 077;
  cap = (move >> 12) & 0xff;
  pi = (move >> 20) & 0xff;
  BitBoard[cap & 0x0f] ^= (1ULL << to);
  BitBoard[pi & 0x0f] ^= (1ULL << to) | (1ULL << from);
  BitBoard[cap & 010] ^= (1ULL << to);
  BitBoard[pi & 010] ^= (1ULL << to) | (1ULL << from);
  w = (pi >> 4) & 0x3;
  k = (cap >> 4) & 0x3;

  if (pi & 0x40) /* White Blocked Pawn */
    {
      PiSq->pi[w] = BlockedPawn;
      PiSq->sq[w] = from;
      PiSq->pi[k] = cap & 0xf;
      PiSq->sq[k] = to;
      Board[to] = cap;
      Board[from] = wEnumP | (w << 4) | 0x40;
      Board[from + 8] = bEnumP | (w << 4) | 0x80;
      goto FIN_ISH;
    }
  if (pi & 0x80) /* Black Blocked Pawn */
    {
      PiSq->pi[w] = BlockedPawn;
      PiSq->sq[w] = from - 8;
      PiSq->pi[k] = cap & 0xf;
      PiSq->sq[k] = to;
      Board[to] = cap;
      Board[from - 8] = wEnumP | (w << 4) | 0x40;
      Board[from] = bEnumP | (w << 4) | 0x80;
      goto FIN_ISH;
    }
  if (cap & 0x40)
    {
      PiSq->pi[k] = BlockedPawn;
      PiSq->sq[k] = to;
      if (pi == bEnumK)
	PiSq->bK = from;
      else
	PiSq->sq[w] = from;
      Board[from] = pi;
      Board[to] =  wEnumP | (k << 4) | 0x40;
      Board[to + 8] =  bEnumP | (k << 4) | 0x80;
      goto FIN_ISH;
    }
  if (cap & 0x80)
    {
      PiSq->pi[k] = BlockedPawn;
      PiSq->sq[k] = to - 8;
      if (pi == wEnumK)
	PiSq->wK = from;
      else
	PiSq->sq[w] = from;      
      Board[from] = pi;
      Board[to - 8] =  wEnumP | (k << 4) | 0x40;
      Board[to] =  bEnumP | (k << 4) | 0x80;
      goto FIN_ISH;
    }
  if (k != PiSq->n)
    {
      PiSq->pi[PiSq->n] = PiSq->pi[k];
      PiSq->sq[PiSq->n] = PiSq->sq[k];
      u = PiSq->n;
      if (PiSq->pi[u] == BlockedPawn)
	{
	  Board[PiSq->sq[u]] = wEnumP | (u << 4) | 0x40;
	  Board[PiSq->sq[u] + 8] = bEnumP | (u << 4) | 0x80;
	}
      else
	Board[PiSq->sq[u]] = PiSq->pi[u] | (u << 4);
    }
  PiSq->pi[k] = cap & 0xf;
  PiSq->sq[k] = to;
  
  if (pi == wEnumK)
    PiSq->wK = from;
  else if (pi == bEnumK)
    PiSq->bK = from;
  else
    PiSq->sq[w] = from;
  Board[from] = pi;
  Board[to] = cap;
  if (move & (1 << 29))
    {
      BitBoard[PiSq->pi[w]] ^= (1ULL << to);
      PiSq->pi[w] -= wEnumQ - wEnumP; /* HACK */
      BitBoard[PiSq->pi[w]] ^= (1ULL << to);
      Board[from] = (PiSq->pi[w]) | (w << 4);
    }
  PiSq->n++;

 FIN_ISH:
  PiSq->ep = 0;  
  PiSq->wtm ^= 1;
  PiSq->pedone = BitBoard[wEnumP] || BitBoard[bEnumP];
}

void MakeEP (uint32 move, Type_PiSq* PiSq, uint64* BitBoard, uint8* Board)
{
  int to, from, cap, pi, w, k, ep;
  to = move & 077;
  from = (move >> 6) & 077;
  cap = (move >> 12) & 0xff;
  k = (cap >> 4) & 0x3;
  pi = (move >> 20) & 0xff;
  w = (pi >> 4) & 0x3;
  BitBoard[pi & 0xf] ^= (1ULL << to) | (1ULL << from);
  BitBoard[pi & 010] ^= (1ULL << to) | (1ULL << from);
  ep = to - (PiSq->wtm ? 010 : -010);
  BitBoard[cap & 0xf] ^= (1ULL << ep);
  BitBoard[cap & 010] ^= (1ULL << ep);
  if (pi & 0x40) /* White Blocked Pawn */
    {
      if (cap & 0x80)
	{
	  /* ASSERT (PiSq->n != 4); */
	  PiSq->pi[w] = wEnumP;
	  PiSq->sq[w] = to;
	  PiSq->pi[k] = wEnumP;
	  PiSq->sq[k] = to - 020;
	  PiSq->pi[PiSq->n] = bEnumP;
	  PiSq->sq[PiSq->n] = from + 010;
	  Board[to] = wEnumP | (w << 4);
	  Board[ep - 010] = wEnumP | (k << 4);
	  Board[from + 010] = bEnumP | (PiSq->n << 4);
	  PiSq->n++;
	  goto FIN_ISH;
	}
      PiSq->pi[w] = wEnumP;
      PiSq->sq[w] = to;
      PiSq->pi[k] = bEnumP;
      PiSq->sq[k] = from + 010;
      Board[to] = wEnumP | (w << 4);
      Board[from + 010] = bEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (pi & 0x80) /* Black Blocked Pawn */
    {
      if (cap & 0x40)
	{
	  /* ASSERT (PiSq->n != 4); */
	  PiSq->pi[w] = bEnumP;
	  PiSq->sq[w] = to;
	  PiSq->pi[k] = bEnumP;
	  PiSq->sq[k] = to + 020;
	  PiSq->pi[PiSq->n] = wEnumP;
	  PiSq->sq[PiSq->n] = from - 010;
	  Board[to] = bEnumP | (w << 4);
	  Board[ep + 010] = bEnumP | (k << 4);
	  Board[from - 010] = wEnumP | (PiSq->n << 4);
	  PiSq->n++;
	  goto FIN_ISH;
	}
      PiSq->pi[w] = bEnumP;
      PiSq->sq[w] = to;
      PiSq->pi[k] = wEnumP;
      PiSq->sq[k] = from - 010;
      Board[to] = bEnumP | (w << 4);
      Board[from - 010] = wEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (cap & 0x80) /* Black Blocked Pawn */
    {
      PiSq->pi[w] = wEnumP;
      PiSq->sq[w] = to;
      PiSq->pi[k] = wEnumP;
      PiSq->sq[k] = to - 020;
      Board[to] = wEnumP | (w << 4);
      Board[to - 020] = wEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (cap & 0x40) /* White Blocked Pawn */
    {
      PiSq->pi[w] = bEnumP;
      PiSq->sq[w] = to;
      PiSq->pi[k] = bEnumP;
      PiSq->sq[k] = to + 020;
      Board[to] = bEnumP | (w << 4);
      Board[to + 020] = bEnumP | (k << 4);
      goto FIN_ISH;
    }
  PiSq->sq[w] = to;
  Board[to] = Board[from];
  PiSq->pi[k] = PiSq->pi[PiSq->n - 1];
  PiSq->sq[k] = PiSq->sq[PiSq->n - 1];
  if (k != PiSq->n - 1)
    {
      if (PiSq->pi[k] == BlockedPawn)
	{
	  Board[PiSq->sq[k]] = PiSq->pi[k] | (k << 4) | 0x40;
	  Board[PiSq->sq[k] + 8] = PiSq->pi[k] | (k << 4) | 0x80;
	}
      else
	Board[PiSq->sq[k]] = PiSq->pi[k] | (k << 4);
    }
  PiSq->n--;
  PiSq->pi[PiSq->n] = 0;
  PiSq->sq[PiSq->n] = 0;

 FIN_ISH:
  Board[from] = 0;
  Board[ep] = 0;
  PiSq->ep = 0;  
  PiSq->wtm ^= 1;
  PiSq->pedone = BitBoard[wEnumP] || BitBoard[bEnumP];
}

void UnDoEP (uint32 move, Type_PiSq* PiSq, uint64* BitBoard, uint8* Board)
{
  int to, from, cap, pi, w, k, ep, u;
  to = move & 077;
  from = (move >> 6) & 077;
  cap = (move >> 12) & 0xff;
  k = (cap >> 4) & 0x3;
  pi = (move >> 20) & 0xff;
  w = (pi >> 4) & 0x3;
  BitBoard[pi & 0xf] ^= (1ULL << to) | (1ULL << from);
  BitBoard[pi & 010] ^= (1ULL << to) | (1ULL << from);
  ep = to + (PiSq->wtm ? 010 : -010);
  BitBoard[cap & 0xf] ^= (1ULL << ep);
  BitBoard[cap & 010] ^= (1ULL << ep);

  if (pi & 0x40) /* White Blocked Pawn */
    {
      if (cap & 0x80)
	{
	  /* ASSERT (PiSq->n != 4); */
	  PiSq->pi[w] = BlockedPawn;
	  PiSq->sq[w] = from;
	  PiSq->pi[k] = BlockedPawn;
	  PiSq->sq[k] = to - 020;
	  PiSq->n--;
	  PiSq->pi[PiSq->n] = 0;
	  PiSq->sq[PiSq->n] = 0;
	  Board[from] = wEnumP | (w << 4) | 0x40;
	  Board[from + 010] = bEnumP | (w << 4) | 0x80;
	  Board[to - 010] = bEnumP | (k << 4) | 0x80;
	  Board[to - 020] = wEnumP | (k << 4) | 0x40;
	  goto FIN_ISH;
	}
      PiSq->pi[w] = BlockedPawn;
      PiSq->sq[w] = from;
      PiSq->pi[k] = bEnumP;
      PiSq->sq[k] = to - 010;
      Board[from] = wEnumP | (w << 4) | 0x40;
      Board[from + 010] = bEnumP | (w << 4) | 0x80;
      Board[to - 010] = bEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (pi & 0x80) /* Black Blocked Pawn */
    {
      if (cap & 0x40)
	{
	  PiSq->pi[w] = BlockedPawn;
	  PiSq->sq[w] = from - 010;
	  PiSq->pi[k] = BlockedPawn;
	  PiSq->sq[k] = to + 010;
	  PiSq->n--;
	  PiSq->pi[PiSq->n] = 0;
	  PiSq->sq[PiSq->n] = 0;
	  Board[from] = bEnumP | (w << 4) | 0x80;
	  Board[from - 010] = wEnumP | (w << 4) | 0x40;
	  Board[to + 010] = wEnumP | (k << 4) | 0x40;
	  Board[to + 020] = bEnumP | (k << 4) | 0x80;
	  goto FIN_ISH;
	}
      PiSq->pi[w] = BlockedPawn;
      PiSq->sq[w] = from - 010;
      PiSq->pi[k] = wEnumP;
      PiSq->sq[k] = to + 010;
      Board[from] = bEnumP | (w << 4) | 0x80;
      Board[from - 010] = wEnumP | (w << 4) | 0x40;
      Board[to + 010] = wEnumP | (k << 4);
      goto FIN_ISH;
    }
  if (cap & 0x80) /* Black Blocked Pawn */
    {
      PiSq->pi[w] = wEnumP;
      PiSq->sq[w] = from;
      PiSq->pi[k] = BlockedPawn;
      PiSq->sq[k] = to - 020;
      Board[from] = wEnumP | (w << 4);
      Board[to - 020] = wEnumP | (k << 4) | 0x40;
      Board[to - 010] = bEnumP | (k << 4) | 0x80;
      goto FIN_ISH;
    }
  if (cap & 0x40) /* White Blocked Pawn */
    {
      PiSq->pi[w] = bEnumP;
      PiSq->sq[w] = from;
      PiSq->pi[k] = BlockedPawn;
      PiSq->sq[k] = to + 010;
      Board[from] = bEnumP | (w << 4);
      Board[to + 010] = wEnumP | (k << 4) | 0x40;
      Board[to + 020] = bEnumP | (k << 4) | 0x80;
      goto FIN_ISH;
    }
  if (k != PiSq->n)
    {
      PiSq->pi[PiSq->n] = PiSq->pi[k];
      PiSq->sq[PiSq->n] = PiSq->sq[k];
      u = PiSq->n;
      if (PiSq->pi[u] == BlockedPawn)
	{
	  Board[PiSq->sq[u]] = PiSq->pi[u] | (u << 4) | 0x40;
	  Board[PiSq->sq[u] + 8] = PiSq->pi[u] | (u << 4) | 0x80;
	}
      else
	Board[PiSq->sq[u]] = PiSq->pi[u] | (u << 4);
    }
  PiSq->pi[k] = cap & 0xf;
  PiSq->sq[k] = ep;
  PiSq->sq[w] = from;
  Board[from] = pi | (w << 4);
  Board[ep] = cap | (k << 4);
  PiSq->n++;

 FIN_ISH:
  Board[to] = 0; /* value */
  PiSq->ep = to;
  PiSq->wtm ^= 1;
  PiSq->pedone = BitBoard[wEnumP] || BitBoard[bEnumP];
}
