Chess Bin

Computer Chess Information and Resources

Computer Chess Information and Resources

This website is a product of a rather rash decision in mid 2008 to learn to program my own Chess Game, hence began my journey into the art of computer chess.  Over the last 2 years I have made some significant progress.  I have learned quite a bit about the art of Computer Chess and amazingly I managed to build an reasonable strong chess engine.  This website is dedicated to documenting the development of my Chess Game as well as the field of Computer Chess in general

In April 2009 I have also begun working on an Online Chess System that allows users to play chess against each other.  This has spun off to a whole new website: GeeksWithChess.com dedicated to hosting my free online chess server.  This website is possible mostly due to the chess engine developed here as my live chess system uses my chess engine to validate and track moves. 

On this site you will find the following information:


Chess Engine Source Code

The index of all the computer chess blog posts documenting the development my chess engine, along with the source code and its explanation.

Online Chess

Free Online Chess Game that will allow you to play for free against the ChessBin.com chess engine and other members.

Chess Game For Windows

Free Windows Chess Game Download, based on the ChessBin.com chess engine

Computer Chess Links

Computer Chess Links that I have collected over the course of my research.



Onlinecasinos.co.uk provides you with links to the top UK online casinos and the best information about the exciting world of UK gaming. Scroll through our game reviews, read our casino recommendations and start playing!  There are also many online casino games available, see them all here.

When you play chess online you are involved in a game of skill - the outcome is based on your skill. When you play casino games online, the skill factor is limited. But there are some things you can do to boost your bankroll and to help you get more money to wager with. You can start by finding exclusive casino bonuses and bonus reviews of online casinos at a reliable and trusted site like CasinoShortlist.org.

While chess games have been available on mobiles for years, many Canadian online casinos are only now offering mobile casino games. To try your luck at a mobile online casino, visit CanadianOnlinecasinos.club

Do you dream of winning the big jackpot? Try casino games online with Casinohawks.com and experience the thrill online. Visit Casinohawks.com and take advantage of great bonuses and promotions at the most popular British gambling companies.

ChessBin.com is created and maintained by Adam Berent. For more information visit www.adamberent.com

Chess Bin | All posts tagged 'chess-piece-motion'

Chess Bin

Computer Chess Information and Resources

Chess Piece Valid Moves

Originally the code in this post was part of the Chess Piece Motion class.  However since I posted the ordinal code I have divided that class into 2 separate classes.  Chess Piece Moves and Chess Piece Valid moves which is discussed here.

This class will be responsible for dynamically figuring out only the valid moves for the current chess board and assigning only the valid moves to each chess piece.  This class will also figure out what pieces are attacking each other, is the king in check, has en passant occurred and assign the information to each piece for the purpose of score evaluation.

The Chess Piece Valid Moves class will be declared as follows:


internal static class PieceValidMoves

To help us understand what is board squares are being attacked we will defina 2 arrays.  One for storing board squares attacked by White, and one for Black.  These arrays are crucial in figuring out things like valid moves for a king, since kings cannot move onto a square that is currently attacked by an opponent.


internal static bool[] BlackAttackBoard;
internal static bool[] WhiteAttackBoard;

Furthermore we can't correctly check for the kings valid moves until we examine all other chess pieces.  This is due to the fact that we won't know if the chess board square is attacked if we don't look at every single chess piece first.  For this reason when we come across a king during our analysis, we don't analyze its possible moves but rather store its position for later analysis.  The following 2 variables are used to store that information.


private static byte BlackKingPosition;
private static byte WhiteKingPosition;

The Analyze Move method will perform a deep analysis or examination of the move itself and its effect on the chess board.  For example this method will record an En Passant scenario as well as recording Checks and Kills.  The Analyze Move method will return true if the move is considered not blocked (not resulting in a kill or blocked by another chess piece of the same color).  Similarly it will return false if the move is blocked and movement cannot continue past this position.  This is very important since this return value will be used to end a loop of moves in a certain direction.  This method is called for all chess pieces other than pawns and kings.

