Skip to content

Commit fc90b15

Browse files
committed
move islegal teste, checkinfo fix
1 parent b1dfc40 commit fc90b15

File tree

6 files changed

+355
-58
lines changed

6 files changed

+355
-58
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System;
2+
using System.Text;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
using NoraGrace.Engine;
7+
using NoraGrace.Engine.Evaluation;
8+
using System.IO;
9+
10+
namespace Sinobyl.Engine.Tests
11+
{
12+
[TestClass]
13+
public class MoveTests
14+
{
15+
[TestMethod]
16+
public void Move_IsLegalPsuedoMoveTest()
17+
{
18+
MovePicker mp = new MovePicker(new MovePicker.MoveHistory(), new StaticExchange());
19+
PlyData pd = new PlyData();
20+
21+
foreach(var pgn in GetPgns())
22+
{
23+
Board board = new Board(pgn.StartingPosition);
24+
List<Move> prevWhite = null;
25+
List<Move> prevBlack = null;
26+
27+
foreach(var gameMove in pgn.Moves)
28+
{
29+
board.MoveApply(gameMove);
30+
31+
var me = board.WhosTurn;
32+
var him = me.PlayerOther();
33+
34+
mp.Initialize(board, Move.EMPTY, false);
35+
var myAttacks = pd.AttacksFor(me, board);
36+
var hisAttacks = pd.AttacksFor(him, board);
37+
var myChecks = pd.ChecksFor(me, board);
38+
var hisChecks = pd.ChecksFor(him, board);
39+
40+
List<Move> psuedoMoves = mp.SortedMoves().ToList();
41+
42+
//IsPsuedoLegal test.
43+
//look through all moves in previous ply, and make sure that
44+
List<Move> prevMoves = board.WhosTurn == Player.White ? prevWhite : prevBlack;
45+
if (prevMoves != null && !board.IsCheck())
46+
{
47+
foreach(var prevMove in prevMoves)
48+
{
49+
bool isPsuedoLegal = prevMove.IsPsuedoLegal(board);
50+
Assert.IsTrue(isPsuedoLegal == psuedoMoves.Contains(prevMove));
51+
}
52+
}
53+
54+
foreach (var psuedoMove in mp.SortedMoves())
55+
{
56+
Assert.IsTrue(psuedoMove.IsPsuedoLegal(board));
57+
58+
var willBeLegal = psuedoMove.IsLegalPsuedoMove(board, hisAttacks, myChecks);
59+
var willCheck = psuedoMove.CausesCheck(board, hisChecks);
60+
61+
board.MoveApply(psuedoMove);
62+
63+
var isCheck = board.IsCheck();
64+
var isLegal = !board.IsCheck(me);
65+
66+
board.MoveUndo();
67+
68+
69+
Assert.AreEqual(isLegal, willBeLegal);
70+
if (isLegal)
71+
{
72+
Assert.AreEqual(isCheck, willCheck);
73+
}
74+
}
75+
76+
//set previous moves for is psuedolegal
77+
if (board.WhosTurn == Player.White)
78+
{
79+
prevWhite = psuedoMoves;
80+
}
81+
else
82+
{
83+
prevBlack = psuedoMoves;
84+
}
85+
86+
}
87+
}
88+
}
89+
90+
public static IEnumerable<PGN> GetPgns()
91+
{
92+
var names = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
93+
var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Sinobyl.Engine.Tests.pgnFiles.gm2600.pgn");
94+
System.IO.StreamReader reader = new System.IO.StreamReader(stream);
95+
96+
while (!reader.EndOfStream)
97+
{
98+
PGN pgn = PGN.NextGame(reader);
99+
if (pgn == null) { break; }
100+
yield return pgn;
101+
}
102+
}
103+
104+
}
105+
}

NoraGrace/NoraGrace.Engine.Tests/NoraGrace.Engine.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
<Compile Include="FENTest.cs" />
6666
<Compile Include="GameTest.cs" />
6767
<Compile Include="gm2600.cs" />
68+
<Compile Include="MoveTests.cs" />
6869
<Compile Include="MovegenTest.cs" />
6970
<Compile Include="PGNTests.cs" />
7071
<Compile Include="PhasedScoreTests.cs" />

