Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.5.1 #33

Merged
merged 5 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions action.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,18 @@
#^^^^^^^^^^^^^^^^Self Discard^^^^^^^^^^^^^^^^
}

with open("settings.json", "r") as f:
settings = json.load(f)
PLAYWRIGHT_RESOLUTION = (settings['Playwright']['width'], settings['Playwright']['height'])
SCALE = PLAYWRIGHT_RESOLUTION[0]/16

class Action:
def __init__(self, rpc_server: ServerProxy):
self.isNewRound = True
self.reached = False
self.latest_operation_list = []
self.rpc_server = rpc_server
with open("settings.json", "r") as f:
settings = json.load(f)
self.new_min = settings['RandomTime']['new_min']
self.new_max = settings['RandomTime']['new_max']
self.min = settings['RandomTime']['min']
self.max = settings['RandomTime']['max']
pass

def page_clicker(self, coord: tuple[float, float]):
Expand All @@ -115,9 +116,8 @@ def do_autohu(self):

def decide_random_time(self):
if self.isNewRound:
return random.uniform(3.5, 4.5)
return random.uniform(1.0, 3.2)

return random.uniform(self.new_min, self.new_max)
return random.uniform(self.min, self.max)

def click_chiponkan(self, mjai_msg: dict | None, tehai: list[str], tsumohai: str | None):
latest_operation_list_temp = self.latest_operation_list.copy()
Expand Down
79 changes: 55 additions & 24 deletions client.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,12 @@ def __init__(self, *args, **kwargs) -> None:
self.value_port_setting_mitm_input = settings["Port"]["MITM"]
self.value_port_setting_xmlrpc_input = settings["Port"]["XMLRPC"]
self.value_unlocker_setting_enable_checkbox = settings["Unlocker"]
self.value_unlocker_setting_v10_checkbox = settings["v10"]
self.value_helper_setting_checkbox = settings["Helper"]
self.value_autoplay_setting_enable_checkbox = settings["Autoplay"]
# self.value_autoplay_setting_random_time_min_input = settings["Autoplay"]["Random Time"]["Min"]
# self.value_autoplay_setting_random_time_max_input = settings["Autoplay"]["Random Time"]["Max"]
self.value_autoplay_setting_random_time_new_min_input = settings["RandomTime"]["new_min"]
self.value_autoplay_setting_random_time_new_max_input = settings["RandomTime"]["new_max"]
self.value_autoplay_setting_random_time_min_input = settings["RandomTime"]["min"]
self.value_autoplay_setting_random_time_max_input = settings["RandomTime"]["max"]
self.value_playwright_setting_enable_checkbox = settings["Playwright"]["enable"]
self.value_playwright_setting_width_input = settings["Playwright"]["width"]
self.value_playwright_setting_height_input = settings["Playwright"]["height"]
Expand All @@ -304,8 +305,7 @@ def compose(self) -> ComposeResult:

self.unlocker_setting_label = Label("Unlocker", id="unlocker_setting_label")
self.unlocker_setting_enable_checkbox = Checkbox("Enable", id="unlocker_setting_enable_checkbox", classes="short", value=self.value_unlocker_setting_enable_checkbox)
self.unlocker_setting_v10_checkbox = Checkbox("v10", id="unlocker_setting_v10_checkbox", classes="short", value=self.value_unlocker_setting_v10_checkbox)
self.unlocker_setting_container = Horizontal(self.unlocker_setting_label, self.unlocker_setting_enable_checkbox, self.unlocker_setting_v10_checkbox, id="unlocker_setting_container")
self.unlocker_setting_container = Horizontal(self.unlocker_setting_label, self.unlocker_setting_enable_checkbox, id="unlocker_setting_container")
self.unlocker_setting_container.border_title = "Unlocker"

