Created
January 3, 2020 10:20
-
-
Save iamevn/cd730bbc3dd8f29c04c00f1f315cb4b5 to your computer and use it in GitHub Desktop.
riichi final scoring (oka & uma)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Do Riichi final scoring based on | |
# http://arcturus.su/wiki/Oka_and_uma | |
def placements(scores): | |
"""return array of relative placements in scores. | |
0 for the best score 1 for second best, etc. | |
ties broken by order in scores | |
ex: | |
placements([1, 2, 3, 4]) | |
=> [3, 2, 1, 0] | |
placements([1, 3, 1]) | |
=> [1, 0, 2] | |
""" | |
res = [] | |
for score in scores: | |
placement = len([s for s in scores if s > score]) | |
while placement in res: | |
placement += 1 | |
res.append(placement) | |
return res | |
def score(raw, | |
start=25000, target=30000, | |
uma=[20, 10, -10, -20], | |
verbose=False): | |
"""Riichi final scoring based on | |
http://arcturus.su/wiki/Oka_and_uma""" | |
places = placements(raw) | |
if verbose: print(f'places: {places}') | |
oka = (target - start) * len(raw) | |
pre_oka = [pt - target for pt in raw] | |
if verbose: print(f'pre_oka: {pre_oka}') | |
post_oka = pre_oka.copy() | |
post_oka[places.index(0)] += oka | |
if verbose: print(f'post_oka: {post_oka}') | |
# 0.5 rounds down | |
pre_uma = [round(((pt - 1) / 1000)) | |
for pt in post_oka] | |
if verbose: print(f'pre_uma: {pre_uma}') | |
post_uma = [] | |
for i, posn in enumerate(places): | |
post_uma.append(pre_uma[i] + uma[posn]) | |
if verbose: print(f'post_uma: {post_uma}') | |
adjust = post_uma.copy() | |
if sum(post_uma) != 0: | |
leftover = 0 - sum(post_uma) | |
adjust[places.index(0)] += leftover | |
return adjust | |
def test(): | |
tests = (([25000, 25000, 25000, 25000], | |
{'uma': [20, 10, -10, -20]}, | |
[35, 5, -15, -25]), | |
([35700, 32400, 22200, 9700], | |
{'uma': [20, 10, -10, -20]}, | |
[46, 12, -18, -40]), | |
([35700, 32400, 30000, 9700], | |
{'uma': [30, 15, -15, -30]}, | |
# [56, 17, -15, -50]), # scores sum to 8??? should be 0 | |
[48, 17, -15, -50]), # adjusted, need to check this with someone | |
([121000, -7000, -7000, -7000], | |
{'uma': [20, 10, -10, -20]}, | |
[131, -27, -47, -57]), | |
([40300, 38400, 11600, 9700], | |
{'uma': [10, 5, -5, -10]}, | |
[40, 13, -23, -30]), | |
([35000, 1500, 26300, 37200], | |
{'uma': [20, 10, -10, -20]}, | |
[15, -49, -14, 48]), | |
) | |
failed = False | |
for raw, kwargs, expected in tests: | |
print(raw, kwargs) | |
res = score(raw, verbose=False, **kwargs) | |
if res == expected: | |
print('[PASS] got: ', res) | |
else: | |
failed = True | |
score(raw, verbose=True, **kwargs) | |
print('[FAIL] expected: ', expected, ' got: ', res) | |
TEST = True | |
VERBOSE = False | |
if __name__ == '__main__': | |
if TEST: | |
test() | |
else: | |
raw = [20900, 9700, 56400, 13000] | |
print('raw scores') | |
print(raw) | |
final = score(raw, uma=[20, 10, -10, -20], verbose=VERBOSE) | |
print('final scores') | |
print(final) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment