Beispiel #1
0
    def moves_by_strategy(self, player):
        picked = []
        if (Army.MAX_PAWNS - 0) == len(player.pawns_deck):
            picked.append(player.take_hq_from_deck())

        elif (Army.MAX_PAWNS - 1) == len(player.pawns_deck):
            picked.append(player.take_random_pawn())

        elif (Army.MAX_PAWNS - 2) == len(player.pawns_deck):
            picked.append(player.take_random_pawn())
            picked.append(player.take_random_pawn())

        else:
            picked.append(player.take_random_pawn())
            picked.append(player.take_random_pawn())
            picked.append(player.take_random_pawn())

        moves = []
        for i, pawn in enumerate(picked):
            if i in [0, 1]:
                move = Move(pawn, where=player.board.any_empty_hex().position, direction=Move.random_direction())

            else:
                move = Discard(pawn)

            move.update_player_pawns(player)

            moves.append(move)

        return moves
Beispiel #2
0
    def is_valid(self, move: Move):
        """ Validate a move.
        :param move: The move to be validated.
        :return: boolean True if move is valid, otherwise a MoveValidationError is raised
        giving the reason for the move being invalid.
        """
        if move.is_valid is not None:
            return move.is_valid

        move.is_valid = False

        if move.direction == Direction.NOT_APPLICABLE:  # we must be passing or swapping letters
            move.is_valid = True
            return True  # Player must have passed or exchanged

        num_tiles = len(move.tiles)
        start_index = move.start_index

        # check we are playing a sensible number of tiles:
        if num_tiles < 1 or num_tiles > RACK_SIZE:
            raise MoveValidationError('move has invalid number of tiles')

        # get row or column as appropriate (columns come back transposed to a row):
        row = move.row

        # check we're not on a sentinel square
        if start_index < 1 or start_index >= BOARD_SIZE:
            raise MoveValidationError("starting square is off the board")

        if not row.square_is_empty(start_index):
            raise MoveValidationError("starting square is not free")

        if len(move.played_squares) < num_tiles:
            raise MoveValidationError("not enough free spaces")

        if not self.has_valid_hook(row, move.played_squares):
            raise MoveValidationError(
                "word must join an existing word or start square")

        row.place_tiles(move.played_squares, move.tiles)

        if not self.crosswords_valid(row):
            row.remove_tiles(move.played_squares)
            raise MoveValidationError("invalid cross-word formed")

        word_formed = row.word_at(start_index)
        if word_formed not in self.lexicon:
            row.remove_tiles(move.played_squares)
            raise MoveValidationError("'" + word_formed +
                                      "'is not a valid word")

        move.calculate_score()
        move.is_valid = True

        return True
Beispiel #3
0
    def update_affected_squares(self, move: Move):
        """ Updates cached running totals and valid letters to play when making cross-words
        """

        # get all the squares in the played word, existing and new tiles:
        filled_squares = move.row.squares_in_word(move.start_index)

        # set blank square at either end as a hook, plus add the total of this word
        # as a crossword score for the orthogonal columns crossing those blank squares
        move.row.update_hooks_and_running_scores(move.start_index)
        self.update_valid_letters(move.row, move.start_index)

        for i in filled_squares:
            column = self.board.get_row(i, move.cross_direction())
            column.update_hooks_and_running_scores(move.row.rank)
            self.update_valid_letters(column, move.row.rank)

        # change multiplier for played squares to 1,
        # the identity for multiplication, so they aren't re-used
        move.row.letter_multipliers[move.played_squares] = 1
        move.row.word_multipliers[move.played_squares] = 1

        # change crosschecks to all true so we don't have to filter them out when checking new words:
        move.row.this_row_crosschecks[move.played_squares] = (1 << 32) - 1
        move.row.orthogonal_column_crosschecks[
            move.played_squares] = (1 << 32) - 1
Beispiel #4
0
 def tile_exchange_move(self, input_string: str):
     try:
         tiles_to_play = self.game.active_player.rack.get_tiles(
             input_string)
     except ValueError as ex:
         print(str(ex))
         return None
     return Move(None, None, tiles_to_play)
Beispiel #5
0
    def best_move(self, potential_moves):

        potential_moves.sort(key=lambda x: x.score, reverse=True)
        best_move = potential_moves[0] if potential_moves else Move(None, None, None)
        # now we've decided on a move, remove those tiles from the rack:
        if best_move.tiles:
            self.rack.get_tiles(''.join([str(t) for t in best_move.tiles]))

        # DEBUG:
        # print(self.name+": Best move is: "+str(best_move))  # DEBUG

        return best_move
Beispiel #6
0
    def play_on_square(self, row, index, played_tiles, rack: Rack):

        valid_moves = []

        # get all the letters we could play on this square without making nonsense in the corresponding column:
        valid_cross_plays = [chr(64 + x) for x in range(1, 27) if read_bit(row.this_row_crosschecks[index], x)]

        # filter that to ones we can actually use with tiles from our rack (all of them if we have a blank!)
        valid_tiles = valid_cross_plays if '@' in rack else [x for x in valid_cross_plays if x in rack]

        # for each of the playable tiles, stick it in the square
        for tile_letter in valid_tiles:
            tile = rack.get_tile(tile_letter)
            played_tiles[index] = tile
            row.existing_letters[index] = ord(tile)-64

            if row.word_at(index) in self.game.lexicon:
                new_move = Move(row, np.where(played_tiles)[0][0], [tile for tile in played_tiles if tile])
                new_move.played_squares = np.where(played_tiles)[0]
                new_move.calculate_score()
                #DEBUG:
                #print(self.name+": Considering move: "+str(new_move))
                valid_moves.append(new_move)

            if len(rack) > 0: # if we still have tiles left
                # try extending into the next square on the left, only if we've made a middle part of a real word:
                if self.game.lexicon.contains_infix(row.word_at(index)):
                    valid_moves.extend(self.extend_left(index, played_tiles, row, rack))
                # and if we've made the start of a word yet, try extending that to the right
                if self.game.lexicon.contains_prefix(row.word_at(index)):
                    valid_moves.extend(self.extend_right(index, played_tiles, row, rack))

            # return the tile to the rack
            rack.add_tile(tile)
            # set board square back to no letter
            row.existing_letters[index] = 0
            # remove tile from list of played tiles:
            played_tiles[index] = None

        return valid_moves
def record_roll(player, move_ing:'Move', game_id: str, count, the_number, is_over):
    session = create_session()

    move = Move()
    move.player_id = player.id
    move.guess = move_ing
    move.game_id = game_id
    move.count = count
    move.is_over = is_over
    move.number = the_number

    session.add(move)

    session.commit()
    session.close()
def record_roll(player, move: 'Move', game_id: str, is_over: bool,
                roll_num: int):
    session = create_session()

    move = Move()
    move.player_id = player.id
    move.roll_id = move.id
    move.game_id = game_id
    move.is_winning_play = is_over
    move.roll_number = roll_num
    session.add(move)

    session.commit()
    session.close()
Beispiel #9
0
    def parse_move_string(self, input_string: str):
        # delete anything other than alphanumeric characters or '?':
        input_string = self.strip_invalid_characters(input_string)

        if not input_string:
            return self.passing_move()

        if not self.contains_digits(input_string):
            return self.tile_exchange_move(input_string)

        # if we got this far we're trying to do a standard move:
        # reject strings not long enough to have square+direction+at least 1 tile,
        # or with no character following a blankChar
        if len(input_string) < 4 or input_string.endswith("?"):
            '''DEBUG'''
            self.describe_square(input_string)
            '''DEBUG'''

            raise MoveValidationError("Invalid number of tiles")

        # get starting square:
        x = ord(input_string[0]) - 64
        y = self.digits_in_string(input_string)

        # now strip digits out:
        input_string = self.letters_in_string(input_string)

        # get direction. This should be at index 1 now we've removed numbers:
        if input_string[1] == 'H':
            row = self.board.get_row(y, Direction.HORIZONTAL)
            starting_square = x
        elif input_string[1] == 'V':
            row = self.board.get_row(x, Direction.VERTICAL)
            starting_square = y
        else:
            raise MoveValidationError("Direction invalid")

        # remove digits then lop off square and direction, to leave actual letters for move
        input_string = input_string[2:]

        # process blanks (converts ?A to a, ?B to b, etc):
        input_string = re.sub(r'\?.', lambda m: m.group(0).lower()[-1],
                              input_string)

        if input_string not in self.game.active_player.rack:
            raise MoveValidationError("No such tiles in rack")

        tiles_to_play = self.game.active_player.rack.get_tiles(input_string)

        return Move(row, starting_square, tiles_to_play)
    def node_expansion(self):
        for play in self._move_generator.plays:

            curr_move = Move(play[0], play[1])

            if curr_move.validate(self.current_node.state):

                state_clone = self.current_node.state.clone()

                curr_move.execute(state_clone)

                child = Node(state_clone, self.current_node.clone(), self.current_node.depth + 1,
                             copy(curr_move))

                unique = True

                for visited_node in self.visited:
                    if child.depth > visited_node.depth + 5:
                        continue
                    if child == visited_node:
                        unique = False
                        break

                for node_in_queue in self.queue:
                    if child.depth == node_in_queue.depth + 5:
                        continue

                    if child == node_in_queue:
                        unique = False
                        break

                if unique:
                    self.exec(child)
                    self.model.header.statistics.current_depth = child.depth
                    self.model.header.statistics.visited_queue_length = len(self.visited)
                    self.model.header.statistics.queue_length = len(self.queue)
