From 754e9f069f9a937fe98bb392f425381e5ce04c0b Mon Sep 17 00:00:00 2001
From: Markus Uhlin <markus@nifty-networks.net>
Date: Sat, 13 Apr 2024 13:14:37 +0200
Subject: Checked out files by tag 1.0

---
 FICS/algcheck.c  |  854 ++++++++++-------------
 FICS/algcheck.h  |   12 +-
 FICS/movecheck.c | 2050 ++++++++++++++++++++++++------------------------------
 FICS/movecheck.h |   48 +-
 4 files changed, 1315 insertions(+), 1649 deletions(-)

diff --git a/FICS/algcheck.c b/FICS/algcheck.c
index 67609b1..10fad0c 100644
--- a/FICS/algcheck.c
+++ b/FICS/algcheck.c
@@ -19,25 +19,17 @@
 
 /* Revision history:
    name		email		yy/mm/dd	Change
-   Richard Nash                 93/10/22	Created
-   Markus Uhlin                 24/01/04	Reformatted functions
-   Markus Uhlin                 24/01/06	Switched to usage of strlcpy,
-						strlcat and snprintf. Also added
-						truncation checks.
+   Richard Nash	              	93/10/22	Created
 */
 
 #include "stdinclude.h"
-#include "common.h"
 
+#include "common.h"
 #include "algcheck.h"
-#include "board.h"
 #include "movecheck.h"
+#include "board.h"
 #include "utils.h"
 
-#if __linux__
-#include <bsd/string.h>
-#endif
-
 /* Well, lets see if I can list the possibilities
  * Piece moves
  * Ne4
@@ -66,484 +58,408 @@
  * x - x
  * @ - drop character (bughouse)
  */
-PRIVATE char *alg_list[] = {
-	"fxfr", "pxfr",  /* These two get confused in case of bishop */
-	"ffr", "pfr",    /* These two get confused in case of bishop */
-	"pffr",
-	"pfxfr",
-	"prfr",
-	"prxfr",
-	"fr",
-	"ff",
-	"fxf",
-	"p@fr",
-	"#fr",
-	"#pfr",
-	NULL
+char *alg_list[] = {
+  "fxfr", "pxfr",		/* These two get confused in case of bishop */
+  "ffr", "pfr",			/* These two get confused in case of bishop */
+  "pffr",
+  "pfxfr",
+  "prfr",
+  "prxfr",
+  "fr",
+  "ff",
+  "fxf",
+  "p@fr",
+  "#fr",
+  "#pfr",
+  NULL
 };
 
-PRIVATE int
-get_move_info(char *str, int *piece, int *ff, int *fr, int *tf, int *tr,
-	      int *bishconfusion)
-{
-	char	*s;
-	char	 c;
-	char	 tmp[1024] = { '\0' };
-	int	 i, j, len;
-	int	 lpiece, lff, lfr, ltf, ltr;
-	int	 matchVal = -1;
-
-	*bishconfusion = 0;
-	strlcpy(tmp, str, sizeof tmp);
-
-	if ((s = strchr(tmp, '+')) != NULL) {	// Cut off any check marks
-		*s = '\0';
-	}
-	if ((s = strchr(tmp, '=')) != NULL) {	// Cut off any promotion marks
-		*s = '\0';
-	}
-
-	*piece = *ff = *fr = *tf = *tr = ALG_UNKNOWN;
-	len = strlen(tmp);
-
-	for (i = 0; alg_list[i]; i++) {
-		lpiece = lff = lfr = ltf = ltr = ALG_UNKNOWN;
-
-		if (strlen(alg_list[i]) != len)
-			continue;
-
-		for (j = len - 1; j >= 0; j--) {
-			switch (alg_list[i][j]) {
-			case 'f':
-				if (tmp[j] < 'a' || tmp[j] > 'h')
-					goto nomatch;
-
-				if (ltf == ALG_UNKNOWN)
-					ltf = (tmp[j] - 'a');
-				else
-					lff = (tmp[j] - 'a');
-				break;
-			case 'r':
-				if (tmp[j] < '1' || tmp[j] > '8')
-					goto nomatch;
-
-				if (ltr == ALG_UNKNOWN)
-					ltr = (tmp[j] - '1');
-				else
-					lfr = (tmp[j] - '1');
-				break;
-			case 'p':
-				if (isupper(tmp[j]))
-					c = tolower(tmp[j]);
-				else
-					c = tmp[j];
-
-				if (c == 'k')
-					lpiece = KING;
-				else if (c == 'q')
-					lpiece = QUEEN;
-				else if (c == 'r')
-					lpiece = ROOK;
-				else if (c == 'b')
-					lpiece = BISHOP;
-				else if (c == 'n')
-					lpiece = KNIGHT;
-				else if (c == 'p')
-					lpiece = PAWN;
-				else
-					goto nomatch;
-				break;
-			case 'x':
-				if (tmp[j] != 'x' && tmp[j] != 'X')
-					goto nomatch;
-				break;
-			case '@':
-				if (tmp[j] != '@' && tmp[j] != '*')
-					goto nomatch;
-				lff = lfr = ALG_DROP;
-				break;
-			case '#':
-				if (tmp[j] != '#')
-					goto nomatch;
-				lff = lfr = ALG_DROP;
-				break;
-			default:
-				fprintf(stderr, "Unknown character in "
-				    "algebraic parsing\n");
-				break;
-			}
-		}
-
-		if (lpiece == ALG_UNKNOWN)
-			lpiece = PAWN;
-
-		if (lpiece == PAWN && lfr == ALG_UNKNOWN) { // ffr or ff
-			if (lff != ALG_UNKNOWN) {
-				if (lff == ltf)
-					goto nomatch;
-				if ((lff - ltf) != 1 && (ltf - lff) != 1)
-					goto nomatch;
-			}
-		}
-
-		*piece = lpiece; // We have a match
-
-		*tf = ltf;
-		*tr = ltr;
-		*ff = lff;
-		*fr = lfr;
-
-		if (matchVal != -1) {
-			/*
-			 * We have two matches, it must be that Bxc4
-			 * vs. bxc4 problem. Or it could be the Bc4 vs
-			 * bc4 problem.
-			 */
-			*bishconfusion = 1;
-		}
+#define ALG_UNKNOWN -1
+/* #define ALG_DROP    -2	IanO: this is in board.h, used in movecheck.c */
 
-		matchVal = i;
-
-	  nomatch:;
-	}
-
-	if (matchVal != -1)
-		return MS_ALG;
+PRIVATE int get_move_info(char *str, int *piece, int *ff, int *fr, int *tf, int *tr, int *bishconfusion)
+{
+  char tmp[1024];
+  char *s;
+  int i, j, len;
+  char c;
+  int matchVal = -1;
+  int lpiece, lff, lfr, ltf, ltr;
+
+  *bishconfusion = 0;
+  strcpy(tmp, str);
+  if ((s = index(tmp, '+'))) {	/* Cut off any check marks */
+    *s = '\0';
+  }
+  if ((s = index(tmp, '='))) {	/* Cut off any promotion marks */
+    *s = '\0';
+  }
+  *piece = *ff = *fr = *tf = *tr = ALG_UNKNOWN;
+  len = strlen(tmp);
+  for (i = 0; alg_list[i]; i++) {
+    lpiece = lff = lfr = ltf = ltr = ALG_UNKNOWN;
+    if (strlen(alg_list[i]) != len)
+      continue;
+    for (j = len - 1; j >= 0; j--) {
+      switch (alg_list[i][j]) {
+      case 'f':
+	if ((tmp[j] < 'a') || (tmp[j] > 'h'))
+	  goto nomatch;
+	if (ltf == ALG_UNKNOWN)
+	  ltf = tmp[j] - 'a';
+	else
+	  lff = tmp[j] - 'a';
+	break;
+      case 'r':
+	if ((tmp[j] < '1') || (tmp[j] > '8'))
+	  goto nomatch;
+	if (ltr == ALG_UNKNOWN)
+	  ltr = tmp[j] - '1';
+	else
+	  lfr = tmp[j] - '1';
+	break;
+      case 'p':
+	if (isupper(tmp[j]))
+	  c = tolower(tmp[j]);
 	else
-		return MS_NOTMOVE;
+	  c = tmp[j];
+	if (c == 'k')
+	  lpiece = KING;
+	else if (c == 'q')
+	  lpiece = QUEEN;
+	else if (c == 'r')
+	  lpiece = ROOK;
+	else if (c == 'b')
+	  lpiece = BISHOP;
+	else if (c == 'n')
+	  lpiece = KNIGHT;
+	else if (c == 'p')
+	  lpiece = PAWN;
+	else
+	  goto nomatch;
+	break;
+      case 'x':
+	if ((tmp[j] != 'x') && (tmp[j] != 'X'))
+	  goto nomatch;
+	break;
+      case '@':
+	if (tmp[j] != '@' && tmp[j] != '*')
+	  goto nomatch;
+	lff = lfr = ALG_DROP;
+	break;
+      case '#':
+	if (tmp[j] != '#')
+	  goto nomatch;
+	lff = lfr = ALG_DROP;
+	break;
+      default:
+	fprintf(stderr, "Unknown character in algebraic parsing\n");
+	break;
+      }
+    }
+    if (lpiece == ALG_UNKNOWN)
+      lpiece = PAWN;
+    if (lpiece == PAWN && (lfr == ALG_UNKNOWN)) {	/* ffr or ff */
+      if (lff != ALG_UNKNOWN) {
+	if (lff == ltf)
+	  goto nomatch;
+	if ((lff - ltf != 1) && (ltf - lff != 1))
+	  goto nomatch;
+      }
+    }
+    *piece = lpiece;		/* We have a match */
+    *tf = ltf;
+    *tr = ltr;
+    *ff = lff;
+    *fr = lfr;
+    if (matchVal != -1) {
+      /* We have two matches, it must be that Bxc4 vs. bxc4 problem */
+      /* Or it could be the Bc4 vs bc4 problem */
+      *bishconfusion = 1;
+    }
+    matchVal = i;
+nomatch:;
+  }
+  if (matchVal != -1)
+    return MS_ALG;
+  else
+    return MS_NOTMOVE;
 }
 
-PUBLIC int
-alg_is_move(char *mstr)
+PUBLIC int alg_is_move(char *mstr)
 {
-	int piece, ff, fr, tf, tr, bc;
+  int piece, ff, fr, tf, tr, bc;
 
-	return get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc);
+  return get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc);
 }
 