private static bool AnalyzeMove(Board board, byte dstPos, Piece pcMoving)
{
    //If I am not a pawn everywhere I move I can attack
    if (pcMoving.PieceColor == ChessPieceColor.White)
    {
        WhiteAttackBoard[dstPos] = true;
    }
    else
    {
        BlackAttackBoard[dstPos] = true;
    }

    //If there no piece there I can potentialy kill just add the move and exit
    if (board.Squares[dstPos].Piece == null)
    {
        pcMoving.ValidMoves.Push(dstPos);

        return true;
    }

    Piece pcAttacked = board.Squares[dstPos].Piece;

    //if that piece is a different color
    if (pcAttacked.PieceColor != pcMoving.PieceColor)
    {
        pcAttacked.AttackedValue += pcMoving.PieceActionValue;

        //If this is a king set it in check                  
        if (pcAttacked.PieceType == ChessPieceType.King)
        {
            if (pcAttacked.PieceColor == ChessPieceColor.Black)
            {
                board.BlackCheck = true;
            }
            else
            {
                board.WhiteCheck = true;
            }
        }
        else
        {
            //Add this as a valid move
            pcMoving.ValidMoves.Push(dstPos);
        }


        //We don't continue movement past this piece
        return false;
    }
    //Same Color I am defending
    pcAttacked.DefendedValue += pcMoving.PieceActionValue;

    //Since this piece is of my kind I can't move there
    return false;
}

Pawns behave slightly differently then regular pieces in that not all of their moves can result in a kill.  A move straight ahead cannon result in a kill while a diagonal move can.  For this reason there are two separate methods to analyze pawn moves.   One Parent that loops through all available pawn moves and one child that analyzes each move at a time.

Parent:

private static void CheckValidMovesPawn(List<byte> moves, Piece pcMoving,
          byte srcPosition,
          Board board, byte count)
{
 for (byte i = 0; i < count; i++)
 {
  byte dstPos = moves[i];

  if (dstPos%8 != srcPosition%8)
  {
   //If there is a piece there I can potentialy kill
   AnalyzeMovePawn(board, dstPos, pcMoving);

   if (pcMoving.PieceColor == ChessPieceColor.White)
   {
    WhiteAttackBoard[dstPos] = true;
   }
   else
   {
    BlackAttackBoard[dstPos] = true;
   }
  }
   // if there is something if front pawns can't move there
  else if (board.Squares[dstPos].Piece != null)
  {
   return;
  }
   //if there is nothing in front of me (blocked == false)
  else
  {
   pcMoving.ValidMoves.Push(dstPos);
  }
 }
}

Child:

private static void AnalyzeMovePawn(Board board, byte dstPos, Piece pcMoving)
{
    //Because Pawns only kill diagonaly we handle the En Passant scenario specialy
    if (board.EnPassantPosition > 0)
    {
        if (pcMoving.PieceColor != board.EnPassantColor)
        {
            if (board.EnPassantPosition == dstPos)
            {
                //We have an En Passant Possible
                pcMoving.ValidMoves.Push(dstPos);

                if (pcMoving.PieceColor == ChessPieceColor.White)
                {
                    WhiteAttackBoard[dstPos] = true;
                }
                else
                {
                    BlackAttackBoard[dstPos] = true;
                }
            }
        }
    }

    Piece pcAttacked = board.Squares[dstPos].Piece;

    //If there no piece there I can potentialy kill
    if (pcAttacked == null)
        return;

    //Regardless of what is there I am attacking this square
    if (pcMoving.PieceColor == ChessPieceColor.White)
    {
        WhiteAttackBoard[dstPos] = true;

        //if that piece is the same color
        if (pcAttacked.PieceColor == pcMoving.PieceColor)
        {
            pcAttacked.DefendedValue += pcMoving.PieceActionValue;
            return;
        }
        //else piece is different so we are attacking
        pcAttacked.AttackedValue += pcMoving.PieceActionValue;

        //If this is a king set it in check                  
        if (pcAttacked.PieceType == ChessPieceType.King)
        {
            board.BlackCheck = true;
        }
        else
        {
            //Add this as a valid move
            pcMoving.ValidMoves.Push(dstPos);
        }
    }
    else
    {
        BlackAttackBoard[dstPos] = true;

        //if that piece is the same color
        if (pcAttacked.PieceColor == pcMoving.PieceColor)
        {
            return;
        }

        //If this is a king set it in check                  
        if (pcAttacked.PieceType == ChessPieceType.King)
        {
            board.WhiteCheck = true;
        }
        else
        {
            //Add this as a valid move
            pcMoving.ValidMoves.Push(dstPos);
        }
    }

    return;
}