Beispiel #11
0
    def test_valid2(self):
        a = self.gen_area()
        positions = {
            (3, 3): True,
            (4, 5): True,
            (5, 5): True,
            (3, 4): True,
            (4, 4): False,
            (5, 4): True,
            (3, 3): True,
            (3, 4): True,
            (3, 5): True
        }

        for (x, y), val in positions.items():
            self.assertEqual(Move(Field(4, 4), Field(x, y)).valid(a), val)
Beispiel #12
0
    def permute_blanks(move):
        """ takes the argument move containing a blank, and returns a list of moves containing
        all permutations of this move with the blank in different positions
        (this will only result in additional moves if the word contains another tile with the
        same letter as has been assigned to the blank)"""

        moves = [move]

        for i in range(0, len(move.tiles)):
            if move.tiles[i].islower():
                for j in range(0, len(move.tiles)):
                    if j != i and move.tiles[i].upper() == move.tiles[j]:
                        reordered_tiles = list(move.tiles)
                        reordered_tiles[i], reordered_tiles[j] = reordered_tiles[j], reordered_tiles[i]
                        moves.append(Move(move.row, move.start_index, reordered_tiles))
                        moves[-1].calculate_score()
        return moves
Beispiel #13
0
    def step(self, target=None):
        possible = []
        for i, j in self.MOVES:
            if self.position.x + i >= 0 and self.position.y + j >= 0:
                candidate_move = Move(self.position, Field(self.position.x + i, self.position.y + j))
                if self.checker.can_make(candidate_move):
                    possible.append(candidate_move)
        # Check if we are not blocked
        if possible.__len__() == 0:
            raise Exception(u"Agent cannot make any moves from field {0:s}".format(self.position))
        # Asking the decision maker for move
        next_move = self.decider.decide(possible, self.position)
        # Making the move
        self.change_position(next_move.target)
        # We can initially update out light map based on possible moves - but a max of 9
        self.react_to_new_place()

        return self.position
Beispiel #14
0
import time

from model.field import Field
from model.move import Move

start = time.time()

f = Move(Field(4, 4), Field(5, 5))

for i in range(0, 1000000):
    f.__hash__()

end = time.time() - start

print end

Beispiel #15
0
 def passing_move():
     return Move(None, None, None)  # will execute a pass