self.helper_setting_label = Label("Helper", id="helper_setting_label")
Expand All @@ -316,11 +316,15 @@ def compose(self) -> ComposeResult:
self.autoplay_setting_enable_label = Label("Enable", id="autoplay_setting_enable_label")
self.autoplay_setting_enable_checkbox = Checkbox("Enable", id="autoplay_setting_enable_checkbox", classes="short", value=self.value_autoplay_setting_enable_checkbox)
self.autoplay_setting_enable_container = Horizontal(self.autoplay_setting_enable_label, self.autoplay_setting_enable_checkbox, id="autoplay_setting_enable_container")
self.autoplay_setting_random_time_label = Label("Random Time", id="autoplay_setting_random_time_label")
self.autoplay_setting_random_time_min_input = Input(placeholder="Min", type="number", id="autoplay_setting_random_time_min_input")
self.autoplay_setting_random_time_max_input = Input(placeholder="Max", type="number", id="autoplay_setting_random_time_max_input")
self.autoplay_setting_random_time_new_label = Label("Random New", id="autoplay_setting_random_time_new_label")
self.autoplay_setting_random_time_new_min_input = Input(placeholder="Min", type="number", id="autoplay_setting_random_time_new_min_input", value=str(self.value_autoplay_setting_random_time_new_min_input))
self.autoplay_setting_random_time_new_max_input = Input(placeholder="Max", type="number", id="autoplay_setting_random_time_new_max_input", value=str(self.value_autoplay_setting_random_time_new_max_input))
self.autoplay_setting_random_time_new_container = Horizontal(self.autoplay_setting_random_time_new_label, self.autoplay_setting_random_time_new_min_input, self.autoplay_setting_random_time_new_max_input, id="autoplay_setting_random_time_new_container")
self.autoplay_setting_random_time_label = Label("Random", id="autoplay_setting_random_time_label")
self.autoplay_setting_random_time_min_input = Input(placeholder="Min", type="number", id="autoplay_setting_random_time_min_input", value=str(self.value_autoplay_setting_random_time_min_input))
self.autoplay_setting_random_time_max_input = Input(placeholder="Max", type="number", id="autoplay_setting_random_time_max_input", value=str(self.value_autoplay_setting_random_time_max_input))
self.autoplay_setting_random_time_container = Horizontal(self.autoplay_setting_random_time_label, self.autoplay_setting_random_time_min_input, self.autoplay_setting_random_time_max_input, id="autoplay_setting_random_time_container")
self.autoplay_setting_container = Vertical(self.autoplay_setting_enable_container, self.autoplay_setting_random_time_container, id="autoplay_setting_container")
self.autoplay_setting_container = Vertical(self.autoplay_setting_enable_container, self.autoplay_setting_random_time_new_container, self.autoplay_setting_random_time_container, id="autoplay_setting_container")
self.autoplay_setting_container.border_title = "Autoplay"

self.playwright_setting_enable_label = Label("Enable", id="playwright_setting_enable_label")
Expand Down Expand Up @@ -352,11 +356,17 @@ def compose(self) -> ComposeResult:

@on(Input.Changed, "#port_setting_mitm_input")
def port_setting_mitm_input_changed(self, event: Input.Changed) -> None:
self.value_port_setting_mitm_input = int(event.value)
try:
self.value_port_setting_mitm_input = int(event.value)
except:
pass

@on(Input.Changed, "#port_setting_xmlrpc_input")
def port_setting_xmlrpc_input_changed(self, event: Input.Changed) -> None:
self.value_port_setting_xmlrpc_input = int(event.value)
try:
self.value_port_setting_xmlrpc_input = int(event.value)
except:
pass

@on(Checkbox.Changed, "#unlocker_setting_enable_checkbox")
def unlocker_setting_enable_checkbox_changed(self, event: Checkbox.Changed) -> None:
Expand All @@ -366,37 +376,57 @@ def unlocker_setting_enable_checkbox_changed(self, event: Checkbox.Changed) -> N
def helper_setting_checkbox_changed(self, event: Checkbox.Changed) -> None:
self.value_helper_setting_checkbox = event.value

@on(Checkbox.Changed, "#unlocker_setting_v10_checkbox")
def unlocker_setting_v10_checkbox_changed(self, event: Checkbox.Changed) -> None:
self.value_unlocker_setting_v10_checkbox = event.value

@on(Checkbox.Changed, "#autoplay_setting_enable_checkbox")
def autoplay_setting_enable_checkbox_changed(self, event: Checkbox.Changed) -> None:
global AUTOPLAY
AUTOPLAY = event.value
self.value_autoplay_setting_enable_checkbox = event.value

@on(Input.Changed, "#autoplay_setting_random_time_new_min_input")
def autoplay_setting_random_time_new_min_input_changed(self, event: Input.Changed) -> None:
try:
self.value_autoplay_setting_random_time_new_min_input = float(event.value)
except:
pass