-/*
- * We already know it is algebraic. Get the move squares.
- */
-PUBLIC int
-alg_parse_move(char *mstr, game_state_t *gs, move_t *mt)
+/* We already know it is algebraic, get the move squares */
+PUBLIC int alg_parse_move(char *mstr, game_state_t * gs, move_t * mt)
 {
-	int	f, r, tmpr, posf, posr, posr2;
-	int	piece, ff, fr, tf, tr, bc;
-
-	if (get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc) != MS_ALG) {
-		fprintf(stderr, "FICS: Shouldn't try to algebraically parse "
-		    "non-algebraic move string.\n");
-		return MOVE_ILLEGAL;
-	}
-
-	if (tf == ALG_UNKNOWN)
-		return MOVE_AMBIGUOUS; /* Must always know to file */
-
-	if (tr == ALG_UNKNOWN) {
-		posr = posr2 = ALG_UNKNOWN;
-
-		if (piece != PAWN)
-			return MOVE_AMBIGUOUS;
-		if (ff == ALG_UNKNOWN)
-			return MOVE_AMBIGUOUS;
-
-		/*
-		 * Need to find pawn on ff that can take to tf and
-		 * fill in ranks.
-		 */
-		for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
-		     NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
-			if (ff != ALG_UNKNOWN && ff != f)
-				continue;
-			if (piecetype(gs->board[f][r]) != piece)
-				continue;
-
-			if (gs->onMove == WHITE) {
-				tmpr = r + 1;
-			} else {
-				tmpr = r - 1;
-			}
-
-			if (gs->board[tf][tmpr] == NOPIECE) {
-				const int is_black = (gs->onMove == WHITE ?
-				    0 : 1);
-
-				if (gs->ep_possible[is_black][ff] != (tf - ff))
-					continue;
-			} else {
-				if (iscolor(gs->board[tf][tmpr], gs->onMove))
-					continue;
-			}
-
-			if (legal_andcheck_move(gs, f, r, tf, tmpr)) {
-				if (posr != ALG_UNKNOWN && posr2 != ALG_UNKNOWN)
-					return MOVE_AMBIGUOUS;
-
-				posr = tmpr;
-				posr2 = r;
-			}
-		}
-
-		tr = posr;
-		fr = posr2;
-	} else if (bc) { /* Could be bxc4 or Bxc4, tr is known. */
-		ff = ALG_UNKNOWN;
-		fr = ALG_UNKNOWN;
-
-		for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
-		     NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
-			if (piecetype(gs->board[f][r]) != PAWN &&
-			    piecetype(gs->board[f][r]) != BISHOP)
-				continue;
-			if (legal_andcheck_move(gs, f, r, tf, tr)) {
-				if (piecetype(gs->board[f][r]) == PAWN &&
-				    f != 1)
-					continue;
-				if (ff != ALG_UNKNOWN && fr != ALG_UNKNOWN)
-					return (MOVE_AMBIGUOUS);
-
-				ff = f;
-				fr = r;
-			}
-		}
-	} else {	/* The from position is unknown */
-		posf = ALG_UNKNOWN;
-		posr = ALG_UNKNOWN;
-
-		if (ff == ALG_UNKNOWN || fr == ALG_UNKNOWN) {
-			/*
-			 * Need to find a piece that can go to tf, tr.
-			 */
-			for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
-			     NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
-				if (ff != ALG_UNKNOWN && ff != f)
-					continue;
-				if (fr != ALG_UNKNOWN && fr != r)
-					continue;
-				if (piecetype(gs->board[f][r]) != piece)
-					continue;
-
-				if (legal_andcheck_move(gs, f, r, tf, tr)) {
-					if (posf != ALG_UNKNOWN &&
-					    posr != ALG_UNKNOWN)
-						return MOVE_AMBIGUOUS;
-
-					posf = f;
-					posr = r;
-				}
-			}
-		} else if (ff == ALG_DROP) {
-			if (legal_andcheck_move(gs, ALG_DROP, piece, tf, tr)) {
-				posf = ALG_DROP;
-				posr = piece;
-			}
-		}
-
-		ff = posf;
-		fr = posr;
+  int f, r, tmpr, posf, posr, posr2;
+  int piece, ff, fr, tf, tr, bc;
+
+  if (get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc) != MS_ALG) {
+    fprintf(stderr, "FICS: Shouldn't try to algebraicly parse non-algabraic move string.\n");
+    return MOVE_ILLEGAL;
+  }
+  /* Resolve ambiguities in to-ness */
+  if (tf == ALG_UNKNOWN)
+    return MOVE_AMBIGUOUS;	/* Must always know to file */
+  if (tr == ALG_UNKNOWN) {
+    posr = posr2 = ALG_UNKNOWN;
+    if (piece != PAWN)
+      return MOVE_AMBIGUOUS;
+    if (ff == ALG_UNKNOWN)
+      return MOVE_AMBIGUOUS;
+    /* Need to find pawn on ff that can take to tf and fill in ranks */
+    for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+	 NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+      if ((ff != ALG_UNKNOWN) && (ff != f))
+	continue;
+      if (piecetype(gs->board[f][r]) != piece)
+	continue;
+      if (gs->onMove == WHITE) {
+	tmpr = r + 1;
+      } else {
+	tmpr = r - 1;
+      }
+/*      if ((gs->board[tf][tmpr] == NOPIECE) ||
+          (iscolor(gs->board[tf][tmpr], gs->onMove))) continue;*/
+/* patch from Soso, added by Sparky 3/16/95                    */
+      if (gs->board[tf][tmpr] == NOPIECE) {
+	if ((gs->ep_possible[((gs->onMove == WHITE) ? 0 : 1)][ff]) != (tf - ff))
+	  continue;
+      } else {
+	if (iscolor(gs->board[tf][tmpr], gs->onMove))
+	  continue;
+      }
+
+      if (legal_andcheck_move(gs, f, r, tf, tmpr)) {
+	if ((posr != ALG_UNKNOWN) && (posr2 != ALG_UNKNOWN))
+	  return MOVE_AMBIGUOUS;
+	posr = tmpr;
+	posr2 = r;
+      }
+    }
+    tr = posr;
+    fr = posr2;
+  } else if (bc) {		/* Could be bxc4 or Bxc4, tr is known */
+    ff = ALG_UNKNOWN;
+    fr = ALG_UNKNOWN;
+    for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+	 NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+      if ((piecetype(gs->board[f][r]) != PAWN) && (piecetype(gs->board[f][r]) != BISHOP))
+	continue;
+      if (legal_andcheck_move(gs, f, r, tf, tr)) {
+	if ((piecetype(gs->board[f][r]) == PAWN) && (f != 1))
+	  continue;
+	if ((ff != ALG_UNKNOWN) && (fr != ALG_UNKNOWN))
+	  return (MOVE_AMBIGUOUS);
+	ff = f;
+	fr = r;
+      }
+    }
+  } else {			/* The from position is unknown */
+    posf = ALG_UNKNOWN;
+    posr = ALG_UNKNOWN;
+    if ((ff == ALG_UNKNOWN) || (fr == ALG_UNKNOWN)) {
+      /* Need to find a piece that can go to tf, tr */
+      for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+	   NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+	if ((ff != ALG_UNKNOWN) && (ff != f))
+	  continue;
+	if ((fr != ALG_UNKNOWN) && (fr != r))
+	  continue;
+	if (piecetype(gs->board[f][r]) != piece)
+	  continue;
+	if (legal_andcheck_move(gs, f, r, tf, tr)) {
+	  if ((posf != ALG_UNKNOWN) && (posr != ALG_UNKNOWN))
+	    return MOVE_AMBIGUOUS;
+	  posf = f;
+	  posr = r;
 	}
-
-	if (tf == ALG_UNKNOWN || tr == ALG_UNKNOWN || ff == ALG_UNKNOWN ||
-	    fr == ALG_UNKNOWN)
-		return MOVE_ILLEGAL;
-
-	mt->fromFile = ff;
-	mt->fromRank = fr;
-	mt->toFile = tf;
-	mt->toRank = tr;
-
-	return MOVE_OK;
+      }
+    } else if (ff == ALG_DROP) {
+      if (legal_andcheck_move(gs, ALG_DROP, piece, tf, tr)) {
+	posf = ALG_DROP;
+	posr = piece;
+      }
+    }
+    ff = posf;
+    fr = posr;
+  }
+  if ((tf == ALG_UNKNOWN) || (tr == ALG_UNKNOWN) ||
+      (ff == ALG_UNKNOWN) || (fr == ALG_UNKNOWN))
+    return MOVE_ILLEGAL;
+  mt->fromFile = ff;
+  mt->fromRank = fr;
+  mt->toFile = tf;
+  mt->toRank = tr;
+  return MOVE_OK;
 }
 
-PRIVATE void
-not_pawn(game_state_t *gs, move_t *mt, game_state_t *fakeMove, const int piece,
-	 char *tmp, char *mStr, size_t tmp_size, size_t mStr_size)
+/* A assumes the move has yet to be made on the board */
+/* this is the old stupid function, we are testing one from soso...
+PUBLIC char *alg_unparse( game_state_t *gs, move_t *mt )
 {
-	int ambig, r_ambig, f_ambig;
-
-	ambig = r_ambig = f_ambig = 0;
-
-	for (int r = 0; r < 8; r++) {
-		for (int f = 0; f < 8; f++) {
-			if (gs->board[f][r] != NOPIECE &&
-			    iscolor(gs->board[f][r], gs->onMove) &&
-			    piecetype(gs->board[f][r]) == piece &&
-			    (f != mt->fromFile || r != mt->fromRank)) {
-				if (legal_move(gs, f, r, mt->toFile,
-				    mt->toRank)) {
-					fakeMove = gs;
-					fakeMove->board[f][r] = NOPIECE;
-					fakeMove->onMove =
-					    CToggle(fakeMove->onMove);
-					gs->onMove = CToggle(gs->onMove);
-
-					/*
-					 * New bracketing below to try
-					 * to fix 'ambiguous move'
-					 * bug.
-					 */
-
-					if (in_check(gs) || !in_check(fakeMove))
-						ambig++;
-
-					if (f == mt->fromFile) {
-						f_ambig++;
-						ambig++;
-					}
-					if (r == mt->fromRank) {
-						r_ambig++;
-						ambig++;
-					}
-
-					gs->onMove = CToggle(gs->onMove);
-				}
-			}
-		} /* for */
-	} /* for */
-
-	if (ambig > 0) {
-		/*
-		 * Ambiguity in short notation. Need to add file, rank
-		 * or _both_ in notation.
-		 */
-
-		if (f_ambig == 0) {
-			snprintf(tmp, tmp_size, "%c", (mt->fromFile + 'a'));
-			strlcat(mStr, tmp, mStr_size);
-		} else if (r_ambig == 0) {
-			snprintf(tmp, tmp_size, "%d", (mt->fromRank + 1));
-			strlcat(mStr, tmp, mStr_size);
-		} else {
-			snprintf(tmp, tmp_size, "%c%d",
-			    (mt->fromFile + 'a'),
-			    (mt->fromRank + 1));
-			strlcat(mStr, tmp, mStr_size);
-		}
-	}
+  static char mStr[20];
+
+  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+       ((mt->fromFile == 4) && (mt->toFile == 6)) )
+    return "o-o";
+  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+       ((mt->fromFile == 4) && (mt->toFile == 2)) )
+    return "o-o-o";
+
+  sprintf( mStr, "%c%d%c%d", mt->fromFile+'a', mt->fromRank+1,
+                                       mt->toFile+'a', mt->toRank+1 );
+  return mStr;
 }
+*/
 