NoraGrace/NoraGrace.Engine/AttackInfo.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public AttackInfo(Player player)
3333
_player = player;
3434
}
3535

36+
public bool IsInitialized(Board board)
37+
{
38+
return _zobrist == board.ZobristBoard;
39+
}
40+
3641
public void Initialize(Board board)
3742
{
3843
//early exit if already set up for this position.
@@ -201,6 +206,15 @@ public Bitboard ByCount(int count)
201206
{
202207
return _counts[count];
203208
}
209+
210+
public Bitboard All
211+
{
212+
get
213+
{
214+
return _counts[1];
215+
}
216+
}
217+
204218
public Bitboard ByPieceType(PieceType pt)
205219
{
206220
return _byPieceType[(int)pt];

NoraGrace/NoraGrace.Engine/CheckInfo.cs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,25 @@ public class CheckInfo
1919
public Bitboard RookDirect { get; private set; }
2020
public Bitboard DirectAll { get; private set; }
2121
public Bitboard PinnedOrDiscovered { get; private set; }
22+
public Bitboard Checkers { get; private set; }
23+
public bool IsCheck { get { return Checkers != Bitboard.Empty; } }
2224

2325
public CheckInfo(Player player)
2426
{
2527
this.Player = player;
2628
}
2729

30+
public bool IsInitialized(Board board)
31+
{
32+
return board.ZobristBoard == Zobrist;
33+
}
34+
2835
public void Initialize(Board board)
2936
{
3037
if (board.ZobristBoard == Zobrist) { return; }
3138

39+
this.Zobrist = board.ZobristBoard;
40+
3241
CheckInfo retval = this;
3342
Position kingPos = board.KingPosition(Player);
3443
Bitboard all = board.PieceLocationsAll;
@@ -40,8 +49,16 @@ public void Initialize(Board board)
4049
retval.KnightDirect = Attacks.KnightAttacks(kingPos);
4150
retval.BishopDirect = Attacks.BishopAttacks(kingPos, all);
4251
retval.RookDirect = Attacks.RookAttacks(kingPos, all);
43-
4452
retval.DirectAll = retval.PawnDirect | retval.KnightDirect | retval.BishopDirect | retval.RookDirect;
53+
54+
//find pieces currently checking king
55+
Bitboard checkers = Bitboard.Empty;
56+
checkers |= PawnDirect & them & board[PieceType.Pawn];
57+
checkers |= KnightDirect & them & board[PieceType.Knight];
58+
checkers |= BishopDirect & them & board.BishopSliders;
59+
checkers |= RookDirect & them & board.RookSliders;
60+
this.Checkers = checkers;
61+
4562

4663
retval.PinnedOrDiscovered = Bitboard.Empty;
4764

@@ -55,14 +72,23 @@ public void Initialize(Board board)
5572
while (xray != Bitboard.Empty)
5673
{
5774
Position xrayAttacker = BitboardUtil.PopFirst(ref xray);
58-
Bitboard xrayBlockers = xrayAttacker.Between(kingPos) & all;
75+
Bitboard between = xrayAttacker.Between(kingPos) & all;
5976

60-
Position xrayBlocker1 = BitboardUtil.PopFirst(ref xrayBlockers);
61-
if (xrayBlockers == Bitboard.Empty)
77+
if (between != Bitboard.Empty)
78+
{
79+
//there are piece(s) between slider and king
80+
Position blocker = BitboardUtil.PopFirst(ref between);
81+
if (between == Bitboard.Empty)
82+
{
83+
//only one piece inbetween xrayAttacker and king, it is pinned, or a discovered attack
84+
retval.PinnedOrDiscovered |= blocker.ToBitboard();
85+
}
86+
}
87+
else
6288
{
63-
//only one piece inbetween xrayAttacker and king
64-
retval.PinnedOrDiscovered |= xrayBlocker1.ToBitboard();
89+
System.Diagnostics.Debug.Assert(checkers.Contains(xrayAttacker));
6590
}
91+
6692

6793
}
6894
}

0 commit comments

Comments
 (0)