Refactored

This commit is contained in:
2024-06-10 21:07:38 +02:00
parent 61d1ab0431
commit e47959373b
5 changed files with 65 additions and 61 deletions
-38
View File
@@ -2,14 +2,6 @@ import numpy as np
from numpy.random import uniform from numpy.random import uniform
def create_test_state() -> np.array:
return np.array([['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']])
def create_empty_state() -> np.array:
return np.array([['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']])
def softmax(values: np.array, eps=1.0E-6) -> np.array: def softmax(values: np.array, eps=1.0E-6) -> np.array:
result = (values + eps) / (sum(values + eps)) result = (values + eps) / (sum(values + eps))
return result return result
@@ -46,36 +38,6 @@ def test_sample(data):
print(c) print(c)
def to_state_string(state, state_nex=None):
sp = ' '
sp_arrow = ' => '
sp_ = [sp, sp_arrow, sp]
def col(str_in, state):
str_out = str_in
for c in range(0, 3):
char = state[r][c]
if char == '-':
char = ' '
str_out += "|" + char
str_out += '|'
return str_out
state_str = ''
for r in range(0, 3):
if state is not None:
state_str = col(state_str, state)
if state_nex is not None:
state_str += sp_[r]
state_str = col(state_str, state_nex)
if r != 2:
state_str += '\x0A'
return state_str
if __name__ == '__main__': if __name__ == '__main__':
print("Testing sample()") print("Testing sample()")
test_sample([0.7, 0.1, 0.1, 0.1]) test_sample([0.7, 0.1, 0.1, 0.1])
+3 -3
View File
@@ -1,7 +1,7 @@
import numpy as np import numpy as np
from a_player import APlayer from a_player import APlayer
from helper import to_state_string, create_empty_state, create_test_state from state import to_state_string, create_empty_state, create_test_state
from state import get_potential_moves from state import get_potential_moves
@@ -17,7 +17,7 @@ class HumanPlayer(APlayer):
print(f"{self.name}, Du bist dran. Das Spielfeld sieht so aus:") print(f"{self.name}, Du bist dran. Das Spielfeld sieht so aus:")
print(to_state_string(state, create_test_state())) print(to_state_string(state, create_test_state()))
print(f"{self.name}, in welches Feld willst Du Dein \"{self.mark}\" setzen?") print(f"{self.name}, in welches Feld willst Du das \"{self.mark}\" setzen?")
choice = input("Feldnummer: ") choice = input("Feldnummer: ")
if choice in "Qq": if choice in "Qq":
@@ -35,7 +35,7 @@ class HumanPlayer(APlayer):
print("Versuche es nochmal") print("Versuche es nochmal")
continue continue
print("So soll es geschehen") print(f"Okay, nächstes \"{self.mark}\" auf Feld {move+1}")
has_moved = True has_moved = True
break break
+3 -6
View File
@@ -6,8 +6,8 @@ from state import get_potential_moves
class MachinePlayer(APlayer): class MachinePlayer(APlayer):
class Params: class Params:
def __init__(self, p_exp, alpha): def __init__(self, p_explore, alpha):
self.p_exp = p_exp self.p_exp = p_explore
self.alpha = alpha self.alpha = alpha
def __init__(self, mark, params: Params, values): def __init__(self, mark, params: Params, values):
@@ -53,7 +53,6 @@ class MachinePlayer(APlayer):
self.state_last = None self.state_last = None
def move(self, state: np.array): def move(self, state: np.array):
do_sample = False
values = np.array([]) values = np.array([])
# get possible move # get possible move
moves = get_potential_moves(state) moves = get_potential_moves(state)
@@ -74,13 +73,11 @@ class MachinePlayer(APlayer):
next_move = best_move next_move = best_move
is_exp = False is_exp = False
# Randomly perform exploratory move
if uniform() < self.params.p_exp: if uniform() < self.params.p_exp:
index = np.random.randint(len(moves)) index = np.random.randint(len(moves))
next_move = moves[index] next_move = moves[index]
is_exp = best_move != next_move is_exp = best_move != next_move
elif do_sample:
index = sample(values)
next_move = moves[index]
if self.with_debug: if self.with_debug:
print(f"{self.mark}: Values = {values}") print(f"{self.mark}: Values = {values}")
+38
View File
@@ -1,6 +1,44 @@
import numpy as np import numpy as np
def create_test_state() -> np.array:
return np.array([['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']])
def create_empty_state() -> np.array:
return np.array([['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']])
def to_state_string(state, state_nex=None):
sp = ' '
sp_arrow = ' => '
sp_ = [sp, sp_arrow, sp]
def col(str_in, state):
str_out = str_in
for c in range(0, 3):
char = state[r][c]
if char == '-':
char = ' '
str_out += "|" + char
str_out += '|'
return str_out
state_str = ''
for r in range(0, 3):
if state is not None:
state_str = col(state_str, state)
if state_nex is not None:
state_str += sp_[r]
state_str = col(state_str, state_nex)
if r != 2:
state_str += '\x0A'
return state_str
def get_potential_moves(state: np.array) -> np.array: def get_potential_moves(state: np.array) -> np.array:
st = state.reshape(state.size) st = state.reshape(state.size)
indices = [idx for idx, s in enumerate(st) if '-' in s] indices = [idx for idx, s in enumerate(st) if '-' in s]
+19 -12
View File
@@ -1,5 +1,5 @@
import numpy as np import numpy as np
from helper import create_empty_state, to_state_string from state import create_empty_state, to_state_string
from machine_player import MachinePlayer from machine_player import MachinePlayer
from human_player import HumanPlayer from human_player import HumanPlayer
from player_provider import PlayerProvider from player_provider import PlayerProvider
@@ -66,21 +66,28 @@ with open("values_x.json", "r") as fp:
with open("values_o.json", "r") as fp: with open("values_o.json", "r") as fp:
o_values = json.load(fp) o_values = json.load(fp)
#px = MachinePlayer(mark='X', params=MachinePlayer.Params(p_exp=0.2, alpha=0.1), values=x_values)
px = HumanPlayer(mark='X', name="Jens")
po = MachinePlayer(mark='O', params=MachinePlayer.Params(p_exp=0.2, alpha=0.1), values=o_values)
player_provider = PlayerProvider(px, po)
do_training = 1 do_training = 1
do_human_player = 1
p_hx = HumanPlayer(mark='X', name="Jens")
p_mx = MachinePlayer(mark='X', params=MachinePlayer.Params(p_explore=0.2, alpha=0.1), values=x_values)
p_mo = MachinePlayer(mark='O', params=MachinePlayer.Params(p_explore=0.2, alpha=0.1), values=o_values)
if do_training: if do_training:
play(player_provider, 10000, True) play(PlayerProvider(p_mx, p_mo), 10000, False)
play(player_provider, 10, True)
# Values after training
# Convert and write JSON object to file # Convert and write JSON object to file
with open("values_x.json", "w") as fp: with open("values_x.json", "w") as fp:
json.dump(x_values, fp, indent=0) json.dump(p_mx.values, fp, indent=0)
with open("values_o.json", "w") as fp: with open("values_o.json", "w") as fp:
json.dump(o_values, fp, indent=0) json.dump(p_mo.values, fp, indent=0)
if do_human_player:
pp = PlayerProvider(p_hx, p_mo)
else:
pp = PlayerProvider(p_mx, p_mo)
play(pp, 10, True)