Discussion of chess software programming and technical issues.
Moderators: hgm , Rebel , chrisw
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Tue Apr 13, 2021 10:37 pm
Henk wrote: ↑ Tue Apr 13, 2021 8:22 pm
Sven wrote: ↑ Tue Apr 13, 2021 7:05 pm
What is the meaning of endBitCoord and moveBB?
Code: Select all
var endBitCoord = UBit(move.End.Index); // = (End).ToBitBoardValue();
var moveBB = move.BitBoardValue; // = (Start.ToBitBoardValue() | (End).ToBitBoardValue();
That would mean: endBitCoord ^ moveBB == ((Start.ToBitBoardValue() | (End).ToBitBoardValue()) ^ (End).ToBitBoardValue();
(A | B) ^ B <=> A
So I better write
Code: Select all
copyPieces[(int)kind] ^= move.Start.Index.ToBitBoardValue();
O wait maybe better assign move.StartBB to each precomputed move just like I did with move.BitBoardValue.
Code: Select all
private ulong[] MoveAux(IMoveBase move)
{
var pieceSort = move.PieceSort;
var kind = GetKind(pieceSort);
var endBitCoord = move.End.BitBoard;
var moveBB = move.BitBoardValue;
ulong[] copyPieces = new ulong[NBITBOARDS];
if (Occupied(endBitCoord))
{
var endKind = PieceKind(endBitCoord);
var color = OccupierColSign(endBitCoord);
Pieces.CopyTo(copyPieces, 0);
if (endKind == kind)
{
copyPieces[(int)kind] ^= move.Start.BitBoard;
}
else
{
copyPieces[(int)endKind] ^= endBitCoord;
copyPieces[(int)kind] ^= moveBB;
}
if (color == ColorSign.White)
{
copyPieces[WHITE_PIECES] ^= endBitCoord;
copyPieces[BLACK_PIECES] ^= moveBB;
}
else
{
copyPieces[BLACK_PIECES] ^= endBitCoord;
copyPieces[WHITE_PIECES] ^= moveBB;
}
}
else
{
Pieces.CopyTo(copyPieces, 0);
copyPieces[(int)kind] ^= moveBB;
if (GetColSign2(pieceSort) == ColorSign.White)
{
copyPieces[WHITE_PIECES] ^= moveBB;
}
else
{
copyPieces[BLACK_PIECES] ^= moveBB;
}
}
return copyPieces;
}
Sven
Posts: 4052 Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle
Post
by Sven » Wed Apr 14, 2021 12:03 am
Henk wrote: ↑ Tue Apr 13, 2021 8:22 pm
Sven wrote: ↑ Tue Apr 13, 2021 7:05 pm
What is the meaning of endBitCoord and moveBB?
Code: Select all
var endBitCoord = UBit(move.End.Index); // = (End).ToBitBoardValue();
var moveBB = move.BitBoardValue; // = (Start.ToBitBoardValue() | (End).ToBitBoardValue();
That would mean: endBitCoord ^ moveBB == ((Start.ToBitBoardValue() | (End).ToBitBoardValue()) ^ (End).ToBitBoardValue();
(A | B) ^ B <=> A
So I better write
Code: Select all
copyPieces[(int)kind] ^= move.Start.Index.ToBitBoardValue();
O wait maybe better assign move.StartBB to each precomputed move just like I did with move.BitBoardValue.
Can you explain it without code?
Just what the two variables are meant for, what they represent?
Btw (A | B) ^ B <=> A is wrong if A and B can overlap ... In that case XOR B clears bits that are also part of A.
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Wed Apr 14, 2021 9:42 am
Sven wrote: ↑ Wed Apr 14, 2021 12:03 am
Henk wrote: ↑ Tue Apr 13, 2021 8:22 pm
Sven wrote: ↑ Tue Apr 13, 2021 7:05 pm
What is the meaning of endBitCoord and moveBB?
Code: Select all
var endBitCoord = UBit(move.End.Index); // = (End).ToBitBoardValue();
var moveBB = move.BitBoardValue; // = (Start.ToBitBoardValue() | (End).ToBitBoardValue();
That would mean: endBitCoord ^ moveBB == ((Start.ToBitBoardValue() | (End).ToBitBoardValue()) ^ (End).ToBitBoardValue();
(A | B) ^ B <=> A
So I better write
Code: Select all
copyPieces[(int)kind] ^= move.Start.Index.ToBitBoardValue();
O wait maybe better assign move.StartBB to each precomputed move just like I did with move.BitBoardValue.
Can you explain it without code?
Just what the two variables are meant for, what they represent?
Btw (A | B) ^ B <=> A is wrong if A and B can overlap ... In that case XOR B clears bits that are also part of A.
(A | B) , B did overlap but A,B don't so (A | B) ^ B <=> A
Because A = Start field of a move, B = End field of a move.
So for example in case of a pawn x pawn capture you only need to clear start field of the move in Pieces[pawn] bit board.
Code: Select all
copyPieces[(int)kind] ^= move.Start.BitBoard;
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Wed Apr 14, 2021 12:26 pm
Henk wrote: ↑ Mon Apr 12, 2021 11:01 pm
I think I fixed the bug in movecount.
Now it is back to normal. That is less than 80kn/sec.
Code: Select all
1 48 8 4 d2d4
2 5 11 129 d2d4 g8f6
3 48 13 616 d2d4 g8f6 g1f3
4 7 15 1353 d2d4 b8c6 g1f3 g8f6
5 50 37 11813 d2d4 b8c6 g1f3 g8f6 b1c3
6 11 60 24771 d2d4 g8f6 b1c3 b8c6 g1f3 d7d5
7 51 101 58692 d2d4 g8f6 b1c3 b8c6 g1f3 d7d5 c1e3
8 15 140 98123 d2d4 g8f6 g1f3 d7d5 b1c3 c8e6 c1e3 b8c6
9 30 293 216667 d2d4 g8f6 b1c3 d7d5 g1f3 b8c6 c1f4
10 22 911 709620 d2d4 g8f6 b1c3 d7d5 g1f3 b8c6 e2e3 a8b8 f1d3 c8e6
11 30 2653 2152557 d2d4 g8f6 b1c3 d7d5 g1f3 b7b6 c1e3 b8c6 f3e5 c8b7 f2f4
12 21 4150 3608862 d2d4 g8f6 b1c3 d7d5 c1f4 c8e6 g1f3 b8c6 g2g3
13 28 11522 8016578 d2d4 d7d5 b1c3 b8c6 f2f3 f7f5 c1f4 a7a6 e2e3 g8f6 a1c1 c8e6 f1d3
14 25 57321 37683014 d2d4 g8f6 c2c4 c7c6 g1f3 d7d5 e2e3 c8f5 b1c3 e7e6 c4d5 e6d5 f1d3 f5d3
Update. But depth means nothing. Being only an upperbound. Also speed means nothing if it skips important moves.
Code: Select all
1 50 8 4 d2d4
2 12 10 129 d2d4 b8c6
3 54 12 505 d2d4 b8c6 b1c3
4 14 14 1684 d2d4 d7d5 b1c3 c8f5
4 16 15 2158 b1c3 e7e5 d2d4 f8d6
5 50 28 11596 b1c3 d7d5 d2d4 c8f5 c1e3
6 18 39 19839 b1c3 b8c6 g1f3 g8f6 d2d4 d7d5
7 47 79 58696 b1c3 e7e5 g1f3 b8c6 e2e4 f8d6 f1c4
7 48 85 64243 d2d4 d7d5 b1c3 b8c6 c1e3
8 14 137 129420 d2d4 d7d5 b1c3 b8c6 g1f3 c8f5 c1e3 g8f6
8 20 195 192722 e2e4 e7e5 b1c3 b8c6 g1f3 f8c5 f1c4 g8f6
9 35 635 631738 e2e4 f7f5 e4f5 d7d5 f1d3 g8h6 b1c3 c8f5 g1f3
9 36 679 676696 d2d4 d7d5 b1c3 b8c6 g1f3 c8f5 c1f4 g8f6 e2e3
10 33 1131 1109218 d2d4 d7d5 g1f3 b8c6 b1c3 c8f5 e2e3 g8f6 f1d3 f6e4
11 47 2532 2678755 d2d4 d7d5 b1c3 b8c6 e2e3 g8f6 g1f3 c8f5 f1d3 f6e4 c1d2
12 38 4308 4527612 d2d4 d7d5 b1c3 b8c6 c1f4 c8f5 e2e3
13 39 12434 11869842 d2d4 c7c5 d4c5 e7e5 g1f3 b8c6 c1e3 g8f6 b1c3 f6g4 c3e4 g4e3 f2e3
14 40 40173 32656035 d2d4 c7c5 d4c5 g8f6 b1c3 e7e5
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Fri Apr 16, 2021 11:06 am
Current interface of chessboard. Previous generic one was an efficiency disaster.
Bytes() not necessary if you use zobrist key.
Code: Select all
public interface IChessBoard
{
IChessBoard Move(IMoveBase move);
IChessBoard PutOnBoard(PieceTypeEnum PieceSort, ulong coord);
ColorSign OccupierColSign(ulong bit);
Kind PieceKind(ulong bit);
bool Occupied(ulong bit);
PieceTypeEnum PieceType(ulong bit);
UInt64 WhitePieces { get; }
UInt64 BlackPieces { get;}
UInt64 Kings { get; }
UInt64 Queens { get; }
UInt64 Rooks { get; }
UInt64 Bishops { get; }
UInt64 Knights { get; }
UInt64 Pawns { get; }
bool BareKing(ColorSign colorSign);
UInt64 Bits(Kind kind, ColorSign colorSign);
UInt64 Bits(ColorSign colorSign);
UInt64 Bits(PieceTypeEnum pieceType);
UInt64 Bits(Kind kind);
UInt64 Occupiers { get; }
UInt64 Sliders(ColorSign colSign);
byte[] Bytes();
}
}
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Fri Apr 16, 2021 1:55 pm
hi, hi, hi.
Code: Select all
public double ComputeFeatureValue(IChessPosition pos, ColorSign side, Func<ISquares<ISquareEval>, IChessPosition, PieceTypeEnum, double> func)
{
double result = 0;
for (var kind = Pawn_Kind; kind <= King_Kind; kind++)
{
var type = ConvertToPieceType(kind, side);
result += func(SquaresEval, pos, type);
}
return result;
}
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Wed Apr 21, 2021 12:07 pm
Looks like Skipper still unable to win from Stockfish.
[pgn]
[Event "Computer Chess Game"]
[Site "LAPTOP-1FK7MTIP"]
[Date "2021.04.21"]
[Round "-"]
[White "Skipper_8_5"]
[Black "Stockfish 13"]
[Result "0-1"]
[TimeControl "300"]
[Annotator "1. +0.10 1... -0.27"]
1. e4 {+0.10/10} e5 {-0.27/29 20} 2. d4 {+0.10/9 6} exd4 {+0.00/24 2.6} 3.
Qxd4 {+0.00/9 6} Nc6 {+0.40/25 6} 4. Qd1 {+0.20/8 6} Nf6 {+0.85/23 3} 5.
Nd2 {+0.03/8 6} Qe7 {+1.30/28 23} 6. f3 {-0.17/9 5} d5 {+1.86/22 4} 7. Bd3
{-0.15/8 5} b6 {+2.14/27 21} 8. Nh3 {+0.26/9 5} Bxh3 {+2.35/24 3} 9. gxh3
{+0.22/9 5} O-O-O {+2.08/28 11} 10. a3 {+0.16/8 5} Nxe4 {+4.23/26 17} 11.
fxe4 {+1.42/9 5} Qh4+ {+5.81/23 3} 12. Ke2 {+1.24/9 5} Nd4+ {+8.21/25 0.1}
13. Kf1 {+2.18/8 5} Qxh3+ {+8.75/25 0.1} 14. Kf2 {+0.88/9 5} Bc5
{+8.82/27 1.5} 15. Ba6+ {-0.20/9 5} Kb8 {+10.28/25 3} 16. b4 {-0.48/9 4}
Rd6 {+10.60/24 0.1} 17. bxc5 {+0.23/8 4} Rf6+ {+16.58/25 2.9} 18. Nf3
{-3.34/10 4} Rxf3+ {+99.75/37 0.2} 19. Ke1 {-3.35/9 4} Qh4+ {+99.77/44 0.1}
20. Kd2 {-4.15/9 4} Qf4+ {+99.79/47 0.1} 21. Ke1 {-5.76/10 4} Qxe4+
{+99.81/51 0.1} 22. Be2 {-7.07/10 4} Re8 {+99.83/55 0.2} 23. cxb6
{-7.52/8 4} Qh4+ {+99.85/55 0.1} 24. Kd2 {-4.98/9 4} Qf2 {+99.87/56 0.1}
25. bxc7+ {-327.54/10 4} Kxc7 {+99.89/67 0.1} 26. Bb2 {-327.56/9 4} Rxe2+
{+99.91/78 0.1} 27. Kc1 {-327.58/9 4} Rxc2+ {+99.93/176 0.1} 28. Kb1
{-327.60/10 3} Rxb2+ {+99.95/245 0.1} 29. Kc1 {-327.62/10 3} Nb3+
{+99.97/245 0.1} 30. Qxb3 {-327.64/11 3} Qd2# {+99.99/245 0.2}
{Xboard adjudication: Checkmate} 0-1
[/pgn]
RoadWarrior
Posts: 73 Joined: Fri Jan 13, 2012 12:39 am
Location: London, England
Post
by RoadWarrior » Thu Apr 22, 2021 7:32 pm
Henk wrote: ↑ Mon Apr 12, 2021 11:01 pm
I think I fixed the bug in movecount.
Now it is back to normal. That is less than 80kn/sec.
Perft in my C# chess engine runs at about 80
M nodes per second on a single core of a mid-range Intel i7-7700 CPU running at 3.6 GHz. So shurely shome mishtake?
There are two types of people in the world: Avoid them both.
Sven
Posts: 4052 Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle
Post
by Sven » Thu Apr 22, 2021 9:39 pm
Is that the number of nodes actually visited, or the number of leaves determined via bulk-counting?
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
Henk
Posts: 7220 Joined: Mon May 27, 2013 10:31 am
Post
by Henk » Thu Apr 22, 2021 9:59 pm
The number of nodes visited while counting null move and standingpats as 1.
By the way I get 150km/sec if I do nothing in evaluation except returning sign * psqValue.
If I try to evaluate pawnshields, isolated pawns etc then speed drops below 90kN/sec.
I also think my immutable transposition table slows down performance. But I will probably need it when I make my engine multi-threaded.
Code: Select all
public class TranspositionTable<IKey, IValue>
{
..
readonly ImmutableDictionary<IKey, IValue> rep;
Maybe if I use zobrist key I can gain some extra speed. I now use a .net hashalhorithm. But to use it I have to convert position into bytes
Code: Select all
public class HashKeyFactory: IKeyFactory
{
readonly HashAlgorithm hashAlgorithm;
public HashKeyFactory()
{
hashAlgorithm = MD5.Create();
}
}
Trying to improve speed by replacing prioq.Sort with a bubble up (bubblesort) for first 3 or 4 moves did not help much.