-/*
- * Soso: rewrote alg_unparse function.  Algebraic deparser - sets the
- * 'mStr' variable with move description in short notation. Used in
- * last move report and in 'moves' command.
- */
-PUBLIC char *
-alg_unparse(game_state_t *gs, move_t *mt)
-{
-	char		tmp[20] = { '\0' };
-	game_state_t	fakeMove;
-	int		piece;
-	size_t		ret = 0;
-	static char	mStr[20] = { '\0' };
-
-	if (mt->fromFile == ALG_DROP) {
-		piece = mt->fromRank;
-	} else {
-		piece = piecetype(gs->board[mt->fromFile][mt->fromRank]);
-	}
-
-	if (piece == KING && (mt->fromFile == 4 && mt->toFile == 6)) {
-		strlcpy(mStr, "O-O", sizeof mStr);
-		goto check;
-	}
-
-	if (piece == KING && (mt->fromFile == 4 && mt->toFile == 2)) {
-		strlcpy(mStr, "O-O-O", sizeof mStr);
-		goto check;
-	}
-
-	mStr[0] = '\0';
-
-	switch (piece) {
-	case PAWN:
-		if (mt->fromFile == ALG_DROP) {
-			strlcpy(mStr, "P", sizeof mStr);
-		} else if (mt->fromFile != mt->toFile) {
-			snprintf(tmp, sizeof tmp, "%c", (mt->fromFile + 'a'));
-			strlcpy(mStr, tmp, sizeof mStr);
-		}
-		break;
-	case KNIGHT:
-		strlcpy(mStr, "N", sizeof mStr);
-		break;
-	case BISHOP:
-		strlcpy(mStr, "B", sizeof mStr);
-		break;
-	case ROOK:
-		strlcpy(mStr, "R", sizeof mStr);
-		break;
-	case QUEEN:
-		strlcpy(mStr, "Q", sizeof mStr);
-		break;
-	case KING:
-		strlcpy(mStr, "K", sizeof mStr);
-		break;
-	default:
-		strlcpy(mStr, "", sizeof mStr);
-		break;
-	} /* switch */
-
-	if (mt->fromFile == ALG_DROP) {
-		strlcat(mStr, DROP_STR, sizeof mStr);
-	} else {
-		/*
-		 * Checks for ambiguity in short notation (Ncb3, R8e8
-		 * or so.)
-		 */
-
-		if (piece != PAWN) {
-			not_pawn(gs, mt, &fakeMove, piece, &tmp[0], &mStr[0],
-			    sizeof tmp, sizeof mStr);
-		} /* not pawn */
-
-		if (gs->board[mt->toFile][mt->toRank] != NOPIECE ||
-		    (piece == PAWN && mt->fromFile != mt->toFile))
-			strlcat(mStr, "x", sizeof mStr);
-	}
-
-	snprintf(tmp, sizeof tmp, "%c%d", (mt->toFile + 'a'), (mt->toRank + 1));
-	ret = strlcat(mStr, tmp, sizeof mStr);
-
-	if (ret >= sizeof mStr) {
-		fprintf(stderr, "FICS: %s (line %d): warning: "
-		    "strlcat() truncated\n", __func__, __LINE__);
-	}
-
-	if (piece == PAWN && mt->piecePromotionTo != NOPIECE) {
-		strlcat(mStr, "=", sizeof mStr); /* = before promoting piece */
-
-		switch (piecetype(mt->piecePromotionTo)) {
-		case KNIGHT:
-			strlcat(mStr, "N", sizeof mStr);
-			break;
-		case BISHOP:
-			strlcat(mStr, "B", sizeof mStr);
-			break;
-		case ROOK:
-			strlcat(mStr, "R", sizeof mStr);
-			break;
-		case QUEEN:
-			strlcat(mStr, "Q", sizeof mStr);
-			break;
-		default:
-			break;
-		}
-	}
 
-  check:;
+/* A assumes the move has yet to be made on the board */
 
-	fakeMove = *gs;
-	execute_move(&fakeMove, mt, 0);
-	fakeMove.onMove = CToggle(fakeMove.onMove);
 
-	if (in_check(&fakeMove)) {
-		ret = strlcat(mStr, "+", sizeof mStr);
+/* Soso: rewrote alg_unparse function.
+ * Algebraic deparser - sets the mStr variable with move description
+ * in short notation. Used in last move report and in 'moves' command.
+ */
 
-		if (ret >= sizeof mStr) {
-			fprintf(stderr, "FICS: %s (line %d): warning: "
-			    "strlcat() truncated\n", __func__, __LINE__);
-		}
+PUBLIC char *alg_unparse(game_state_t * gs, move_t * mt)
+{
+  static char mStr[20];
+  char tmp[20];
+  int piece, f, r;
+  int ambig, r_ambig, f_ambig;
+  game_state_t fakeMove;
+
+  if (mt->fromFile == ALG_DROP) {
+    piece = mt->fromRank;
+  } else {
+    piece = piecetype(gs->board[mt->fromFile][mt->fromRank]);
+  }
+
+  if ((piece == KING) && ((mt->fromFile == 4) && (mt->toFile == 6))) {
+    strcpy(mStr, "O-O");
+    goto check;
+  }
+  if ((piece == KING) && ((mt->fromFile == 4) && (mt->toFile == 2))) {
+    strcpy(mStr, "O-O-O");
+    goto check;
+  }
+  strcpy(mStr, "");
+  switch (piece) {
+  case PAWN:
+    if (mt->fromFile == ALG_DROP) {
+      strcpy(mStr,"P");
+    } else if (mt->fromFile != mt->toFile) {
+      sprintf(tmp, "%c", mt->fromFile + 'a');
+      strcpy(mStr, tmp);
+    }
+    break;
+  case KNIGHT:
+    strcpy(mStr, "N");
+    break;
+  case BISHOP:
+    strcpy(mStr, "B");
+    break;
+  case ROOK:
+    strcpy(mStr, "R");
+    break;
+  case QUEEN:
+    strcpy(mStr, "Q");
+    break;
+  case KING:
+    strcpy(mStr, "K");
+    break;
+  default:
+    strcpy(mStr, "");
+    break;
+  }
+
+  if (mt->fromFile == ALG_DROP) {
+    strcat(mStr, DROP_STR);
+  } else {
+  /* Checks for ambiguity in short notation ( Ncb3, R8e8 or so) */
+  if (piece != PAWN) {
+    ambig = r_ambig = f_ambig = 0;
+    for (r = 0; r < 8; r++)
+      for (f = 0; f < 8; f++) {
+	if ((gs->board[f][r] != NOPIECE) && iscolor(gs->board[f][r], gs->onMove)
+	    && (piecetype(gs->board[f][r]) == piece) &&
+	    ((f != mt->fromFile) || (r != mt->fromRank))) {
+	  if (legal_move(gs, f, r, mt->toFile, mt->toRank)) {
+	    fakeMove = *gs;
+	    fakeMove.board[f][r] = NOPIECE;
+	    fakeMove.onMove = CToggle(fakeMove.onMove);
+	    gs->onMove = CToggle(gs->onMove);
+
+            /* New bracketing below to try to fix 'ambiguous move' bug. */
+	    if ((in_check(gs)) || !in_check(&fakeMove)) {
+	      ambig++;
+	    }
+	    if (f == mt->fromFile) {
+	      f_ambig++;
+	      ambig++;
+	    }
+	    if (r == mt->fromRank) {
+	      r_ambig++;
+	      ambig++;
+	    }
+	    gs->onMove = CToggle(gs->onMove);
+	  }
 	}
-
-	return mStr;
+      }
+    if (ambig > 0) {
+      /* Ambiguity in short notation, need to add file,rank or _both_ in
+         notation */
+      if (f_ambig == 0) {
+	sprintf(tmp, "%c", mt->fromFile + 'a');
+	strcat(mStr, tmp);
+      } else if (r_ambig == 0) {
+	sprintf(tmp, "%d", mt->fromRank + 1);
+	strcat(mStr, tmp);
+      } else {
+	sprintf(tmp, "%c%d", mt->fromFile + 'a', mt->fromRank + 1);
+	strcat(mStr, tmp);
+      }
+    }
+  }
+  if ((gs->board[mt->toFile][mt->toRank] != NOPIECE) ||
+      ((piece == PAWN) && (mt->fromFile != mt->toFile))) {
+    strcat(mStr, "x");
+  }
+  }
+  sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1);
+  strcat(mStr, tmp);
+
+  if ((piece == PAWN) && (mt->piecePromotionTo != NOPIECE)) {
+    strcat(mStr, "=");		/* = before promoting piece */
+    switch (piecetype(mt->piecePromotionTo)) {
+    case KNIGHT:
+      strcat(mStr, "N");
+      break;
+    case BISHOP:
+      strcat(mStr, "B");
+      break;
+    case ROOK:
+      strcat(mStr, "R");
+      break;
+    case QUEEN:
+      strcat(mStr, "Q");
+      break;
+    default:
+      break;
+    }
+  }
+check:;
+  fakeMove = *gs;
+  execute_move(&fakeMove, mt, 0);
+  fakeMove.onMove = CToggle(fakeMove.onMove);
+  if (in_check(&fakeMove)) {
+    strcat(mStr, "+");
+  }
+  return mStr;
 }
diff --git a/FICS/algcheck.h b/FICS/algcheck.h
index 8f7bda7..60d971b 100644
--- a/FICS/algcheck.h
+++ b/FICS/algcheck.h
@@ -29,13 +29,13 @@
 #include "board.h"
 #endif
 
-#define ALG_UNKNOWN -1
+#define DROP_CHAR '@'	/* used by algcheck.c and movecheck.c */
+#define DROP_STR  "@"
 
-#define DROP_CHAR	'@' /* used by algcheck.c and movecheck.c */
-#define DROP_STR	"@"
+extern int alg_is_move(char *);
+extern int alg_parse_move(char *, game_state_t *, move_t *);
+extern char *alg_unparse(game_state_t *, move_t *);
 
-extern char	*alg_unparse(game_state_t *, move_t *);
-extern int	 alg_is_move(char *);
-extern int	 alg_parse_move(char *, game_state_t *, move_t *);
+/* extern int tolower(); */
 
 #endif /* _ALGCHECK_H */
diff --git a/FICS/movecheck.c b/FICS/movecheck.c
index 872814a..3cb109f 100644
--- a/FICS/movecheck.c
+++ b/FICS/movecheck.c
@@ -23,760 +23,631 @@
    Markus Uhlin                 23/12/14	Fixed compiler warnings
    Markus Uhlin                 23/12/17	Fixed compiler warnings
    Markus Uhlin                 23/12/24	Fixed dead assignment
-   Markus Uhlin                 24/03/16	Refactored and reformatted
-						functions.
-   Markus Uhlin                 24/03/17	Replaced sprintf() calls
 */
 
 #include "stdinclude.h"
-#include "common.h"
 
 #include "algcheck.h"
 #include "board.h"
+#include "common.h"
 #include "gamedb.h"
 #include "movecheck.h"
 #include "network.h"
 #include "playerdb.h"
 #include "utils.h"
 
-#if __linux__
-#include <bsd/string.h>
-#endif
-
-/*
- * Simply tests if the input string is a move or not. If it matches
- * patterns below. Add to this list as you improve the move parser.
- *
- *   - MS_COMP e2e4
- *   - MS_COMPDASH e2-e4
- *   - MS_CASTLE o-o, o-o-o
- *
- * Not done yet
- * MS_ALG e4, Nd5 Ncd5
- */
-PUBLIC int
-is_move(char *mstr)
+/* Simply tests if the input string is a move or not. */
+/* If it matches patterns below */
+/* Add to this list as you improve the move parser */
+/* MS_COMP e2e4 */
+/* MS_COMPDASH e2-e4 */
+/* MS_CASTLE o-o, o-o-o */
+/* Not done yet */
+/* MS_ALG e4, Nd5 Ncd5 */
+PUBLIC int is_move(char *mstr)
 {
-	int	len = strlen(mstr);
-
-	if (len > 3 && mstr[len - 2] == '=')
-		len -= 2;
-
-	if (len == 4) {       // Test for e2e4
-		if (isfile(mstr[0]) && isrank(mstr[1]) &&
-		    isfile(mstr[2]) && isrank(mstr[3]))
-			return MS_COMP;
-	}
-
-	if (len == 5) {       // Test for e2-e4
-		if (isfile(mstr[0]) &&
-		    isrank(mstr[1]) &&
-		    mstr[2] == '-' &&
-		    isfile(mstr[3]) &&
-		    isrank(mstr[4]))
-			return MS_COMPDASH;
-	}
-
-	if (len == 3) {       // Test for o-o
-		if (mstr[0] == 'o' && mstr[1] == '-' && mstr[2] == 'o')
-			return MS_KCASTLE;
-		if (mstr[0] == 'O' && mstr[1] == '-' && mstr[2] == 'O')
-			return MS_KCASTLE;
-		if (mstr[0] == '0' && mstr[1] == '-' && mstr[2] == '0')
-			return MS_KCASTLE;
-	}
-
-	if (len == 2) {       // Test for oo
-		if (mstr[0] == 'o' && mstr[1] == 'o')
-			return MS_KCASTLE;
-		if (mstr[0] == 'O' && mstr[1] == 'O')
-			return MS_KCASTLE;
-		if (mstr[0] == '0' && mstr[1] == '0')
-			return MS_KCASTLE;
-	}
-
-	if (len == 5) {       // Test for o-o-o
-		if (mstr[0] == 'o' && mstr[1] == '-' && mstr[2] == 'o' &&
-		    mstr[3] == '-' && mstr[4] == 'o')
-			return MS_QCASTLE;
-		if (mstr[0] == 'O' && mstr[1] == '-' && mstr[2] == 'O' &&
-		    mstr[3] == '-' && mstr[4] == 'O')
-			return MS_QCASTLE;
-		if (mstr[0] == '0' && mstr[1] == '-' && mstr[2] == '0' &&
-		    mstr[3] == '-' && mstr[4] == '0')
-			return MS_QCASTLE;
-	}
-
-	if (len == 3) {       // Test for ooo
-		if (mstr[0] == 'o' && mstr[1] == 'o' && mstr[2] == 'o')
-			return MS_QCASTLE;
-		if (mstr[0] == 'O' && mstr[1] == 'O' && mstr[2] == 'O')
-			return MS_QCASTLE;
-		if (mstr[0] == '0' && mstr[1] == '0' && mstr[2] == '0')
-			return MS_QCASTLE;
-	}
-
-	return alg_is_move(mstr);
+  int len = strlen(mstr);
+  if ((len > 3) && (mstr[len - 2] == '='))
+    len -= 2;
+
+  if (len == 4) {		/* Test for e2e4 */
+    if (isfile(mstr[0]) && isrank(mstr[1]) &&
+	isfile(mstr[2]) && isrank(mstr[3])) {
+      return MS_COMP;
+    }
+  }
+  if (len == 5) {		/* Test for e2-e4 */
+    if (isfile(mstr[0]) && isrank(mstr[1]) &&
+	(mstr[2] == '-') &&
+	isfile(mstr[3]) && isrank(mstr[4])) {
+      return MS_COMPDASH;
+    }
+  }
+  if (len == 3) {		/* Test for o-o */
+    if ((mstr[0] == 'o') && (mstr[1] == '-') && (mstr[2] == 'o')) {
+      return MS_KCASTLE;
+    }
+    if ((mstr[0] == 'O') && (mstr[1] == '-') && (mstr[2] == 'O')) {
+      return MS_KCASTLE;
+    }
+    if ((mstr[0] == '0') && (mstr[1] == '-') && (mstr[2] == '0')) {
+      return MS_KCASTLE;
+    }
+  }
+  if (len == 2) {		/* Test for oo */
+    if ((mstr[0] == 'o') && (mstr[1] == 'o')) {
+      return MS_KCASTLE;
+    }
+    if ((mstr[0] == 'O') && (mstr[1] == 'O')) {
+      return MS_KCASTLE;
+    }
+    if ((mstr[0] == '0') && (mstr[1] == '0')) {
+      return MS_KCASTLE;
+    }
+  }
+  if (len == 5) {		/* Test for o-o-o */
+    if ((mstr[0] == 'o') && (mstr[1] == '-') && (mstr[2] == 'o') && (mstr[3] == '-') && (mstr[4] == 'o')) {
+      return MS_QCASTLE;
+    }
+    if ((mstr[0] == 'O') && (mstr[1] == '-') && (mstr[2] == 'O') && (mstr[3] == '-') && (mstr[4] == 'O')) {
+      return MS_QCASTLE;
+    }
+    if ((mstr[0] == '0') && (mstr[1] == '-') && (mstr[2] == '0') && (mstr[3] == '-') && (mstr[4] == '0')) {
+      return MS_QCASTLE;
+    }
+  }
+  if (len == 3) {		/* Test for ooo */
+    if ((mstr[0] == 'o') && (mstr[1] == 'o') && (mstr[2] == 'o')) {
+      return MS_QCASTLE;
+    }
+    if ((mstr[0] == 'O') && (mstr[1] == 'O') && (mstr[2] == 'O')) {
+      return MS_QCASTLE;
+    }
+    if ((mstr[0] == '0') && (mstr[1] == '0') && (mstr[2] == '0')) {
+      return MS_QCASTLE;
+    }
+  }
+  return alg_is_move(mstr);
 }
 
-PUBLIC int
-NextPieceLoop(board_t b, int *f, int *r, int color)
-{
-	while (1) {
-		(*r) = (*r) + 1;
-
-		if (*r > 7) {
-			*r = 0;
-			*f = *f + 1;
-
-			if (*f > 7)
-				break;
-		}
 
-		if (b[*f][*r] != NOPIECE && iscolor(b[*f][*r], color))
-			return 1;
-	}
-
-	return 0;
+PUBLIC int NextPieceLoop(board_t b, int *f, int *r, int color)
+{
+  while (1) {
+    (*r) = (*r) + 1;
+    if (*r > 7) {
+      *r = 0;
+      *f = *f + 1;
+      if (*f > 7)
+	break;
+    }
+    if ((b[*f][*r] != NOPIECE) && iscolor(b[*f][*r], color))
+      return 1;
+  }
+  return 0;
 }
 
-PUBLIC int
-InitPieceLoop(board_t b, int *f, int *r, int color)
+PUBLIC int InitPieceLoop(board_t b, int *f, int *r, int color)
 {
-	*f = 0;
-	*r = -1;
-
-	/* XXX: not referenced */
-	(void) b;
-	(void) color;
-	return 1;
+  *f = 0;
+  *r = -1;
+  return 1;
 }
 
-/*
- * All of the routines assume that the obvious problems have been
- * checked. See legal_move().
- */
-PRIVATE int
-legal_pawn_move(game_state_t *gs, int ff, int fr, int tf, int tr)
+/* All of the routines assume that the obvious problems have been checked */
+/* See legal_move() */
+PRIVATE int legal_pawn_move( game_state_t *gs, int ff, int fr, int tf, int tr )
 {
-	if (ff == tf) {
-		if (gs->board[tf][tr] != NOPIECE)
-			return 0;
-
-		if (gs->onMove == WHITE) {
-			if (tr - fr == 1)
-				return 1;
-			if (fr == 1 &&
-			    (tr - fr) == 2 &&
-			    gs->board[ff][2] == NOPIECE)
-				return 1;
-		} else {
-			if (fr - tr == 1)
-				return 1;
-			if (fr == 6 &&
-			    (fr - tr) == 2 &&
-			    gs->board[ff][5] == NOPIECE)
-				return 1;
-		}
-
-		return 0;
-	}
-
-	if (ff != tf) {  // Capture ?
-		if ((ff - tf) != 1 && (tf - ff) != 1)
-			return 0;
-		if ((fr - tr) != 1 && (tr - fr) != 1)
-			return 0;
-
-		if (gs->onMove == WHITE) {
-			if (fr > tr)
-				return 0;
-			if (gs->board[tf][tr] != NOPIECE &&
-			    iscolor(gs->board[tf][tr], BLACK))
-				return 1;
-
-			if (gs->ep_possible[0][ff] == 1) {
-				if (tf == (ff + 1) && gs->board[ff + 1][fr] ==
-				    B_PAWN)
-					return 1;
-			} else if (gs->ep_possible[0][ff] == -1) {
-				if (tf == (ff - 1) && gs->board[ff - 1][fr] ==
-				    B_PAWN)
-					return 1;
-			}
-		} else {
-			if (tr > fr)
-				return 0;
-			if (gs->board[tf][tr] != NOPIECE &&
-			    iscolor(gs->board[tf][tr], WHITE))
-				return 1;
-
-			if (gs->ep_possible[1][ff] == 1) {
-				if (tf == (ff + 1) && gs->board[ff + 1][fr] ==
-				    W_PAWN)
-					return 1;
-			} else if (gs->ep_possible[1][ff] == -1) {
-				if (tf == (ff - 1) && gs->board[ff - 1][fr] ==
-				    W_PAWN)
-					return 1;
-			}
-		}
-	}
-
-	return 0;
+  if (ff == tf) {
+    if (gs->board[tf][tr] != NOPIECE) return 0;
+    if (gs->onMove == WHITE) {
+      if (tr - fr == 1) return 1;
+      if ((fr == 1) && (tr - fr == 2) && gs->board[ff][2]==NOPIECE) return 1;
+    } else {
+      if (fr - tr == 1) return 1;
+      if ((fr == 6) && (fr - tr == 2) && gs->board[ff][5]==NOPIECE) return 1;
+    }
+    return 0;
+  }
+  if (ff != tf) { /* Capture ? */
+    if ((ff - tf != 1) && (tf - ff != 1)) return 0;
+    if ((fr - tr != 1) && (tr - fr != 1)) return 0;
+    if (gs->onMove == WHITE) {
+      if (fr > tr) return 0;
+      if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],BLACK))
+        return 1;
+      if (gs->ep_possible[0][ff] == 1) {
+        if ((tf==ff+1) && (gs->board[ff+1][fr] == B_PAWN)) return 1;
+      } else if (gs->ep_possible[0][ff] == -1) {
+        if ((tf==ff-1) && (gs->board[ff-1][fr] == B_PAWN)) return 1;
+      }
+    } else {
+      if (tr > fr) return 0;
+      if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],WHITE))
+        return 1;
+      if (gs->ep_possible[1][ff] == 1) {
+        if ((tf==ff+1) && (gs->board[ff+1][fr] == W_PAWN)) return 1;
+      } else if (gs->ep_possible[1][ff] == -1) {
+        if ((tf==ff-1) && (gs->board[ff-1][fr] == W_PAWN)) return 1;
+      }
+    }
+  }
+  return 0;
 }
 
