Well the only place I saw to post that let attach files was the bug tracker
ticket thing. So I will try one more time here. Hopefully this does not
spam out the patch file into the page again. I will attach it without the
big pgn.
Index: src/game.cpp
===================================================================
--- src/game.cpp        (revision 2569)
+++ src/game.cpp        (working copy)
@@ -473,7 +473,8 @@
 void
 Game::SaveState ()
 {
-    if (!SavedPos) { SavedPos = new Position; }
+    if (!SavedPos) { SavedPos = new Position(this); }
+    CurrentPos->SetOwner(this); // just in case?
     SavedPos->CopyFrom (CurrentPos);
     SavedMove = CurrentMove;
     SavedPlyCount = CurrentPlyCount;
@@ -490,6 +491,7 @@
     if (SavedMove) {
         ASSERT (SavedPos != NULL);
         CurrentPos->CopyFrom (SavedPos);
+        CurrentPos->SetOwner(this);
         CurrentMove = SavedMove;
         CurrentPlyCount = SavedPlyCount;
         VarDepth = SavedVarDepth;
@@ -591,9 +593,9 @@
     StartPos = NULL;
 #ifdef WINCE
     if (!LowMem)
-      CurrentPos = new Position;
+      CurrentPos = new Position(this);
 #else
-    CurrentPos = new Position;
+    CurrentPos = new Position(this);
 #endif
     KeepDecodedMoves = true;
     SavedPos = NULL;
@@ -700,6 +702,10 @@
 
     // Set up standard start
     CurrentPos->StdStart();
+    CurrentPos->SetOwner(this);
+    if ( ! StartPos ) { StartPos = new Position; }
+    StartPos->CopyFrom( CurrentPos );
+
     KeepDecodedMoves = true;
 }
 
@@ -774,8 +780,12 @@
     }
     VarDepth = 0;
     if (!StartPos) { StartPos = new Position; }
+
+    pos->SetOwner(this);
+    
     StartPos->CopyFrom (pos);
     CurrentPos->CopyFrom (pos);
+    //
     // Now make the material signature:
     FinalMatSig = matsig_Make (StartPos->GetMaterial());
     NonStandardStart = true;
