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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
import logging
from gettext import gettext as _
from dominoview import Tile
from dominopiece import DominoPiece
class DominoPlayer:
"""
Jugadores (automaticos o humanos) del domino
"""
def __init__(self, game, number):
self.number = number
self.name = _('Player ')+str(self.number)
self.game = game
self._pieces = []
self.order_piece_selected = 0
self.playing = False
self.color = None
# se usa para saber si este usuario paso la ultima vuelta
self.has_passed = False
# where are displayed the pieces for this player
self.pieces_y_position = self.game.table.bottom_limit
def set_pieces(self, pieces):
self._pieces = pieces
for piece in self._pieces:
piece.player = self
piece.state = DominoPiece.PIECE_PLAYER
self.order_piece_selected = 0
def get_pieces(self):
return self._pieces
def play(self):
# "Play player",self.number
self.playing = True
# "Cant piezas",len(self._pieces)
if self == self.game.ui_player:
# "Abilitando botones"
self.game.game_state = self.game.GAME_STATE_SELECT_PIECE
if len(self.game.pieces) > 0:
# si hay piezas puede pedir pero no pasar
self.game.btnNew.props.sensitive = True
self.game.btnPass.props.sensitive = False
else:
# si no hay piezas no puede pedir pero si pasar
self.game.btnNew.props.sensitive = False
self.game.btnPass.props.sensitive = True
def end_play(self):
if self == self.game.ui_player:
# "Deshabilitando botones"
self.game.btnPass.props.sensitive = False
self.game.btnNew.props.sensitive = False
# "End player",self.number
self.playing = False
self.game.next_player(self.number).play()
def remove_piece(self, piece):
cantPieces = len(self._pieces)
# TODO: there are a better way?
for n in range(0, len(self._pieces)):
p = self._pieces[n]
if piece == p:
self._pieces[n] = cantPieces
self._pieces.remove(cantPieces)
return
def test_good_position(self, tile, piece):
n, p = tile.n, tile.p
logging.error('tile value %s direction %s piece a %s piece b %s',
tile.value, tile.direction, piece.a, piece.b)
# check using the tile direction if the next 3 spaces are free
# (2 for the piece, and 1 more)
ok = True
for i in range(0, 3):
n = n + tile.direction[0]
p = p + tile.direction[1]
if not self.game.test_free_position(n, p):
ok = False
break
if ok:
logging.error('3 spaces free')
# define piece position
# substract one to n, p. (we added 3 to have one more free
n = n - tile.direction[0]
p = p - tile.direction[1]
logging.error('piece position n %s, p %s', n, p)
# get the minimal between the original tile + 1 and
# the final n, p values calculated
ori_n = tile.n + tile.direction[0]
ori_p = tile.p + tile.direction[1]
min_n, min_p = min(n, ori_n), min(p, ori_p)
logging.error('piece position n %s, p %s', min_n, min_p)
logging.error('tile.value %s piece a %s b %s direction %s',
tile.value, piece.a, piece.b, tile.direction)
# define piece orientation
if tile.value == piece.b:
if tile.direction in (Tile.RIGHT, Tile.DOWN):
piece.reversed = True
new_value = piece.a
elif tile.value == piece.a:
if tile.direction in (Tile.LEFT, Tile.UP):
piece.reversed = True
new_value = piece.b
piece.vertical = tile.direction in (Tile.DOWN, Tile.UP)
logging.error('test_good_position vertical %s reversed %s',
piece.vertical, piece.reversed)
return new_value, tile.direction, piece, min_n, min_p
else:
# rotate the tile direction
if tile.direction == Tile.LEFT:
tile.direction = Tile.UP
elif tile.direction == Tile.UP:
tile.direction = Tile.RIGHT
elif tile.direction == Tile.RIGHT:
tile.direction = Tile.DOWN
elif tile.direction == Tile.DOWN:
tile.direction = Tile.LEFT
return self.test_good_position(tile, piece)
def place_piece(self, piece):
if piece.a == self.game.start.value or \
piece.b == self.game.start.value:
# try with start tile
new_tile_value, direction, piece, piece_n, piece_p = \
self.test_good_position(self.game.start, piece)
self.game.put_piece(self, piece, piece_n, piece_p)
self.game.start.value = new_tile_value
self.game.start.n += direction[0] * 2
self.game.start.p += direction[1] * 2
self.game.start.direction = direction
elif piece.a == self.game.end.value or \
piece.b == self.game.end.value:
# try with end
new_tile_value, direction, piece, piece_n, piece_p = \
self.test_good_position(self.game.end, piece)
self.game.put_piece(self, piece, piece_n, piece_p)
self.game.end.value = new_tile_value
self.game.end.n += direction[0] * 2
self.game.end.p += direction[1] * 2
self.game.end.direction = direction
else:
return False
self.game.show_pieces_player(self)
return True
class SimpleAutoPlayer(DominoPlayer):
"""
Jugador automatico simple
Busca la primera ficha que pueda ubicarse en alguna de las posiciones
si no encuentra una pide
NO TIENE NINGUNA ESTRATEGIA
"""
def __init__(self, game, number):
DominoPlayer.__init__(self, game, number)
self.pieces_y_position = 0
def play(self):
# "Jugando automatico"
if self.game.start is None:
# si no hay ninguna pieza en el tablero ponemos la primera
piece = self._pieces[0]
n, p = self.game.cantX / 2 - 1, self.game.cantY / 2
self.game.put_piece(self, piece, n, p)
# seteamos comienzo y fin del domino
startTile = Tile(n, p)
startTile.value = piece.a
startTile.direction = Tile.LEFT
self.game.start = startTile
endTile = Tile(n + 1, p)
endTile.value = piece.b
endTile.direction = Tile.RIGHT
self.game.end = endTile
self.game.show_pieces_player(self)
else:
# "automatica siguiente"
# buscamos si tenemos alguna ficha que corresponda
# en el comienzo
ok = self.check_put_piece()
if not ok:
# pido una hasta que sea valida o no hayan mas disponibles
# si no encontramos pedimos hasta que alguna sirva
while not ok:
# "Pido pieza"
pieces = self.game.take_pieces(1)
if len(pieces) > 0:
piece = pieces[0]
piece.player = self
self.get_pieces().append(piece)
ok = self.check_put_piece()
else:
ok = True # No hay mas piezas
self.has_passed = True
if not ok:
self.has_passed = True
# juega el siguiente jugador
self.end_play()
def check_put_piece(self):
for tile in (self.game.start, self.game.end):
# look for a piece with the value
piece = self._get_piece_with_value(tile.value)
if piece is not None:
self.place_piece(piece)
return True
return False
# elige una pieza que tenga un valor
def _get_piece_with_value(self, value):
for piece in self._pieces:
if piece.player == self:
# "get_piece_with_value",piece.a, piece.b
if (piece.a == value) or (piece.b == value):
return piece
return None
|