-PRIVATE int
-legal_knight_move(game_state_t *gs, int ff, int fr, int tf, int tr)
+PRIVATE int legal_knight_move(game_state_t * gs, int ff, int fr, int tf, int tr)
 {
-	int	dx, dy;
-
-	dx = ff - tf;
-	dy = fr - tr;
-
-	if (dx == 2 || dx == -2) {
-		if (dy == -1 || dy == 1)
-			return 1;
-	}
-	if (dy == 2 || dy == -2) {
-		if (dx == -1 || dx == 1)
-			return 1;
-	}
-
-	return 0;
+  int dx, dy;
+
+  dx = ff - tf;
+  dy = fr - tr;
+  if ((dx == 2) || (dx == -2)) {
+    if ((dy == -1) || (dy == 1))
+      return 1;
+  }
+  if ((dy == 2) || (dy == -2)) {
+    if ((dx == -1) || (dx == 1))
+      return 1;
+  }
+  return 0;
 }
 
-PRIVATE int
-legal_bishop_move(game_state_t *gs, int ff, int fr, int tf, int tr)
+PRIVATE int legal_bishop_move(game_state_t * gs, int ff, int fr, int tf, int tr)
 {
-	int	count;
-	int	dx, dy, x, y;
-	int	incx, incy;
-	int	startx, starty;
-
-	if (ff > tf) {
-		dx = ff - tf;
-		incx = -1;
-	} else {
-		dx = tf - ff;
-		incx = 1;
-	}
-
-	startx = ff + incx;
-
-	if (fr > tr) {
-		dy = fr - tr;
-		incy = -1;
-	} else {
-		dy = tr - fr;
-		incy = 1;
-	}
-
-	starty = fr + incy;
-
-	if (dx != dy)
-		return 0;	// Not diagonal
-	if (dx == 1)
-		return 1;	// One square, ok.
-
-	count = dx - 1;
-	x = startx;
-	y = starty;
-
-	while (count) {
-		if (gs->board[x][y] != NOPIECE)
-			return 0;
-		x += incx;
-		y += incy;
-		count--;
-	}
-
-	return 1;
+  int dx, dy, x, y;
+  int startx, starty;
+  int count;
+  int incx, incy;
+
+  if (ff > tf) {
+    dx = ff - tf;
+    incx = -1;
+  } else {
+    dx = tf - ff;
+    incx = 1;
+  }
+  startx = ff + incx;
+  if (fr > tr) {
+    dy = fr - tr;
+    incy = -1;
+  } else {
+    dy = tr - fr;
+    incy = 1;
+  }
+  starty = fr + incy;
+  if (dx != dy)
+    return 0;			/* Not diagonal */
+  if (dx == 1)
+    return 1;			/* One square, ok */
+  count = dx - 1;
+  for (x = startx, y = starty; count; x += incx, y += incy, count--) {
+    if (gs->board[x][y] != NOPIECE)
+      return 0;
+  }
+  return 1;
 }
 
-PRIVATE int
-legal_rook_move(game_state_t *gs, int ff, int fr, int tf, int tr)
+PRIVATE int legal_rook_move(game_state_t * gs, int ff, int fr, int tf, int tr)
 {
-	int	i;
-	int	start, stop;
-
-	if (ff == tf) {
-		if ((fr - tr) == 1 || (tr - fr) == 1)
-			return 1;
-		if (fr < tr) {
-			start = fr + 1;
-			stop = tr - 1;
-		} else {
-			start = tr + 1;
-			stop = fr - 1;
-		}
-
-		for (i = start; i <= stop; i++) {
-			if (gs->board[ff][i] != NOPIECE)
-				return 0;
-		}
-
-		return 1;
-	} else if (fr == tr) {
-		if ((ff - tf) == 1 || (tf - ff) == 1)
-			return 1;
-		if (ff < tf) {
-			start = ff + 1;
-			stop = tf - 1;
-		} else {
-			start = tf + 1;
-			stop = ff - 1;
-		}
-
-		for (i = start; i <= stop; i++) {
-			if (gs->board[i][fr] != NOPIECE)
-				return 0;
-		}
-
-		return 1;
-	}
-
+  int i;
+  int start, stop;
+
+  if (ff == tf) {
+    if (((fr - tr) == 1) || ((tr - fr) == 1))
+      return 1;
+    if (fr < tr) {
+      start = fr + 1;
+      stop = tr - 1;
+    } else {
+      start = tr + 1;
+      stop = fr - 1;
+    }
+    for (i = start; i <= stop; i++) {
+      if (gs->board[ff][i] != NOPIECE)
+	return 0;
+    }
+    return 1;
+  } else if (fr == tr) {
+    if (((ff - tf) == 1) || ((tf - ff) == 1))
+      return 1;
+    if (ff < tf) {
+      start = ff + 1;
+      stop = tf - 1;
+    } else {
+      start = tf + 1;
+      stop = ff - 1;
+    }
+    for (i = start; i <= stop; i++) {
+      if (gs->board[i][fr] != NOPIECE)
 	return 0;
+    }
+    return 1;
+  } else {
+    return 0;
+  }
 }
 
-PRIVATE int
-legal_queen_move(game_state_t *gs, int ff, int fr, int tf, int tr)
+PRIVATE int legal_queen_move(game_state_t * gs, int ff, int fr, int tf, int tr)
 {
-	return (legal_rook_move(gs, ff, fr, tf, tr) ||
-		legal_bishop_move(gs, ff, fr, tf, tr));
+  return legal_rook_move(gs, ff, fr, tf, tr) || legal_bishop_move(gs, ff, fr, tf, tr);
 }
 
-PRIVATE int
-is_square_attacked(game_state_t *gs, int kf, int kr)
-{
-	game_state_t fakeMove;
-
-	fakeMove		= *gs;
-	fakeMove.board[4][kr]	= NOPIECE;
-	fakeMove.board[kf][kr]	= (KING | fakeMove.onMove);
-	fakeMove.onMove		= CToggle(fakeMove.onMove);
+/* Ckeck, if square (kf,kr) is attacked by enemy piece.
+ * Used in castling from/through check testing.
+ */
 
-	if (in_check(&fakeMove))
-		return 1;
-	return 0;
+/* new one from soso: */
+PRIVATE int is_square_attacked (game_state_t *gs, int kf, int kr)
+{
+  game_state_t fakeMove;
+
+  fakeMove = *gs;
+  fakeMove.board[4][kr] = NOPIECE;
+  fakeMove.board[kf][kr] = KING | fakeMove.onMove;
+  fakeMove.onMove = CToggle (fakeMove.onMove);
+  if (in_check(&fakeMove)) return 1;
+    else return 0;
 }
 
-PRIVATE int
-legal_king_move(game_state_t *gs, int ff, int fr, int tf, int tr)
+/* old one:
+PRIVATE int is_square_attacked(game_state_t * gs, int kf, int kr)
 {
-	if (gs->onMove == WHITE) {
-		/* King side castling */
-		if (fr == 0 && tr == 0 && ff == 4 && tf == 6 &&
-		    !gs->wkmoved &&
-		    !gs->wkrmoved &&
-		    gs->board[5][0] == NOPIECE &&
-		    gs->board[6][0] == NOPIECE &&
-		    gs->board[7][0] == W_ROOK &&
-		    !is_square_attacked(gs, 4, 0) &&
-		    !is_square_attacked(gs, 5, 0))
-			return 1;
-
-		/* Queen side castling */
-		if (fr == 0 && tr == 0 && ff == 4 && tf == 2 &&
-		    !gs->wkmoved &&
-		    !gs->wqrmoved &&
-		    gs->board[3][0] == NOPIECE &&
-		    gs->board[2][0] == NOPIECE &&
-		    gs->board[1][0] == NOPIECE &&
-		    gs->board[0][0] == W_ROOK &&
-		    !is_square_attacked(gs, 4, 0) &&
-		    !is_square_attacked(gs, 3, 0))
-			return 1;
-	} else {	/* Black */
-		/* King side castling */
-		if (fr == 7 && tr == 7 && ff == 4 && tf == 6 &&
-		    !gs->bkmoved &&
-		    !gs->bkrmoved &&
-		    gs->board[5][7] == NOPIECE &&
-		    gs->board[6][7] == NOPIECE &&
-		    gs->board[7][7] == B_ROOK &&
-		    !is_square_attacked(gs, 4, 7) &&
-		    !is_square_attacked(gs, 5, 7))
-			return 1;
-
-		/* Queen side castling */
-		if (fr == 7 && tr == 7 && ff == 4 && tf == 2 &&
-		    !gs->bkmoved &&
-		    !gs->bqrmoved &&
-		    gs->board[3][7] == NOPIECE &&
-		    gs->board[2][7] == NOPIECE &&
-		    gs->board[1][7] == NOPIECE &&
-		    gs->board[0][7] == B_ROOK &&
-		    !is_square_attacked(gs, 4, 7) &&
-		    !is_square_attacked(gs, 3, 7))
-			return 1;
-	}
-
-	if ((ff - tf) > 1 ||
-	    (tf - ff) > 1)
-		return 0;
-	if ((fr - tr) > 1 ||
-	    (tr - fr) > 1)
-		return 0;
-
-	return 1;
+  int f, r;
+  gs->onMove = CToggle(gs->onMove);
+
+  for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+       NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+    if (legal_move(gs, f, r, kf, kr)) {
+      gs->onMove = CToggle(gs->onMove);
+      return 1;
+    }
+  }
+  gs->onMove = CToggle(gs->onMove);
+  return 0;
 }
