Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Engine work #61

Open
wants to merge 119 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
bd2a7c0
.net 7 update
rudzen Nov 30, 2022
e61fb7a
Fixed minor formatting etc.
rudzen Dec 22, 2022
01536f4
Various minor additions
rudzen Feb 12, 2023
543d49d
Update copyright year
rudzen Feb 12, 2023
f266641
Updated tables etc
rudzen Feb 12, 2023
f6919fd
Minor refactor
rudzen Feb 12, 2023
acd7091
Fixed unintended non-cleared span for piece validation
rudzen Feb 12, 2023
c16f3b4
Updated some types to be more clear
rudzen Feb 13, 2023
6a779d2
Modernized Perft application
rudzen Feb 13, 2023
150faf6
HiResTimer no longer computes delay if never going to be needed
rudzen Feb 18, 2023
b0082a8
Updated KillerMoves to jagged array
rudzen Feb 18, 2023
7408832
Various minor code updates
rudzen Feb 18, 2023
46a16d6
Improved HiResTimer a bit
rudzen Feb 18, 2023
8bd0fcf
Reworked basic setup to be IoC friendly
rudzen Feb 19, 2023
2f3cca9
Added move list object pool as IoC object
rudzen Feb 19, 2023
3d48a7c
PositionValidator can now be controlled through IoC
rudzen Feb 19, 2023
9a7a947
Minor update to PieceSquareEventArgs
rudzen Feb 19, 2023
bbddc16
Update State use a bit + added missing properties from IGame
rudzen Feb 20, 2023
00455d7
Refactorings
rudzen Mar 24, 2023
9d369f9
Nullability warnings fixed + minor pos validator fix
rudzen Mar 25, 2023
839f542
Fix xunit serializaton fatal error
rudzen Mar 25, 2023
6c57c0c
Added basic PGN file parser library
rudzen Mar 26, 2023
0b50b99
Update reg ex pgn parser
rudzen Mar 26, 2023
eb3164c
Fix using old sample pgn
rudzen Mar 27, 2023
0ac7a06
Added basic non-regex pgn parser
rudzen Mar 27, 2023
20b3ee1
Added simple SAN to move converter
rudzen Mar 27, 2023
00f86f7
Added notational move converter
rudzen Mar 27, 2023
de0188b
Accumative minor code updates
rudzen Apr 3, 2023
4c9af1a
Optimized Board.Squares() + minor styling
rudzen Apr 9, 2023
cb17655
Optimized start-up of KpkBitbase slightly
rudzen Apr 9, 2023
bea50c5
Reorder arguments for move generator internal methods
rudzen Apr 9, 2023
1155f9b
Cleanup + move gen types are now flags for simpler type detection
rudzen Apr 10, 2023
742f7b3
Enabled tiered pgo as default
rudzen Apr 10, 2023
7d01927
Updated various functionalities
rudzen Apr 12, 2023
4916c68
Better use of BitBoard.IsNotEmpty etc
rudzen Apr 12, 2023
542a90c
Minor updates
rudzen Apr 16, 2023
3a2e856
Minor improvements
rudzen Apr 24, 2023
c3d2c41
Updated RKiss method arguments
rudzen Apr 24, 2023
185465f
HashKeys now retrieved with ref from Zobrist (reminder: don't modify …
rudzen Apr 24, 2023
c05d910
Added Sign for Player (1 = White, -1 = Black)
rudzen Apr 26, 2023
ad6ee5b
Slightly improved startup-time + position init-time
rudzen Apr 27, 2023
063772c
Code update
rudzen May 3, 2023
b8d0b3d
Couple of updates
rudzen May 13, 2023
865774f
Update perft a bit
rudzen May 13, 2023
947e874
Updated code design
rudzen May 14, 2023
65ead6c
Update to progress towards stabilizing transposition table hashing
rudzen Aug 15, 2023
20ef9fa
Cleanup
rudzen Aug 15, 2023
7044184
Simplified
rudzen Aug 15, 2023
48d8670
Cleanup and fixed pgn tests
rudzen Aug 16, 2023
3f0fde1
Update dependencies + update perft applicaton to use actors (not comp…
rudzen Aug 29, 2023
67548b5
Microsoft.NET.Test.Sdk 17.7.1 -> 17.7.2
rudzen Aug 29, 2023
f25a25b
minor update to perft + uci now uses move list pool to convert move
rudzen Aug 30, 2023
e45ca03
minor code update + updated some dependencies
rudzen Oct 12, 2023
3430bfb
updated kpk bit base code to use refs
rudzen Nov 13, 2023
dfcc354
update zobrist with material key method
rudzen Nov 13, 2023
8a67e1c
update state stack to use regular string builder for now
rudzen Nov 13, 2023
4d7367a
simplify perft runner a bit
rudzen Nov 13, 2023
b8fe3bd
removed not needed dependency
rudzen Nov 13, 2023
ac6f462
update san to move tests
rudzen Nov 13, 2023
3c62e9b
update regex pgn parser
rudzen Nov 13, 2023
00ced65
update perft slightly
rudzen Nov 13, 2023
c3a834e
update position with an improved CanEnPassant() functionality
rudzen Nov 13, 2023
c516c02
update position key create
rudzen Nov 13, 2023
f18ce78
simplify perft tests
rudzen Nov 13, 2023
6d7a83b
update name of polyglot stream
rudzen Nov 13, 2023
d60dda3
update to .net 8
rudzen Nov 14, 2023
d2b28db
minor cleanup
rudzen Nov 14, 2023
dfbb979
minor simplifications
rudzen Nov 14, 2023
aee0b20
update todo file
rudzen Nov 14, 2023
2910a65
minor cleanups after .net 8 upgrade
rudzen Nov 14, 2023
2af2513
c# 12 update to collections + minor update to bitboard ToString
rudzen Jan 8, 2024
8512d69
simplify move list properties
rudzen Jan 11, 2024
71ccd00
update notation to be more compatible with DI
rudzen Jan 11, 2024
39b9f75
adopted new magic bb implementation (from portfish)
rudzen Feb 7, 2024
bc0c4da
updated fen generate function
rudzen Feb 7, 2024
b37d8c2
minor updates + chase for weird table hash bug
rudzen Feb 7, 2024
5305f58
update readme
rudzen Feb 7, 2024
aa41330
update magicbb
rudzen Feb 29, 2024
34946b7
various
rudzen Feb 29, 2024
0509f68
Added first draft for PGN generate
rudzen Feb 29, 2024
af47ed8
testing out ValMove no longer uses properties
rudzen Feb 29, 2024
61afc93
Added explicit Vector2 operator for Score
rudzen Feb 29, 2024
c9eec94
Added test version for new Perft Table
rudzen Feb 29, 2024
db7ae58
Updated MagicBB to use PEXT (from StockFish 16)
rudzen Feb 29, 2024
171acb2
cleaned up MagicBB class
rudzen Feb 29, 2024
6fb6fc8
Added implicit int operator for Piece + simplify usage of previous .A…
rudzen Feb 29, 2024
6023d3c
added int implicit operator to Square
rudzen Feb 29, 2024
7cbabb8
added implicit Player byte operator
rudzen Feb 29, 2024
dddc95e
added implicit Rank int operator
rudzen Feb 29, 2024
ea9e9b4
added more int implicit overloads + removed redundant perft stuff
rudzen Mar 1, 2024
e459479
minor updates
rudzen Mar 2, 2024
c653dc9
simplify move generator a bit
rudzen Mar 2, 2024
c58caab
simplify en-passant setup when parsing fen
rudzen Mar 2, 2024
7c97a7e
simplify board structure
rudzen Mar 3, 2024
1fe5571
updates
rudzen Mar 4, 2024
e4583c3
added Peter Jones' perft tests
rudzen Mar 4, 2024
abaea7d
Semi-major update:
rudzen Jun 26, 2024
5285b3a
simplify bitboard static ctor a bit
rudzen Jun 27, 2024
4c327fd
added methodimpl attributes to Board and updated File
rudzen Jun 27, 2024
9946645
remove redundant method call when updating board position
rudzen Jun 27, 2024
0a0010f
SetupPieces uses correct types for rank and file
rudzen Jun 27, 2024
86cc2f1
added more methodimpl to position
rudzen Jun 27, 2024
4fa0f20
update akka version
rudzen Jun 27, 2024
6737232
fix for updating File size
rudzen Jun 27, 2024
d7b7650
update location of perft + using akka host
rudzen Jun 27, 2024
790eee6
re-arrange src files structure in a more vertical friendly way
rudzen Jun 27, 2024
6174d6d
Update test.yml
rudzen Jun 27, 2024
4cf3bc6
Update publish.yml
rudzen Jun 27, 2024
28bdad4
link some files
rudzen Jun 28, 2024
298ae5c
various minor issues and warnings fixed
rudzen Jun 28, 2024
0ac016b
removed attribute from exceptions
rudzen Jun 28, 2024
7833774
fix a position assert
rudzen Jun 28, 2024
7f23f1d
fix several warnings and problems with projects + simplify configurat…
rudzen Jun 28, 2024
6171174
tests no longer configures options for configuration
rudzen Jun 28, 2024
0ecf070
remove duplicate package version declaration
rudzen Jun 29, 2024
96ba919
simplify some perft functionality a bit
rudzen Jun 29, 2024
98120fc
simplify move tests a bit
rudzen Jun 29, 2024
42d4f6f
simplify bitboard to string method a bit
rudzen Jun 29, 2024
f43af73
removed redundant project settings for perft project
rudzen Jun 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cleanup and fixed pgn tests
rudzen committed Aug 16, 2023
commit 48d86709caddf380837bed8671d2cade0f94eb55
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@ public SanToMoveTests()
.AddSingleton<IValues, Values>()
.AddSingleton<IZobrist, Zobrist>()
.AddSingleton<ICuckoo, Cuckoo>()
.AddSingleton<IRKiss, RKiss>()
.AddSingleton<IPositionValidator, PositionValidator>()
.AddTransient<IPosition, Position>()
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
37 changes: 19 additions & 18 deletions src/Rudzoft.ChessLib.PGN/NonRegexPgnParser.cs
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ public async IAsyncEnumerable<PgnGame> ParseFile(string pgnFile, CancellationTok
else if (char.IsLetter(word[0]))
{
if (currentGameMoves.Count == 0 || !string.IsNullOrEmpty(currentGameMoves[^1].BlackMove))
currentGameMoves.Add(new PgnMove(currentMoveNumber, word, string.Empty));
currentGameMoves.Add(new(currentMoveNumber, word, string.Empty));
else
{
var lastMove = currentGameMoves[^1];
@@ -71,35 +71,36 @@ public async IAsyncEnumerable<PgnGame> ParseFile(string pgnFile, CancellationTok
else if (word.Contains("1-0") || word.Contains("0-1") || word.Contains("1/2-1/2") ||
word.Contains('*'))
{
yield return new PgnGame(currentGameTags, currentGameMoves);
currentGameTags = new Dictionary<string, string>();
currentGameMoves = new List<PgnMove>();
yield return new(currentGameTags, currentGameMoves);
currentGameTags = new();
currentGameMoves = new();
inMoveSection = false;
}
}
}
else
{
if (line.StartsWith("[") && line.EndsWith("]") && line.Contains("\""))
{
var firstSpaceIndex = line.IndexOf(' ');
var firstQuoteIndex = line.IndexOf('"');
var lastQuoteIndex = line.LastIndexOf('"');
if (!line.StartsWith("[") || !line.EndsWith("]") || !line.Contains('"'))
continue;

var firstSpaceIndex = line.IndexOf(' ');
var firstQuoteIndex = line.IndexOf('"');
var lastQuoteIndex = line.LastIndexOf('"');

if (firstSpaceIndex <= 0 || firstQuoteIndex <= firstSpaceIndex
|| lastQuoteIndex <= firstQuoteIndex)
continue;
if (firstSpaceIndex <= 0 || firstQuoteIndex <= firstSpaceIndex
|| lastQuoteIndex <= firstQuoteIndex)
continue;

var tagName = line.Substring(1, firstSpaceIndex - 1).Trim();
var tagValue = line.Substring(firstQuoteIndex + 1, lastQuoteIndex - firstQuoteIndex - 1)
.Trim();
var tagName = line.Substring(1, firstSpaceIndex - 1).Trim();
var tagValue = line
.Substring(firstQuoteIndex + 1, lastQuoteIndex - firstQuoteIndex - 1)
.Trim();

currentGameTags[tagName] = tagValue;
}
currentGameTags[tagName] = tagValue;
}
}

if (currentGameTags.Count > 0 && currentGameMoves.Count > 0)
yield return new PgnGame(currentGameTags, currentGameMoves);
yield return new(currentGameTags, currentGameMoves);
}
}
4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib.PGN/RegexPgnParser.cs
Original file line number Diff line number Diff line change
@@ -70,8 +70,8 @@ public async IAsyncEnumerable<PgnGame> ParseFile(
if (IsPgnGameResult(line))
{
yield return new(currentGameTags, currentGameMoves);
currentGameTags = new Dictionary<string, string>(DefaultTagCapacity);
currentGameMoves = new List<PgnMove>(DefaultMoveListCapacity);
currentGameTags = new(DefaultTagCapacity);
currentGameMoves = new(DefaultMoveListCapacity);
inMoveSection = false;
}
}
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ public BitBoard SliderAttacks(PieceTypes pt, Square sq, in BitBoard occ)
{
0 => sq.BishopAttacks(in occ),
1 => sq.RookAttacks(in occ),
_ => sq.QueenAttacks(in occ)
var _ => sq.QueenAttacks(in occ)
};
}

