Skip to content

Commit 4c02231

Browse files
committed
separated mobility evaluation to own class
1 parent 10bc401 commit 4c02231

File tree

4 files changed

+160
-143
lines changed

4 files changed

+160
-143
lines changed

NoraGrace/NoraGrace.Engine/Evaluation/Evaluator.cs

Lines changed: 5 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@ public class Evaluator: IChessEval
2222
public readonly MaterialEvaluator _evalMaterial;
2323
private readonly PcSqEvaluator _evalPcSq;
2424
private readonly KingAttackEvaluator _evalKing;
25+
private readonly MobilityEvaluator _evalMobility;
2526

26-
public readonly PhasedScore[][] _mobilityPieceTypeCount = new PhasedScore[PieceTypeUtil.LookupArrayLength][];
2727

2828
public readonly int[] _endgameMateKingPcSq;
2929

3030

3131
protected readonly Settings _settings;
3232

33-
protected readonly PhasedScore RookFileOpen;
34-
protected readonly PhasedScore RookFileHalfOpen;
33+
3534

3635

3736

@@ -60,31 +59,10 @@ public Evaluator(Settings settings)
6059
_evalMaterial = new MaterialEvaluator(_settings.MaterialValues);
6160
_evalPcSq = new PcSqEvaluator(settings);
6261
_evalKing = new KingAttackEvaluator(settings.KingAttack);
63-
62+
_evalMobility = new MobilityEvaluator(settings.Mobility);
6463
//setup mobility arrays
6564

66-
foreach (PieceType pieceType in new PieceType[]{PieceType.Knight, PieceType.Bishop, PieceType.Rook, PieceType.Queen})
67-
{
68-
var pieceSettings = settings.Mobility[pieceType];
69-
70-
int[] openingVals = pieceSettings.Opening.GetValues(pieceType.MaximumMoves());
71-
int[] endgameVals = pieceSettings.Endgame.GetValues(pieceType.MaximumMoves());
72-
73-
PhasedScore[] combined = PhasedScoreUtil.Combine(openingVals, endgameVals).ToArray();
7465

75-
_mobilityPieceTypeCount[(int)pieceType] = combined;
76-
//for (int attacksCount = 0; attacksCount < 28; attacksCount++)
77-
//{
78-
// var mobSettings = settings.Mobility;
79-
80-
81-
82-
// int startVal = (attacksCount - opiece[GameStage.Opening].ExpectedAttacksAvailable) * opiece[GameStage.Opening].AmountPerAttackDefault;
83-
// int endVal = (attacksCount - opiece[GameStage.Endgame].ExpectedAttacksAvailable) * opiece[GameStage.Endgame].AmountPerAttackDefault;
84-
85-
// _mobilityPieceTypeCount[(int)pieceType][attacksCount] = PhasedScoreUtil.Create(startVal, endVal);
86-
//}
87-
}
8866

8967
//initialize pcsq for trying to mate king in endgame, try to push it to edge of board.
9068
_endgameMateKingPcSq = new int[64];
@@ -99,8 +77,6 @@ public Evaluator(Settings settings)
9977
_endgameMateKingPcSq[(int)pos] = minDist * 50;
10078
}
10179

102-
RookFileOpen = PhasedScoreUtil.Create(settings.RookFileOpen, settings.RookFileOpen / 2);
103-
RookFileHalfOpen = PhasedScoreUtil.Create(settings.RookFileOpen / 2, settings.RookFileOpen / 4);
10480

10581

10682