+*/
 
-PRIVATE void
-add_pos(int tof, int tor, int *posf, int *posr, int *numpos)
+PRIVATE int legal_king_move(game_state_t * gs, int ff, int fr, int tf, int tr)
 {
-	posf[*numpos] = tof;
-	posr[*numpos] = tor;
-	(*numpos)++;
+  if (gs->onMove == WHITE) {
+    /* King side castling */
+    if ((fr == 0) && (tr == 0) && (ff == 4) && (tf == 6) && !gs->wkmoved
+	&& (!gs->wkrmoved) && (gs->board[5][0] == NOPIECE) &&
+	(gs->board[6][0] == NOPIECE) && (gs->board[7][0] == W_ROOK) &&
+	(!is_square_attacked(gs, 4, 0)) && (!is_square_attacked(gs, 5, 0))) {
+      return 1;
+    }
+    /* Queen side castling */
+    if ((fr == 0) && (tr == 0) && (ff == 4) && (tf == 2) && !gs->wkmoved
+	&& (!gs->wqrmoved) && (gs->board[3][0] == NOPIECE) &&
+	(gs->board[2][0] == NOPIECE) && (gs->board[1][0] == NOPIECE) &&
+	(gs->board[0][0] == W_ROOK) &&
+	(!is_square_attacked(gs, 4, 0)) && (!is_square_attacked(gs, 3, 0))) {
+      return 1;
+    }
+  } else {			/* Black */
+    /* King side castling */
+    if ((fr == 7) && (tr == 7) && (ff == 4) && (tf == 6) && !gs->bkmoved
+	&& (!gs->bkrmoved) && (gs->board[5][7] == NOPIECE) &&
+	(gs->board[6][7] == NOPIECE) && (gs->board[7][7] == B_ROOK) &&
+	(!is_square_attacked(gs, 4, 7)) && (!is_square_attacked(gs, 5, 7))) {
+      return 1;
+    }
+    /* Queen side castling */
+    if ((fr == 7) && (tr == 7) && (ff == 4) && (tf == 2) && (!gs->bkmoved)
+	&& (!gs->bqrmoved) && (gs->board[3][7] == NOPIECE) &&
+	(gs->board[2][7] == NOPIECE) && (gs->board[1][7] == NOPIECE) &&
+	(gs->board[0][7] == B_ROOK) &&
+	(!is_square_attacked(gs, 4, 7)) && (!is_square_attacked(gs, 3, 7))) {
+      return 1;
+    }
+  }
+  if (((ff - tf) > 1) || ((tf - ff) > 1))
+    return 0;
+  if (((fr - tr) > 1) || ((tr - fr) > 1))
+    return 0;
+  return 1;
 }
 
-PRIVATE void
-possible_pawn_moves(game_state_t *gs, int onf, int onr, int *posf, int *posr,
-    int *numpos)
+PRIVATE void add_pos(int tof, int tor, int *posf, int *posr, int *numpos)
 {
-	if (gs->onMove == WHITE) {
-		if (gs->board[onf][onr + 1] == NOPIECE) {
-			add_pos(onf, onr + 1, posf, posr, numpos);
-
-			if (onr == 1 && gs->board[onf][onr + 2] == NOPIECE)
-				add_pos(onf, onr + 2, posf, posr, numpos);
-		}
-
-		if (onf > 0 &&
-		    gs->board[onf - 1][onr + 1] != NOPIECE &&
-		    iscolor(gs->board[onf - 1][onr + 1], BLACK))
-			add_pos(onf - 1, onr + 1, posf, posr, numpos);
-		if (onf < 7 &&
-		    gs->board[onf + 1][onr + 1] != NOPIECE &&
-		    iscolor(gs->board[onf + 1][onr + 1], BLACK))
-			add_pos(onf + 1, onr + 1, posf, posr, numpos);
-
-		if (gs->ep_possible[0][onf] == -1)
-			add_pos(onf - 1, onr + 1, posf, posr, numpos);
-		if (gs->ep_possible[0][onf] == 1)
-			add_pos(onf + 1, onr + 1, posf, posr, numpos);
-	} else {
-		if (gs->board[onf][onr - 1] == NOPIECE) {
-			add_pos(onf, onr - 1, posf, posr, numpos);
-
-			if (onr == 6 && gs->board[onf][onr - 2] == NOPIECE)
-				add_pos(onf, onr - 2, posf, posr, numpos);
-		}
-
-		if (onf > 0 &&
-		    gs->board[onf - 1][onr - 1] != NOPIECE &&
-		    iscolor(gs->board[onf - 1][onr - 1], WHITE))
-			add_pos(onf - 1, onr - 1, posf, posr, numpos);
-		if (onf < 7 &&
-		    gs->board[onf + 1][onr - 1] != NOPIECE &&
-		    iscolor(gs->board[onf + 1][onr - 1], WHITE))
-			add_pos(onf + 1, onr - 1, posf, posr, numpos);
-
-		if (gs->ep_possible[1][onf] == -1)
-			add_pos(onf - 1, onr - 1, posf, posr, numpos);
-		if (gs->ep_possible[1][onf] == 1)
-			add_pos(onf + 1, onr - 1, posf, posr, numpos);
-	}
+  posf[*numpos] = tof;
+  posr[*numpos] = tor;
+  (*numpos)++;
 }
 
-PRIVATE void
-possible_knight_moves(game_state_t *gs, int onf, int onr, int *posf, int *posr,
-    int *numpos)
+PRIVATE void possible_pawn_moves(game_state_t * gs,
+				  int onf, int onr,
+				  int *posf, int *posr, int *numpos)
 {
-	int		f, r;
-	int		j;
-	static int	knightJumps[8][2] = {
-		{-1, 2}, {1, 2}, {2, -1}, {2, 1}, {-1, -2}, {1, -2}, {-2, 1},
-		{-2, -1}
-	};
-
-	for (j = 0; j < 8; j++) {
-		f = knightJumps[j][0] + onf;
-		r = knightJumps[j][1] + onr;
-
-		if (f < 0 || f > 7)
-			continue;
-		if (r < 0 || r > 7)
-			continue;
-
-		if (gs->board[f][r] == NOPIECE || iscolor(gs->board[f][r],
-		    CToggle(gs->onMove)))
-			add_pos(f, r, posf, posr, numpos);
-	}
+  if (gs->onMove == WHITE) {
+    if (gs->board[onf][onr + 1] == NOPIECE) {
+      add_pos(onf, onr + 1, posf, posr, numpos);
+      if ((onr == 1) && (gs->board[onf][onr + 2] == NOPIECE))
+	add_pos(onf, onr + 2, posf, posr, numpos);
+    }
+    if ((onf > 0) && (gs->board[onf - 1][onr + 1] != NOPIECE) &&
+	(iscolor(gs->board[onf - 1][onr + 1], BLACK)))
+      add_pos(onf - 1, onr + 1, posf, posr, numpos);
+    if ((onf < 7) && (gs->board[onf + 1][onr + 1] != NOPIECE) &&
+	(iscolor(gs->board[onf + 1][onr + 1], BLACK)))
+      add_pos(onf + 1, onr + 1, posf, posr, numpos);
+    if (gs->ep_possible[0][onf] == -1)
+      add_pos(onf - 1, onr + 1, posf, posr, numpos);
+    if (gs->ep_possible[0][onf] == 1)
+      add_pos(onf + 1, onr + 1, posf, posr, numpos);
+  } else {
+    if (gs->board[onf][onr - 1] == NOPIECE) {
+      add_pos(onf, onr - 1, posf, posr, numpos);
+      if ((onr == 6) && (gs->board[onf][onr - 2] == NOPIECE))
+	add_pos(onf, onr - 2, posf, posr, numpos);
+    }
+    if ((onf > 0) && (gs->board[onf - 1][onr - 1] != NOPIECE) &&
+	(iscolor(gs->board[onf - 1][onr - 1], WHITE)))
+      add_pos(onf - 1, onr - 1, posf, posr, numpos);
+/* loon: changed what looks like a typo, here's the original line:
+      add_pos(onf - 1, onr + 1, posf, posr, numpos);
+*/
+    if ((onf < 7) && (gs->board[onf + 1][onr - 1] != NOPIECE) &&
+	(iscolor(gs->board[onf + 1][onr - 1], WHITE)))
+      add_pos(onf + 1, onr - 1, posf, posr, numpos);
+    if (gs->ep_possible[1][onf] == -1)
+      add_pos(onf - 1, onr - 1, posf, posr, numpos);
+    if (gs->ep_possible[1][onf] == 1)
+      add_pos(onf + 1, onr - 1, posf, posr, numpos);
+  }
 }
 