2 changes: 1 addition & 1 deletion src/Rudzoft.ChessLib/Fen/FenData.cs
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ private record struct SplitPoint(int Begin, int End);

private FenData()
{
_splitPoints = new Queue<SplitPoint>(6);
_splitPoints = new(6);
}

public FenData(ReadOnlyMemory<char> fen) : this()
2 changes: 1 addition & 1 deletion src/Rudzoft.ChessLib/MoveGeneration/IMoveList.cs
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ public interface IMoveList : IReadOnlyCollection<ValMove>
ValMove this[int index] { get; set; }

int Length { get; }
Move CurrentMove { get; }
ref ValMove CurrentMove { get; }
void Add(in ValMove item);
void Add(Move item);

4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib/MoveGeneration/MoveGenerator.cs
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ private static int GenerateCapturesQuietsNonEvasions(
MoveGenerationTypes.Captures => pos.Pieces(~us),
MoveGenerationTypes.Quiets => ~pos.Pieces(),
MoveGenerationTypes.NonEvasions => ~pos.Pieces(us),
_ => BitBoard.Empty
var _ => BitBoard.Empty
};

return GenerateAll(in pos, moves, index, in target, us, types);
@@ -288,7 +288,7 @@ private static int GeneratePawnMoves(
{
MoveGenerationTypes.Evasions => pos.Pieces(them) & target,
MoveGenerationTypes.Captures => target,
_ => pos.Pieces(them)
var _ => pos.Pieces(them)
};

var ksq = pos.GetKingSquare(them);
14 changes: 9 additions & 5 deletions src/Rudzoft.ChessLib/MoveGeneration/MoveList.cs
Original file line number Diff line number Diff line change
@@ -39,16 +39,20 @@ namespace Rudzoft.ChessLib.MoveGeneration;
*/
public sealed class MoveList : IMoveList
{
private readonly ValMove[] _moves;
private readonly ValMove[] _moves = new ValMove[218];
private int _cur;

public MoveList() => _moves = new ValMove[218];

int IReadOnlyCollection<ValMove>.Count => Length;
int IReadOnlyCollection<ValMove>.Count
{
get => Length;
}

public int Length { get; private set; }

public Move CurrentMove => _moves[_cur].Move;
public ref ValMove CurrentMove
{
get => ref _moves[_cur];
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MoveList operator ++(MoveList moveList)
4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib/Notation/Notations/IccfNotation.cs
Original file line number Diff line number Diff line change
@@ -59,12 +59,12 @@ public override string Convert(Move move)
PieceTypes.Rook => 2,
PieceTypes.Bishop => 3,
PieceTypes.Knight => 4,
_ => throw new NotImplementedException()
var _ => throw new NotImplementedException()
};

re[i++] = (char)('0' + c);
}

return new string(re[..i]);
return new(re[..i]);
}
}
4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib/Notation/Notations/Notation.cs
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ protected char GetCheckChar() =>
Pos.GenerateMoves().Length switch
{
0 => '+',
_ => '#'
var _ => '#'
};

