Refactored
This commit is contained in:
@@ -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
@@ -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
@@ -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}")
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user