-PRIVATE void
-possible_bishop_moves(game_state_t *gs, int onf, int onr, int *posf, int *posr,
-    int *numpos)
+PRIVATE void possible_knight_moves(game_state_t * gs,
+				    int onf, int onr,
+				    int *posf, int *posr, int *numpos)
 {
-	int f, r;
-
-	/* Up Left */
-	f = onf;
-	r = onr;
-	while (1) {
-		f--;
-		r++;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
-
-	/* Up Right */
-	f = onf;
-	r = onr;
-	while (1) {
-		f++;
-		r++;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
-
-	/* Down Left */
-	f = onf;
-	r = onr;
-	while (1) {
-		f--;
-		r--;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
-
-	/* Down Right */
-	f = onf;
-	r = onr;
-	while (1) {
-		f++;
-		r--;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
+  static int knightJumps[8][2] = {{-1, 2}, {1, 2}, {2, -1}, {2, 1},
+  {-1, -2}, {1, -2}, {-2, 1}, {-2, -1}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 8; j++) {
+    f = knightJumps[j][0] + onf;
+    r = knightJumps[j][1] + onr;
+    if ((f < 0) || (f > 7))
+      continue;
+    if ((r < 0) || (r > 7))
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+	(iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
 }
 
-PRIVATE void
-possible_rook_moves(game_state_t *gs, int onf, int onr, int *posf, int *posr,
-    int *numpos)
+PRIVATE void possible_bishop_moves(game_state_t * gs,
+				    int onf, int onr,
+				    int *posf, int *posr, int *numpos)
 {
-	int f, r;
-
-	/* Left */
-	f = onf;
-	r = onr;
-	while (1) {
-		f--;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
-
-	/* Right */
-	f = onf;
-	r = onr;
-	while (1) {
-		f++;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
-
-	/* Up */
-	f = onf;
-	r = onr;
-	while (1) {
-		r++;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
-
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
-
-	/* Down */
-	f = onf;
-	r = onr;
-	while (1) {
-		r--;
-
-		if (f < 0 || f > 7)
-			break;
-		if (r < 0 || r > 7)
-			break;
-		if (gs->board[f][r] != NOPIECE && iscolor(gs->board[f][r],
-		    gs->onMove))
-			break;
-
-		add_pos(f, r, posf, posr, numpos);
+  int f, r;
+
+  /* Up Left */
+  f = onf;
+  r = onr;
+  while (1) {
+    f--;
+    r++;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Up Right */
+  f = onf;
+  r = onr;
+  while (1) {
+    f++;
+    r++;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down Left */
+  f = onf;
+  r = onr;
+  while (1) {
+    f--;
+    r--;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down Right */
+  f = onf;
+  r = onr;
+  while (1) {
+    f++;
+    r--;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+}
 
-		if (gs->board[f][r] != NOPIECE)
-			break;
-	}
+PRIVATE void possible_rook_moves(game_state_t * gs,
+				  int onf, int onr,
+				  int *posf, int *posr, int *numpos)
+{
+  int f, r;
+
+  /* Left */
+  f = onf;
+  r = onr;
+  while (1) {
+    f--;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Right */
+  f = onf;
+  r = onr;
+  while (1) {
+    f++;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Up */
+  f = onf;
+  r = onr;
+  while (1) {
+    r++;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down */
+  f = onf;
+  r = onr;
+  while (1) {
+    r--;
+    if ((f < 0) || (f > 7))
+      break;
+    if ((r < 0) || (r > 7))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
 }
 
-PRIVATE void
-possible_queen_moves(game_state_t *gs, int onf, int onr, int *posf, int *posr,
-    int *numpos)
+PRIVATE void possible_queen_moves(game_state_t * gs,
+				   int onf, int onr,
+				   int *posf, int *posr, int *numpos)
 {
-	possible_rook_moves(gs, onf, onr, posf, posr, numpos);
-	possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
+  possible_rook_moves(gs, onf, onr, posf, posr, numpos);
+  possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-PRIVATE void
-possible_king_moves(game_state_t *gs, int onf, int onr, int *posf, int *posr,
-    int *numpos)
+PRIVATE void possible_king_moves(game_state_t * gs,
+				  int onf, int onr,
+				  int *posf, int *posr, int *numpos)
 {
-	int		f, r;
-	int		j;
-	static int	kingJumps[8][2] = {
-		{-1, -1}, {0, -1}, {1, -1}, {-1, 1}, {0, 1}, {1, 1}, {-1, 0},
-		{1, 0}
-	};
-
-	for (j = 0; j < 8; j++) {
-		f = kingJumps[j][0] + onf;
-		r = kingJumps[j][1] + onr;
-
-		if (f < 0 || f > 7)
-			continue;
-		if (r < 0 || r > 7)
-			continue;
-
-		if (gs->board[f][r] == NOPIECE || iscolor(gs->board[f][r],
-		    CToggle(gs->onMove)))
-			add_pos(f, r, posf, posr, numpos);
-	}
+  static int kingJumps[8][2] = {{-1, -1}, {0, -1}, {1, -1}, {-1, 1},
+  {0, 1}, {1, 1}, {-1, 0}, {1, 0}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 8; j++) {
+    f = kingJumps[j][0] + onf;
+    r = kingJumps[j][1] + onr;
+    if ((f < 0) || (f > 7))
+      continue;
+    if ((r < 0) || (r > 7))
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+	(iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
 }
 
 /* Doesn't check for check */
-PUBLIC int
-legal_move(game_state_t *gs,
-    int fFile, int fRank,
-    int tFile, int tRank)
+PUBLIC int legal_move(game_state_t * gs,
+		       int fFile, int fRank,
+		       int tFile, int tRank)
 {
-	int	legal;
-	int	move_piece;
-
-	if (fFile == ALG_DROP) {
-		if ((move_piece = fRank) == KING)
-			return 0;
-		if (gs->holding[gs->onMove == WHITE ? 0 : 1][move_piece - 1]
-		    == 0)
-			return 0;
-		if (gs->board[tFile][tRank] != NOPIECE)
-			return 0;
-		if (move_piece == PAWN && (tRank == 0 || tRank == 7))
-			return 0;
-		return 1;
-	} else {
-		move_piece = piecetype(gs->board[fFile][fRank]);
-	}
-
-	if (gs->board[fFile][fRank] == NOPIECE)
-		return 0;
-	if (!iscolor(gs->board[fFile][fRank], gs->onMove))  // Wrong color
-		return 0;
-	if (gs->board[tFile][tRank] != NOPIECE &&
-	    iscolor(gs->board[tFile][tRank], gs->onMove))   // Can't capture own
-		return 0;
-	if (fFile == tFile && fRank == tRank)	// Same square
-		return 0;
-
-	switch (move_piece) {
-	case PAWN:
-		legal = legal_pawn_move(gs, fFile, fRank, tFile, tRank);
-		break;
-	case KNIGHT:
-		legal = legal_knight_move(gs, fFile, fRank, tFile, tRank);
-		break;
-	case BISHOP:
-		legal = legal_bishop_move(gs, fFile, fRank, tFile, tRank);
-		break;
-	case ROOK:
-		legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
-		break;
-	case QUEEN:
-		legal = legal_queen_move(gs, fFile, fRank, tFile, tRank);
-		break;
-	case KING:
-		legal = legal_king_move(gs, fFile, fRank, tFile, tRank);
-		break;
-	default:
-		return 0;
-	}
-
-	return legal;
+  int move_piece;
+  int legal;
+
+  if (fFile == ALG_DROP) {
+    move_piece = fRank;
+    if (move_piece == KING)
+      return 0;
+    if (gs->holding[gs->onMove==WHITE ? 0 : 1][move_piece-1] == 0)
+      return 0;
+    if (gs->board[tFile][tRank] != NOPIECE)
+      return 0;
+    if (move_piece == PAWN && (tRank == 0 || tRank == 7))
+      return 0;
+    return 1;
+  } else {
+    move_piece = piecetype(gs->board[fFile][fRank]);
+  }
+  if (gs->board[fFile][fRank] == NOPIECE)
+    return 0;
+  if (!iscolor(gs->board[fFile][fRank], gs->onMove))	/* Wrong color */
+    return 0;
+  if ((gs->board[tFile][tRank] != NOPIECE) &&
+      iscolor(gs->board[tFile][tRank], gs->onMove))	/* Can't capture own */
+    return 0;
+  if ((fFile == tFile) && (fRank == tRank))	/* Same square */
+    return 0;
+  switch (move_piece) {
+  case PAWN:
+    legal = legal_pawn_move(gs, fFile, fRank, tFile, tRank);
+    break;
+  case KNIGHT:
+    legal = legal_knight_move(gs, fFile, fRank, tFile, tRank);
+    break;
+  case BISHOP:
+    legal = legal_bishop_move(gs, fFile, fRank, tFile, tRank);
+    break;
+  case ROOK:
+    legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
+    break;
+  case QUEEN:
+    legal = legal_queen_move(gs, fFile, fRank, tFile, tRank);
+    break;
+  case KING:
+    legal = legal_king_move(gs, fFile, fRank, tFile, tRank);
+    break;
+  default:
+    return 0;
+    break;
+  }
+  return legal;
 }
 
+
 /*
  * This fills in the rest of the mt structure once it is determined
  * that. (Returns 'MOVE_ILLEGAL' if move leaves you in check.)
@@ -827,11 +698,11 @@ move_calculate(game_state_t *gs, move_t *mt, int promote)
 		if (piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING &&
 		    mt->fromFile == 4 &&
 		    mt->toFile == 2) {
-			strlcpy(mt->moveString, "o-o-o", sizeof mt->moveString);
+			sprintf(mt->moveString, "o-o-o");
 		} else if (piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING &&
 		    mt->fromFile == 4 &&
 		    mt->toFile == 6) {
-			strlcpy(mt->moveString, "o-o", sizeof mt->moveString);
+			sprintf(mt->moveString, "o-o");
 		} else {
 			ret = snprintf(mt->moveString, sizeof mt->moveString,
 			    "%s/%c%d-%c%d",
@@ -864,65 +735,57 @@ move_calculate(game_state_t *gs, move_t *mt, int promote)
 	return MOVE_OK;
 }
 
-PUBLIC int
-legal_andcheck_move(game_state_t *gs, int fFile, int fRank,
-    int tFile, int tRank)
+PUBLIC int legal_andcheck_move(game_state_t * gs,
+			        int fFile, int fRank,
+			        int tFile, int tRank)
 {
-	move_t	mt;
-
-	if (!legal_move(gs, fFile, fRank, tFile, tRank))
-		return 0;
-
-	mt.color	= gs->onMove;
-	mt.fromFile	= fFile;
-	mt.fromRank	= fRank;
-	mt.toFile	= tFile;
-	mt.toRank	= tRank;
-
-	if (move_calculate(gs, &mt, QUEEN) == MOVE_OK)
-		return 1;
-	return 0;
+  move_t mt;
+  if (!legal_move(gs, fFile, fRank, tFile, tRank))
+    return 0;
+  mt.color = gs->onMove;
+  mt.fromFile = fFile;
+  mt.fromRank = fRank;
+  mt.toFile = tFile;
+  mt.toRank = tRank;
+  /* This should take into account a pawn promoting to another piece */
+  if (move_calculate(gs, &mt, QUEEN) == MOVE_OK)
+    return 1;
+  else
+    return 0;
 }
 
-PUBLIC int
-in_check(game_state_t *gs)
+PUBLIC int in_check(game_state_t * gs)
 {
-	int	f, r;
-	int	kf = -1, kr = -1;
-
-	/* Find the king */
-	if (gs->onMove == WHITE) {
-		for (f = 0; f < 8 && kf < 0; f++) {
-			for (r = 0; r < 8 && kf < 0; r++) {
-				if (gs->board[f][r] == B_KING) {
-					kf = f;
-					kr = r;
-				}
-			}
-		}
-	} else {
-		for (f = 0; f < 8 && kf < 0; f++) {
-			for (r = 0; r < 8 && kf < 0; r++) {
-				if (gs->board[f][r] == W_KING) {
-					kf = f;
-					kr = r;
-				}
-			}
-		}
+  int f, r;
+  int kf = -1, kr = -1;
+
+  /* Find the king */
+  if (gs->onMove == WHITE) {
+    for (f = 0; f < 8 && kf < 0; f++)
+      for (r = 0; r < 8 && kf < 0; r++)
+	if (gs->board[f][r] == B_KING) {
+	  kf = f;
+	  kr = r;
 	}
-
-	if (kf < 0) {
-		fprintf(stderr, "FICS: Error game with no king!\n");
-		return 0;
+  } else {
+    for (f = 0; f < 8 && kf < 0; f++)
+      for (r = 0; r < 8 && kf < 0; r++)
+	if (gs->board[f][r] == W_KING) {
+	  kf = f;
+	  kr = r;
 	}
-
-	for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
-	     NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
-		if (legal_move(gs, f, r, kf, kr))	// In Check?
-			return 1;
-	}
-
-	return 0;
+  }
+  if (kf < 0) {
+    fprintf(stderr, "FICS: Error game with no king!\n");
+    return 0;
+  }
+  for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+       NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+    if (legal_move(gs, f, r, kf, kr)) {	/* In Check? */
+      return 1;
+    }
+  }
+  return 0;
 }
 
 PRIVATE int
@@ -1010,68 +873,64 @@ has_legal_move(game_state_t *gs)
 	return 0;
 }
 
-PUBLIC int
-parse_move(char *mstr, game_state_t *gs, move_t *mt, int promote)
+/* This will end up being a very complicated function */
+PUBLIC int parse_move(char *mstr, game_state_t * gs, move_t * mt, int promote)
 {
-	int	result;
-	int	type = is_move(mstr);
-
-	mt->color = gs->onMove;
-
-	switch (type) {
-	case MS_NOTMOVE:
-		return MOVE_ILLEGAL;
-	case MS_COMP:
-		mt->fromFile = mstr[0] - 'a';
-		mt->fromRank = mstr[1] - '1';
-		mt->toFile = mstr[2] - 'a';
-		mt->toRank = mstr[3] - '1';
-		break;
-	case MS_COMPDASH:
-		mt->fromFile = mstr[0] - 'a';
-		mt->fromRank = mstr[1] - '1';
-		mt->toFile = mstr[3] - 'a';
-		mt->toRank = mstr[4] - '1';
-		break;
-	case MS_KCASTLE:
-		mt->fromFile = 4;
-		mt->toFile = 6;
-
-		if (gs->onMove == WHITE) {
-			mt->fromRank = 0;
-			mt->toRank = 0;
-		} else {
-			mt->fromRank = 7;
-			mt->toRank = 7;
-		}
-
-		break;
-	case MS_QCASTLE:
-		mt->fromFile = 4;
-		mt->toFile = 2;
-
-		if (gs->onMove == WHITE) {
-			mt->fromRank = 0;
-			mt->toRank = 0;
-		} else {
-			mt->fromRank = 7;
-			mt->toRank = 7;
-		}
-
-		break;
-	case MS_ALG:
-		/* Fills in the mt structure */
-		if ((result = alg_parse_move(mstr, gs, mt)) != MOVE_OK)
-			return result;
-		break;
-	default:
-		return MOVE_ILLEGAL;
-	}
-
-	if (!legal_move(gs, mt->fromFile, mt->fromRank, mt->toFile, mt->toRank))
-		return MOVE_ILLEGAL;
-
-	return move_calculate(gs, mt, promote);
+  int type = is_move(mstr);
+  int result;
+
+  mt->color = gs->onMove;
+  switch (type) {
+  case MS_NOTMOVE:
+    return MOVE_ILLEGAL;
+    break;
+  case MS_COMP:
+    mt->fromFile = mstr[0] - 'a';
+    mt->fromRank = mstr[1] - '1';
+    mt->toFile = mstr[2] - 'a';
+    mt->toRank = mstr[3] - '1';
+    break;
+  case MS_COMPDASH:
+    mt->fromFile = mstr[0] - 'a';
+    mt->fromRank = mstr[1] - '1';
+    mt->toFile = mstr[3] - 'a';
+    mt->toRank = mstr[4] - '1';
+    break;
+  case MS_KCASTLE:
+    mt->fromFile = 4;
+    mt->toFile = 6;
+    if (gs->onMove == WHITE) {
+      mt->fromRank = 0;
+      mt->toRank = 0;
+    } else {
+      mt->fromRank = 7;
+      mt->toRank = 7;
+    }
+    break;
+  case MS_QCASTLE:
+    mt->fromFile = 4;
+    mt->toFile = 2;
+    if (gs->onMove == WHITE) {
+      mt->fromRank = 0;
+      mt->toRank = 0;
+    } else {
+      mt->fromRank = 7;
+      mt->toRank = 7;
+    }
+    break;
+  case MS_ALG:
+    /* Fills in the mt structure */
+    if ((result = alg_parse_move(mstr, gs, mt)) != MOVE_OK)
+      return result;
+    break;
+  default:
+    return MOVE_ILLEGAL;
+    break;
+  }
+  if (!legal_move(gs, mt->fromFile, mt->fromRank, mt->toFile, mt->toRank)) {
+    return MOVE_ILLEGAL;
+  }
+  return move_calculate(gs, mt, promote);
 }
 
 /*
@@ -1266,369 +1125,260 @@ execute_move(game_state_t *gs, move_t *mt, int check_game_status)
 	return MOVE_OK;
 }
 
-PRIVATE void
-piecetype_rook(int g, int mode, game_state_t *gs, move_t *m, move_t **m1)
+PUBLIC int backup_move(int g, int mode)
 {
-	int i;
-
-	if (m->color == WHITE) {
-		if (m->fromFile == 0 && m->fromRank == 0) {
-			for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
-				*m1 = ((mode == REL_GAME)
-				       ? &garray[g].moveList[i]
-				       : &garray[g].examMoveList[i]);
-
-				if ((*m1)->fromFile == 0 &&
-				    (*m1)->fromRank == 0)
-					break;
-			}
-
-			if (i == (garray[g].numHalfMoves - 1))
-				gs->wqrmoved = 0;
-		}
-
-		if (m->fromFile == 7 && m->fromRank == 0) {
-			for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
-				*m1 = ((mode == REL_GAME)
-				       ? &garray[g].moveList[i]
-				       : &garray[g].examMoveList[i]);
-
-				if ((*m1)->fromFile == 7 &&
-				    (*m1)->fromRank == 0)
-					break;
-			}
-
-			if (i == (garray[g].numHalfMoves - 1))
-				gs->wkrmoved = 0;
-		}
-	} else {
-		if (m->fromFile == 0 && m->fromRank == 7) {
-			for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
-				*m1 = ((mode == REL_GAME)
-				       ? &garray[g].moveList[i]
-				       : &garray[g].examMoveList[i]);
-
-				if ((*m1)->fromFile == 0 &&
-				    (*m1)->fromRank == 0)
-					break;
-			}
-
-			if (i == (garray[g].numHalfMoves - 1))
-				gs->bqrmoved = 0;
-		}
-
-		if (m->fromFile == 7 && m->fromRank == 7) {
-			for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
-				*m1 = ((mode == REL_GAME)
-				       ? &garray[g].moveList[i]
-				       : &garray[g].examMoveList[i]);
-
-				if ((*m1)->fromFile == 7 &&
-				    (*m1)->fromRank == 0)
-					break;
-			}
-
-			if (i == (garray[g].numHalfMoves - 1))
-				gs->bkrmoved = 0;
-		}
+  game_state_t *gs;
+  move_t *m, *m1;
+  int now, i;
+
+  if (garray[g].link >= 0)	/*IanO: not implemented for bughouse yet */
+    return MOVE_ILLEGAL;
+  if (garray[g].numHalfMoves < 1)
+    return MOVE_ILLEGAL;
+  gs = &garray[g].game_state;
+  m = (mode==REL_GAME) ? &garray[g].moveList[garray[g].numHalfMoves - 1] :
+                         &garray[g].examMoveList[garray[g].numHalfMoves - 1];
+  if (m->toFile < 0) {
+    return MOVE_ILLEGAL;
+  }
+  gs->board[m->fromFile][m->fromRank] = gs->board[m->toFile][m->toRank];
+  if (m->piecePromotionTo != NOPIECE) {
+    gs->board[m->fromFile][m->fromRank] = PAWN |
+      colorval(gs->board[m->fromFile][m->fromRank]);
+  }
+  /******************
+     When takeback a _first_ move of rook, the ??rmoved variable
+     must be cleared . To check, if the move is first, we should
+     scan moveList.
+  *******************/
+  if (piecetype(gs->board[m->fromFile][m->fromRank]) == ROOK) {
+    if (m->color == WHITE) {
+      if ((m->fromFile == 0) && (m->fromRank == 0)) {
+	for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
+	  m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+	  if ((m1->fromFile == 0) && (m1->fromRank == 0))
+	    break;
 	}
-}
-
-#ifdef TIMESEAL
-PRIVATE void
-backup_move_timeseal_block(int g, move_t *m)
-{
-	if (m->color == WHITE) {
-		if (con[parray[garray[g].white].socket].timeseal) {
-			garray[g].wRealTime += (m->tookTime * 100);
-			garray[g].wRealTime -= (garray[g].wIncrement * 100);
-			garray[g].wTime = (garray[g].wRealTime / 100);
-
-			if (con[parray[garray[g].black].socket].timeseal) {
-				garray[g].bTime = (garray[g].bRealTime / 100);
-			} else {   // Opp has no timeseal
-				garray[g].bTime += (garray[g].lastDecTime -
-						    garray[g].lastMoveTime);
-			}
-		} else { // White has no timeseal
-			garray[g].wTime += m->tookTime;
-			garray[g].wTime -= garray[g].wIncrement;
-
-			if (con[parray[garray[g].black].socket].timeseal) {
-				garray[g].bTime = (garray[g].bRealTime / 100);
-			} else {   // Opp has no timeseal
-				garray[g].bTime += (garray[g].lastDecTime -
-						    garray[g].lastMoveTime);
-			}
-		}
-	} else {
-		if (con[parray[garray[g].black].socket].timeseal) {
-			garray[g].bRealTime += (m->tookTime * 100);
-			garray[g].bRealTime -= (garray[g].wIncrement * 100);
-			garray[g].bTime = (garray[g].bRealTime / 100);
-
-			if (con[parray[garray[g].white].socket].timeseal) {
-				garray[g].wTime = (garray[g].wRealTime / 100);
-			} else {   // Opp has no timeseal
-				garray[g].wTime += (garray[g].lastDecTime -
-						    garray[g].lastMoveTime);
-			}
-		} else { // Black has no timeseal
-			garray[g].bTime += m->tookTime;
-
-			if (!garray[g].bIncrement)
-				garray[g].bTime -= garray[g].wIncrement;
-			else
-				garray[g].bTime -= garray[g].bIncrement;
-
-			if (con[parray[garray[g].white].socket].timeseal) {
-				garray[g].wTime = (garray[g].wRealTime / 100);
-			} else {   // Opp has no timeseal
-				garray[g].wTime += (garray[g].lastDecTime -
-						    garray[g].lastMoveTime);
-			}
-		}
+	if (i == garray[g].numHalfMoves - 1)
+	  gs->wqrmoved = 0;
+      }
+      if ((m->fromFile == 7) && (m->fromRank == 0)) {
+	for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
+	  m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+	  if ((m1->fromFile == 7) && (m1->fromRank == 0))
+	    break;
 	}
-}
-#endif // TIMESEAL
-
-PRIVATE void
-update_enpassant_array(int g, int mode, game_state_t *gs)
-{
-	move_t *m1;
-
-	if (!(garray[g].numHalfMoves > 0))
-		return;
-
-	m1 = ((mode == REL_GAME)
-	      ? &garray[g].moveList[garray[g].numHalfMoves - 1]
-	      : &garray[g].examMoveList[garray[g].numHalfMoves - 1]);
-
-	if (piecetype(gs->board[m1->toFile][m1->toRank]) == PAWN) {
-		if ((m1->toRank - m1->fromRank) == 2) {
-			if (m1->toFile < 7 &&
-			    gs->board[m1->toFile + 1][3] == B_PAWN)
-				gs->ep_possible[1][m1->toFile + 1] = -1;
-			if (m1->toFile - 1 >= 0 &&
-			    gs->board[m1->toFile - 1][3] == B_PAWN)
-				gs->ep_possible[1][m1->toFile - 1] = 1;
-		}
-
-		if ((m1->toRank - m1->fromRank) == -2) {
-			if (m1->toFile < 7 &&
-			    gs->board[m1->toFile + 1][4] == W_PAWN)
-				gs->ep_possible[0][m1->toFile + 1] = -1;
-			if (m1->toFile - 1 >= 0 &&
-			    gs->board[m1->toFile - 1][4] == W_PAWN)
-				gs->ep_possible[0][m1->toFile - 1] = 1;
-		}
+	if (i == garray[g].numHalfMoves - 1)
+	  gs->wkrmoved = 0;
+      }
+    } else {
+      if ((m->fromFile == 0) && (m->fromRank == 7)) {
+	for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
+	  m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+	  if ((m1->fromFile == 0) && (m1->fromRank == 0))
+	    break;
 	}
-}
-
-PRIVATE void
-clean_up_doit(int g, int mode, game_state_t *gs, move_t *m)
-{
-	unsigned int now;
-
-	if (garray[g].status != GAME_EXAMINE)
-		game_update_time(g);
-
-	garray[g].numHalfMoves--;
+	if (i == garray[g].numHalfMoves - 1)
+	  gs->bqrmoved = 0;
+      }
+      if ((m->fromFile == 7) && (m->fromRank == 7)) {
+	for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
+	  m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+	  if ((m1->fromFile == 7) && (m1->fromRank == 0))
+	    break;
+	}
+	if (i == garray[g].numHalfMoves - 1)
+	  gs->bkrmoved = 0;
+      }
+    }
+  }
+  if (piecetype(gs->board[m->fromFile][m->fromRank]) == KING) {
+    gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+
+    if (m->toFile - m->fromFile == 2) {
+      gs->board[7][m->fromRank] = ROOK |
+	colorval(gs->board[m->fromFile][m->fromRank]);
+      gs->board[5][m->fromRank] = NOPIECE;
+
+      /********
+         If takeback a castling, the appropriates ??moved variables
+         must be cleared
+      ********/
+      if (m->color == WHITE) {
+	gs->wkmoved = 0;
+	gs->wkrmoved = 0;
+      } else {
+	gs->bkmoved = 0;
+	gs->bkrmoved = 0;
+      }
+      goto cleanupMove;
+    }
+    if (m->fromFile - m->toFile == 2) {
+      gs->board[0][m->fromRank] = ROOK |
+	colorval(gs->board[m->fromFile][m->fromRank]);
+      gs->board[3][m->fromRank] = NOPIECE;
+
+      /**********
+         If takeback a castling, the appropriate ??moved variables
+         must be cleared
+      ***********/
+      if (m->color == WHITE) {
+	gs->wkmoved = 0;
+	gs->wqrmoved = 0;
+      } else {
+	gs->bkmoved = 0;
+	gs->bqrmoved = 0;
+      }
+      goto cleanupMove;
+    }
+    /******************
+       When takeback a _first_ move of king (not the castling),
+       the ?kmoved variable must be cleared . To check, if the move is first,
+       we should scan moveList.
+    *******************/
+
+    if (m->color == WHITE) {
+
+      if ((m->fromFile == 4) && (m->fromRank == 0)) {
+	for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
+	  m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+	  if ((m1->fromFile == 4) && (m1->fromRank == 0))
+	    break;
+	}
+	if (i == garray[g].numHalfMoves - 1)
+	  gs->wkmoved = 0;
+      }
+    } else {
+      if ((m->fromFile == 4) && (m->fromRank == 7)) {
+	for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
+	  m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+	  if ((m1->fromFile == 4) && (m1->fromRank == 7))
+	    break;
+	}
+	if (i == garray[g].numHalfMoves - 1)
+	  gs->bkmoved = 0;
+      }
+    }
+  }
+  if (m->enPassant) {		/* Do enPassant */
+    gs->board[m->toFile][m->fromRank] = PAWN |
+      (colorval(gs->board[m->fromFile][m->fromRank]) == WHITE ? BLACK : WHITE);
+    gs->board[m->toFile][m->toRank] = NOPIECE;
+    /* Should set the enpassant array, but I don't care right now */
+    goto cleanupMove;
+  }
+  gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+cleanupMove:
+  if (garray[g].status != GAME_EXAMINE) {
+    game_update_time(g);
+  }
+  garray[g].numHalfMoves--;
+  if (garray[g].status != GAME_EXAMINE) {
+    if (garray[g].wInitTime) {	/* Don't update times in untimed games */
+      now = tenth_secs();
 
-	if (garray[g].status != GAME_EXAMINE) {
-		if (garray[g].wInitTime) {	// Don't update times in untimed
-						// games.
-			now = tenth_secs();
 #ifdef TIMESEAL
-			backup_move_timeseal_block(g, m);
-#else
-			if (m->color == WHITE) {
-				garray[g].wTime   += m->tookTime;
-				garray[g].wTime   = (garray[g].wTime -
-						     garray[g].wIncrement);
-				garray[g].bTime   +=
-				    (garray[g].lastDecTime -
-				     garray[g].lastMoveTime);
-			} else {
-				garray[g].bTime += m->tookTime;
-
-				if (!garray[g].bIncrement) {
-					garray[g].bTime =
-					    (garray[g].bTime -
-					     garray[g].wIncrement);
-				} else {
-					garray[g].bTime =
-					    (garray[g].bTime -
-					     garray[g].bIncrement);
-				}
 
-				garray[g].wTime += (garray[g].lastDecTime -
-						    garray[g].lastMoveTime);
-			}
-#endif
-
-			if (garray[g].numHalfMoves == 0)
-				garray[g].timeOfStart = now;
-			garray[g].lastMoveTime = now;
-			garray[g].lastDecTime = now;
-		}
+      if (m->color == WHITE) {
+        if (con[parray[garray[g].white].socket].timeseal) {  /* white uses timeseal? */
+          garray[g].wRealTime += (m->tookTime * 100);
+          garray[g].wRealTime -= (garray[g].wIncrement * 100);
+          garray[g].wTime = garray[g].wRealTime / 100;
+          if (con[parray[garray[g].black].socket].timeseal) { /* opp uses timeseal? */
+            garray[g].bTime = garray[g].bRealTime / 100;
+	  } else {    /* opp has no timeseal */
+            garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+	  }
+	} else {  /* white has no timeseal */
+          garray[g].wTime += m->tookTime;
+          garray[g].wTime -= garray[g].wIncrement;
+          if (con[parray[garray[g].black].socket].timeseal) { /* opp uses timeseal? */
+            garray[g].bTime = garray[g].bRealTime / 100;
+	  } else {    /* opp has no timeseal */
+            garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+	  }
 	}
-
-	if (gs->onMove == BLACK) {
-		gs->onMove = WHITE;
-	} else {
-		gs->onMove = BLACK;
-		gs->moveNum--;
+      } else {
+        if (con[parray[garray[g].black].socket].timeseal) {  /* black uses timeseal? */
+          garray[g].bRealTime += (m->tookTime * 100);
+          garray[g].bRealTime -= (garray[g].wIncrement * 100);
+          garray[g].bTime = garray[g].bRealTime / 100;
+          if (con[parray[garray[g].white].socket].timeseal) { /* opp uses timeseal? */
+            garray[g].wTime = garray[g].wRealTime / 100;
+	  } else {    /* opp has no timeseal */
+            garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+	  }
+	} else {  /* black has no timeseal */
+          garray[g].bTime += m->tookTime;
+          if (!garray[g].bIncrement)
+            garray[g].bTime -= garray[g].wIncrement;
+          else
+  	    garray[g].bTime -= garray[g].bIncrement;
+          if (con[parray[garray[g].white].socket].timeseal) { /* opp uses timeseal? */
+            garray[g].wTime = garray[g].wRealTime / 100;
+	  } else {    /* opp has no timeseal */
+            garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+	  }
 	}
+      }
 
-	/*
-	 * takeback of last move is done already. It's time to update
-	 * enpassant array...
-	 */
-	update_enpassant_array(g, mode, gs);
-}
-
-PUBLIC int
-backup_move(int g, int mode)
-{
-	game_state_t	*gs;
-	int		 i;
-	move_t		*m, *m1;
-
-	if (garray[g].link >= 0)   // Not implemented for bughouse yet.
-		return MOVE_ILLEGAL;
-	if (garray[g].numHalfMoves < 1)
-		return MOVE_ILLEGAL;
-
-	gs = &garray[g].game_state;
-	m = ((mode == REL_GAME)
-	     ? &garray[g].moveList[garray[g].numHalfMoves - 1]
-	     : &garray[g].examMoveList[garray[g].numHalfMoves - 1]);
+#else
 
-	if (m->toFile < 0)
-		return MOVE_ILLEGAL;
+      if (m->color == WHITE) {
+        garray[g].wTime += m->tookTime;
+        garray[g].wTime = garray[g].wTime - garray[g].wIncrement;
+        garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+      } else {
+        garray[g].bTime += m->tookTime;
+        if (!garray[g].bIncrement)
+          garray[g].bTime = garray[g].bTime - garray[g].wIncrement;
+        else
+	  garray[g].bTime = garray[g].bTime - garray[g].bIncrement;
+        garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+      }
 
-	gs->board[m->fromFile][m->fromRank] = gs->board[m->toFile][m->toRank];
+#endif
 
-	if (m->piecePromotionTo != NOPIECE) {
-		gs->board[m->fromFile][m->fromRank] = (PAWN |
-		    colorval(gs->board[m->fromFile][m->fromRank]));
+      if (garray[g].numHalfMoves == 0)
+        garray[g].timeOfStart = now;
+      garray[g].lastMoveTime = now;
+      garray[g].lastDecTime = now;
+    }
+  }
+  if (gs->onMove == BLACK)
+    gs->onMove = WHITE;
+  else {
+    gs->onMove = BLACK;
+    gs->moveNum--;
+  }
+
+  /******* Here begins the patch : ********************************
+     Takeback of last move is done already, it's time to update enpassant
+     array.  (patch from Soso, added by Sparky 3/17/95)
+  ********/
+
+  if (garray[g].numHalfMoves > 0) {
+    m1 = (mode==REL_GAME) ? &garray[g].moveList[garray[g].numHalfMoves - 1] :
+                            &garray[g].examMoveList[garray[g].numHalfMoves - 1];
+    if (piecetype(gs->board[m1->toFile][m1->toRank]) == PAWN) {
+      if ((m1->toRank - m1->fromRank) == 2) {
+	if ((m1->toFile < 7) && gs->board[m1->toFile + 1][3] == B_PAWN) {
+	  gs->ep_possible[1][m1->toFile + 1] = -1;
 	}
-
-	/*
-	 * When takeback a _first_ move of rook, the ??rmoved
-	 * variable must be cleared. To check if the move is first we
-	 * should the scan move list.
-	 */
-	if (piecetype(gs->board[m->fromFile][m->fromRank]) == ROOK)
-		piecetype_rook(g, mode, gs, m, &m1);
-
-	if (piecetype(gs->board[m->fromFile][m->fromRank]) == KING) {
-		gs->board[m->toFile][m->toRank] = m->pieceCaptured;
-
-		if (m->toFile - m->fromFile == 2) {
-			gs->board[7][m->fromRank] = (ROOK |
-			    colorval(gs->board[m->fromFile][m->fromRank]));
-			gs->board[5][m->fromRank] = NOPIECE;
-
-			/*
-			 * If takeback a castling, the appropriates
-			 * ??moved variables must be cleared.
-			 */
-			if (m->color == WHITE) {
-				gs->wkmoved = 0;
-				gs->wkrmoved = 0;
-			} else {
-				gs->bkmoved = 0;
-				gs->bkrmoved = 0;
-			}
-
-			goto cleanupMove;
-		}
-
-		if (m->fromFile - m->toFile == 2) {
-			gs->board[0][m->fromRank] = (ROOK |
-			    colorval(gs->board[m->fromFile][m->fromRank]));
-			gs->board[3][m->fromRank] = NOPIECE;
-
-			/*
-			 * If takeback a castling, the appropriate
-			 * ??moved variables must be cleared.
-			 */
-			if (m->color == WHITE) {
-				gs->wkmoved = 0;
-				gs->wqrmoved = 0;
-			} else {
-				gs->bkmoved = 0;
-				gs->bqrmoved = 0;
-			}
-
-			goto cleanupMove;
-		}
-
-		/*
-		 * When takeback a _first_ move of king (not the
-		 * castling), the ?kmoved variable must be cleared. To
-		 * check if the move is first we should scan the move
-		 * list.
-		 */
-		if (m->color == WHITE) {
-			if (m->fromFile == 4 && m->fromRank == 0) {
-				for (i = 2;
-				    i < garray[g].numHalfMoves - 1;
-				    i += 2) {
-					m1 = ((mode == REL_GAME)
-					      ? &garray[g].moveList[i]
-					      : &garray[g].examMoveList[i]);
-
-					if (m1->fromFile == 4 &&
-					    m1->fromRank == 0)
-						break;
-				}
-
-				if (i == (garray[g].numHalfMoves - 1))
-					gs->wkmoved = 0;
-			}
-		} else {
-			if (m->fromFile == 4 && m->fromRank == 7) {
-				for (i = 3;
-				    i < garray[g].numHalfMoves - 1;
-				    i += 2) {
-					m1 = ((mode == REL_GAME)
-					      ? &garray[g].moveList[i]
-					      : &garray[g].examMoveList[i]);
-
-					if (m1->fromFile == 4 &&
-					    m1->fromRank == 7)
-						break;
-				}
-
-				if (i == (garray[g].numHalfMoves - 1))
-					gs->bkmoved = 0;
-			}
-		}
+	if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][3] == B_PAWN) {
+	  gs->ep_possible[1][m1->toFile - 1] = 1;
 	}
-
-	if (m->enPassant) {
-		if (colorval(gs->board[m->fromFile][m->fromRank]) == WHITE)
-			gs->board[m->toFile][m->fromRank] = (PAWN | BLACK);
-		else
-			gs->board[m->toFile][m->fromRank] = (PAWN | WHITE);
-
-		gs->board[m->toFile][m->toRank] = NOPIECE;
-
-		/*
-		 * Should set the enpassant array. But I don't care
-		 * right now.
-		 */
-		goto cleanupMove;
+      }
+      if ((m1->toRank - m1->fromRank) == -2) {
+	if ((m1->toFile < 7) && gs->board[m1->toFile + 1][4] == W_PAWN) {
+	  gs->ep_possible[0][m1->toFile + 1] = -1;
 	}
-
-	gs->board[m->toFile][m->toRank] = m->pieceCaptured;
-
-  cleanupMove:
-
-	clean_up_doit(g, mode, gs, m);
-
-	return MOVE_OK;
+	if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][4] == W_PAWN) {
+	  gs->ep_possible[0][m1->toFile - 1] = 1;
+	}
+      }
+    }
+  }
+  /************** and here's the end **************/
+  return MOVE_OK;
 }
diff --git a/FICS/movecheck.h b/FICS/movecheck.h
index 9cd65c8..53a1712 100644
--- a/FICS/movecheck.h
+++ b/FICS/movecheck.h
@@ -19,26 +19,25 @@
 
 /* Revision history:
    name		email		yy/mm/dd	Change
-   Richard Nash                 93/10/22	Created
-   Markus Uhlin                 24/03/17	Revised
+   Richard Nash	              	93/10/22	Created
 */
 
 #ifndef _MOVECHECK_H
 #define _MOVECHECK_H
 
-#define MOVE_OK          0
-#define MOVE_ILLEGAL     1
-#define MOVE_STALEMATE   2
-#define MOVE_CHECKMATE   3
-#define MOVE_AMBIGUOUS   4
-#define MOVE_NOMATERIAL  5
+#define MOVE_OK 0
+#define MOVE_ILLEGAL 1
+#define MOVE_STALEMATE 2
+#define MOVE_CHECKMATE 3
+#define MOVE_AMBIGUOUS 4
+#define MOVE_NOMATERIAL 5
 
-#define MS_NOTMOVE       0
-#define MS_COMP          1
-#define MS_COMPDASH      2
-#define MS_ALG           3
-#define MS_KCASTLE       4
-#define MS_QCASTLE       5
+#define MS_NOTMOVE 0
+#define MS_COMP 1
+#define MS_COMPDASH 2
+#define MS_ALG 3
+#define MS_KCASTLE 4
+#define MS_QCASTLE 5
 
 #define isrank(c) (((c) <= '8') && ((c) >= '1'))
 #define isfile(c) (((c) >= 'a') && ((c) <= 'h'))
@@ -47,15 +46,16 @@
 #include "board.h"
 #endif
 
-extern int	InitPieceLoop(board_t, int *, int *, int);
-extern int	NextPieceLoop(board_t, int *, int *, int);
-
-extern int	backup_move(int, int);
-extern int	execute_move(game_state_t *, move_t *, int);
-extern int	in_check(game_state_t *);
-extern int	is_move(char *);
-extern int	legal_andcheck_move(game_state_t *, int, int, int, int);
-extern int	legal_move(game_state_t *, int, int, int, int);
-extern int	parse_move(char *, game_state_t *, move_t *, int);
+extern int is_move(char *);
+extern int parse_move(char *, game_state_t *, move_t *, int);
+extern int execute_move(game_state_t *, move_t *, int);
+extern int backup_move(int, int);
+
+/* Some useful chess utilities */
+extern int NextPieceLoop(board_t, int *, int *, int);
+extern int InitPieceLoop(board_t, int *, int *, int);
+extern int legal_move(game_state_t *, int, int, int, int);
+extern int legal_andcheck_move(game_state_t *, int, int, int, int);
+extern int in_check(game_state_t *);
 
 #endif /* _MOVECHECK_H */
-- 
cgit v1.2.3