@@ -791,7 +801,7 @@
 Game::SetStartFen (const char * fenStr)
 {
     // First try to read the position:
-    Position * pos = new Position;
+    Position * pos = new Position(this);
     errorT err = pos->ReadFromFEN (fenStr);
     if (err != OK) { delete pos; return err; }
 
@@ -803,6 +813,7 @@
     VarDepth = 0;
     if (StartPos) { delete StartPos; }
     StartPos = pos;
+    StartPos->SetOwner(this);
     CurrentPos->CopyFrom (StartPos);
     // Now make the material signature:
     FinalMatSig = matsig_Make (StartPos->GetMaterial());
@@ -965,6 +976,8 @@
         CurrentPos->CopyFrom (StartPos);
     } else {
         CurrentPos->StdStart();
+        CurrentPos->SetOwner(this);
+        StartPos->CopyFrom(CurrentPos);
     }
     CurrentPlyCount = 0;
     for (ushort i=0; i < hmNumber; i++) {
@@ -1360,6 +1373,7 @@
     ASSERT (CurrentMove != NULL);
     while (MoveExitVariation() == OK);  // exit variations
     if (!StartPos) { StartPos = new Position; }
+    CurrentPos->SetOwner(this); // just in case?
     StartPos->CopyFrom (CurrentPos);
     NonStandardStart = true;
     CurrentMove->prev->marker = END_MARKER;
@@ -3753,7 +3767,7 @@
 // encodeKing(): encoding of King moves.
 //
 static inline void
-encodeKing (ByteBuffer * buf, simpleMoveT * sm)
+encodeKing (ByteBuffer * buf, simpleMoveT * sm, Position * pos)
 {
     // Valid King difference-from-old-square values are:
     // -9, -8, -7, -1, 1, 7, 8, 9, and -2 and 2 for castling.
@@ -3763,6 +3777,31 @@
 
     ASSERT(sm->pieceNum == 0);  // Kings MUST be piece Number zero.
     int diff = (int) sm->to - (int) sm->from;
+
+    squareT kr = NS;
+    squareT qr = NS;
+    rankT krank = square_Rank(sm->from);
+    
+    pieceT * board = pos->GetBoard();
+
+    pieceT friendlyrook = piece_Make( pos->GetToMove(), ROOK );
+
+    squareT kcur;
+    
+    kcur = sm->from;
+    while ( square_Rank(kcur) == krank ) {
+        if ( board[kcur] == friendlyrook ) { kr = kcur; break; }
+        kcur++;
+    }
+    kcur = sm->from;
+    while ( square_Rank(kcur) == krank ) {
+        if ( board[kcur] == friendlyrook ) { qr = kcur; break; }
+        kcur--;
+    }
+
+    if (sm->to == kr) { diff = 2; }
+    if (sm->to == qr) { diff = -2; }
+    
     static const byte val[] = {
     /* -9 -8 -7 -6 -5 -4 -3 -2 -1  0  1   2  3  4  5  6  7  8  9 */
         1, 2, 3, 0, 0, 0, 0, 9, 4, 0, 5, 10, 0, 0, 0, 0, 6, 7, 8
@@ -3785,7 +3824,7 @@
 // decodeKing(): decoding of King moves.
 //
 static inline errorT
-decodeKing (byte val, simpleMoveT * sm)
+decodeKing (byte val, simpleMoveT * sm, Position * pos)
 {
     static const int sqdiff[] = {
         0, -9, -8, -7, -1, 1, 7, 8, 9, -2, 2
@@ -3797,8 +3836,34 @@
     }
 
     if (val < 1  ||  val > 10) { return ERROR_Decode; }
-    sm->to = sm->from + sqdiff[val];
-    return OK;
+    if (val >= 1 && val <= 8) {
+        sm->to = sm->from + sqdiff[val];
+        return OK;
+    }
+    else {
+        int direction;
+        if (val == 9) { direction = -1; }  //queenside
+        if (val == 10) { direction = 1; }  //kingside
+
+        squareT kdest;
+        kdest = NS;
+        squareT kcur = sm->from;
+        rankT krank = square_Rank(sm->from);
+
+        pieceT friendlyrook = piece_Make( pos->GetToMove(), ROOK );
+        pieceT * board = pos->GetBoard();
+
+        while ( square_Rank(kcur) == krank ) {
+            if ( board[kcur] == friendlyrook ) { kdest = kcur; break; }
+            kcur = kcur + direction;
+        }
+        
+        if (kcur != NS) {
+            sm->to = kdest;
+            return OK;
+        }
+    }
+    return ERROR_Decode;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -4129,7 +4194,7 @@
         err = decodeBishop (val & 15, sm);
         break;
     case KING:
-        err = decodeKing (val & 15, sm);
+        err = decodeKing (val & 15, sm, pos);
         break;
     // For queen moves: Rook-like moves are in 1 byte, diagonals are in 2.
     case QUEEN:
@@ -4146,7 +4211,7 @@
 //  Encode one move and output it to the bytebuffer.
 //
 static void
-encodeMove (ByteBuffer * buf, moveT * m)
+encodeMove (ByteBuffer * buf, moveT * m, Position * pos)
 {
     simpleMoveT * sm = &(m->moveData);
     pieceT pt = piece_Type(sm->movingPiece);
@@ -4154,7 +4219,7 @@
     typedef void encodeFnType (ByteBuffer *, simpleMoveT *);
     static encodeFnType * encodeFn[] = {
         NULL         /* 0 */,
-        encodeKing   /*1=KING*/,
+        NULL         /*1=KING*/,
         encodeQueen  /*2=QUEEN*/,
         encodeRook   /*3=ROOK*/,
         encodeBishop /*4=BISHOP*/,
@@ -4162,15 +4227,18 @@
         encodePawn   /*6=PAWN*/
     };
     ASSERT (pt >= KING  &&  pt <= PAWN);
-    (encodeFn[pt]) (buf, sm);
+    if (pt > KING ) { (encodeFn[pt]) (buf, sm); }
+    else {
+        encodeKing(buf, sm, pos);
+    }
 }
-
+//
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// encodeVariation(): Used by Encode() to encode the game's moves.
+// Game::EncodeVariation(): Used by Encode() to encode the game's moves.
 //      Recursive; calls itself to encode subvariations.
 //
-static errorT
-encodeVariation (ByteBuffer * buf, moveT * m, uint * subVarCount,
+errorT
+Game::EncodeVariation (ByteBuffer * buf, moveT * m, uint * subVarCount,
                  uint * nagCount, uint depth)
 {
     ASSERT (m != NULL);
@@ -4180,8 +4248,14 @@
         buf->PutByte (ENCODE_COMMENT);
     }
 
-    while (m->marker != END_MARKER) {
-        encodeMove (buf, m);
+    errorT err;                                  
+    while (m->marker != END_MARKER) {            
+        encodeMove (buf, m, CurrentPos);         
+        err = MoveForward();                     
+        if (err != OK) { 
+            m = m->next;
+            continue; 
+        } 
         for (uint i=0; i < (uint) m->nagCount; i++) {
             buf->PutByte (ENCODE_NAG);
             buf->PutByte (m->nags[i]);
@@ -4195,7 +4269,7 @@
             for (uint i=0; i < m->numVariations; i++) {
                 *subVarCount += 1;
                 buf->PutByte (ENCODE_START_MARKER);
-                encodeVariation (buf, subVar->next, subVarCount, nagCount, 
depth+1);
+                EncodeVariation (buf, subVar->next, subVarCount, nagCount, 
depth+1);
                 subVar = subVar->varChild;
             }
         }
@@ -4501,7 +4575,8 @@
     // Now the movelist:
     uint varCount = 0;
     uint nagCount = 0;
-    err = encodeVariation (buf, FirstMove->next, &varCount, &nagCount, 0);
+    MoveToPly(0);
+    err = EncodeVariation (buf, FirstMove->next, &varCount, &nagCount, 0);
     if (err != OK) { return err; }
 
     // Now do the comments
@@ -4689,6 +4764,7 @@
             NonStandardStart = 0;
             return err;
         }
+        StartPos->SetOwner(this);
         CurrentPos->CopyFrom (StartPos);
     }
 
@@ -4737,6 +4813,7 @@
             NonStandardStart = 0;
             return err;
         }
+        StartPos->SetOwner(this);
         *CurrentPos = *StartPos;
     }
 
Index: src/game.h
===================================================================
--- src/game.h  (revision 2569)
+++ src/game.h  (working copy)
@@ -327,6 +327,8 @@
     errorT     DecodeTags (ByteBuffer * buf, bool storeTags);
     errorT     DecodeVariation (ByteBuffer * buf, byte flags, uint level);
 
+    errorT     EncodeVariation (ByteBuffer * buf, moveT * m, uint * 
subVarCount, uint * nagCount, uint depth);
+
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     //  Game:  Public Functions
 public:
Index: src/movelist.h
===================================================================
--- src/movelist.h      (revision 2569)
+++ src/movelist.h      (working copy)
@@ -46,6 +46,11 @@
     squareT  epSquare;       // pre-move information
     ushort   oldHalfMoveClock;
     int      score;          // used for alpha/beta ordering.
+
+    squareT  kingFrom;
+    squareT  kingTo;
+    squareT  rookFrom;
+    squareT  rookTo;
 };
 
 inline bool isNullMove (simpleMoveT * sm)
Index: src/position.cpp
===================================================================
--- src/position.cpp    (revision 2569)
+++ src/position.cpp    (working copy)
@@ -14,6 +14,7 @@
 
 #include "common.h"
 #include "position.h"
+#include "game.h"
 #include "attacks.h"
 #include "misc.h"
 #include "sqlist.h"
@@ -295,6 +296,32 @@
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Position::GetRookOrigSq():
+//    Get the original square of a rook
+//    Uses newly programmed pointer to the owner game so we
+//    can use it to find the rook in it's StartPos
+//
+squareT
+Position::GetRookOrigSq( colorT tomove, int dir ) {
+    Game * thisgame = GetOwner();
+    if ( thisgame != NULL ) {
+        Position * startpos = thisgame->GetStartPos();
+        if ( startpos != NULL ) {
+            pieceT * startboard = startpos->GetBoard();
+            squareT kSquare = startpos->GetKingSquare(tomove);
+            rankT kRank = square_Rank(kSquare);
+            pieceT friendlyRook = piece_Make(ToMove, ROOK);
+            for (squareT sq = kSquare; square_Rank(sq) == kRank; sq=sq+dir) {
+                if (startboard[sq] == friendlyRook) {
+                    return sq;
+                }
+            }
+        }
+    }
+    return NS;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Position::GenCastling():
 //    Generate the legal castling moves.
 //    Assumes the side to move is NOT in check, so the caller
@@ -305,44 +332,68 @@
 {
     ASSERT (! IsKingInCheck());
     squareT from = GetKingSquare(ToMove);
-    if (from != (ToMove == WHITE ? E1 : E8))  { return; }
     squareT enemyKingSq = GetEnemyKingSquare();
-    squareT target, skip, rookSq;
-    pieceT rookPiece;
+    
+    squareT krookOrig = GetRookOrigSq ( ToMove, 1 );
+    squareT qrookOrig = GetRookOrigSq ( ToMove, -1 );
 
-    // Try kingside first
+    for ( int dir = -1; dir < 2; dir++ ) {
+        if ( dir == 0 ) { continue; }
+        bool ok = false;
+        if ( dir == -1 and (!StrictCastling  ||  GetCastling (ToMove, QSIDE)) 
) { ok = true; }
+        if ( dir == 1 and (!StrictCastling  ||  GetCastling (ToMove, KSIDE)) ) 
{ ok = true; }
+        if ( ! ok ) { continue; }
 
-    // Kingside Castling:
-    if (!StrictCastling  ||  GetCastling (ToMove, KSIDE)) {
-        if (ToMove == WHITE) {
-            target = G1; skip = F1; rookSq = H1; rookPiece = WR;
-        } else {
-            target = G8; skip = F8; rookSq = H8; rookPiece = BR;
-        }
-        if (Board[target] == EMPTY  &&  Board[skip] == EMPTY
-                &&  Board[rookSq] == rookPiece
-                &&  CalcNumChecks (target) == 0
-                &&  CalcNumChecks (skip) == 0
-                &&  ! square_Adjacent (target, enemyKingSq)) {
-            AddLegalMove (mlist, from, target, EMPTY);
-        }
-    }
+        for ( squareT rookSq = from; square_Rank(rookSq) == square_Rank(from); 
rookSq=rookSq+dir ) {
+            if ( Board[rookSq] == piece_Make(ToMove, ROOK) ) { 
+                if ( dir == -1 && rookSq != qrookOrig ) { break; } // correct 
side, wrong rook
+                if ( dir == 1 && rookSq != krookOrig ) { break; } // correct 
side, wrong rook
+                squareT furthest_left, furthest_right, king_left, king_right;
+                squareT kdest, rdest;
+                squareT kingSq = from;
 
-    // Queenside Castling:
-    if (!StrictCastling  ||  GetCastling (ToMove, QSIDE)) {
-        if (ToMove == WHITE) {
-            target = C1; skip = D1; rookSq = A1; rookPiece = WR;
-        } else {
-            target = C8; skip = D8; rookSq = A8; rookPiece = BR;
+                if ( dir > 0 ) {
+                    kdest = (ToMove == WHITE ? G1 : G8);
+                    rdest = (ToMove == WHITE ? F1 : F8);
+                }
+                if (dir < 0) {
+                    kdest = (ToMove == WHITE ? C1 : C8);
+                    rdest = (ToMove == WHITE ? D1 : D8);
+                }
+                furthest_left = kdest;
+                if (kingSq < furthest_left) { furthest_left = kingSq; }
+                if (rookSq < furthest_left) { furthest_left = rookSq; }
+                if (rdest < furthest_left) { furthest_left = rdest; }
+
+                king_left = kdest;
+                if (kingSq < king_left) { king_left = kingSq; }
+
+                furthest_right = kdest;
+                if (kingSq > furthest_right) { furthest_right = kingSq; }
+                if (rookSq > furthest_right) { furthest_right = rookSq; }
+                if (rdest > furthest_right) { furthest_right = rdest; }
+
+                king_right = kdest;
+                if (kingSq > king_right) { king_right = kingSq; }
+                
+                bool ok2 = true;
+                for (squareT sq = king_left; sq <= king_right; sq++) {
+                    if (CalcNumChecks(sq) > 0) { ok2 = false; break; }
+                    if (square_Adjacent (sq, enemyKingSq)) { ok2 = false; 
break; }
+                }
+
+                if ( ! ok2 ) { break; }
+
+                uint piececount = 0;
+                for (squareT sq = furthest_left; sq <= furthest_right; sq++) {
+                    if (Board[sq] != EMPTY) { piececount++ ; }
+                }
+                if (piececount > 2) { break; }
+
+                AddLegalMove (mlist, from, rookSq, EMPTY);
+                break;
+            }
         }
-        if (Board[target] == EMPTY  &&  Board[skip] == EMPTY
-                &&  Board[rookSq] == rookPiece
-                &&  Board[target - 1] == EMPTY // B1 or B8 must be empty too!
-                &&  CalcNumChecks (target) == 0
-                &&  CalcNumChecks (skip) == 0
-                &&  ! square_Adjacent (target, enemyKingSq)) {
-            AddLegalMove (mlist, from, target, EMPTY);
-        }
     }
 }
 
@@ -563,9 +614,10 @@
 //      Initialise the position after it is constructed.
 //
 void
-Position::Init (void)
+Position::Init (Game * owner)
 {
     // Setting up a valid board is left to StdStart() or Clear().
+    Owner = owner;
     Board [COLOR_SQUARE] = EMPTY;
     Board [NULL_SQUARE] = END_OF_BOARD;
        LegalMoves.Clear();
@@ -1252,51 +1304,83 @@
     squareT kingSq = GetKingSquare(ToMove);
     sint diff = (int)target - (int) kingSq;
 
-    // Valid diffs are: -9, -8, -7, -2, -1, 1, 2, 7, 8, 9. (-2,2: Castling)
-
-    if (diff < -9  ||  diff > 9) { return ERROR_InvalidMove; }
-    if (diff > -7  &&  diff < -2) { return ERROR_InvalidMove; }
-    if (diff > 2  &&  diff < 7) { return ERROR_InvalidMove; }
     if (diff == 0) { return ERROR_InvalidMove; }
 
-    if (diff == 2) { // KingSide Castling
-        if (kingSq != (ToMove == WHITE ? E1 : E8)) {
-            return ERROR_InvalidMove;
+    squareT rookSq;
+    rankT kingRnk = square_Rank(kingSq);
+    rankT targetRnk = square_Rank(target);
+
+    bool castle_attempt = false;
+    if ( Board[target] == piece_Make(ToMove, ROOK) ) { 
+        castle_attempt = true; 
+    }
+    if (! castle_attempt) {
+        if (targetRnk != kingRnk) {
+            if (diff < -9  ||  diff > 9) { return ERROR_InvalidMove; }
+            if (diff > -6  &&  diff < 6) { return ERROR_InvalidMove; }
         }
-        if (StrictCastling  &&  ! GetCastling (ToMove, KSIDE)) {
-            return ERROR_InvalidMove;
+        else if ( diff > 1 || diff < -1 ) { return ERROR_InvalidMove; }
+    }
+
+    //check for all squares king has to move not touched by king or in check
+    //check all furthest  only occupied by 2 pieces
+
+    squareT enemyKingSq = GetEnemyKingSquare();
+
+    if (castle_attempt) {
+        rookSq = target;
+
+        squareT furthest_left, furthest_right, king_left, king_right;
+        squareT kdest, rdest;
+
+        if ( diff > 0 ) { // KingSide Castling
+            if ( rookSq != GetRookOrigSq ( ToMove, 1 ) ) { return 
ERROR_InvalidMove; }
+            kdest = (ToMove == WHITE ? G1 : G8);
+            rdest = (ToMove == WHITE ? F1 : F8);
         }
+        if (diff < 0) { // Queenside Castling
+            if ( rookSq != GetRookOrigSq ( ToMove, -1 ) ) { return 
ERROR_InvalidMove; }
+            kdest = (ToMove == WHITE ? C1 : C8);
+            rdest = (ToMove == WHITE ? D1 : D8);
+        }
 
-        // XXX We also need to verify that the target square does not
-        //     lie adjacent to the location of the enemy king!
+        furthest_left = kdest;
+        if (kingSq < furthest_left) { furthest_left = kingSq; }
+        if (rookSq < furthest_left) { furthest_left = rookSq; }
+        if (rdest < furthest_left) { furthest_left = rdest; }
 
-        if (Board[kingSq + 1] != EMPTY  ||  Board[kingSq + 2] != EMPTY
-            ||  CalcNumChecks(kingSq) > 0
-            ||  CalcNumChecks(kingSq + 1) > 0
-            ||  CalcNumChecks(kingSq + 2) > 0) {
-            return ERROR_InvalidMove;
+        king_left = kdest;
+        if (kingSq < king_left) { king_left = kingSq; }
+
+        furthest_right = kdest;
+        if (kingSq > furthest_right) { furthest_right = kingSq; }
+        if (rookSq > furthest_right) { furthest_right = rookSq; }
+        if (rdest > furthest_right) { furthest_right = rdest; }
+
+        king_right = kdest;
+        if (kingSq > king_right) { king_right = kingSq; }
+
+        for (squareT sq = king_left; sq <= king_right; sq++) {
+            if (CalcNumChecks(sq) > 0) { return ERROR_InvalidMove; }
         }
-        AddLegalMove (mlist, kingSq, target, EMPTY);
-        return OK;
-    }
 
-    if (diff == -2) { // Queenside Castling
-        if (kingSq != (ToMove == WHITE ? E1 : E8)) {
-            return ERROR_InvalidMove;
+        uint piececount = 0;
+        for (squareT sq = furthest_left; sq <= furthest_right; sq++) {
+            if (Board[sq] != EMPTY) { piececount++ ; }
         }
-        if (StrictCastling  &&  ! GetCastling (ToMove, QSIDE)) {
-            return ERROR_InvalidMove;
+        if (piececount > 2) { return ERROR_InvalidMove; }
+
+        bool ok2 = true;
+        for (squareT sq = king_left; sq <= king_right; sq++) {
+            if (CalcNumChecks(sq) > 0) { ok2 = false; break; }
+            if (square_Adjacent (sq, enemyKingSq)) { ok2 = false; break; }
         }
-        if (Board[kingSq - 1] != EMPTY  ||  Board[kingSq - 2] != EMPTY
-            ||  Board[kingSq - 3] != EMPTY
-            ||  CalcNumChecks(kingSq) > 0
-            ||  CalcNumChecks(kingSq - 1) > 0
-            ||  CalcNumChecks(kingSq - 2) > 0) {
-            return ERROR_InvalidMove;
-        }
+        if (!ok2) { return ERROR_InvalidMove; }
+
         AddLegalMove (mlist, kingSq, target, EMPTY);
         return OK;
     }
+
     pieceT captured = Board[target];
     if (piece_Color(captured) == ToMove) {
         // Capturing a friendly piece!
@@ -1307,6 +1391,8 @@
     // leaves the King in check:
     // XXX We should also check for adjacency to enemy King!!
 
+    // why not get rid of :
+    /*
     Board[target] = piece_Make(ToMove, KING);
     Board[kingSq] = EMPTY;
     if (captured != EMPTY) { Material[captured]--; }
@@ -1319,10 +1405,18 @@
         AddLegalMove (mlist, kingSq, target, EMPTY);
         return OK;
     }
+    */
+    // and just do:
+    if ( CalcNumChecks(target) == 0 && ! square_Adjacent (target, enemyKingSq) 
) {
+        AddLegalMove (mlist, kingSq, target, EMPTY);
+        return OK;
+    }
+
+
+
     return ERROR_InvalidMove;
 }
 
-
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Position::GenCheckEvasions():
 //      Generate legal moves for the side to move when the
@@ -1820,6 +1914,25 @@
     sm->epSquare = EPTarget;
     sm->oldHalfMoveClock = HalfMoveClock;
 
+    sm->kingTo = NS;
+    sm->kingFrom = NS;
+    sm->rookFrom = NS;
+    sm->rookTo = NS;
+
+    if ( ptype == KING && Board[to] == piece_Make( ToMove, ROOK) ) { 
+        sm->capturedPiece = EMPTY; 
+        sm->kingFrom = from;
+        sm->rookFrom = to;
+        if (from < to) {  //kingside
+            sm->kingTo = ( ToMove == WHITE ? G1 : G8 );
+            sm->rookTo = ( ToMove == WHITE ? F1 : F8 );
+        }
+        else {  //queenside
+            sm->kingTo = ( ToMove == WHITE ? C1 : C8 );
+            sm->rookTo = ( ToMove == WHITE ? D1 : D8 );
+        }
+    }
+
     HalfMoveClock++;
     PlyCounter++;
        LegalMoves.Clear();
@@ -1871,28 +1984,30 @@
     }
 
     // now make the move:
-    List[ToMove][sm->pieceNum] = to;
-    ListPos[to] = sm->pieceNum;
-    RemoveFromBoard (p, from);
-    AddToBoard (p, to);
+    if ( sm->kingFrom == NS ) { // not castling
+        List[ToMove][sm->pieceNum] = to;
+        ListPos[to] = sm->pieceNum;
+        RemoveFromBoard (p, from);
+        AddToBoard (p, to);
+    }
 
     // handle Castling:
 
-    if (ptype == KING  &&  square_Fyle(from) == E_FYLE  &&
-            (square_Fyle(to) == C_FYLE  ||  square_Fyle(to) == G_FYLE)) {
-        squareT rookfrom, rookto;
+    if ( sm->kingFrom != NS ) { // castling
         pieceT rook = piece_Make (ToMove, ROOK);
-        if (square_Fyle(to) == C_FYLE) {
-            rookfrom = to - 2;
-            rookto = to + 1;
-        } else {
-            rookfrom = to + 1;
-            rookto = to - 1;
-        }
-        ListPos[rookto] = ListPos[rookfrom];
-        List[ToMove][ListPos[rookto]] = rookto;
-        RemoveFromBoard (rook, rookfrom);
-        AddToBoard (rook, rookto);
+
+        byte king_pieceNum = sm->pieceNum;
+        byte rook_pieceNum = ListPos[sm->rookFrom];
+
+        List[ToMove][king_pieceNum] = sm->kingTo;
+        List[ToMove][rook_pieceNum] = sm->rookTo;
+        ListPos[sm->kingTo] = king_pieceNum;
+        ListPos[sm->rookTo] = rook_pieceNum;
+
+        RemoveFromBoard (p, sm->kingFrom);
+        RemoveFromBoard (rook, sm->rookFrom);
+        AddToBoard (p, sm->kingTo);
+        AddToBoard (rook, sm->rookTo);
     }
 
     // Handle clearing of castling flags:
@@ -1903,6 +2018,7 @@
             SetCastling (ToMove, KSIDE, false);
         }
         // See if a rook moved or was captured:
+/*
         if (ToMove == WHITE) {
             if (from == A1)  { SetCastling (WHITE, QSIDE, false); }
             if (from == H1)  { SetCastling (WHITE, KSIDE, false); }
@@ -1914,6 +2030,24 @@
             if (to == A1)    { SetCastling (WHITE, QSIDE, false); }
             if (to == H1)    { SetCastling (WHITE, KSIDE, false); }
         }
+*/
+
+        squareT WKR_sq = GetRookOrigSq ( WHITE, 1 );
+        squareT WQR_sq = GetRookOrigSq ( WHITE, -1 );
+        squareT BKR_sq = GetRookOrigSq ( BLACK, 1 );
+        squareT BQR_sq = GetRookOrigSq ( BLACK, -1 );
+
+        if (ToMove == WHITE) {
+            if (from == WQR_sq)  { SetCastling (WHITE, QSIDE, false); }
+            if (from == WKR_sq)  { SetCastling (WHITE, KSIDE, false); }
+            if (to == BQR_sq)    { SetCastling (BLACK, QSIDE, false); }
+            if (to == BKR_sq)    { SetCastling (BLACK, KSIDE, false); }
+        } else {
+            if (from == BQR_sq)  { SetCastling (BLACK, QSIDE, false); }
+            if (from == BKR_sq)  { SetCastling (BLACK, KSIDE, false); }
+            if (to == WQR_sq)    { SetCastling (WHITE, QSIDE, false); }
+            if (to == WKR_sq)    { SetCastling (WHITE, KSIDE, false); }
+        }
     }
 
     // Set the EPTarget square, if a pawn advanced two squares and an
@@ -2000,29 +2134,37 @@
 
     // now make the move:
 
-    List[ToMove][m->pieceNum] = from;
-    ListPos[from] = m->pieceNum;
-    RemoveFromBoard (p, to);
-    AddToBoard (p, from);
-    if (m->capturedPiece != EMPTY) {
-        AddToBoard (m->capturedPiece, m->capturedSquare);
+    if ( m->kingFrom > H8 ) { // not castling
+        List[ToMove][m->pieceNum] = from;
+        ListPos[from] = m->pieceNum;
+        RemoveFromBoard (p, to);
+        AddToBoard (p, from);
+        if (m->capturedPiece != EMPTY) {
+            AddToBoard (m->capturedPiece, m->capturedSquare);
+        }
     }
 
     // handle Castling:
 
-    if ((piece_Type(p) == KING) && square_Fyle(from) == E_FYLE
-            && (square_Fyle(to) == C_FYLE || square_Fyle(to) == G_FYLE)) {
-        squareT rookfrom, rookto;
+    if ( m->kingFrom <= H8 ) { // castling
+        m->pieceNum = ListPos[m->kingTo];
+        p = Board[m->kingTo];
         pieceT rook = (ToMove == WHITE? WR : BR);
-        if (square_Fyle(to) == C_FYLE) {
-            rookfrom = to - 2;   rookto = to + 1;
-        } else {
-            rookfrom = to + 1;   rookto = to - 1;
-        }
-        ListPos[rookfrom] = ListPos[rookto];
-        List[ToMove][ListPos[rookto]] = rookfrom;
-        RemoveFromBoard (rook, rookto);
-        AddToBoard (rook, rookfrom);
+
+        byte king_pieceNum = m->pieceNum;
+        byte rook_pieceNum = ListPos[m->rookTo];
+
+        List[ToMove][king_pieceNum] = m->kingFrom;
+        List[ToMove][rook_pieceNum] = m->rookFrom;
+        ListPos[m->kingFrom] = king_pieceNum;
+        ListPos[m->rookFrom] = rook_pieceNum;
+
+        RemoveFromBoard (p, m->kingTo);
+        RemoveFromBoard (rook, m->rookTo);
+        AddToBoard (p, m->kingFrom);
+        AddToBoard (rook, m->rookFrom);
+
+        m->to = m->rookFrom;
     }
 
 #ifdef ASSERTIONS
@@ -2136,6 +2278,7 @@
 
     // Make sure m->pieceNum is updated:
     m->pieceNum = ListPos[m->from];
+
     pieceT  p    = piece_Type (Board[List[ToMove][m->pieceNum]]);
     squareT from = List[ToMove][m->pieceNum];
     squareT to   = m->to;
@@ -2158,11 +2301,13 @@
             //*c++ = 'n'; *c++ = 'u'; *c++ = 'l'; *c++ = 'l';
             *c++ = '-'; *c++ = '-';
         } else
-        if ((square_Fyle(from)==E_FYLE) && (square_Fyle(to)==G_FYLE)) {
-            *c++ = 'O'; *c++ = '-'; *c++ = 'O';
-        } else
-        if ((square_Fyle(from)==E_FYLE) && (square_Fyle(to)==C_FYLE)) {
-            *c++ = 'O'; *c++ = '-'; *c++ = 'O'; *c++ = '-'; *c++ = 'O';
+        if ( Board[to] == piece_Make(ToMove,ROOK) ) {
+            if (from < to) {
+                *c++ = 'O'; *c++ = '-'; *c++ = 'O';
+            }
+            else {
+                *c++ = 'O'; *c++ = '-'; *c++ = 'O'; *c++ = '-'; *c++ = 'O';
+            }
         } else {  // regular King move
             *c++ = 'K';
             if (Board[to] != EMPTY)  *c++ = 'x';
@@ -2430,9 +2575,22 @@
     // Here we handle piece moves, including castling
     if (token != TOKEN_Move_Piece) {  // Must be castling move
         ASSERT (token == TOKEN_Move_Castle_King  ||  token == 
TOKEN_Move_Castle_Queen);
-        from = (ToMove == WHITE ? E1 : E8);
-        if (GetKingSquare(ToMove) != from) { return ERROR_InvalidMove; }
-        to = (token == TOKEN_Move_Castle_King ? (from + 2) : (from - 2));
+
+        rankT kingrank;
+        from = GetKingSquare(ToMove);
+        kingrank = square_Rank(from);
+
+        int direction = ( token == TOKEN_Move_Castle_King ? 1 : -1 );
+
+        for (squareT sq = from + direction; square_Rank(sq) == kingrank; sq = 
sq + direction) {
+            if ( Board[sq] == piece_Make(ToMove, ROOK) ) {
+                to = sq;
+                break;
+            }
+        }
+
+        if (to == NS) { return ERROR_InvalidMove; }
+
         if (MatchKingMove (&mlist, to) != OK) {
             return ERROR_InvalidMove;
         } else {
Index: src/position.h
===================================================================
--- src/position.h      (revision 2569)
+++ src/position.h      (working copy)
@@ -24,6 +24,8 @@
 #include "sqset.h"
 #include "tokens.h"
 
+class Game;
+
 //////////////////////////////////////////////////////////////////////
 //  Position:  Constants
 
@@ -77,6 +79,8 @@
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     //  Position:  Data structures
 
+    Game *          Owner;
+
     pieceT          Board[66];      // the actual board + a color square
                                     // and a NULL square.
     uint            Count[2];       // count of pieces & pawns each
@@ -157,11 +161,12 @@
   }
 
 #endif
-    Position()   { Init(); }
+    Position()   { Init( NULL ); }
+    Position(Game * owner)   { Init( owner ); }
     Position(const Position& p);
     ~Position()  {}
 
-    void        Init();
+    void        Init(Game * owner);
     void        Clear();        // No pieces on board
     void        StdStart();     // Standard chess starting position
     bool        IsStdStart();
@@ -179,6 +184,10 @@
     ushort      GetPlyCounter ()         { return PlyCounter; }
     ushort      GetFullMoveCount ()      { return PlyCounter / 2 + 1; }
 
+    Game *      GetOwner()               { return Owner; }
+    void        SetOwner(Game * owner)   { Owner = owner; }
+    squareT     GetRookOrigSq( colorT tomove, int dir );
+
     // Methods to get the Board or piece lists -- used in game.cpp to
     // decode moves:
     squareT *   GetList (colorT c)    { return List[c]; }
Index: src/tkscid.cpp
===================================================================
--- src/tkscid.cpp      (revision 2569)
+++ src/tkscid.cpp      (working copy)
@@ -516,8 +516,8 @@
     clipbase->backupCache->SetPolicy (TREECACHE_Oldest);
 
     currentBase = 0;
-    scratchPos = new Position;
     scratchGame = new Game;
+    scratchPos = new Position(scratchGame);
     db = &(dbList[currentBase]);
 
 #ifndef TCL_ONLY
@@ -14947,6 +14947,7 @@
         char cboard [40];
         pos->PrintCompactStrFlipped (cboard);
         posFlip->ReadFromCompactStr ((byte *) cboard);
+        posFlip->SetOwner(db->game);
         hpSigFlip = posFlip->GetHPSig();
         msigFlip = matsig_Make (posFlip->GetMaterial());
     }
------------------------------------------------------------------------------
_______________________________________________
Scidvspc-users mailing list
Scidvspc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/scidvspc-users

Reply via email to