Check Valid Moves King Castle Method handles the complicated castling scenarios by examining the chess board squares between the king and the rook to make sure they are empty, not attacked and that the rook and king are both in their starting positions.

private static void GenerateValidMovesKingCastle(Board board, Piece king)
{
 if (king == null)
 {
  return;
 }

 if (king.Moved)
 {
  return;
 }
 if (king.PieceColor == ChessPieceColor.White &&
  board.WhiteCastled)
 {
  return;
 }
 if (king.PieceColor == ChessPieceColor.Black &&
  board.BlackCastled)
 {
  return;
 }
 if (king.PieceColor == ChessPieceColor.Black &&
  board.BlackCheck)
 {
  return;
 }
 if (king.PieceColor == ChessPieceColor.White &&
  board.WhiteCheck)
 {
  return;
 }


 //This code will add the castleling move to the pieces available moves
 if (king.PieceColor == ChessPieceColor.White)
 {
  if (board.WhiteCheck)
  {
   return;
  }

  if (board.Squares[63].Piece != null)
  {
   //Check if the Right Rook is still in the correct position
   if (board.Squares[63].Piece.PieceType == ChessPieceType.Rook)
   {
    if (board.Squares[63].Piece.PieceColor == king.PieceColor)
    {
     //Move one column to right see if its empty
     if (board.Squares[62].Piece == null)
     {
      if (board.Squares[61].Piece == null)
      {
       if (BlackAttackBoard[61] == false &&
        BlackAttackBoard[62] == false)
       {
        //Ok looks like move is valid lets add it
        king.ValidMoves.Push(62);
        WhiteAttackBoard[62] = true;
       }
      }
     }
    }
   }
  }

  if (board.Squares[56].Piece != null)
  {
   //Check if the Left Rook is still in the correct position
   if (board.Squares[56].Piece.PieceType == ChessPieceType.Rook)
   {
    if (board.Squares[56].Piece.PieceColor == king.PieceColor)
    {
     //Move one column to right see if its empty
     if (board.Squares[57].Piece == null)
     {
      if (board.Squares[58].Piece == null)
      {
       if (board.Squares[59].Piece == null)
       {
        if (BlackAttackBoard[58] == false &&
         BlackAttackBoard[59] == false)
        {
         //Ok looks like move is valid lets add it
         king.ValidMoves.Push(58);
         WhiteAttackBoard[58] = true;
        }
       }
      }
     }
    }
   }
  }
 }
 else if (king.PieceColor == ChessPieceColor.Black)
 {
  if (board.BlackCheck)
  {
   return;
  }

  //There are two ways to castle, scenario 1:
  if (board.Squares[7].Piece != null)
  {
   //Check if the Right Rook is still in the correct position
   if (board.Squares[7].Piece.PieceType == ChessPieceType.Rook
    && !board.Squares[7].Piece.Moved)
   {
    if (board.Squares[7].Piece.PieceColor == king.PieceColor)
    {
     //Move one column to right see if its empty

     if (board.Squares[6].Piece == null)
     {
      if (board.Squares[5].Piece == null)
      {
       if (WhiteAttackBoard[5] == false && WhiteAttackBoard[6] == false)
       {
        //Ok looks like move is valid lets add it
        king.ValidMoves.Push(6);
        BlackAttackBoard[6] = true;
       }
      }
     }
    }
   }
  }
  //There are two ways to castle, scenario 2:
  if (board.Squares[0].Piece != null)
  {
   //Check if the Left Rook is still in the correct position
   if (board.Squares[0].Piece.PieceType == ChessPieceType.Rook &&
    !board.Squares[0].Piece.Moved)
   {
    if (board.Squares[0].Piece.PieceColor ==
     king.PieceColor)
    {
     //Move one column to right see if its empty
     if (board.Squares[1].Piece == null)
     {
      if (board.Squares[2].Piece == null)
      {
       if (board.Squares[3].Piece == null)
       {
        if (WhiteAttackBoard[2] == false &&
         WhiteAttackBoard[3] == false)
        {
         //Ok looks like move is valid lets add it
         king.ValidMoves.Push(2);
         BlackAttackBoard[2] = true;
        }
       }
      }
     }
    }
   }
  }
 }
}