Beispiel #16
0
    def generate_all_moves(self):
        """ returns a list of all possible moves """
        valid_moves = []
        #row_queue = queue.Queue()

        self.rack.reset_blanks()

        if '@' in self.rack:
            self.rack.assign_blanks()

        # grab a list of all the rows which have start squares/hooks in them:
        rows_to_consider = \
            [self.board.get_row(i, Direction.HORIZONTAL)
             for i in range(1, BOARD_SIZE)
             if self.board.hook_squares[i, :].any()]

        # do the same for columns:
        rows_to_consider.extend(
            [self.board.get_row(i, Direction.VERTICAL)
             for i in range(1, BOARD_SIZE)
             if self.board.hook_squares[:, i].any()])

        # rows are independent of each other, but share some squares with columns,
        # so we can consider all rows at once, and all columns too provided we
        # act on copies of the rows. We can consider each row/column in its own thread:

        # make list of lists of possible moves, each index will be list from a different thread
        moves = np.full(len(rows_to_consider), None)
        # to keep track of thread references:
        row_threads = []
        # consider each row in separate thread:
        for i in range(len(rows_to_consider)):
            row = rows_to_consider[i]
            thread = Thread(target=self.get_moves_for_row, args=(moves, i, row))
            row_threads.append(thread)
            thread.start()
        # wait for all threads to finish:
        [t.join() for t in row_threads]

        #    concatenate all move lists from all threads
        [valid_moves.extend(moves[i]) for i in range(len(rows_to_consider))]

        # now add all combinations of pass and exchange moves by generating all combinations of rack
        # letters of any length, from 0 tiles up to however many is in the rack:
        tile_combos = [
            Move(None, None,list(i)) for i in set([x for l in range(0, len(self.rack))
                                                   for x in itertools.combinations(self.rack.rack_tiles, l)])
        ]
        valid_moves.extend(tile_combos)

        # DEBUG:
        # print(str(valid_moves))

        # DEBUG
        # ("*** moving on ***")
        # print(threading.get_ident())

        if '@' in self.rack:
            self.check_blank_permutations(valid_moves)

        valid_moves = list(set(valid_moves))

        return valid_moves
Beispiel #17
0
 def _next_state(self, move: Move) -> 'State':
     return State(move.apply(self.current_board),
                  self.move_history + [move],
                  self.board_history + [self.current_board],
                  self._move_order)
Beispiel #18
0
from flask import Flask, jsonify, request

from model.game import Game, GameSchema
from model.move import Move, MoveSchema

app = Flask(__name__)

games = [
    Game('test', ['Ola', 'Justyna'], [Move(0, 'Ola', 4, 3, 2)]),
    Game('finals_k_k', ['Garri Kasparow', 'Anatolij Karpow']),
    Game('finals_k_c', ['Siergiej Kariakin', 'Magnus Carlsen']),
    Game('match_s_g', ['Dariusz Świercz', 'Anisz Giri'])
]


@app.route('/games')
def get_games():
    schema = GameSchema(many=True)
    result = schema.dump(filter(lambda t: t.finished is not True, games))
    return jsonify(result.data)


@app.route('/createGame', methods=['POST'])
def create_game():
    game = GameSchema().load(request.get_json())
    games.append(game.data)
    return '', 201


@app.route('/endGame', methods=['GET'])
def end_game():
Beispiel #19
0
def build_move():
    x, y = random.randint(1, 50), random.randint(1, 50)
    dx, dy = random.randint(-1, 1), random.randint(-1, 1)
    return Move(Field(x,y),Field(x+dx,y+dy))
Beispiel #20
0
 def test_init(self):
     start = Field(2, 2)
     end = Field(8, 4)
     m = Move(start, end)
     self.assertEqual(m.source, start)
     self.assertEqual(m.target, end)
Beispiel #21
0
import time

from mock.mock import self

from model.field import Field
from model.move import Move
from model.point import Point
from model.view import ViewGenerator
from examples.Scenario1 import Scenario1

start = time.time()

m1 = Move(Field(2, 2), Field(5, 5))
m2 = Move(Field(3, 3), Field(5, 5))

for i in range(0, 1000000):
    m1 == m2

end = time.time() - start

print end
Beispiel #22
0
 def can_step(self, target):
     return self.checker.can_make(Move(self.position, target))
