public static PlayerPieceSet MovePiece(PlayerPieceSet base_obj, Exports.Pieces piece, int remove_at_cell, int new_cell) { Debug.Assert(base_obj != null); Debug.Assert(piece != Exports.Pieces.NoPiece); Debug.Assert(remove_at_cell >= 0 && remove_at_cell < 64); Debug.Assert(new_cell >= 0 && new_cell < 64); Debug.Assert(remove_at_cell != new_cell); Debug.Assert(base_obj.IsOccupiedCell(remove_at_cell)); Debug.Assert(!base_obj.IsOccupiedCell(new_cell)); var result = (PlayerPieceSet)base_obj.MemberwiseClone(); result.m_bitboard.UnsetBit(remove_at_cell); result.m_bitboard.SetBit(new_cell); // Insert new_cell first. Easier to do it now, because we know // the sorted ranges uint range_begin = 0; uint range_length = 0; switch (piece) { case Exports.Pieces.Pawn: range_begin = result.PawnsStartIndex; range_length = result.PawnsCount; break; case Exports.Pieces.Knight: range_begin = result.KnightsStartIndex; range_length = result.KnightsCount; break; case Exports.Pieces.Bishop: range_begin = result.BishopsStartIndex; range_length = result.BishopsCount; break; case Exports.Pieces.Rook: range_begin = result.RooksStartIndex; range_length = result.RooksCount; break; case Exports.Pieces.Queen: range_begin = result.QueensStartIndex; range_length = result.QueensCount; break; case Exports.Pieces.King: range_begin = 0; range_length = 1; break; } bool is_inserted = false; for (uint i = range_begin, e = range_begin + range_length; i < e; ++i) { if (new_cell < result.m_pieces_cells.GetCell(i)) { result.m_pieces_cells.InsertAt(i, new_cell); is_inserted = true; break; } } if (!is_inserted) { result.m_pieces_cells.InsertAt(range_begin + range_length, new_cell); } result.m_pieces_cells.EraseAt( (uint)result.m_pieces_cells.FindIndex(remove_at_cell)); return result; }
public static PlayerPieceSet RemovePiece(PlayerPieceSet base_obj, Exports.Pieces piece_to_remove, int remove_at_cell) { Debug.Assert(base_obj != null); Debug.Assert(piece_to_remove != Exports.Pieces.NoPiece && piece_to_remove != Exports.Pieces.King); Debug.Assert(remove_at_cell >= 0 && remove_at_cell < 64); Debug.Assert(base_obj.IsOccupiedCell(remove_at_cell)); var result = (PlayerPieceSet)base_obj.MemberwiseClone(); result.m_bitboard.UnsetBit(remove_at_cell); uint start_index = 0; switch (piece_to_remove) { case Exports.Pieces.Pawn: start_index = result.PawnsStartIndex; Debug.Assert(result.PawnsCount > 0); --result.PawnsCount; break; case Exports.Pieces.Knight: start_index = result.KnightsStartIndex; Debug.Assert(result.KnightsCount > 0); // Decrement result.KnightsCount --result.PawnsStartIndex; break; case Exports.Pieces.Bishop: start_index = result.BishopsStartIndex; Debug.Assert(result.BishopsCount > 0); // Decrement result.BishopsCount --result.PawnsStartIndex; --result.KnightsStartIndex; break; case Exports.Pieces.Rook: start_index = result.RooksStartIndex; Debug.Assert(result.RooksCount > 0); // Decrement result.RooksCount --result.PawnsStartIndex; --result.KnightsStartIndex; --result.BishopsStartIndex; break; case Exports.Pieces.Queen: start_index = result.QueensStartIndex; Debug.Assert(result.QueensCount > 0); // Decrement result.QueensCount --result.PawnsStartIndex; --result.KnightsStartIndex; --result.BishopsStartIndex; --result.RooksStartIndex; break; } result.m_pieces_cells.EraseAt((uint)result.m_pieces_cells .FindNextIndex(start_index, remove_at_cell)); return result; }
public static PlayerPieceSet InsertPiece(PlayerPieceSet base_obj, Exports.Pieces piece_to_insert, int insert_at_cell) { Debug.Assert(base_obj != null); Debug.Assert(piece_to_insert != Exports.Pieces.NoPiece && piece_to_insert != Exports.Pieces.King); Debug.Assert(insert_at_cell >= 0 && insert_at_cell < 64); Debug.Assert(!base_obj.IsOccupiedCell(insert_at_cell)); var result = (PlayerPieceSet)base_obj.MemberwiseClone(); result.m_bitboard.SetBit(insert_at_cell); uint start_index = 0; uint cur_piece_count = 0; switch (piece_to_insert) { // TODO - add checks like PawnsCount < MAX_PAWN_COUNT case Exports.Pieces.Pawn: start_index = result.PawnsStartIndex; cur_piece_count = result.PawnsCount; ++result.PawnsCount; break; case Exports.Pieces.Knight: start_index = result.KnightsStartIndex; cur_piece_count = result.KnightsCount; // Increment result.KnightsCount ++result.PawnsStartIndex; break; case Exports.Pieces.Bishop: start_index = result.BishopsStartIndex; cur_piece_count = result.BishopsCount; // Increment result.BishopsCount ++result.PawnsStartIndex; ++result.KnightsStartIndex; break; case Exports.Pieces.Rook: start_index = result.RooksStartIndex; cur_piece_count = result.RooksCount; // Increment result.RooksCount ++result.PawnsStartIndex; ++result.KnightsStartIndex; ++result.BishopsStartIndex; break; case Exports.Pieces.Queen: start_index = result.QueensStartIndex; cur_piece_count = result.QueensCount; // Increment result.QueensCount ++result.PawnsStartIndex; ++result.KnightsStartIndex; ++result.BishopsStartIndex; ++result.RooksStartIndex; break; } result.m_pieces_cells.InsertAt(result.m_pieces_cells .GetInsertionIndex(start_index, cur_piece_count, insert_at_cell), insert_at_cell); return result; }