예제 #1
0
        // https://github.com/ledpup/Othello/blob/cf3f21ebe2550393cf9300d01f02182184364b91/Othello.Model/Play.cs#L61
        public static ulong GetWouldFlips(this BitBoard board, byte player, ulong bitMove)
        {
            // TODO improve this function, make it faster
            var playerPiece   = board.Pieces[player];
            var opponentPiece = board.Pieces[Constant.Opponent(player)];
            var wouldFlips    = 0UL;

            foreach (var direction in DirectionValues)
            {
                var potentialEndPoint   = bitMove.Shift(direction);
                var potentialWouldFlips = 0UL;

                do
                {
                    if ((potentialEndPoint & playerPiece) != 0)
                    {
                        wouldFlips |= potentialWouldFlips;
                        break;
                    }

                    potentialEndPoint   &= opponentPiece;
                    potentialWouldFlips |= potentialEndPoint;
                    potentialEndPoint    = potentialEndPoint.Shift(direction);
                } while (potentialEndPoint != 0);
            }

            return(wouldFlips);
        }
예제 #2
0
        public static void MakeMove(this BitBoard board, byte player, ulong bitMove)
        {
            var wouldFlips = board.GetWouldFlips(player, bitMove);

            board.Pieces[player] |= wouldFlips | bitMove;
            board.Pieces[Constant.Opponent(player)] ^= wouldFlips;
        }
예제 #3
0
        public static BitBoard Rotate90AntiClockwise(this BitBoard board)
        {
            var clone = board.Clone();

            clone.Pieces[Black] = clone.Pieces[Black].Rotate90AntiClockwise();
            clone.Pieces[White] = clone.Pieces[White].Rotate90AntiClockwise();
            return(clone);
        }
예제 #4
0
        public static BitBoard FlipDiagA1H8(this BitBoard board)
        {
            var clone = board.Clone();

            clone.Pieces[Black] = clone.Pieces[Black].FlipDiagA1H8();
            clone.Pieces[White] = clone.Pieces[White].FlipDiagA1H8();
            return(clone);
        }
예제 #5
0
        public static BitBoard MirrorHorizontal(this BitBoard board)
        {
            var clone = board.Clone();

            clone.Pieces[Black] = clone.Pieces[Black].MirrorHorizontal();
            clone.Pieces[White] = clone.Pieces[White].MirrorHorizontal();
            return(clone);
        }
예제 #6
0
        public static bool IsLegalMove(this BitBoard board, byte player, ulong bitMove)
        {
            if (board.GetPieceAt(bitMove) != Constant.EmptyCell)
            {
                return(false);
            }
            var legalMoves = board.GetLegalMoves(player);

            return((bitMove & legalMoves) != 0);
        }
예제 #7
0
 public static byte GetPieceAt(this BitBoard board, ulong position)
 {
     if ((board.Pieces[Black] & position) != 0)
     {
         return(Constant.BlackCell);
     }
     if ((board.Pieces[White] & position) != 0)
     {
         return(Constant.WhiteCell);
     }
     return(Constant.EmptyCell);
 }
예제 #8
0
        public static void DisplayWithLastMoveAndLegalMoves(this BitBoard board, ulong lastBitMove, byte player)
        {
            Console.WriteLine("  a b c d e f g h");

            var legalMoves = board.GetLegalMoves(player);
            var moveIndex  = lastBitMove.BitScanReverse();
            var row        = 0;

            for (var i = 0; i < 64; i++)
            {
                if (i % 8 == 0)
                {
                    row++;
                    if (i != 0)
                    {
                        Console.WriteLine();
                    }
                    Console.Write(row + " ");
                }

                var pos     = 1UL << i;
                var isBlack = (board.Pieces[Black] & pos) != 0;
                var isWhite = (board.Pieces[White] & pos) != 0;

                if (isBlack && isWhite)
                {
                    Console.Write(Constant.WrongCellStr);
                }
                else if (isBlack)
                {
                    Console.Write(moveIndex == i ? Constant.LastBlackMoveStr : Constant.BlackPieceStr);
                }
                else if (isWhite)
                {
                    Console.Write(moveIndex == i ? Constant.LastWhiteMoveStr : Constant.WhitePieceStr);
                }
                else if ((legalMoves & pos) != 0)
                {
                    Console.Write(Constant.LegalMoveStr);
                }
                else
                {
                    Console.Write(Constant.EmptyCellStr);
                }
            }

            Console.WriteLine();
        }