Beispiel #23
0
def process_game(gcg_lines, game_number):
    players = [None, None]
    game = GameController(players, Bag())
    gui = ConsoleGui(game)
    movelist = [line.split() for line in gcg_lines]
    player1 = AiPlayer(game, gui, movelist.pop(0)[1])
    player2 = AiPlayer(game, gui, movelist.pop(0)[1])
    game.players = [player1, player2]
    game.active_player = player1 if player1.name == movelist[0][0][1:-1] else player2

    current_move = 0  # current move
    while movelist:
        current_move += 1
        current_move_info = movelist.pop(0)

        # if there are things in brackets, they are score adjustments so we've
        # finished all the moves:
        if '(' in current_move_info[1]:
            return

        # we use '@' for blank for pragmatic reasons (it's the ASCII character before 'A')
        # GCG uses '?', so let's fix that:
        game.active_player.rack.rack_tiles = list(current_move_info[1].replace('?', '@'))

        # Now we have the correct tiles in the rack and the board is advanced to the correct position,
        # let's get a list of all the moves ALexIS can come up with:
        alexis_moves = game.active_player.generate_all_moves()
        alexis_moves.sort(key=lambda x: x.score, reverse=True)  # Sort if with highest scores first

        # put any blanks back to having letter un-assigned, ready for parsing Quackle move
        game.active_player.rack.reset_blanks()

        # Now let's move onto getting our 'good' move from the GCG file:

        # GCG has digit(s) followed by letter for horizontal move, or vice versa for vertical,
        # wheras we are expecting digit, then letter, then 'H' or 'V', so let's fix that:

        start_square = current_move_info[2]

        if start_square.startswith('-'):
            tiles = ''
            if len(start_square)>1:
                tiles = start_square[1]
            start_square = ''
        else:
            if start_square[0].isdigit():
                start_square = start_square[-1] + start_square[:-1] + 'H'
            else:
                start_square += 'V'
            # lowercase letters in the GCG represent blanks. We're expecting a question mark for a blank,
            # followed by the desired letter, so replace 'a' with '?A', etc:
            tiles = ''.join(['?' + letter.upper() if letter.islower() else letter for letter in current_move_info[3]])

        # GCG gives the start square as the first letter in the word,
        # and uses '.' as a placeholder for any tile already on the board,
        # whereas we list the first square we're actually playing on, and
        # just the tiles actually played, so let's strip out '.' and adjust the
        # starting square if necessary:

        if '.' in tiles:
            start_square = list(start_square)  # treat string as char list
            x = 0
            while tiles[x] == '.':  # whilst there's a dot at the start
                if start_square[-1] == 'V':
                    start_square[-2] = str(int(start_square[-2]) + 1)  # increase the row if playing vertical
                else:
                    start_square[0] = chr(ord(start_square[0]) + 1)  # or the column if horizontal
                x += 1
            start_square = ''.join(start_square)  # make a string again
            tiles = tiles.replace('.', '')  # strip out any dot in the middle of the word

        # save the rack for later:
        cached_rack = copy.deepcopy(game.active_player.rack)

        # This will get a move and remove tiles from rack:
        quackle_move = gui.parse_move_string(start_square + tiles)

        if quackle_move.direction is not Direction.NOT_APPLICABLE:
            # validator will place tiles onto row in course of validation,
            # so first we'll copy the row so as not to mess up the board:
            quackle_move.row = copy.deepcopy(quackle_move.row)
            game.validator.is_valid(quackle_move)

            # this will calculate score (but only if tiles are already played on row):
            quackle_move.calculate_score()

        # now choose some moves. If we do data augmentation by transposing the 'correct' Quackle-derived moves,
        # we'll have 2 correct moves, so picking six of these would give us multiples of 8 moves.
        # Picking the top couple and randomly picking the rest would analyse a couple of 'good' moves
        # but still allow a little exploration (c.f. Q learning)

        if quackle_move in alexis_moves:
            alexis_moves.remove(quackle_move)  # don't process the quackle move as one of the wrong ones

        # just in case it's the end game:
        while len(alexis_moves) < 6:
            # add a pass:
            alexis_moves.append(Move(None, None, None))

        wrong_moves = []
        wrong_moves.append(alexis_moves.pop(0))
        wrong_moves.append(alexis_moves.pop(0))

        # add 4 randomly chosen moves:
        wrong_moves.extend(choices(alexis_moves, k=4))

        for option in range(len(wrong_moves)):
            base_layer = copy.deepcopy(game.board.existing_letters[:-1, :-1])  # slice off last sentinel
            # set first sentinel squares to zero instead of sentinel value:
            base_layer[0, :] = 0
            base_layer[:, 0] = 0

            move_layer = np.zeros([16, 16], dtype='int')
            # put rack tiles we're playing from in first row:
            move_layer[0][0:len(cached_rack)] = [ord(t) - 64 for t in cached_rack.rack_tiles]

            # set first sentinel squares to zero instead of sentinel value:
            word_mult = np.where(game.board.word_multipliers > 1, game.board.word_multipliers * 8, 0)
            letter_mult = np.where(game.board.letter_multipliers > 1, game.board.letter_multipliers * 2, 0)
            score_layer = np.where(game.board.existing_letter_scores > 0, game.board.existing_letter_scores * 2,
                                   word_mult + letter_mult)
            score_layer = score_layer[:-1, :-1]  # slice off last sentinel
            # set first sentinel squares to zero instead of sentinel value:
            score_layer[0, :] = 0
            score_layer[:, 0] = 0

            move = wrong_moves[option]
            move_tiles = move.tiles if move.tiles else []

            if move.direction == Direction.NOT_APPLICABLE:  # pass or exchange
                # put rack tiles we're exchanging in first row:
                if move.tiles: # unless it's a pass with no tiles
                    move_layer[0][0:len(move_tiles)] = [ord(t) - 64 for t in move.tiles]

            else:  # regular move
                row = move_layer[move.row.rank, :] if move.direction == Direction.HORIZONTAL else move_layer[:,
                                                                                                  move.row.rank]
                # put rack tiles we're playing on board:
                row[move.played_squares] = [ord(t) - 64 for t in move.tiles]
                # change score of square containing blank to zero:
                score_layer = np.where(move_layer <= 26, score_layer, 0)
                # change blanks to normal letter ordinal (by subtracting 32)
                move_layer = np.where(move_layer <= 26, move_layer, move_layer - 32)

            # flatten arrays and convert int8 to int so values aren't clipped at 128:
            rgb = zip((base_layer.astype(int)).flatten() * 9, (score_layer.astype(int)).flatten() * 9,
                      (move_layer.astype(int)).flatten() * 9)
            # put in a list:
            rgb = [pixel for pixel in rgb]

            # convert to an image, and resize so things like
            # max pooling layers won't lose all the information in the image:
            img = Image.new('RGB', (16, 16))
            img.putdata(rgb)
            img = img.resize((256, 256), Image.NEAREST)

            # save the image
            img.save(img_path + 'a_g' + str(game_number).zfill(4)
                     + '_m' + str(current_move).zfill(2)
                     + '_option' + str(option + 1) + '.png')

            # add a little feedback to the console:
            print(":" + str((game_number, current_move, option)))

        # now process the Quackle move:
        base_layer = copy.deepcopy(game.board.existing_letters[:-1, :-1])  # slice off last sentinel
        # set first sentinel squares to zero instead of sentinel value:
        base_layer[0, :] = 0
        base_layer[:, 0] = 0

        move_layer = np.zeros([16, 16], dtype='int')
        # put rack tiles we're playing from in first row:
        move_layer[0][0:len(cached_rack)] = [ord(t) - 64 for t in cached_rack.rack_tiles]

        # set first sentinel squares to zero instead of sentinel value:
        word_mult = np.where(game.board.word_multipliers > 1, game.board.word_multipliers * 8, 0)
        letter_mult = np.where(game.board.letter_multipliers > 1, game.board.letter_multipliers * 2, 0)
        score_layer = np.where(game.board.existing_letter_scores > 0, game.board.existing_letter_scores * 2,
                               word_mult + letter_mult)
        score_layer = score_layer[:-1, :-1]  # slice off last sentinel
        # set first sentinel squares to zero instead of sentinel value:
        score_layer[0, :] = 0
        score_layer[:, 0] = 0

        move = quackle_move
        move_tiles = move.tiles if move.tiles else []

        if move.direction == Direction.NOT_APPLICABLE:  # pass or exchange
            # put rack tiles we're exchanging in first row:
            if move_tiles:
                move_layer[0][0:len(move_tiles)] = [ord(t) - 64 for t in move.tiles]

        else:  # regular move
            row = move_layer[move.row.rank, :] if move.direction == Direction.HORIZONTAL else move_layer[:,
                                                                                              move.row.rank]
            # put rack tiles we're playing on board:
            row[move.played_squares] = [ord(t) - 64 for t in move.tiles]
            # change score of square containing blank to zero:
            score_layer = np.where(move_layer <= 26, score_layer, 0)
            # change blanks to normal letter ordinal (by subtracting 32)
            move_layer = np.where(move_layer <= 26, move_layer, move_layer - 32)

        # flatten arrays and convert int8 to int so values aren't clipped at 128:
        rgb = zip((base_layer.astype(int)).flatten() * 9, (score_layer.astype(int)).flatten() * 9,
                  (move_layer.astype(int)).flatten() * 9)
        # put in a list:
        rgb = [pixel for pixel in rgb]

        # convert to an image, and resize so things like
        # max pooling layers won't lose all the information in the image:
        img = Image.new('RGB', (16, 16))
        img.putdata(rgb)
        img = img.resize((256, 256), Image.NEAREST)

        # save the image
        img.save(img_path + 'q_g' + str(game_number).zfill(4)
                 + '_m' + str(current_move).zfill(2)
                 + '_option1.png')

        # now do data augmentation by transposing the board:
        base_layer[1:16, 1:16] = base_layer[1:16, 1:16].T
        move_layer[1:16, 1:16] = move_layer[1:16, 1:16].T
        score_layer[1:16, 1:16] = score_layer[1:16, 1:16].T

        # save the transposed version:
        rgb = zip((base_layer.astype(int)).flatten() * 9, (score_layer.astype(int)).flatten() * 9,
                  (move_layer.astype(int)).flatten() * 9)
        rgb = [pixel for pixel in rgb]
        img = Image.new('RGB', (16, 16))
        img.putdata(rgb)
        # img = img.resize((256, 256), Image.NEAREST)
        img.save(img_path + 'q_q' + str(game_number).zfill(4)
                 + '_m' + str(current_move).zfill(2)
                 + '_option2.png')

        # now actually execute the move to prepare the board for the next move:

        # we've probably fake-played all the tiles so put them back in the rack:
        game.active_player.rack = cached_rack

        # only bother playing the move if it actually changes the board,
        # since we're not tracking what's in the bag, or what the current scores are:
        if quackle_move.direction is not Direction.NOT_APPLICABLE:
            # ensure the row we're using is a slice of the board, not a copy:
            if quackle_move.row:
                quackle_move.row = game.board.get_row(quackle_move.row.rank, quackle_move.row.direction)

            # clear move validation and re-validate the move, in doing so play it onto the correct row:
            quackle_move.is_valid = None
            game.validator.is_valid(quackle_move)

            game.execute_move(quackle_move)