The last method in this class is the only non private method in this listing.  The Generate Valid Moves method will be called directly by the chess engine to create valid moves for each chess board it examines.  This method will loop through all chess pieces on the chess board and examine each possible move based on the chess piece’s position.  Please note that we have already calculated each pieces move in the Chess Piece Moves class for every single position on the chess board.  We now just have to figure out which one of those moves is valid and what their results will be.  While we are looping through all of the chess pieces we also collect some information such as how many pawns are in each file, how many pawns are isolated.  At the end of this method we will sum up this information and store it on the Chess Board.

internal static void GenerateValidMoves(Board board)
{
 // Reset Board
 board.BlackCheck = false;
 board.WhiteCheck = false;

 WhiteAttackBoard = new bool[64];
 BlackAttackBoard = new bool[64];

 //Generate Moves
 for (byte x = 0; x < 64; x++)
 {
  Square sqr = board.Squares[x];

  if (sqr.Piece == null)
   continue;

  sqr.Piece.ValidMoves = new Stack<byte>(sqr.Piece.LastValidMoveCount);

  switch (sqr.Piece.PieceType)
  {
   case ChessPieceType.Pawn:
    {
     if (sqr.Piece.PieceColor == ChessPieceColor.White)
     {
      CheckValidMovesPawn(MoveArrays.WhitePawnMoves[x].Moves, sqr.Piece, x,
           board,
           MoveArrays.WhitePawnTotalMoves[x]);
      break;
     }
     if (sqr.Piece.PieceColor == ChessPieceColor.Black)
     {
      CheckValidMovesPawn(MoveArrays.BlackPawnMoves[x].Moves, sqr.Piece, x,
           board,
           MoveArrays.BlackPawnTotalMoves[x]);
      break;
     }

     break;
    }
   case ChessPieceType.Knight:
    {
     for (byte i = 0; i < MoveArrays.KnightTotalMoves[x]; i++)
     {
      AnalyzeMove(board, MoveArrays.KnightMoves[x].Moves[i], sqr.Piece);
     }

     break;
    }
   case ChessPieceType.Bishop:
    {
     for (byte i = 0; i < MoveArrays.BishopTotalMoves1[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.BishopMoves1[x].Moves[i],
          sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.BishopTotalMoves2[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.BishopMoves2[x].Moves[i],
          sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.BishopTotalMoves3[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.BishopMoves3[x].Moves[i],
          sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.BishopTotalMoves4[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.BishopMoves4[x].Moves[i],
          sqr.Piece) ==
       false)
      {
       break;
      }
     }

     break;
    }
   case ChessPieceType.Rook:
    {
     for (byte i = 0; i < MoveArrays.RookTotalMoves1[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.RookMoves1[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.RookTotalMoves2[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.RookMoves2[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.RookTotalMoves3[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.RookMoves3[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.RookTotalMoves4[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.RookMoves4[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }

     break;
    }
   case ChessPieceType.Queen:
    {
     for (byte i = 0; i < MoveArrays.QueenTotalMoves1[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves1[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.QueenTotalMoves2[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves2[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.QueenTotalMoves3[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves3[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.QueenTotalMoves4[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves4[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }

     for (byte i = 0; i < MoveArrays.QueenTotalMoves5[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves5[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.QueenTotalMoves6[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves6[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.QueenTotalMoves7[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves7[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }
     for (byte i = 0; i < MoveArrays.QueenTotalMoves8[x]; i++)
     {
      if (
       AnalyzeMove(board, MoveArrays.QueenMoves8[x].Moves[i], sqr.Piece) ==
       false)
      {
       break;
      }
     }

     break;
    }
   case ChessPieceType.King:
    {
     if (sqr.Piece.PieceColor == ChessPieceColor.White)
     {
      WhiteKingPosition = x;
     }
     else
     {
      BlackKingPosition = x;
     }

     break;
    }
  }
 }


 if (board.WhoseMove == ChessPieceColor.White)
 {
  GenerateValidMovesKing(board.Squares[BlackKingPosition].Piece, board,
          BlackKingPosition);
  GenerateValidMovesKing(board.Squares[WhiteKingPosition].Piece, board,
          WhiteKingPosition);
 }
 else
 {
  GenerateValidMovesKing(board.Squares[WhiteKingPosition].Piece, board,
          WhiteKingPosition);
  GenerateValidMovesKing(board.Squares[BlackKingPosition].Piece, board,
          BlackKingPosition);
 }


 //Now that all the pieces were examined we know if the king is in check
 GenerateValidMovesKingCastle(board, board.Squares[WhiteKingPosition].Piece);
 GenerateValidMovesKingCastle(board, board.Squares[BlackKingPosition].Piece);
}

This concludes the Chess Piece Valid Moves class. 

If you want to get started on creating your own chess engine download my C# Chess Game Starter Kit.

Chess Piece Moves

This post at one point discussed the Chess Piece Motion Class.  I have since then divided the code from this class into two separate classes. 

Piece Moves 
Piece Valid Moves

This post will discuss Piece Moves class.  This class is responsible for providing all available chess piece moves regardless of the state of the chess board.  The information stored in this class will not change throughout the game play so it is static and calculated only once before the game starts.  Having a set of possible moves for any chess piece at any position allows us to later to generate only the valid moves for each chess piece based on the current state of the board. 
 
The Chess Piece Moves listing will contain a Valid Move Set struct.  This struct will be used to store a set of moves available from a single position.


internal struct PieceMoveSet
{
    internal readonly List<byte> Moves;

    internal PieceMoveSet(List<byte> moves)
    {
        Moves = moves;
    }
}


Furthermore we will need some additional array to store all the above move sets for every position on the board.

For example KnightMoves[0]. Moves will return a Knight Moves available from position 0 or A8.  KnightMoves[63] will return all of the possible moves for position 63 or H1.

Some chess pieces can move in a single direction for an undefined number of squares until they reach the end of the board or another chess piece.  For this purpose moves sets for some pieces are divided into several arrays, each describing a move in a certain direction.  This makes it easier to manage these movements in the Chess Piece Valid Moves Class by having the ability to loop through each array until a chess piece or the end of the board is reached and no further.

One other explanation is required around the Total Moves arrays.  Example there is an array called KnightTotalMoves.  This array will hold the number of moves available for every position on the chess board.  This is a performance related addition as it allows me to replace all my foreach loops with regular for loops.  It’s a small performance gain (1%-2%) but they all add up.


internal struct MoveArrays
{
    internal static PieceMoveSet[] BishopMoves1;
    internal static byte[] BishopTotalMoves1;
   
    internal static PieceMoveSet[] BishopMoves2;
    internal static byte[] BishopTotalMoves2;

    internal static PieceMoveSet[] BishopMoves3;
    internal static byte[] BishopTotalMoves3;

    internal static PieceMoveSet[] BishopMoves4;
    internal static byte[] BishopTotalMoves4;

    internal static PieceMoveSet[] BlackPawnMoves;
    internal static byte[] BlackPawnTotalMoves;

    internal static PieceMoveSet[] WhitePawnMoves;
    internal static byte[] WhitePawnTotalMoves;

    internal static PieceMoveSet[] KnightMoves;
    internal static byte[] KnightTotalMoves;

    internal static PieceMoveSet[] QueenMoves1;
    internal static byte[] QueenTotalMoves1;
    internal static PieceMoveSet[] QueenMoves2;
    internal static byte[] QueenTotalMoves2;
    internal static PieceMoveSet[] QueenMoves3;
    internal static byte[] QueenTotalMoves3;
    internal static PieceMoveSet[] QueenMoves4;
    internal static byte[] QueenTotalMoves4;
    internal static PieceMoveSet[] QueenMoves5;
    internal static byte[] QueenTotalMoves5;
    internal static PieceMoveSet[] QueenMoves6;
    internal static byte[] QueenTotalMoves6;
    internal static PieceMoveSet[] QueenMoves7;
    internal static byte[] QueenTotalMoves7;
    internal static PieceMoveSet[] QueenMoves8;
    internal static byte[] QueenTotalMoves8;

    internal static PieceMoveSet[] RookMoves1;
    internal static byte[] RookTotalMoves1;
    internal static PieceMoveSet[] RookMoves2;
    internal static byte[] RookTotalMoves2;
    internal static PieceMoveSet[] RookMoves3;
    internal static byte[] RookTotalMoves3;
    internal static PieceMoveSet[] RookMoves4;
    internal static byte[] RookTotalMoves4;

    internal static PieceMoveSet[] KingMoves;
    internal static byte[] KingTotalMoves;
}


To make use of the above structs we will declare a static class called Piece Moves:

internal static class PieceMoves

To make life a bit easier, we will add a helper method called Position.  This method will accept a chess board column and row, and return a single byte representing the chess board position.  Usually we would not want to use a method like this because it will slow things down.  However this method is only used when the Chess Engine starts when super fast performance is not really all that necessary.


private static byte Position(byte col, byte row)
{
    return (byte)(col + (row * 8));
}

Initiate Chess Piece Motion Class is called only once in the Chess Engine Constructor.  It will construct all of the arrays and call the methods responsible for populating the Move Set arrays will all of the moves for each position on the board for each chess piece.


internal static void InitiateChessPieceMotion()
{
    MoveArrays.WhitePawnMoves = new PieceMoveSet[64];
    MoveArrays.WhitePawnTotalMoves = new byte[64];

    MoveArrays.BlackPawnMoves = new PieceMoveSet[64];
    MoveArrays.BlackPawnTotalMoves = new byte[64];

    MoveArrays.KnightMoves = new PieceMoveSet[64];
    MoveArrays.KnightTotalMoves = new byte[64];

    MoveArrays.BishopMoves1 = new PieceMoveSet[64];
    MoveArrays.BishopTotalMoves1 = new byte[64];

    MoveArrays.BishopMoves2 = new PieceMoveSet[64];
    MoveArrays.BishopTotalMoves2 = new byte[64];

    MoveArrays.BishopMoves3 = new PieceMoveSet[64];
    MoveArrays.BishopTotalMoves3 = new byte[64];

    MoveArrays.BishopMoves4 = new PieceMoveSet[64];
    MoveArrays.BishopTotalMoves4 = new byte[64];

    MoveArrays.RookMoves1 = new PieceMoveSet[64];
    MoveArrays.RookTotalMoves1 = new byte[64];

    MoveArrays.RookMoves2 = new PieceMoveSet[64];
    MoveArrays.RookTotalMoves2 = new byte[64];

    MoveArrays.RookMoves3 = new PieceMoveSet[64];
    MoveArrays.RookTotalMoves3 = new byte[64];

    MoveArrays.RookMoves4 = new PieceMoveSet[64];
    MoveArrays.RookTotalMoves4 = new byte[64];

    MoveArrays.QueenMoves1 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves1 = new byte[64];

    MoveArrays.QueenMoves2 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves2 = new byte[64];

    MoveArrays.QueenMoves3 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves3 = new byte[64];

    MoveArrays.QueenMoves4 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves4 = new byte[64];

    MoveArrays.QueenMoves5 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves5 = new byte[64];

    MoveArrays.QueenMoves6 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves6 = new byte[64];

    MoveArrays.QueenMoves7 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves7 = new byte[64];

    MoveArrays.QueenMoves8 = new PieceMoveSet[64];
    MoveArrays.QueenTotalMoves8 = new byte[64];

    MoveArrays.KingMoves = new PieceMoveSet[64];
    MoveArrays.KingTotalMoves = new byte[64];
   
    SetMovesWhitePawn();
    SetMovesBlackPawn();
    SetMovesKnight();
    SetMovesBishop();
    SetMovesRook();
    SetMovesQueen();
    SetMovesKing();
}


Set Moves methods are responsible for populating the Move Arrays with the moves available for each chess piece from a given position.  I am not going to explain this much further.  These methods basically add some predetermined positions to the arrays defined above.  Again performance is not really all that key here, since these methods run only once when the Chess Engine starts.
private static void SetMovesBlackPawn()
{
    for (byte index = 8; index <= 55; index++)
    {
        var moveset = new PieceMoveSet(new List<byte>());
       
        byte x = (byte)(index % 8);
        byte y = (byte)((index / 8));
       
        //Diagonal Kill
        if (y < 7 && x < 7)
        {
            moveset.Moves.Add((byte)(index + 8 + 1));
            MoveArrays.BlackPawnTotalMoves[index]++;
        }
        if (x > 0 && y < 7)
        {
            moveset.Moves.Add((byte)(index + 8 - 1));
            MoveArrays.BlackPawnTotalMoves[index]++;
        }
       
        //One Forward
        moveset.Moves.Add((byte)(index + 8));
        MoveArrays.BlackPawnTotalMoves[index]++;

        //Starting Position we can jump 2
        if (y == 1)
        {
            moveset.Moves.Add((byte)(index + 16));
            MoveArrays.BlackPawnTotalMoves[index]++;
        }

        MoveArrays.BlackPawnMoves[index] = moveset;
    }
}

private static void SetMovesWhitePawn()
{
    for (byte index = 8; index <= 55; index++)
    {
        byte x = (byte)(index % 8);
        byte y = (byte)((index / 8));

        var moveset = new PieceMoveSet(new List<byte>());
      
        //Diagonal Kill
        if (x < 7 && y > 0)
        {
            moveset.Moves.Add((byte)(index - 8 + 1));
            MoveArrays.WhitePawnTotalMoves[index]++;
        }
        if (x > 0 && y > 0)
        {
            moveset.Moves.Add((byte)(index - 8 - 1));
            MoveArrays.WhitePawnTotalMoves[index]++;
        }

        //One Forward
        moveset.Moves.Add((byte)(index - 8));
        MoveArrays.WhitePawnTotalMoves[index]++;

        //Starting Position we can jump 2
        if (y == 6)
        {
            moveset.Moves.Add((byte)(index - 16));
            MoveArrays.WhitePawnTotalMoves[index]++;
        }

        MoveArrays.WhitePawnMoves[index] = moveset;
    }
}

private static void SetMovesKnight()
{
    for (byte y = 0; y < 8; y++)
    {
        for (byte x = 0; x < 8; x++)
        {
            byte index = (byte)(y + (x * 8));

            var moveset = new PieceMoveSet(new List<byte>());
           
            byte move;

            if (y < 6 && x > 0)
            {
                move = Position((byte)(y + 2), (byte)(x - 1));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            if (y > 1 && x < 7)
            {
                move = Position((byte)(y - 2), (byte)(x + 1));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            if (y > 1 && x > 0)
            {
                move = Position((byte)(y - 2), (byte)(x - 1));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            if (y < 6 && x < 7)
            {
                move = Position((byte)(y + 2), (byte)(x + 1));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            if (y > 0 && x < 6)
            {
                move = Position((byte)(y - 1), (byte)(x + 2));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            if (y < 7 && x > 1)
            {
                move = Position((byte)(y + 1), (byte)(x - 2));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            if (y > 0 && x > 1)
            {
                move = Position((byte)(y - 1), (byte)(x - 2));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }
           
            if (y < 7 && x < 6)
            {
                move = Position((byte)(y + 1), (byte)(x + 2));

                if (move < 64)
                {
                    moveset.Moves.Add(move);
                    MoveArrays.KnightTotalMoves[index]++;
                }
            }

            MoveArrays.KnightMoves[index] = moveset;
        }
    }
}

private static void SetMovesBishop()
{
    for (byte y = 0; y < 8; y++)
    {
        for (byte x = 0; x < 8; x++)
        {
            byte index = (byte)(y + (x * 8));

            var moveset = new PieceMoveSet(new List<byte>());
            byte move;

            byte row = x;
            byte col = y;

            while (row < 7 && col < 7)
            {
                row++;
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.BishopTotalMoves1[index]++;
            }

            MoveArrays.BishopMoves1[index] = moveset;
            moveset = new PieceMoveSet(new List<byte>());

            row = x;
            col = y;

            while (row < 7 && col > 0)
            {
                row++;
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.BishopTotalMoves2[index]++;
            }

            MoveArrays.BishopMoves2[index] = moveset;
            moveset = new PieceMoveSet(new List<byte>());

            row = x;
            col = y;

            while (row > 0 && col < 7)
            {
                row--;
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.BishopTotalMoves3[index]++;
            }

            MoveArrays.BishopMoves3[index] = moveset;
            moveset = new PieceMoveSet(new List<byte>());

            row = x;
            col = y;

            while (row > 0 && col > 0)
            {
                row--;
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.BishopTotalMoves4[index]++;
            }

            MoveArrays.BishopMoves4[index] = moveset;
        }
    }
}

private static void SetMovesRook()
{
    for (byte y = 0; y < 8; y++)
    {
        for (byte x = 0; x < 8; x++)
        {
            byte index = (byte)(y + (x * 8));

            var moveset = new PieceMoveSet(new List<byte>());
            byte move;

            byte row = x;
            byte col = y;

            while (row < 7)
            {
                row++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.RookTotalMoves1[index]++;
            }

            MoveArrays.RookMoves1[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (row > 0)
            {
                row--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.RookTotalMoves2[index]++;
            }

            MoveArrays.RookMoves2[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (col > 0)
            {
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.RookTotalMoves3[index]++;
            }

            MoveArrays.RookMoves3[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (col < 7)
            {
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.RookTotalMoves4[index]++;
            }

            MoveArrays.RookMoves4[index] = moveset;
        }
    }
}

private static void SetMovesQueen()
{
    for (byte y = 0; y < 8; y++)
    {
        for (byte x = 0; x < 8; x++)
        {
            byte index = (byte)(y + (x * 8));

            var moveset = new PieceMoveSet(new List<byte>());
            byte move;

            byte row = x;
            byte col = y;

            while (row < 7)
            {
                row++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves1[index]++;
            }

            MoveArrays.QueenMoves1[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (row > 0)
            {
                row--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves2[index]++;
            }

            MoveArrays.QueenMoves2[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (col > 0)
            {
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves3[index]++;
            }

            MoveArrays.QueenMoves3[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (col < 7)
            {
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves4[index]++;
            }

            MoveArrays.QueenMoves4[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (row < 7 && col < 7)
            {
                row++;
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves5[index]++;
            }

            MoveArrays.QueenMoves5[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (row < 7 && col > 0)
            {
                row++;
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves6[index]++;
            }

            MoveArrays.QueenMoves6[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (row > 0 && col < 7)
            {
                row--;
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves7[index]++;
            }

            MoveArrays.QueenMoves7[index] = moveset;

            moveset = new PieceMoveSet(new List<byte>());
            row = x;
            col = y;

            while (row > 0 && col > 0)
            {
                row--;
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.QueenTotalMoves8[index]++;
            }

            MoveArrays.QueenMoves8[index] = moveset;
        }
    }
}

private static void SetMovesKing()
{
    for (byte y = 0; y < 8; y++)
    {
        for (byte x = 0; x < 8; x++)
        {
            byte index = (byte)(y + (x * 8));

            var moveset = new PieceMoveSet(new List<byte>());
            byte move;

            byte row = x;
            byte col = y;

            if (row < 7)
            {
                row++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            row = x;
            col = y;

            if (row > 0)
            {
                row--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            row = x;
            col = y;

            if (col > 0)
            {
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            row = x;
            col = y;

            if (col < 7)
            {
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            row = x;
            col = y;

            if (row < 7 && col < 7)
            {
                row++;
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            row = x;
            col = y;

            if (row < 7 && col > 0)
            {
                row++;
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            row = x;
            col = y;

            if (row > 0 && col < 7)
            {
                row--;
                col++;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }


            row = x;
            col = y;

            if (row > 0 && col > 0)
            {
                row--;
                col--;

                move = Position(col, row);
                moveset.Moves.Add(move);
                MoveArrays.KingTotalMoves[index]++;
            }

            MoveArrays.KingMoves[index] = moveset;
        }
    }
}


This concludes the Chess Piece Moves class.  To continue reading the chess piece motion series follow this link to the Chess Piece Valid Move class, that will discuss how my chess engine generates valid moves based on the current state of the chess board.

If you want to get started on creating your own chess engine download my C# Chess Game Starter Kit.