Discussion of chess software programming and technical issues.
Moderators: hgm, Dann Corbit, Harvey Williamson
Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Tue Feb 16, 2021 11:44 am
Result after rewrite. In reality class is about 190 lines of code. But methods fit on my screen.
Code: Select all
...
public PawnSquareDirectionMovesBuilder(IMoveFactory mvFactory, ISquares<ISquareMoveGen> boardSquares)
{
MVFactory = mvFactory;
BoardSquares = boardSquares;
}
public IImmutableList<IMoveBase> BuildPawnSquareDirectionMoves(
ICoord coord, IPieceColor color,PawnDirection dir)
{
var lastRow = color == White() ? LASTROW : 0;
var square = BoardSquares[coord];
int rowNr = square.RowNr;
if (rowNr == 0 || rowNr == lastRow)
return null;
switch (dir)
{
case LEFT:
case RIGHT:
return BuildNonEPCaptures(color, square, dir);
case EP_LEFT:
case EP_RIGHT:
return BuildEPCaptures(color, square, dir);
case FRONT:
return BuildPawnFrontMoves(color, square);
default:
return null;
}
}
...
Might as well have used ISquares<ISquare> BoardSquares. But strangely C# does not see that ISquares<ISquareMoveGen> is an ISquares<ISquare> while my code contains public interface ISquareMoveGen: ISquare
-
Sven
- Posts: 3970
- Joined: Thu May 15, 2008 7:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
-
Contact:
Post
by Sven » Tue Feb 16, 2021 8:04 pm
Henk wrote: ↑Tue Feb 16, 2021 11:44 am
Result after rewrite. In reality class is about 190 lines of code. But methods fit on my screen.
Code: Select all
...
public PawnSquareDirectionMovesBuilder(IMoveFactory mvFactory, ISquares<ISquareMoveGen> boardSquares)
{
MVFactory = mvFactory;
BoardSquares = boardSquares;
}
public IImmutableList<IMoveBase> BuildPawnSquareDirectionMoves(
ICoord coord, IPieceColor color,PawnDirection dir)
{
var lastRow = color == White() ? LASTROW : 0;
var square = BoardSquares[coord];
int rowNr = square.RowNr;
if (rowNr == 0 || rowNr == lastRow)
return null;
switch (dir)
{
case LEFT:
case RIGHT:
return BuildNonEPCaptures(color, square, dir);
case EP_LEFT:
case EP_RIGHT:
return BuildEPCaptures(color, square, dir);
case FRONT:
return BuildPawnFrontMoves(color, square);
default:
return null;
}
}
...
Might as well have used ISquares<ISquare> BoardSquares. But strangely C# does not see that ISquares<ISquareMoveGen> is an ISquares<ISquare> while my code contains public interface ISquareMoveGen: ISquare
C<Derived> is not automatically a derived class of C<Base>. That is not specific for C#.
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Tue Feb 16, 2021 8:57 pm
Sven wrote: ↑Tue Feb 16, 2021 8:04 pm
Henk wrote: ↑Tue Feb 16, 2021 11:44 am
Result after rewrite. In reality class is about 190 lines of code. But methods fit on my screen.
Code: Select all
...
public PawnSquareDirectionMovesBuilder(IMoveFactory mvFactory, ISquares<ISquareMoveGen> boardSquares)
{
MVFactory = mvFactory;
BoardSquares = boardSquares;
}
public IImmutableList<IMoveBase> BuildPawnSquareDirectionMoves(
ICoord coord, IPieceColor color,PawnDirection dir)
{
var lastRow = color == White() ? LASTROW : 0;
var square = BoardSquares[coord];
int rowNr = square.RowNr;
if (rowNr == 0 || rowNr == lastRow)
return null;
switch (dir)
{
case LEFT:
case RIGHT:
return BuildNonEPCaptures(color, square, dir);
case EP_LEFT:
case EP_RIGHT:
return BuildEPCaptures(color, square, dir);
case FRONT:
return BuildPawnFrontMoves(color, square);
default:
return null;
}
}
...
Might as well have used ISquares<ISquare> BoardSquares. But strangely C# does not see that ISquares<ISquareMoveGen> is an ISquares<ISquare> while my code contains public interface ISquareMoveGen: ISquare
C<Derived> is not automatically a derived class of C<Base>. That is not specific for C#.
https://docs.microsoft.com/en-us/dotnet ... ravariance
Probably have to implement covariance interface yourself unless it is a system type like list or so. I don't know yet.
-
Sven
- Posts: 3970
- Joined: Thu May 15, 2008 7:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
-
Contact:
Post
by Sven » Tue Feb 16, 2021 9:43 pm
Did you make ISquares covariant on its type parameter?
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Wed Feb 17, 2021 9:42 am
No I had never heard of covariant. I changed it, Only had to add 'out'. That's all to make it work.
Don't understand why compiler or intellisense does not give a hint.
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Wed Feb 17, 2021 1:19 pm
By the way in essence a square is an int or ulong. Depends on how much squares you need.
For standard chess no more than 64.
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Thu Feb 18, 2021 12:50 pm
Again I have trouble with C#.
I want to write
Code: Select all
enum Angle { 0, 45, 90, 135, 180}
etc.
But that does not compile. So I have to use this workaround which I don't like.
Code: Select all
enum Angle { Right, RightUp, Up, LeftUp, Left, LeftDown, Down, RightDown }
Alternative is to define a class Angle. But that's too much.
O wait I can use this:
Code: Select all
enum Angle { A_0, A_45, A_90, A_135, A_180}
Not very readable
Or maybe
Code: Select all
enum Angle { _0, _45, _90, _135, _180}
Have not tried but still looks silly/ugly
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Thu Feb 18, 2021 5:27 pm
Hmm bit communistic code. Maybe better have used operator overloading.
Code: Select all
public ICoordSet QueenMoves(ICoordSet occupiers)
=>
StraightMoves(occupiers)
.Union(DiagonalMoves(occupiers));
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Fri Feb 19, 2021 12:16 pm
Trying to understand bitboard movegen. I get:
Square64MoveGen:
Should have two magic numbers + keyLengths (that is number of bits). One for diagonal and one for straight moves.
Has two hastables: one for diagonal and one for straight moves
Number of buckets of each hash table = Pow(2, keyLength)
Code: Select all
hashKey = (int)((occupancy * magic) >> (64 - nBitsKeyLength));
hastable returns the coords of the diagonal/vertical moves for a given occupancy for a bishop/rook/queen on this square.
By the way I don't understand that code or formula for computing the hashkey.
But I am trying to rewrite it and implement it this way and see if it still works.
I forgot how the magic numbers were created. So If I would change the number of squares I first have to implement code to generate magic numbers or not use magic bitboard movegeneration at all.
-
Henk
- Posts: 6838
- Joined: Mon May 27, 2013 8:31 am
Post
by Henk » Fri Feb 19, 2021 12:51 pm
A similar formula I used earlier to map a bitboard into an index of a table with 64 entries.
So looks like magic numbers are just debruijn constants.
Code: Select all
const UInt64 debruijn64 = 157587932685088877;
public int Index(ulong bb)
{
unchecked
{
return index[((bb * debruijn64) >> 58)];
}
}