NewContest4 / Bot.py
ffzeroHua's picture
Upload Bot.py
728bdcc verified
import json
import sys
import model
import model3p
import numpy as np
tiles_tenhou = {
'1m': 0, '2m': 1, '3m': 2, '4m': 3, '5m': 4, '5mr': 4.5, '6m': 5, '7m': 6, '8m': 7, '9m': 8,
'1p': 9, '2p': 10, '3p': 11, '4p': 12, '5p': 13, '5pr': 13.5, '6p': 14, '7p': 15, '8p': 16, '9p': 17,
'1s': 18, '2s': 19, '3s': 20, '4s': 21, '5s': 22, '5sr': 22.5, '6s': 23, '7s': 24, '8s': 25, '9s': 26,
'E': 27, 'S': 28, 'W': 29, 'N': 30, 'P': 31, 'F': 32, 'C': 33
}
MASK_4P = [
"1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m",
"1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p",
"1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s",
"E", "S", "W", "N", "P", "F", "C",
'5mr', '5pr', '5sr',
'reach', 'chi_low', 'chi_mid', 'chi_high', 'pon', 'kan', 'hora', 'ryukyoku', 'none'
]
MASK_3P = [
"1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m",
"1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p",
"1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s",
"E", "S", "W", "N", "P", "F", "C",
'5mr', '5pr', '5sr',
'reach', 'pon', 'kan', 'nukidora', 'hora', 'ryukyoku', 'none'
]
def SoftMax(arr, temperature=1.0):
arr = np.array(arr, dtype=float) # Ensure the input is a numpy array of floats
if arr.size == 0:
return arr # Return the empty array if input is empty
if not temperature == 1.0:
arr /= temperature # Scale by temperature if temperature is not approximately 1
# Shift values by max for numerical stability
max_val = np.max(arr)
arr = arr - max_val
# Apply the softmax transformation
exp_arr = np.exp(arr)
sum_exp = np.sum(exp_arr)
softmax_arr = exp_arr / sum_exp
return softmax_arr
def ToBinStr(mask_bits):
binary_string = bin(mask_bits)[2:]
binary_string = binary_string.zfill(46)
return binary_string
def ToBoolList(mask_bits):
binary_string = ToBinStr(mask_bits)
bool_list = []
for bit in binary_string[::-1]:
bool_list.append(bit == '1')
return bool_list
def ParseMeta(is_3p, meta):
if is_3p:
mask_list = MASK_3P
else:
mask_list = MASK_4P
q_values = meta['q_values']
mask_bits = meta['mask_bits']
mask = ToBoolList(mask_bits)
weight_values = SoftMax(q_values)
q_value_idx = 0
option_list = []
for i in range(46):
if mask[i]:
option_list.append((mask_list[i], weight_values[q_value_idx]))
q_value_idx += 1
option_list = sorted(option_list, key=lambda x: x[1], reverse=True)
return option_list
class Bot:
def __init__(self):
self.player_id: int = None
self.model = None
def react(self, events: str):
events = json.loads(events)
return_action = None
for e in events:
if e["type"] == "start_game":
self.player_id = e["id"]
model_type = e.get('model')
self.model = model3p.load_model(self.player_id, model_type)
continue
if self.model is None or self.player_id is None:
raise Exception(f"Model is not loaded yet")
continue
if e["type"] == "end_game":
self.player_id = None
self.model = None
continue
return_action = self.model.react(json.dumps(e, separators=(",", ":")))
return return_action
class Bot4P:
def __init__(self):
self.player_id: int = None
self.model = None
def react(self, events: str, H = True):
events = json.loads(events)
return_action = None
for e in events:
if e["type"] == "start_game":
self.player_id = e["id"]
model_type = e.get('model')
self.model = model.load_model(self.player_id, model_type)
continue
if self.model is None or self.player_id is None:
raise Exception(f"Model is not loaded yet")
continue
if e["type"] == "end_game":
self.player_id = None
self.model = None
continue
return_action = self.model.react(json.dumps(e, separators=(",", ":")))
if H:
return return_action
if return_action == None:
return None
original = json.loads(return_action)
return Select(original, ParseMeta(False, original['meta']))
false = False
true = True
if __name__ == '__main__':
bot = Bot()
print(bot)
events = {
"is3p": false,
"model": "v2-a",
"events": [
{'type':'start_game','id':0},
{
"oya": 0,
"type": "start_kyoku",
"honba": 0,
"kyoku": 1,
"bakaze": "E",
"scores": [35000,35000,35000,0],
"kyotaku": 0,
"dora_marker": "5s",
"tehais": [
['1m','9m','1s','2s','3s','1p','2p','3p','E','N','N','P','P'],
['?','?','?','?','?','?','?','?','?','?','?','?','?',],
['?','?','?','?','?','?','?','?','?','?','?','?','?',],
['?','?','?','?','?','?','?','?','?','?','?','?','?',],
]
},
{
"pai": "1p",
"type": "tsumo",
"actor": 0
},
]}
res = bot.react(json.dumps(events['events']))
print(res)
print(ParseMeta(True, json.loads(res)['meta']))