@on(Input.Changed, "#autoplay_setting_random_time_new_max_input")
def autoplay_setting_random_time_new_max_input_changed(self, event: Input.Changed) -> None:
try:
self.value_autoplay_setting_random_time_new_max_input = float(event.value)
except:
pass

@on(Input.Changed, "#autoplay_setting_random_time_min_input")
def autoplay_setting_random_time_min_input_changed(self, event: Input.Changed) -> None:
# self.value_autoplay_setting_random_time_min_input = event.value
pass
try:
self.value_autoplay_setting_random_time_min_input = float(event.value)
except:
pass

@on(Input.Changed, "#autoplay_setting_random_time_max_input")
def autoplay_setting_random_time_max_input_changed(self, event: Input.Changed) -> None:
# self.value_autoplay_setting_random_time_max_input = event.value
pass
try:
self.value_autoplay_setting_random_time_max_input = float(event.value)
except:
pass

@on(Checkbox.Changed, "#playwright_setting_enable_checkbox")
def playwright_setting_enable_checkbox_changed(self, event: Checkbox.Changed) -> None:
self.value_playwright_setting_enable_checkbox = event.value

@on(Input.Changed, "#playwright_setting_width_input")
def playwright_setting_width_input_changed(self, event: Input.Changed) -> None:
self.value_playwright_setting_width_input = int(event.value)
try:
self.value_playwright_setting_width_input = int(event.value)
except:
pass

@on(Input.Changed, "#playwright_setting_height_input")
def playwright_setting_height_input_changed(self, event: Input.Changed) -> None:
self.value_playwright_setting_height_input = int(event.value)
try:
self.value_playwright_setting_height_input = int(event.value)
except:
pass

@on(Button.Pressed, "#setting_save_button")
def setting_save_button_pressed(self) -> None:
Expand All @@ -405,11 +435,12 @@ def setting_save_button_pressed(self) -> None:
settings["Port"]["MITM"] = self.value_port_setting_mitm_input
settings["Port"]["XMLRPC"] = self.value_port_setting_xmlrpc_input
settings["Unlocker"] = self.value_unlocker_setting_enable_checkbox
settings["v10"] = self.value_unlocker_setting_v10_checkbox
settings["Helper"] = self.value_helper_setting_checkbox
settings["Autoplay"] = self.value_autoplay_setting_enable_checkbox
# settings["Autoplay"]["Random Time"]["Min"] = self.value_autoplay_setting_random_time_min_input
# settings["Autoplay"]["Random Time"]["Max"] = self.value_autoplay_setting_random_time_max_input
settings["RandomTime"]["new_min"] = self.value_autoplay_setting_random_time_new_min_input
settings["RandomTime"]["new_max"] = self.value_autoplay_setting_random_time_new_max_input
settings["RandomTime"]["min"] = self.value_autoplay_setting_random_time_min_input
settings["RandomTime"]["max"] = self.value_autoplay_setting_random_time_max_input
settings["Playwright"]["enable"] = self.value_playwright_setting_enable_checkbox
settings["Playwright"]["width"] = self.value_playwright_setting_width_input
settings["Playwright"]["height"] = self.value_playwright_setting_height_input
Expand Down
27 changes: 27 additions & 0 deletions client.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,33 @@ Button.action_nukidora.-active {
margin: 0;
}

#autoplay_setting_random_time_new_label {
padding: 1 0;
width: 11;
height: 3;
align: center middle;
margin: 0 1;
}

#autoplay_setting_random_time_new_min_input {
width: 1fr;
align: center top;
margin: 0 1;
}

#autoplay_setting_random_time_new_max_input {
width: 1fr;
align: center top;
margin: 0 1;
}

#autoplay_setting_random_time_new_container {
width: 1fr;
height: auto;
align: center top;
margin: 0;
}

#autoplay_setting_random_time_label {
padding: 1 0;
width: 11;
Expand Down
23 changes: 22 additions & 1 deletion mjai/bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
import sys
import hashlib
import pathlib
import requests

from loguru import logger
from my_logger import logger

from . import model

