def duplicate_state(state): # dup state and clear associated objects new_state = deepcopy(state) new_state.players = [] new_state._bag = Bag() new_state._board = Board() # dup players for cp in state.computer_players: new_cp = ComputerPlayer(cp.name, False) # dup player's tiles and attrs for t in cp.tiles: new_cp.tiles.append(Tile(t.letter)) new_cp.score = cp.score new_cp.passes = cp.passes new_cp.utility_function = cp.utility_function new_state.players.append(new_cp) # dup bag tiles for t in state.tile_bag.inventory: new_state.tile_bag.inventory.append(Tile(t.letter)) # dup board state length = ScrabbleConfig.board_length new_state.playing_board.grid = [[ ScrabbleConfig.board_layout(Coordinate(i, j)) for j in xrange(0, length) ] for i in xrange(0, length)] # synch moves already done for i in range(0, length): for j in range(0, length): tile = state.playing_board.has_tile(Coordinate(i, j)) if tile: new_state.playing_board.put_tile_coord( Tile(tile.letter), Coordinate(i, j)) return new_state
def save_common(tiles, move, state): ts = [Tile(t.letter) for t in tiles] for _, tile in move.items(): if tile in ts: ts.remove(tile) scale = 0 for tile in ts: if tile.letter in ['E', 'A', 'I', 'O', 'N']: scale += 5 return float(Move(move, state).score() + scale)
def calculate_first_move(self, tiles_in_hand, utility_mapper): possible_words = self.lookup.find_all_words( [tile.letter for tile in tiles_in_hand]) horizontal = [True, False] best_score = 0.0 best_move = None if GameConfig.debug: print "calculate_first_move" while self.restarts > 0: if GameConfig.debug: print "restarts to go: %i" % self.restarts stop = False current_score = 0.0 current_move = None random_possibilities = deepcopy(possible_words) shuffle(random_possibilities) if not random_possibilities: stop = True self.restarts -= 1 for o in horizontal: for word in random_possibilities: for start in self.possible_starts(word, o): if not stop: lts = [(start.next(o, i), Tile(word.upper()[i])) for i in range(0, len(word))] move = Move(dict(lts), self.state) score = utility_mapper(tiles_in_hand, move.letters, self.state) if score > current_score: current_score = score current_move = move else: stop = True self.restarts -= 1 if current_score > best_score: best_score = current_score best_move = current_move if best_score > 0.0: return PlaceMove(best_move.letters) else: return Pass()
def max_value(self, tiles_in_hand, utility_mapper, state, alpha, beta, depth): # print "-------------------------------------- MAX: %i" % depth # print [t.letter for t in tiles_in_hand] if depth == 0: util = self.utility_state(state) # if self.moves: # self.moves_score.setdefault(self.moves[0], util) # self.moves_score[self.moves[0]] = max(util, self.moves_score[self.moves[0]]) # del self.moves[-1] if not self.cut: self.scores.append(util) self.cut = True return util # else: # if len(self.moves) > 1: # del self.moves[-1] v = -10000 # print '===' # print [t.letter for t in tiles_in_hand] for succ, move in self.successors(state, tiles_in_hand, utility_mapper): tih = [Tile(t.letter) for t in succ.current_player.tiles] if depth == self.max_depth: self.moves.append(move) v = max( v, self.min_value(tih, utility_mapper, succ, alpha, beta, depth - 1)) if v >= beta: return v alpha = max(alpha, v) if depth == self.max_depth: self.cut = False return v
def valid_moves(self, c, word, o, board): letter = board.get(c).tile.letter unchecked_starts = [] for i in range(0, len(word)): if word.upper()[i] == letter: if o == Orientation.horizontal: if (c.x - i) >= 0 and (c.x + len(word) - i) <= 14: unchecked_starts.append(Coordinate(c.x - i, c.y)) else: if (c.y - i) >= 0 and (c.y + len(word) - i) <= 14: unchecked_starts.append(Coordinate(c.x, c.y - i)) vmoves = [] for start in unchecked_starts: coords_letters = [] for i in range(0, len(word)): coord = start.next(o, i) if not board.has_tile(coord): coords_letters.append((coord, Tile(word.upper()[i]))) if coords_letters: move = Move(dict(coords_letters), self.state) if move.is_valid: vmoves.append(move) if GameConfig.debug: the_pusher[GameConfig.debug_channel].trigger( 'debug', [{ 'x': c.x, 'y': c.y, 'tile': { 'letter': t.letter, 'score': t.score } } for c, t in move.letters.items()]) time.sleep(1) the_pusher[GameConfig.debug_channel].trigger( 'clear_debug') return vmoves
def first_possible_moves(self, tiles_in_hand, state, utility_mapper): possible_words = self.lookup.find_all_words( [tile.letter for tile in tiles_in_hand]) horizontal = [True, False] moves = [] if GameConfig.debug: print "calculate_first_move" for o in horizontal: for word in possible_words: for start in self.possible_starts(word, o): moves.append( Move( dict([(start.next(o, i), Tile(word.upper()[i])) for i in xrange(0, len(word))]), state)) fm = sorted( [ move for move in moves if utility_mapper(tiles_in_hand, move.letters, state) > 0.0 ], key=lambda i: -utility_mapper(tiles_in_hand, i.letters, state)) return fm[0:self.max_depth - 1]