[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -123,7 +123,7 @@ private BitBoard GetSimilarAttacks(Move move)
return pt switch
{
PieceTypes.Pawn or PieceTypes.King => BitBoard.Empty,
_ => Pos.GetAttacks(move.ToSquare(), pt, Pos.Pieces()) ^ from
var _ => Pos.GetAttacks(move.ToSquare(), pt, Pos.Pieces()) ^ from
};
}
}
24 changes: 12 additions & 12 deletions src/Rudzoft.ChessLib/Position.cs
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ public Position(
Values = values;
_zobrist = zobrist;
_cuckoo = cuckoo;
State = new State();
State = new();
Clear();
}

@@ -181,7 +181,7 @@ public bool IsCaptureOrPromotion(Move m)
return mt switch
{
MoveTypes.Normal => Board.Pieces(~SideToMove).Contains(m.ToSquare()),
_ => mt != MoveTypes.Castling
var _ => mt != MoveTypes.Castling
};
}

@@ -294,14 +294,14 @@ public FenData GenerateFen()
for (var file = Files.FileA; file <= Files.FileH; file++)
{
var empty = 0;
for (; file <= Files.FileH && Board.IsEmpty(new Square(rank, file)); ++file)
for (; file <= Files.FileH && Board.IsEmpty(new(rank, file)); ++file)
++empty;

if (empty != 0)
fen[length++] = (char)(zero + empty);

if (file <= Files.FileH)
fen[length++] = Board.PieceAt(new Square(rank, file)).GetPieceChar();
fen[length++] = Board.PieceAt(new(rank, file)).GetPieceChar();
}

