2
# -*- coding: utf-8 -*-
5
Copyright (C) 2009,2010 Wolfgang Rohdewald <wolfgang@rohdewald.de>
7
kajongg is free software you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
from scoringengine import HandContent, Score, Regex
24
from predefined import ClassicalChinese
25
from common import InternalParameters
27
RULESETS = [ClassicalChinese()]
31
class RegTest(unittest.TestCase):
32
"""tests lots of hand examples. We might want to add comments which test should test which rule"""
33
# pylint: disable-msg=R0904
34
# pylint - we need more than 40 public methods
36
def __init__(self, arg):
37
unittest.TestCase.__init__(self, arg)
39
def testPartials(self):
40
"""some partial hands"""
41
self.scoreTest(r'drdrdr fe mesdr', Score(8, 1))
42
self.scoreTest(r'fe mesdr', Score(4))
43
self.scoreTest(r'fs fw fe fn mesdr', Score(16, 1))
44
self.scoreTest(r'drdrdr mesdr', Score(4, 1))
45
def testFalseColorGame(self):
46
"""false color games"""
47
self.scoreTest(r'c1c1c1 c7c7c7 c2c3c4 c5c5 c6c6c6 Mwn Lc5c5c5', Score(points=34, doubles=3))
48
self.scoreTest(r'c1c2c3 wewewe drdrdr dbdb DgDgDg Mwn Ldbdbdb', Score(points=46, doubles=4))
49
self.scoreTest(r's1s1s1 wewewe c2c3c4 c5c5 c6c6c6 Mwn Lc5c5c5', Score(points=36))
50
def testWindingSnake(self):
51
"""the winding snake"""
52
self.scoreTest(r'c1c1c1 c3c4c5 c9c9c9 c6c7c8 c2c2 Mee Lc1c1c1c1', Score(limits=1))
53
self.scoreTest(r'c1c1c1 c4c5c6 c9c9c9 c6c7c8 c2c2 Mee Lc1c1c1c1', Score(points=28, doubles=3))
54
self.scoreTest(r'c1c1c1 c3c4c5 c9c9c9 c6c7c8 s2s2 Mee Lc1c1c1c1', Score(points=28))
55
self.scoreTest(r's1s1s1 s2s3s4 s9s9s9 s6s7s8 s5s5 Mee Ls1s1s1s1', Score(limits=1))
56
self.scoreTest(r'b1b1b1 c3c4c5 c6c7c8 c9c9c9 c2c2 Mee Lc3c3c4c5', Score(points=28))
57
self.scoreTest(r'b1b1b1 c3c4c5 c6c7c8 c9c9c9 c2c2 Mee Lc4c3c4c5', Score(points=32))
58
def testTrueColorGame(self):
59
"""true color games"""
60
self.scoreTest(r'b1b1b1b1 B2B3B4B5B6B7B8B8B2B2B2 fe fs fn fw Mwe LB3B2B3B4', Score(points=62, doubles=4))
61
self.scoreTest(r'b1b1b1B1 B2B3B4B5B6B7B8B8B2B2B2 fe fs fn fw Mwe LB3B2B3B4', Score(limits=1))
62
def testOnlyConcealedMelds(self):
63
"""only concealed melds"""
64
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B9DrDr fe ys Mwe LDrDrDr', Score(48, 2))
65
self.scoreTest(r'b1B1B1b1 B2B3B4 B5B6B7 B8B8B8 DrDr fe ys Mwe LDrDrDr', Score(76, 2))
67
def testLimitHands(self):
68
"""various limit hands"""
69
self.scoreTest(r'c1c1c1 c9c9 b9b9b9b9 s1s1s1 s9s9s9 Mee Lc1c1c1c1', Score(limits=1))
70
self.scoreTest(r'c1c1c1c1 drdr wewewewe c3c3c3C3 s1S1S1s1 Mee Ldrdrdr', Score(limits=1))
71
self.scoreTest(r'drdr c1c1c1c1 wewewewe c3c3c3C3 s1S1S1s1 Mee Ldrdrdr', Score(limits=1))
72
self.scoreTest(r'c1c1c1c1 wewewewe c3c3c3C3 s1S1S1s1 drdr Mee Ldrdrdr', Score(limits=1))
73
def testAllGreen(self):
75
self.scoreTest(r'b2b2b2b2 DgDgDg b6b6b6 b4b4b4 b8b8 Mee Lb6b6b6b6', Score(limits=1))
76
self.scoreTest(r'b1b1b1b1 DgDgDg b6b6b6 b4b4b4 b8b8 Mee Lb6b6b6b6', Score(points=48, doubles=3))
77
def testNineGates(self):
79
self.scoreTest(r'C1C1C1 C2C3C4 C5C6C7 C8 C9C9C9 c5 Mee LC5C5', Score(limits=1))
81
"""some manual rules for manual scoring"""
82
# this should actually never happen but anyway we want to be sure that no rule
84
self.scoreTest(r' Mse L', Score(points=0))
85
self.scoreTest(r' mse', Score(points=0))
86
def testThirteenOrphans(self):
88
self.scoreTest(r'C1C9B9B1S1S9WeDgWsWnWwDbDrS1 mes', Score())
89
self.scoreTest(r'C1C9B9B1S1S9WeDgWsWnwwDbDrS9 Mes LDrDr', Score(limits=1))
90
self.scoreTest(r'C1C9B9B1S1S9S9WeDgWsWnWwDbDr Mes LDrDr', Score(limits=1))
91
self.scoreTest(r'C1C9B9B1S1S9S9WeDgWsWnWwDbdr Mes Ldrdr', Score(limits=1))
92
def testSimpleNonWinningCases(self):
94
self.scoreTest(r's2s2s2 s2s3s4 B1B1B1B1 c9c9c9C9 mes', Score(26))
95
def testFourBlessingsOverTheDoor(self):
97
self.scoreTest(r'b1b1 wewewe wswsws WnWnWn wwwwwwww Mne Lb1b1b1', Score(limits=1))
98
self.scoreTest(r'DgDg wewewe wswsws WnWnWn wwwwwwww Mne Lb1b1b1', Score(limits=1))
99
self.scoreTest(r'wewewe wswsws WnWnWn wwwwwwww DrDr Mne LDrDrDr', Score(limits=1))
100
self.scoreTest(r'wewewe wswsws WnWnWn wwwwwwww DrDr Mne LDrDrDr', Score(limits=1))
101
self.scoreTest(r'wewewe wswsws WnWnWn wwwwwwww DrDr Mnez LDrDrDr', Score(limits=1))
102
def testAllHonours(self):
104
self.scoreTest(r'drdrdr wewe wswsws wnwnwn dbdbdb Mesz Ldrdrdrdr', Score(limits=1))
105
self.scoreTest(r'wewewe wswsws WnWnWn wwwwwwww B1 mne', Score(32, 4))
106
self.scoreTest(r'wewe wswsws WnWnWn wwwwwwww b1b1 mne', Score(30, 2))
107
def testHiddenTreasure(self):
108
"""hidden treasure"""
109
self.scoreTest(r'WeWeWe C3C3C3 c4c4c4C4 b8B8B8b8 S3S3 Meee LWeWeWeWe',
111
self.scoreTest(r'WeWeWe C3C3C3 c4c4c4C4 b8B8B8b8 S3S3 Mee LC3C3C3C3',
113
self.scoreTest(r'WeWeWe C3C3C3 c4c4c4C4 b8B8B8b8 s3s3 Mee Ls3s3s3',
115
def testFourfoldPlenty(self):
117
self.scoreTest(r'B3B3B3 C1C1C1 b1b1b1 s3s4s5 wewe Mee LB3B3B3B3', Score(42))
118
self.scoreTest(r'b3B3B3b3 c1C1C1c1 b1b1b1b1 s3s3s3s3 wewe Mee LB3B3B3B3', Score(limits=1))
119
self.scoreTest(r'b3b3 c1C1C1c1 b1b1b1b1 s3s3s3s3 wewewewe Mee LB3B3B3B3', Score(limits=1))
120
self.scoreTest(r'b3b3b3b3 c1c1 b1b1b1b1 s3s3s3s3 wewewewe Mee LB3B3B3B3', Score(limits=1))
123
self.scoreTest(r's1s1s1s1 s2s2s2 wewe S3S3S3 s4s4s4 Msw Ls2s2s2s2',
125
self.scoreTest(r's1s1s1s1 s2s2s2 wewe S3S3S3 s4s4s4 Mswe LS3S3S3S3',
127
self.scoreTest(r'b3B3B3b3 DbDbDb DrDrDr wewewewe s2s2 Mee Ls2s2s2', Score(74, 6))
128
self.scoreTest(r'b3B3B3b3 DbDbDb DrDr Dg wewewewe s2s2 Mee Ls2s2s2', Score(42, 3))
129
self.scoreTest(r's1s2s3 s1s2s3 b3b3b3 b4b4b4 B5 fn yn mne', Score(12, 1))
130
self.scoreTest(r'b3b3b3b3 DbDbDb drdrdr weWeWewe s2s2 Mee Ls2s2s2', Score(78, 5))
131
self.scoreTest(r's2s2s2 s2s3s4 B1B1B1B1 c9C9C9c9 mes', Score(42))
132
self.scoreTest(r's2s2s2 DgDg DbDbDb b2b2b2b2 DrDrDr Mee Ls2s2s2s2', Score(48, 4))
133
self.scoreTest(r's2s2 DgDgDg DbDbDb b2b2b2b2 DrDrDr Mee Ls2s2s2', Score(limits=1))
134
self.scoreTest(r's2 DgDgDg DbDbDb b2b2b2b2 DrDrDr mee', Score(32, 6))
135
self.scoreTest(r's1s1s1s1 s2s2s2 s3s3s3 s4s4s4 s5s5 Msww Ls3s3s3s3', Score(42, 4))
136
self.scoreTest(r'B2C1B2C1B2C1WeWeS4WeS4WeS6 mee', Score(20, 3))
137
self.scoreTest(r'b6b6b6 B1B1B2B2B3B3B7S7C7B8 mnn', Score(2))
138
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B9DrDr fe fs fn fw Mwe LDrDrDr', Score(56, 3))
139
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B9DrDr fe fs fn fw Mwee LDrDrDr',
141
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B9DrDr fe fs fn fw Mwez LDrDrDr',
143
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B9DrDr fe fs fn fw MweZ LDrDrDr',
145
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B9drdr fe fs fn fw MweZ Ldrdrdr',
147
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B7B8B8B2B2 fe fs fn fw mwe', Score())
148
self.scoreTest(r'B1B1B1B1B2B3B4B5B6B8B8B2B2 fe fs fn fw mwe', Score(28, 1))
149
self.scoreTest(r'wewe wswsws WnWnWn wwwwwwww b1b1b1 Mnez Lb1b1b1b1',
151
self.scoreTest(r'wewe wswsws WnWnWn wwwwwwww B1B1B1 Mnez LB1B1B1B1',
153
def testRobbingKong(self):
154
"""robbing the kong"""
155
self.scoreTest(r's1s2s3 s1s2s3 B6B6B7B7B8B8 b5b5 fn yn Mne.a Lb5b5b5',
157
self.scoreTest(r's1s2s3 s1s2s3 B6B6B7B7B8B8 b5b5 fn yn Mneka Ls1s1s2s3',
159
self.scoreTest(r'S1S2S3 s4s5s6 B6B6B7B7B8B8 b5b5 fn yn Mne.a LS1S1S2S3',
161
def testBlessing(self):
162
"""blessing of heaven or earth"""
163
self.scoreTest(r'S1S2S3 s4s5s6 B6B6B7B7B8B8 b5b5 fn yn Mne1 LS1S1S2S3',
165
self.scoreTest(r'S1S2S3 s4s5s6 B6B6B7B7B8B8 b5b5 fn yn Mee1 LS1S1S2S3',
168
def testTerminals(self):
170
# must disallow chows:
171
self.scoreTest(r'b1b1 c1c2c3 c1c2c3 c1c2c3 c1c2c3 Mes Lb1b1b1', Score(28, 1))
172
def testLongHand(self):
174
self.scoreTest(r's1s2s3 s1s2s3 b3b3b3 b4b4b4 B5B5 fn yn mne', Score())
175
self.scoreTest(r'B2C1B2C1B2C1WeWeS4WeS4WeS6S5 mee', Score())
176
self.scoreTest(r'B2C1B2C1B2C1WeWeS4WeS4WeS6S5S5 mee', Score())
177
self.scoreTest(r'B2C1B2C1B2C1WeWeS4WeS4WeS6S5S5 Mee', Score())
178
self.scoreTest(r'WsWsWsWsWnS6 C1C1 WeWeWe S4S4 S5S5 Mee', Score(0))
180
def testSingle(self):
181
"""for testing test rules"""
185
"""test winner hands.
186
Are the hidden melds grouped correctly?"""
187
self.scoreTest(r'B1B1B1B2B2B2B3B4 wnwnwn wewewe Mee', Score(36, 3))
188
self.scoreTest(r'B1B1B1B2B2B2B3B3B3S1S1 c3c4c5 Mee', Score(36, 1))
189
self.scoreTest(r'B1B1B1B2B2B2B3B3S1S2S3 c3c4c5 Mee', Score(32))
190
self.scoreTest(r'c1C1C1c1 b5B5B5b5 c2C2C2c2 c3C3C3c3 C4B6 fs fw fn fe Mee', Score(96, 2))
191
self.scoreTest(r'wewewe wswsws wnwnwnWn WwWwWw C3B6 Mee', Score(32, 4))
192
self.scoreTest(r'wewewe wswsws wnwnwnWn WwWwWw C3C3 Mee', Score(limits=1))
194
def testIsCalling(self):
195
"""test calling hands"""
196
for content in ['s1s1s1s1 b5b6b7 B8B8C2C2C6C7C8',
197
's1s1s1s1 b5b6b7 B7B8C2C2C6C7C8',
198
'Db Dg Dr Ws Ww Wn Wn B1B9C1S1S9C9',
199
'Db Dg Dr Ws Ww We Wn B1B9C1S1S9C9']:
200
hand = HandContent(RULESETS[0], content)
201
self.assert_(hand.isCalling(), content)
202
for content in ['s1s1s1s1 b5b6b7 B1B8C2C2C6C7C8',
203
'Dg Dg Dr We Ws Ww Wn Wn B1B9C1S1S9',
204
'Db Dg Dr We Ws Ww Wn B7 B1B9C1S1S9']:
205
hand = HandContent(RULESETS[0], content)
206
self.assert_(not hand.isCalling(), content)
208
def testZZ(self): # pylint: disable-msg=R0201
209
"""show the slowest 10 regexes"""
211
for ruleset in RULESETS:
212
for lst in ruleset.ruleLists:
214
for variant in rule.variants:
215
if isinstance(variant, Regex):
217
if len(RULESETS) == 1:
218
profiles.append(('avg msec', variant.timeSum / variant.count * 1000,
219
'count',variant.count,
220
rule.name, variant.definition))
222
profiles.append(('avg msec', variant.timeSum / variant.count * 1000,
223
'count',variant.count,
224
ruleset.name, rule.name, variant.definition))
226
print 'The slowest 10 regular expressions were:'
227
for profile in list(reversed(sorted(profiles)))[:10]:
230
def scoreTest(self, string, expected, rulesetIdx = 0):
231
"""execute one scoreTest test"""
233
ruleset = RULESETS[rulesetIdx]
234
variant = HandContent(ruleset, string)
235
variants.append(variant)
236
score = variant.score
237
# activate depending on what you are testing
238
# print(string, 'expected:', expected.__str__()), variant.normalized, variant.original, variant.mjStr
239
# print(ruleset.name.encode('utf8'))
240
# print('\n'.join(variant.explain).encode('utf8'))
241
self.assert_(score == expected, self.dumpCase(variants, expected))
243
def dumpCase(self, variants, expected):
248
result.append(variants[0].string)
249
for hand in variants:
251
if score != expected:
252
result.append('%s: %s should be %s' % (hand.ruleset.name, score.__str__(), expected.__str__()))
253
result.append('original:%s' % hand.original)
254
result.append('normalized:%s' % hand.normalized)
255
result.extend(hand.explain())
256
result.append('base=%d,doubles=%d,total=%d' % (score.points, score.doubles, hand.total()))
258
return '\n'.join(result).encode('ascii', 'ignore')
260
if __name__ == '__main__':
261
InternalParameters.profileRegex = True
262
# InternalParameters.debugRegex = True