Expand All @@ -15,6 +16,24 @@ def __init__(self, player_id: int):
self.model = model.load_model(player_id)
with open(model_path, "rb") as f:
self.model_hash = hashlib.sha256(f.read()).hexdigest()
try:
with open(pathlib.Path(__file__).parent / "online.json", "r") as f:
online_json = json.load(f)
self.online = online_json["online"]
if not self.online:
return
api_key = online_json["api_key"]
server = online_json["server"]
headers = {
'Authorization': api_key,
}
r = requests.post(f"{server}/check", headers=headers)
r_json = r.json()
if r_json["result"] == "success":
self.model_hash = "online"
except Exception as e:
logger.error(e)
self.online = False

def react(self, events: str) -> str:
events = json.loads(events)
Expand All @@ -27,6 +46,8 @@ def react(self, events: str) -> str:
return json.dumps({"type":"none"}, separators=(",", ":"))
else:
raw_data = json.loads(return_action)
if self.online:
raw_data["online"] = model.online_valid
return json.dumps(raw_data, separators=(",", ":"))

def state(self):
Expand Down
57 changes: 55 additions & 2 deletions mjai/bot/model.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import numpy as np
import torch
import pathlib
Expand All @@ -9,6 +10,8 @@
from functools import partial
from itertools import permutations
import riichi
import gzip
import requests

class ChannelAttention(nn.Module):
def __init__(self, channels, ratio=16, actv_builder=nn.ReLU, bias=True):
Expand Down Expand Up @@ -233,6 +236,7 @@ def forward(self, phi, mask):
q = (v + a - a_mean).masked_fill(~mask, -torch.inf)
return q

online_valid = False

class MortalEngine:
def __init__(
Expand All @@ -250,6 +254,9 @@ def __init__(
boltzmann_epsilon = 0,
boltzmann_temp = 1,
top_p = 1,
online = False,
api_key = None,
server = None,
):
self.engine_type = 'mortal'
self.device = device or torch.device('cpu')
Expand All @@ -269,7 +276,40 @@ def __init__(
self.boltzmann_temp = boltzmann_temp
self.top_p = top_p

self.online = online
self.api_key = api_key
self.server = server
if self.online:
assert self.version == 4, 'To use online, local model version must be 4'

def react_batch(self, obs, masks, invisible_obs):
if self.online:
global online_valid
try:
list_obs = [o.tolist() for o in obs]
list_masks = [m.tolist() for m in masks]
post_data = {
'obs': list_obs,
'masks': list_masks,
}
data = json.dumps(post_data, separators=(',', ':'))
compressed_data = gzip.compress(data.encode('utf-8'))
headers = {
'Authorization': self.api_key,
'Content-Encoding': 'gzip',
}
r = requests.post(f'{self.server}/react_batch',
headers=headers,
data=compressed_data,
timeout=2)
assert r.status_code == 200
online_valid = True
r_json = r.json()
return r_json['actions'], r_json['q_out'], r_json['masks'], r_json['is_greedy']
except:
online_valid = False
pass

with (
torch.autocast(self.device.type, enabled=self.enable_amp),
torch.no_grad(),
Expand Down Expand Up @@ -320,6 +360,11 @@ def sample_top_p(logits, p):
return sampled

def load_model(seat: int) -> riichi.mjai.Bot:
engine = get_engine()
bot = riichi.mjai.Bot(engine, seat)
return bot

def get_engine() -> MortalEngine:

# check if GPU is available
if torch.cuda.is_available():
Expand All @@ -341,6 +386,12 @@ def load_model(seat: int) -> riichi.mjai.Bot:
mortal.load_state_dict(state['mortal'])
dqn.load_state_dict(state['current_dqn'])

with open(pathlib.Path(__file__).parent / 'online.json', 'r') as f:
json_load = json.load(f)
server = json_load['server']
online = json_load['online']
api_key = json_load['api_key']

engine = MortalEngine(
mortal,
dqn,
Expand All @@ -351,7 +402,9 @@ def load_model(seat: int) -> riichi.mjai.Bot:
enable_rule_based_agari_guard = False,
name = 'mortal',
version = state['config']['control']['version'],
online = online,
api_key = api_key,
server = server,
)

bot = riichi.mjai.Bot(engine, seat)
return bot
return engine
5 changes: 5 additions & 0 deletions mjai/bot/online.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"server": "http://34.71.176.237:5000",
"online": false,
"api_key": "your_api_key_here"
}
Loading