if (rank > Ranks.Rank1)
@@ -362,7 +362,7 @@ public FenData GenerateFen()
fen[length++] = space;
length = fen.Append(1 + (Ply - _sideToMove.IsBlack.AsByte() / 2), length);

return new FenData(new string(fen[..length]));
return new(new string(fen[..length]));
}

public BitBoard GetAttacks(Square sq, PieceTypes pt, in BitBoard occ)
@@ -376,7 +376,7 @@ public BitBoard GetAttacks(Square sq, PieceTypes pt, in BitBoard occ)
PieceTypes.Bishop => sq.BishopAttacks(in occ),
PieceTypes.Rook => sq.RookAttacks(in occ),
PieceTypes.Queen => sq.QueenAttacks(in occ),
_ => BitBoard.Empty
var _ => BitBoard.Empty
};
}

@@ -519,7 +519,7 @@ public bool IsDraw(int ply)
=> State.Rule50 switch
{
> 99 when State.Checkers.IsEmpty || HasMoves() => true,
_ => State.Repetition > 0 && State.Repetition < ply
var _ => State.Repetition > 0 && State.Repetition < ply
};

[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -884,7 +884,7 @@ public void MoveToString(Move m, in StringBuilder output)
if (type == MoveTypes.Castling && ChessMode == ChessMode.Normal)
{
var file = to > from ? Files.FileG : Files.FileC;
to = new Square(from.Rank, file);
to = new(from.Rank, file);
}

Span<char> s = stackalloc char[5];
@@ -1140,7 +1140,7 @@ private void SetupEnPassant(ReadOnlySpan<char> fenChunk)

if (enPassant)
{
State.EnPassantSquare = new Square(fenChunk[1] - '1', fenChunk[0] - 'a');
State.EnPassantSquare = new(fenChunk[1] - '1', fenChunk[0] - 'a');

var otherSide = ~_sideToMove;

@@ -1340,7 +1340,7 @@ public override string ToString()

for (var file = Files.FileA; file <= Files.FileH; file++)
{
var piece = GetPiece(new Square(rank, file));
var piece = GetPiece(new(rank, file));
row[rowIndex++] = splitter;
row[rowIndex++] = space;
row[rowIndex++] = piece.GetPieceChar();
@@ -1545,8 +1545,8 @@ private void SetupCastle(ReadOnlySpan<char> castle)
{
'K' => RookSquare(Square.H1.Relative(c), rook),
'Q' => RookSquare(Square.A1.Relative(c), rook),
_ => char.IsBetween(token, 'A', 'H')
? new Square(Rank.Rank1.Relative(c), new File(token - 'A'))
var _ => char.IsBetween(token, 'A', 'H')
? new(Rank.Rank1.Relative(c), new(token - 'A'))
: Square.None
};

2 changes: 1 addition & 1 deletion src/Rudzoft.ChessLib/Protocol/UCI/Cpu.cs
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ private double Usage()
return percentage switch
{
<= 0 => 0,
_ => Math.Round(percentage * 1000, MidpointRounding.ToEven)
var _ => Math.Round(percentage * 1000, MidpointRounding.ToEven)
};
}
}
4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib/Protocol/UCI/Option.cs
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ public int GetInt()
return Type switch
{
UciOptionType.Spin => Convert.ToInt32(_currentValue),
_ => bool.Parse(_currentValue).AsByte()
var _ => bool.Parse(_currentValue).AsByte()
};
}

