1
1
{-# LANGUAGE NamedFieldPuns #-}
2
2
{-# LANGUAGE RecordWildCards #-}
3
3
{-# LANGUAGE OverloadedStrings #-}
4
+ {-# LANGUAGE ExistentialQuantification #-}
4
5
module Core.Evaluator
5
6
( SimpleEvaluator (.. ),
7
+ SimpleEvaluatorInterface (.. ),
8
+ SimpleEvaluatorSupport (.. ),
6
9
defaultEvaluator
7
10
) where
8
11
@@ -14,11 +17,12 @@ import Core.Types
14
17
import Core.Board
15
18
16
19
data SimpleEvaluator = SimpleEvaluator {
17
- seRules :: SomeRules ,
20
+ seRules :: SimpleEvaluatorInterface ,
18
21
seUsePositionalScore :: Bool ,
19
22
seMobilityWeight :: ScoreBase ,
20
23
seCenterWeight :: ScoreBase ,
21
24
seOppositeSideWeight :: ScoreBase ,
25
+ seBorderMenBad :: Bool ,
22
26
seBackedWeight :: ScoreBase ,
23
27
seAsymetryWeight :: ScoreBase ,
24
28
sePreKingWeight :: ScoreBase ,
@@ -27,13 +31,26 @@ data SimpleEvaluator = SimpleEvaluator {
27
31
}
28
32
deriving (Show )
29
33
30
- defaultEvaluator :: GameRules rules => rules -> SimpleEvaluator
34
+ class GameRules rules => SimpleEvaluatorSupport rules where
35
+ getBackDirections :: rules -> [PlayerDirection ]
36
+ getBackDirections _ = [BackwardLeft , BackwardRight ]
37
+
38
+ getForwardDirections :: rules -> [PlayerDirection ]
39
+ getForwardDirections _ = [ForwardLeft , ForwardRight ]
40
+
41
+ data SimpleEvaluatorInterface = forall g . SimpleEvaluatorSupport g => SimpleEvaluatorInterface g
42
+
43
+ instance Show SimpleEvaluatorInterface where
44
+ show (SimpleEvaluatorInterface rules) = rulesName rules
45
+
46
+ defaultEvaluator :: SimpleEvaluatorSupport rules => rules -> SimpleEvaluator
31
47
defaultEvaluator rules = SimpleEvaluator
32
- { seRules = SomeRules rules
48
+ { seRules = SimpleEvaluatorInterface rules
33
49
, seUsePositionalScore = True
34
50
, seMobilityWeight = 3
35
51
, seCenterWeight = 4
36
52
, seOppositeSideWeight = 4
53
+ , seBorderMenBad = True
37
54
, seBackedWeight = 2
38
55
, seAsymetryWeight = 1
39
56
, sePreKingWeight = 3
@@ -74,7 +91,7 @@ instance Default PreScore where
74
91
}
75
92
76
93
preEval :: SimpleEvaluator -> Side -> Board -> PreScore
77
- preEval (SimpleEvaluator { seRules = SomeRules rules, .. }) side board =
94
+ preEval (SimpleEvaluator { seRules = SimpleEvaluatorInterface rules, .. }) side board =
78
95
let
79
96
kingCoef =
80
97
-- King is much more useful when there are enough men to help it
@@ -108,13 +125,13 @@ preEval (SimpleEvaluator { seRules = SomeRules rules, ..}) side board =
108
125
Just back -> isPieceAt back board side
109
126
110
127
backedScoreOf addr =
111
- length $ filter (isBackedAt addr) [ BackwardLeft , BackwardRight ]
128
+ length $ filter (isBackedAt addr) $ getBackDirections rules
112
129
113
130
backedScore =
114
131
fromIntegral $ sum $ map backedScoreOf $ allMyAddresses side board
115
132
116
133
tempNumber (Label col row)
117
- | col == 0 || col == ncols - 1 = 0
134
+ | seBorderMenBad && ( col == 0 || col == ncols - 1 ) = 0
118
135
| otherwise = case boardSide (boardOrientation rules) side of
119
136
Top -> nrows - row
120
137
Bottom -> row + 1
@@ -123,7 +140,7 @@ preEval (SimpleEvaluator { seRules = SomeRules rules, ..}) side board =
123
140
opponentSideCount =
124
141
let (men, kings) = myLabelsCount' side board tempNumber in men
125
142
126
- preKing board src = sum $ map check [ ForwardLeft , ForwardRight ]
143
+ preKing board src = sum $ map check $ getForwardDirections rules
127
144
where
128
145
check dir =
129
146
case myNeighbour rules side dir src of
0 commit comments