@@ -154,8 +130,8 @@ public void EvalAdvanced(Board board, PlyData plyData, MaterialResults material,
154130
attacksWhite.King = Attacks.KingAttacks(board.KingPosition(Player.White));
155131
attacksBlack.King = Attacks.KingAttacks(board.KingPosition(Player.Black));
156132

157-
EvaluateMyPieces(board, Player.White, evalInfo);
158-
EvaluateMyPieces(board, Player.Black, evalInfo);
133+
_evalMobility.EvaluateMyPieces(board, Player.White, evalInfo);
134+
_evalMobility.EvaluateMyPieces(board, Player.Black, evalInfo);
159135

160136
_evalKing.EvaluateMyKingAttack(board, Player.White, evalInfo);
161137
_evalKing.EvaluateMyKingAttack(board, Player.Black, evalInfo);
@@ -230,116 +206,6 @@ public static PhasedScore EvaluateOutpost(Board board, Player me, PieceType piec
230206

231207
}
232208

233-
protected int EvaluateMyPieces(Board board, Player me, EvalResults info)
234-
{
235-
int retval = 0;
236-
PhasedScore mobility = 0;
237-
var him = me.PlayerOther();
238-
var myAttacks = info.Attacks[(int)me];
239-
var hisAttacks = info.Attacks[(int)him];
240-
241-
var hisKing = board.KingPosition(him);
242-
var hisKingZone = KingAttackEvaluator.KingRegion(hisKing);
243-
244-
245-
Bitboard myPieces = board[me];
246-
Bitboard pieceLocationsAll = board.PieceLocationsAll;
247-
Bitboard pawns = board[PieceType.Pawn];
248-
249-
Bitboard slidersAndKnights = myPieces &
250-
(board[PieceType.Knight]
251-
| board[PieceType.Bishop]
252-
| board[PieceType.Rook]
253-
| board[PieceType.Queen]);
254-
255-
Bitboard MobilityTargets = ~myPieces & ~(hisAttacks.PawnEast | hisAttacks.PawnWest);
256-
257-
Bitboard myDiagSliders = myPieces & board.BishopSliders;
258-
Bitboard myHorizSliders = myPieces & board.RookSliders;
259-
Bitboard potentialOutputs = OUTPOST_AREA & (myAttacks.PawnEast | myAttacks.PawnWest);
260-
261-
while (slidersAndKnights != Bitboard.Empty) //foreach(ChessPosition pos in slidersAndKnights.ToPositions())
262-
{
263-
Position pos = BitboardUtil.PopFirst(ref slidersAndKnights);
264-
265-
PieceType pieceType = board.PieceAt(pos).ToPieceType();
266-
267-
//generate attacks
268-
Bitboard slidingAttacks = Bitboard.Empty;
269-
270-
switch (pieceType)
271-
{
272-
case PieceType.Knight:
273-
slidingAttacks = Attacks.KnightAttacks(pos);
274-
if (myAttacks.Knight != Bitboard.Empty)
275-
{
276-
myAttacks.Knight2 |= slidingAttacks;
277-
}
278-
else
279-
{
280-
myAttacks.Knight |= slidingAttacks;
281-
}
282-
//if (potentialOutputs.Contains(pos))
283-
//{
284-
// mobility = mobility.Add(EvaluateOutpost(board, me, PieceType.Knight, pos));
285-
//}
286-
break;
287-
case PieceType.Bishop:
288-
slidingAttacks = Attacks.BishopAttacks(pos, pieceLocationsAll & ~myHorizSliders);
289-
myAttacks.Bishop |= slidingAttacks;
290-
//if (potentialOutputs.Contains(pos))
291-
//{
292-
// mobility = mobility.Add(EvaluateOutpost(board, me, PieceType.Bishop, pos));
293-
//}
294-
break;
295-
case PieceType.Rook:
296-
slidingAttacks = Attacks.RookAttacks(pos, pieceLocationsAll & ~myDiagSliders);
297-
if (myAttacks.Rook != Bitboard.Empty)
298-
{
299-
myAttacks.Rook2 |= slidingAttacks;
300-
}
301-
else
302-
{
303-
myAttacks.Rook |= slidingAttacks;
304-
}
305-
if ((pos.ToFile().ToBitboard() & pawns & myPieces) == Bitboard.Empty)
306-
{
307-
if ((pos.ToFile().ToBitboard() & pawns) == Bitboard.Empty)
308-
{
309-
mobility = mobility.Add(RookFileOpen);
310-
}
311-
else
312-
{
313-
mobility = mobility.Add(RookFileHalfOpen);
314-
}
315-
}
316-
break;
317-
case PieceType.Queen:
318-
slidingAttacks = Attacks.QueenAttacks(pos, pieceLocationsAll & ~(myDiagSliders | myHorizSliders));
319-
myAttacks.Queen |= slidingAttacks;
320-
321-
myAttacks.KingQueenTropism = hisKing.DistanceTo(pos) + hisKing.DistanceToNoDiag(pos);
322-
break;
323-
}
324-
325-
// calc mobility score
326-
int mobilityCount = (slidingAttacks & MobilityTargets).BitCount();
327-
mobility = mobility.Add(_mobilityPieceTypeCount[(int)pieceType][mobilityCount]);
328-
329-
//see if involved in a king attack
330-
if((hisKingZone & slidingAttacks) != Bitboard.Empty)
331-
{
332-
myAttacks.KingAttackerCount++;
333-
myAttacks.KingAttackerWeight += KingAttackEvaluator.KingAttackerWeight(pieceType);
334-
}
335-
336-
}
337-
338-
339-
340-
myAttacks.Mobility = mobility;
341-
return retval;
342-
}
343209

344210
protected virtual float CalcStartWeight(int basicMaterialCount)
345211
{
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace NoraGrace.Engine.Evaluation
8+
{
9+
10+
public class MobilitySettings : ChessPieceTypeDictionary<ChessGameStageDictionary<Helpers.Mobility>>
11+
{
12+
public int RookFileOpen = 0;
13+
}
14+
public class MobilityEvaluator
15+
{
16+
protected readonly PhasedScore RookFileOpen;
17+
protected readonly PhasedScore RookFileHalfOpen;
18+
public readonly PhasedScore[][] _mobilityPieceTypeCount = new PhasedScore[PieceTypeUtil.LookupArrayLength][];
19+
20+
public MobilityEvaluator(MobilitySettings settings)
21+
{
22+
RookFileOpen = PhasedScoreUtil.Create(settings.RookFileOpen, settings.RookFileOpen / 2);
23+
RookFileHalfOpen = PhasedScoreUtil.Create(settings.RookFileOpen / 2, settings.RookFileOpen / 4);
24+
25+
foreach (PieceType pieceType in new PieceType[] { PieceType.Knight, PieceType.Bishop, PieceType.Rook, PieceType.Queen })
26+
{
27+
var pieceSettings = settings[pieceType];
28+
29+
int[] openingVals = pieceSettings.Opening.GetValues(pieceType.MaximumMoves());
30+
int[] endgameVals = pieceSettings.Endgame.GetValues(pieceType.MaximumMoves());
31+
32+
PhasedScore[] combined = PhasedScoreUtil.Combine(openingVals, endgameVals).ToArray();
33+
34+
_mobilityPieceTypeCount[(int)pieceType] = combined;
35+
36+
}
37+
38+
}
39+
40+
public void EvaluateMyPieces(Board board, Player me, EvalResults info)
41+
{
42+
PhasedScore mobility = 0;
43+
var him = me.PlayerOther();
44+
var myAttacks = info.Attacks[(int)me];
45+
var hisAttacks = info.Attacks[(int)him];
46+
47+
var hisKing = board.KingPosition(him);
48+
var hisKingZone = KingAttackEvaluator.KingRegion(hisKing);
49+
50+
51+
Bitboard myPieces = board[me];
52+
Bitboard pieceLocationsAll = board.PieceLocationsAll;
53+
Bitboard pawns = board[PieceType.Pawn];
54+
55+
Bitboard slidersAndKnights = myPieces &
56+
(board[PieceType.Knight]
57+
| board[PieceType.Bishop]
58+
| board[PieceType.Rook]
59+
| board[PieceType.Queen]);
60+
61+
Bitboard MobilityTargets = ~myPieces & ~(hisAttacks.PawnEast | hisAttacks.PawnWest);
62+
63+
Bitboard myDiagSliders = myPieces & board.BishopSliders;
64+
Bitboard myHorizSliders = myPieces & board.RookSliders;
65+
Bitboard potentialOutputs = Evaluator.OUTPOST_AREA & (myAttacks.PawnEast | myAttacks.PawnWest);
66+
67+
while (slidersAndKnights != Bitboard.Empty) //foreach(ChessPosition pos in slidersAndKnights.ToPositions())
68+
{
69+
Position pos = BitboardUtil.PopFirst(ref slidersAndKnights);
70+
71+
PieceType pieceType = board.PieceAt(pos).ToPieceType();
72+
73+
//generate attacks
74+
Bitboard slidingAttacks = Bitboard.Empty;
75+
76+
switch (pieceType)
77+
{
78+
case PieceType.Knight:
79+
slidingAttacks = Attacks.KnightAttacks(pos);
80+
if (myAttacks.Knight != Bitboard.Empty)
81+
{
82+
myAttacks.Knight2 |= slidingAttacks;
83+
}
84+
else
85+
{
86+
myAttacks.Knight |= slidingAttacks;
87+
}
88+
//if (potentialOutputs.Contains(pos))
89+
//{
90+
// mobility = mobility.Add(EvaluateOutpost(board, me, PieceType.Knight, pos));
91+
//}
92+
break;
93+
case PieceType.Bishop:
94+
slidingAttacks = Attacks.BishopAttacks(pos, pieceLocationsAll & ~myHorizSliders);
95+
myAttacks.Bishop |= slidingAttacks;
96+
//if (potentialOutputs.Contains(pos))
97+
//{
98+
// mobility = mobility.Add(EvaluateOutpost(board, me, PieceType.Bishop, pos));
99+
//}
100+
break;
101+
case PieceType.Rook:
102+
slidingAttacks = Attacks.RookAttacks(pos, pieceLocationsAll & ~myDiagSliders);
103+
if (myAttacks.Rook != Bitboard.Empty)
104+
{
105+
myAttacks.Rook2 |= slidingAttacks;
106+
}
107+
else
108+
{
109+
myAttacks.Rook |= slidingAttacks;
110+
}
111+
if ((pos.ToFile().ToBitboard() & pawns & myPieces) == Bitboard.Empty)
112+
{
113+
if ((pos.ToFile().ToBitboard() & pawns) == Bitboard.Empty)
114+
{
115+
mobility = mobility.Add(RookFileOpen);
116+
}
117+
else
118+
{
119+
mobility = mobility.Add(RookFileHalfOpen);
120+
}
121+
}
122+
break;
123+
case PieceType.Queen:
124+
slidingAttacks = Attacks.QueenAttacks(pos, pieceLocationsAll & ~(myDiagSliders | myHorizSliders));
125+
myAttacks.Queen |= slidingAttacks;
126+
127+
myAttacks.KingQueenTropism = hisKing.DistanceTo(pos) + hisKing.DistanceToNoDiag(pos);
128+
break;
129+
}
130+
131+
// calc mobility score
132+
int mobilityCount = (slidingAttacks & MobilityTargets).BitCount();
133+
mobility = mobility.Add(_mobilityPieceTypeCount[(int)pieceType][mobilityCount]);
134+
135+
//see if involved in a king attack
136+
if ((hisKingZone & slidingAttacks) != Bitboard.Empty)
137+
{
138+
myAttacks.KingAttackerCount++;
139+
myAttacks.KingAttackerWeight += KingAttackEvaluator.KingAttackerWeight(pieceType);
140+
}
141+
142+
}
143+
144+
myAttacks.Mobility = mobility;
145+
}
146+
147+
}
148+
}

NoraGrace/NoraGrace.Engine/Evaluation/Settings.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ public static Settings Default()
403403
PawnPassedFarPct = 0.7f,
404404
PawnShelterFactor = 6,
405405

406-
RookFileOpen = 20,
406+
407407

408408
KingAttack = new KingAttackSettings()
409409
{
@@ -418,8 +418,10 @@ public static Settings Default()
418418

419419

420420

421-
Mobility = new ChessPieceTypeDictionary<ChessGameStageDictionary<Helpers.Mobility>>()
421+
Mobility = new MobilitySettings()
422422
{
423+
RookFileOpen = 20,
424+
423425
Knight = new ChessGameStageDictionary<Helpers.Mobility>()
424426
{
425427
Opening = new Helpers.Mobility() { ExpectedAttacksAvailable = 3, Amplitude = 60, BezControlPct = new Helpers.Point(.3, .6)},
@@ -456,7 +458,7 @@ public static Settings Default()
456458
public ChessGameStageDictionary<int> PawnDoubled = new ChessGameStageDictionary<int>();
457459
public ChessGameStageDictionary<int> PawnIsolated = new ChessGameStageDictionary<int>();
458460
public ChessGameStageDictionary<int> PawnUnconnected = new ChessGameStageDictionary<int>();
459-
public ChessPieceTypeDictionary<ChessGameStageDictionary<Helpers.Mobility>> Mobility = new ChessPieceTypeDictionary<ChessGameStageDictionary<Helpers.Mobility>>();
461+
public MobilitySettings Mobility = new MobilitySettings();
460462
public KingAttackSettings KingAttack = new KingAttackSettings();
461463

462464
public int PawnPassed8thRankScore = 0;
@@ -469,7 +471,7 @@ public static Settings Default()
469471
public double PawnPassedFarPct = 0;
470472
public int PawnShelterFactor = 0;
471473

472-
public int RookFileOpen = 0;
474+
473475

474476

475477

NoraGrace/NoraGrace.Engine/NoraGrace.Engine.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
<Compile Include="Evaluation\KingAttackEvaluator.cs" />
6565
<Compile Include="Evaluation\Lazy.cs" />
6666
<Compile Include="Evaluation\MaterialEvaluator.cs" />
67+
<Compile Include="Evaluation\MobilityEvaluator.cs" />
6768
<Compile Include="Evaluation\PawnEvaluator.cs" />
6869
<Compile Include="Evaluation\PcSqEvaluator.cs" />
6970
<Compile Include="Evaluation\ScaleFactor.cs" />

0 commit comments

Comments
 (0)