@@ -134,7 +134,7 @@ public IOption SetCurrentValue(string v)
{
var isButton = Type == UciOptionType.Button;
if (((!isButton && v.IsNullOrEmpty())
|| (Type == UciOptionType.Check && !bool.TryParse(v, out _))
|| (Type == UciOptionType.Check && !bool.TryParse(v, out var _))
|| Type == UciOptionType.Spin) && Maths.ToIntegral(v, out int val) && val < Min && val > Max)
return this;

4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib/Types/BitBoards.cs
Original file line number Diff line number Diff line change
@@ -544,7 +544,7 @@ public static string Stringify(in BitBoard bb, string title = "")

span[idx] = '\n';

return new string(span[..idx]);
return new(span[..idx]);
}

/// <summary>
@@ -762,7 +762,7 @@ private static BitBoard GetAttacks(this in Square sq, PieceTypes pt, in BitBoard
PieceTypes.Bishop => sq.BishopAttacks(in occ),
PieceTypes.Rook => sq.RookAttacks(in occ),
PieceTypes.Queen => sq.QueenAttacks(in occ),
_ => EmptyBitBoard
var _ => EmptyBitBoard
};
}

4 changes: 2 additions & 2 deletions src/Rudzoft.ChessLib/Types/Move.cs
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ public void Deconstruct(out Square from, out Square to, out MoveTypes type)

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Move(string value)
=> new(new Square(value[1] - '1', value[0] - 'a'), new Square(value[3] - '1', value[2] - 'a'));
=> new(new(value[1] - '1', value[0] - 'a'), new(value[3] - '1', value[2] - 'a'));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Move(ValMove valMove) => valMove.Move;
@@ -155,7 +155,7 @@ public override string ToString()

Span<char> s = stackalloc char[MaxMoveStringSize];
return TryFormat(s, out var size)
? new string(s[..size])
? new(s[..size])
: "(error)";
}

24 changes: 7 additions & 17 deletions src/Rudzoft.ChessLib/Types/Piece.cs
Original file line number Diff line number Diff line change
@@ -197,24 +197,14 @@ private Piece(Piece pc) : this(pc.Value) { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override string ToString() => this.GetPieceString();

public static Piece GetPiece(char character)
public static Piece GetPiece(char c)
{
return character switch
{
'P' => WhitePawn,
'p' => BlackPawn,
'N' => WhiteKnight,
'B' => WhiteBishop,
'R' => WhiteRook,
'Q' => WhiteQueen,
'K' => WhiteKing,
'n' => BlackKnight,
'b' => BlackBishop,
'r' => BlackRook,
'q' => BlackQueen,
'k' => BlackKing,
_ => EmptyPiece
};
var pcIndex = PieceExtensions.PieceChars.IndexOf(c);
if (pcIndex == -1)
return EmptyPiece;

Player p = new(char.IsLower(PieceExtensions.PieceChars[pcIndex]));
return ((PieceTypes)pcIndex).MakePiece(p);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]