Beispiel #24
0
def move_socket(message):
    match = manager.get_match(message['match'])
    if match.is_admin(message['player']):
        match.change_turn(match.color_at(message['from']))
        try:
            move = Move(message['player'], message['from'], message['to'],
                        message['crown'])
        except KeyError:
            move = Move(message['player'], message['from'], message['to'])
        match.force_move(move)
        match.print_map()
        manager.update(match)
        app.logger.info("Admin moved " + move.get_move().uci())
    elif match.valid_turn(message['player']) and not match.has_finished():
        if not match.timer_alive():
            if match.match_start():
                app.logger.info("MATCH " + message['match'] + " STARTED!!!!")
            else:
                if not match.white_has_joined():
                    app.logger.info("WHITE HASNT JOINED")
                if not match.black_has_joined():
                    app.logger.info("BLACK HASNT JOINED")
                app.logger.info("WAITING FOR ONE PLAYER TO START THE MATCH")
                emit('receive_movement',
                     match.pack_data(),
                     room=message['match'])
                return
        try:
            move = Move(message['player'], message['from'], message['to'],
                        message['crown'])
        except KeyError:
            move = Move(message['player'], message['from'], message['to'])
        response = match.make_move(move)
        manager.update(match)
        if response != None:
            emit('chat', {'data': response}, room=message['match'])
        else:
            app.logger.info("RESPONSE WAS NONE: " + move.get_move().uci())


#        except:
#            app.logger.error("[MOVE] ERROR")
#            traceback.print_exc()
    else:
        app.logger.info("Bad turn!")
    emit('receive_movement', match.pack_data(), room=message['match'])
    out = match.get_outcome()
    if out != None:
        app.logger.info("[END] M: " + message['match'] + " C: " +
                        str(out.termination) + " W: " + str(out.winner) +
                        " R: " + out.result())
        emit('ended', {
            'cause': out.termination.value,
            'winner': out.winner,
            'result': out.result()
        },
             room=message['match'])
        match.finish_match(out.termination.value, out.winner)

    if match.match_end_time() != 0:
        if match.match_end_time() == 1:
            emit('ended', {
                'cause': 8,
                'winner': False,
                'result': "0-1"
            },
                 room=message['match'])
            match.finish_match(1, False)
        elif match.match_end_time() == 2:
            emit('ended', {
                'cause': 9,
                'winner': True,
                'result': "1-0"
            },
                 room=message['match'])
            match.finish_match(1, True)
Beispiel #25
0
 def setUp(self):
     game.getRandomMove = MagicMock(return_value=Move('test-move'))