예제 #9
0
        public static void Display(this BitBoard board)
        {
            Console.WriteLine("  a b c d e f g h");

            var row = 0;

            for (var i = 0; i < 64; i++)
            {
                if (i % 8 == 0)
                {
                    row++;
                    if (i != 0)
                    {
                        Console.WriteLine();
                    }
                    Console.Write(row + " ");
                }

                var pos     = 1UL << i;
                var isBlack = (board.Pieces[Black] & pos) != 0;
                var isWhite = (board.Pieces[White] & pos) != 0;

                if (isBlack && isWhite)
                {
                    Console.Write(Constant.WrongCellStr);
                }
                else if (isBlack)
                {
                    Console.Write(Constant.BlackPieceStr);
                }
                else if (isWhite)
                {
                    Console.Write(Constant.WhitePieceStr);
                }
                else
                {
                    Console.Write(Constant.EmptyCellStr);
                }
            }

            Console.WriteLine();
        }
예제 #10
0
        public static ulong GetLegalMoves(this BitBoard board, byte player)
        {
            // https://intellitect.com/when-to-use-and-not-use-var-in-c/
            // https://stackoverflow.com/a/41505/11898496
            var moves         = 0UL;
            var playerPiece   = board.Pieces[player];
            var opponentPiece = board.Pieces[Constant.Opponent(player)];
            var empties       = board.GetEmpties();

            // https://stackoverflow.com/a/105402/11898496
            foreach (var direction in DirectionValues)
            {
                var candidates = opponentPiece & playerPiece.Shift(direction);
                while (candidates != 0)
                {
                    var candidatesShifted = candidates.Shift(direction);
                    moves     |= empties & candidatesShifted;
                    candidates = opponentPiece & candidatesShifted;
                }
            }

            return(moves);
        }
예제 #11
0
 public static void Clear(this BitBoard board)
 {
     board.Pieces[Black] = 0;
     board.Pieces[White] = 0;
 }
예제 #12
0
 public static void SetPieceAt(this BitBoard board, ulong position, byte color)
 {
     board.Pieces[color] |= position;
 }
예제 #13
0
 public static bool HasAnyPlayerHasAnyLegalMove(this BitBoard board)
 {
     return(board.HasLegalMoves(Black) || board.HasLegalMoves(White));
 }
예제 #14
0
 public static byte CountPieces(this BitBoard board, byte player)
 {
     return(board.Pieces[player].PopCount());
 }
예제 #15
0
 public static ulong GetFilled(this BitBoard board)
 {
     return(board.Pieces[Black] | board.Pieces[White]);
 }
예제 #16
0
 public static ulong GetEmpties(this BitBoard board)
 {
     return(~board.Pieces[Black] & ~board.Pieces[White]);
 }
예제 #17
0
 public static bool IsEquals(this BitBoard board, BitBoard other)
 {
     return(board.Pieces[Black] == other.Pieces[Black] &&
            board.Pieces[White] == other.Pieces[White]);
 }
예제 #18
0
 public static BitBoard Clone(this BitBoard board)
 {
     return(new(board));
 }
예제 #19
0
 public static bool HasLegalMoves(this BitBoard board, byte player)
 {
     return(board.GetLegalMoves(player) != 0);
 }
예제 #20
0
 public State(BitBoard board, byte player)
 {
     Player        = player;
     Board         = board;
     BitLegalMoves = board.GetLegalMoves(player);
 }
예제 #21
0
 public BitBoard(BitBoard board)
 {
     Pieces = new[] { board.Pieces[0], board.Pieces[1] };
 }
예제 #22
0
 public State(BitBoard board, byte player, ulong bitLegalMoves)
 {
     Player        = player;
     Board         = board;
     BitLegalMoves = bitLegalMoves;
 }
예제 #23
0
 public static bool IsGameComplete(this BitBoard board)
 {
     return(board.GetEmpties() == 0 || !board.HasAnyPlayerHasAnyLegalMove());
 }