-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplayer.py
121 lines (92 loc) · 3.76 KB
/
player.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from oracle import BaseOracle, ColumnClassification, ColumnRecommendation
import random
from list_utils import all_same
from move import Move
from settings import BOARD_LENGTH, DEBUG
from beautifultable import BeautifulTable
class Player():
# juega en un tablero despues de preguntar al oraculo
def __init__(self, name, char = None, opponent = None, oracle=BaseOracle()) -> None:
self.name = name
self.char = char
self._oracle = oracle
self.opponent = opponent
self.last_moves = []
@property
def opponent(self):
return self._opponent
@opponent.setter
def opponent(self, other):
if other != None:
self._opponent = other
other._opponent = self
def play(self, board):
# Elije la mejor columna de aquellas que recomienda el oraculo
# Pregunto al oraculo () primeros es una tupla
(best, recommendations) = self._ask_oracle(board)
# Juego en la mejor
self._play_on(board, best.index, recommendations)
def display_recommendations(self, board):
recs = map(lambda x: str(x.classification).split('.')[1].lower(), self._oracle.get_recommendation(board, self))
bt = BeautifulTable()
bt.rows.append(recs)
bt.columns.header =[str(i) for i in range(BOARD_LENGTH)]
print(bt)
def on_win(self):
pass
def on_lose(self):
pass
def _play_on(self, board, position, recomendations):
# imprimo recs en caso de debug
if DEBUG:
self.display_recommendations(board)
# juega en la posicion
board.add(self.char, position)
# guardo mi ultima jugada (siempre al principio de la lista)
self.last_moves.insert(0, Move(position, board.as_code(), recomendations, self))
def _ask_oracle(self, board):
# pregunta al oraculo y devuelve la mejor opcion
# obtenemos las recomendaciones
recommendation = self._oracle.get_recommendation(board, self)
# seleccionamos la mejor
best = self._choose(recommendation)
return(best, recommendation)
def _choose(self, recomendations):
# Quitamos la no validas
valid = list(filter(lambda x : x.classification != ColumnClassification.FULL, recomendations))
# ordenamos por el valor de clasificiacion
valid = sorted(valid, key=lambda x: x.classification.value, reverse=True)
# si son todas iguales, agarro una al azar
if all_same(valid):
return random.choice(valid)
else:
# si no lo son todas iguales agarro la mas deseable(que sera la primera)
return valid[0]
class HumanPlayer(Player):
def __init__(self, name, char = None):
super().__init__(name, char)
def _ask_oracle(self, board):
# Le pido al humano que es mi oraculo
while True:
# pedimos columna al humano
raw = input('Select a column, puny Human: ')
#verificacmos que su respuesta no sea una pendejada
if _is_int(raw) and _is_within_column_range(board, int(raw)) and _is_non_full_column(board, int(raw)):
# si no lo es, jugamos donde ha dicho y salimos del bucle
pos = int(raw)
return(ColumnRecommendation(pos, None), None)
class ReportingPlayer(Player):
def on_lose(self):
# le pide al oraculo que revise sus recomendaciones
self._oracle.backtrack(self.last_moves)
# funciones de validacion de indice de columna
def _is_non_full_column(board, num):
return not board._columns[num].is_full()
def _is_within_column_range(board, num):
return num >= 0 and num < len(board)
def _is_int(aString):
try:
num = int(aString)
return True
except:
return False