def get_first_level_actions(gcb: Board) -> List[TetrisAction]:
    first_empty_p = Point(0, 0)

    while not first_empty_p.is_out_of_board():
        if gcb.get_element_at(first_empty_p).get_char() == EMPTY:
            break
        first_empty_p = first_empty_p.shift_right(1)

    fig_point = gcb.get_current_figure_point()
    diff = fig_point.get_x() - first_empty_p.get_x()

    actions = []

    if diff > 0:
        actions = [TetrisAction.LEFT] * diff
    if diff < 0:
        actions = [TetrisAction.RIGHT] * -diff

    actions.append(TetrisAction.DOWN)

    return actions
Exemple #2
0
def turn(gcb: Board) -> TetrisAction:
    # this function must return list actions from TetrisAction: tetris_client/internals/tetris_action.py
    #     LEFT = 'left'
    #     RIGHT = 'right'
    #     DOWN = 'down'
    #     ACT = 'act'
    #     ACT_2 = 'act(2)'
    #     ACT_3 = 'act(3),'
    #     ACT_0_0 = 'act(0,0)'
    # change return below to your code (right now its returns random aciton):
    # код ниже является примером и сэмплом для демонстрации - после подстановки корректного URI к своей игре
    # запустите клиент и посмотрите как отображаются изменения в UI игры и что приходит как ответ от API
    elem = gcb.get_current_figure_type()
    print(gcb.get_future_figures())
    print(gcb.get_current_figure_point())
    print(gcb.get_current_figure_type())
    print(gcb.find_element(elem))
    # predict_figure_points_after_rotation - предсказывает положение фигуры после вращения
    print('rotate prediction: ',
          gcb.predict_figure_points_after_rotation(rotation=3))
    actions = [x for x in TetrisAction if x.value != "act(0,0)"]
    # return [TetrisAction.LEFT] - example how to send only one action, list with 1 element
    return [
        TetrisAction.LEFT,
        random.choice(actions),
        random.choice(actions),
    ]  # это те действия, которые выполнятся на игровом сервере в качестве вашего хода
def start_debug_print(gcb: Board) -> None:
    elem = gcb.get_current_figure_type()
    print(gcb.get_future_figures())
    print(gcb.get_current_figure_point())
    print(gcb.get_current_figure_type())
    print(gcb.find_element(elem))

    # predict_figure_points_after_rotation - предсказывает положение фигуры после вращения
    print('rotate prediction: ',
          gcb.predict_figure_points_after_rotation(rotation=3))
def get_board(gcb: Board, remove_points: List[Point], add_points: List[Point], add_char: Optional[str] = None) -> List[List[str]]:
    global total_get_board_time
    time_board_start = time.time()

    board = [list(line) for line in reversed(gcb._line_by_line())]

    for p in remove_points:
        if not p.is_out_of_board(gcb._size):
            board[p.get_y()][p.get_x()] = EMPTY

    for p in add_points:
        if not p.is_out_of_board(gcb._size):
            board[p.get_y()][p.get_x()] = add_char

    time_board_end = time.time()
    total_get_board_time += time_board_end - time_board_start

    return board
def find_best_action(gcb: Board):
    board_list = board_to_list(gcb)
    best_score = 100000
    best_delta = 0
    best_rotate = 0
    best_fullness = 0
    min_delta, max_delta = (0, 0)
    for rotate in range(0, 4):
        figure = [(temp._x, 17 - temp._y)
                  for temp in gcb.predict_figure_points_after_rotation(
                      rotation=rotate)]
        min_delta, max_delta = get_min_max_x(figure, board_list)
        for delta in range(min_delta, max_delta):
            board = table_after_fall([(temp[0] + delta, temp[1])
                                      for temp in figure], board_list)
            min_y = min([y_coord[1] for y_coord in board])
            full_lines = count_full_lines(board)
            #temp = 0
            #if full_lines < 3:
            #    temp = full_lines * 4
            #else:
            #    temp = full_lines * (-4)
            score = (find_empty(board) + 20) * 15 + (18 - min_y -
                                                     full_lines * 3)
            if score < best_score:
                best_score = score
                best_delta = delta
                best_rotate = rotate
            elif score == best_score:
                fullness = count_fullness(board)
                if fullness >= best_fullness:
                    best_score = score
                    best_delta = delta
                    best_rotate = rotate
                    best_fullness = fullness
    print("Score: ", best_score)
    print("Fullness: ", best_fullness)
    print(min_delta, max_delta)
    return best_delta, best_rotate
def board_to_list(gcb: Board) -> list:
    list_of_dot = []
    for y in range(17, -1, -1):
        is_row_empty = True
        for x in range(0, 18):
            if gcb.get_element_at(Point(x, y)).get_char() != ".":
                list_of_dot.append((x, y))
                is_row_empty = False
        if is_row_empty:
            break
    if (8, 0) in list_of_dot:
        list_of_dot.remove((8, 0))

    if (8, 1) in list_of_dot:
        list_of_dot.remove((8, 1))

    if (9, 0) in list_of_dot:
        list_of_dot.remove((9, 0))

    if (9, 1) in list_of_dot:
        list_of_dot.remove((9, 1))

    return list_of_dot
def turn(gcb: Board) -> List[TetrisAction]:
    # this function must return list actions from TetrisAction: tetris_client/internals/tetris_action.py
    #     LEFT = 'left'
    #     RIGHT = 'right'
    #     DOWN = 'down'
    #     ACT = 'act'
    #     ACT_2 = 'act(2)'
    #     ACT_3 = 'act(3),'
    #     ACT_0_0 = 'act(0,0)'
    # change return below to your code (right now its returns random aciton):
    # код ниже является примером и сэмплом для демонстрации - после подстановки корректного URI к своей игре
    # запустите клиент и посмотрите как отображаются изменения в UI игры и что приходит как ответ от API
    # for elem in dcb.

    # actions = get_first_level_actions(gcb)
    # start_debug_print(gdb)

    global total_get_board_time
    global total_get_score_time
    global total_get_cols_heights_time

    start_time = time.time()
    total_get_board_time = 0
    total_get_score_time = 0
    total_get_cols_heights_time = 0

    cur_figure_p = gcb.get_current_figure_point()
    cur_figure_coords = gcb.get_current_element().get_all_coords(cur_figure_p)

    actions = [TetrisAction.DOWN]

    cur_el = gcb.get_current_element()
    cur_char = cur_el.get_char()

    future_figures = gcb.get_future_figures()
    next_el = Element(future_figures[0])
    next_char = next_el.get_char()

    base_board = get_board(gcb, cur_figure_coords, [])

    base_board_cols_heights = get_cols_heights(base_board)

    # print("base_board_cols_heights:  ", base_board_cols_heights)

    best_score = None
    best_shift = None
    best_rot = None

    for rot in range(ROTATION_COUNTS[cur_el.get_char()]):
        cur_rotate_coords = cur_el.get_all_coords_after_rotation(
            cur_figure_p, rot)

        min_x = min(p.get_x() for p in cur_rotate_coords)
        max_x = max(p.get_x() for p in cur_rotate_coords)

        shifts = list(range(-min_x, gcb._size - max_x))
        for shift in shifts:
            if shift < 0:
                pre_final_coords = [
                    p.shift_left(-shift) for p in cur_rotate_coords
                ]
            elif shift > 0:
                pre_final_coords = [
                    p.shift_right(shift) for p in cur_rotate_coords
                ]
            else:
                pre_final_coords = cur_rotate_coords

            pre_final_coords = shift_to_bottom(base_board_cols_heights,
                                               pre_final_coords)

            # add first figure
            update_board(base_board, [], pre_final_coords, cur_char)
            prefinal_board, sub_score = remove_full_rows(base_board)
            base_board_cols_heights_next = get_cols_heights_updated_up(
                base_board_cols_heights, pre_final_coords)

            for rot_next in range(ROTATION_COUNTS[next_el.get_char()]):
                cur_rotate_coords_next = next_el.get_all_coords_after_rotation(
                    cur_figure_p, rot_next)

                min_x_next = min(p.get_x() for p in cur_rotate_coords_next)
                max_x_next = max(p.get_x() for p in cur_rotate_coords_next)

                shifts_next = list(range(-min_x_next, gcb._size - max_x_next))
                for shift_next in shifts_next:
                    if shift_next < 0:
                        final_coords = [
                            p.shift_left(-shift_next)
                            for p in cur_rotate_coords_next
                        ]
                    elif shift_next > 0:
                        final_coords = [
                            p.shift_right(shift_next)
                            for p in cur_rotate_coords_next
                        ]
                    else:
                        final_coords = cur_rotate_coords_next

                    final_coords = shift_to_bottom(
                        base_board_cols_heights_next, final_coords)

                    # add final_coords to board
                    update_board(prefinal_board, [], final_coords, cur_char)
                    final_cols_heights = get_cols_heights_updated_up(
                        base_board_cols_heights, final_coords)

                    score = sub_score + get_score(
                        prefinal_board, final_cols_heights, next_char)

                    # remove final_coords from board
                    update_board(prefinal_board, final_coords, [])

                    if best_score is None or best_score > score:
                        best_score = score
                        best_shift = shift
                        best_rot = rot

            # remove first figure
            update_board(base_board, pre_final_coords, [])

    # prev_cols_heights = cols_heights

    # print("BEST.  score: {},  shift: {},  rot: {}".format(best_score, best_shift, best_rot))
    actions = []

    if best_rot == 1:
        actions.append(TetrisAction.ACT)
    elif best_rot == 2:
        actions.append(TetrisAction.ACT_2)
    elif best_rot == 3:
        actions.append(TetrisAction.ACT_3)

    if best_shift > 0:
        actions.extend([TetrisAction.RIGHT] * best_shift)
    elif best_shift < 0:
        actions.extend([TetrisAction.LEFT] * -best_shift)

    actions.append(TetrisAction.DOWN)

    end_time = time.time()
    print(
        "  TIME.  get_board: {:.6f}  get_score: {:.6f}  get_cols_heights: {:.6f}  total: {:.6f}"
        .format(total_get_board_time, total_get_score_time,
                total_get_cols_heights_time, end_time - start_time), )

    # time.sleep(10)

    return actions
def turn(gcb: Board) -> List[TetrisAction]:
    # this function must return list actions from TetrisAction: tetris_client/internals/tetris_action.py
    #     LEFT = 'left'
    #     RIGHT = 'right'
    #     DOWN = 'down'
    #     ACT = 'act'
    #     ACT_2 = 'act(2)'
    #     ACT_3 = 'act(3),'
    #     ACT_0_0 = 'act(0,0)'
    # change return below to your code (right now its returns random aciton):
    # код ниже является примером и сэмплом для демонстрации - после подстановки корректного URI к своей игре
    # запустите клиент и посмотрите как отображаются изменения в UI игры и что приходит как ответ от API
    # for elem in dcb.

    global get_scores__calls_count
    get_scores__calls_count = 0

    global total_get_board_time
    global total_get_score_time
    global total_get_cols_heights_time

    start_time = time.time()

    total_get_board_time = 0
    total_get_score_time = 0
    total_get_cols_heights_time = 0

    elements = [gcb.get_current_element()] + [Element(c) for c in gcb.get_future_figures()]
    cur_figure_p = gcb.get_current_figure_point()

    base_board = get_board(gcb, elements[0].get_all_coords(cur_figure_p), [])
    prev__states = [State(
        board=base_board,
        cols_heights=get_cols_heights(base_board),
        score=0,
        fill_score=0,
        first_shift=None,
        first_rotation=None,
    )]

    board_size = gcb._size

    for cur__el in elements:
        cur__char = cur__el.get_char()

        cur__states: List[State] = []

        for prev__state in prev__states:
            prev_state__max_height = max(prev__state.cols_heights)

            for cur__rotation in range(ROTATION_COUNTS[cur__char]):
                cur__rotate_coords = cur__el.get_all_coords_after_rotation(cur_figure_p, cur__rotation)

                min_x = min(p.get_x() for p in cur__rotate_coords)
                max_x = max(p.get_x() for p in cur__rotate_coords)

                shifts = list(range(-min_x, board_size - max_x))
                for cur__shift in shifts:
                    if cur__shift < 0:
                        cur__final_coords = [p.shift_left(-cur__shift) for p in cur__rotate_coords]
                    elif cur__shift > 0:
                        cur__final_coords = [p.shift_right(cur__shift) for p in cur__rotate_coords]
                    else:
                        cur__final_coords = cur__rotate_coords

                    cur__final_coords = shift_to_bottom(prev__state.cols_heights, cur__final_coords)

                    # add first figure
                    if not update_board(prev__state.board, [], cur__final_coords, cur__char):
                        # invalid state
                        continue

                    # process state
                    added_points_dict = defaultdict(list)
                    for p in cur__final_coords:
                        added_points_dict[p.get_y()].append(p.get_x())

                    cur__board, cur__filled_rows_count = remove_filled_rows(prev__state.board, added_points_dict)
                    cur__cols_heights = get_cols_heights_updated_up(prev__state.cols_heights, cur__final_coords)
                    cur__cols_heights = [h - cur__filled_rows_count for h in cur__cols_heights]

                    cur__score = prev__state.fill_score + get_score(cur__board, cur__cols_heights, added_points_dict, cur__char)

                    cur__states.append(State(
                        board=cur__board,
                        cols_heights=cur__cols_heights,
                        score=cur__score,
                        fill_score=SCORES_FOR_FILLED_ROWS[prev_state__max_height - 1][cur__filled_rows_count] * MULTIPLIER_FILLED_ROWS,
                        first_shift=prev__state.first_shift if prev__state.first_shift is not None else cur__shift,
                        first_rotation=prev__state.first_rotation if prev__state.first_rotation is not None else cur__rotation,
                    ))

                    # remove first figure
                    update_board(prev__state.board, cur__final_coords, [])

        # i have a lot of states
        cur__states.sort(key=lambda state: state.score)

        prev__states = cur__states[:TOP_STATES_COUNT]

    if not cur__states:
        print(TEXT_LOST)
        return [TetrisAction.ACT_0_0]

    print("    get_scores  calls count: ", get_scores__calls_count)

    best_state = cur__states[0]

    actions = []
    if best_state.first_rotation == 1:
        actions.append(TetrisAction.ACT)
    elif best_state.first_rotation == 2:
        actions.append(TetrisAction.ACT_2)
    elif best_state.first_rotation == 3:
        actions.append(TetrisAction.ACT_3)

    if best_state.first_shift > 0:
        actions.extend([TetrisAction.RIGHT] * best_state.first_shift)
    elif best_state.first_shift < 0:
        actions.extend([TetrisAction.LEFT] * -best_state.first_shift)

    actions.append(TetrisAction.DOWN)

    end_time = time.time()
    print("  TIME.  get_board: {:.6f}  get_score: {:.6f}  get_cols_heights: {:.6f}  total: {:.6f}".format(
        total_get_board_time, total_get_score_time, total_get_cols_heights_time, end_time - start_time),
    )

    return actions
Exemple #9
0
def turn(gcb: Board) -> TetrisAction:
    start_time = datetime.datetime.now()
    test_board = [[
        'O', '.', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
        'O', 'O', 'O', 'O'
    ],
                  [
                      'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
                      'O', 'O', 'O', 'O', 'O', 'O', 'O'
                  ],
                  [
                      'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
                      'O', 'O', 'O', 'O', 'O', 'O', 'O'
                  ],
                  [
                      'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
                      'O', 'O', 'O', 'O', 'O', 'O', 'O'
                  ],
                  [
                      'O', '.', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O',
                      'O', 'O', 'O', 'O', 'O', 'O', 'O'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ],
                  [
                      '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
                      '.', '.', '.', '.', '.', '.', '.'
                  ]]

    #информация о фигуре
    figure_type = gcb.get_current_figure_type()
    figure_point = gcb.get_current_figure_point()
    #создаем игрвое поле
    board = format_board(gcb)
    #убираем новую фигуру с поля
    board = remove_figure_from_board(figure_type, figure_point,
                                     copy.deepcopy(board))

    #решаем, каким будет режим игры
    agressive_mode = True
    print("\n\n\n", gcb.get_level()._current, "\n\n\n")
    level = gcb.get_level()
    if get_height(board) >= 15 or (level._current == 1 and level._total != 1):
        agressive_mode = False

    #создаем все возможные варианты установки фигуры
    new_board = copy.deepcopy(board)

    boards = predict_landing(figure_type, figure_point, new_board,
                             agressive_mode)

    if board == [['.' for i in range(18)] for j in range(18)]:
        print("""

██████╗  ██████╗ ████████╗██████╗  █████╗  ██████╗██╗  ██╗███████╗███╗   ██╗ ██████╗ 
██╔══██╗██╔═══██╗╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██║  ██║██╔════╝████╗  ██║██╔═══██╗
██████╔╝██║   ██║   ██║   ██████╔╝███████║██║     ███████║█████╗  ██╔██╗ ██║██║   ██║
██╔═══╝ ██║   ██║   ██║   ██╔══██╗██╔══██║██║     ██╔══██║██╔══╝  ██║╚██╗██║██║   ██║
██║     ╚██████╔╝   ██║   ██║  ██║██║  ██║╚██████╗██║  ██║███████╗██║ ╚████║╚██████╔╝
╚═╝      ╚═════╝    ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═══╝ ╚═════╝

            """)
    #board info:
    #0 - move (left/right)
    #1 - turn
    #2 - board list
    #3 - perimeter
    #4 - height weight
    #5 - number of holes
    #выбираем лучшую комбинацию

    for boar in boards:
        boar.append(find_perimeter(boar[2]))
        boar.append(calculate_height(boar[2]))
        boar.append(count_holes(boar[2]))

    current_holes_number = count_holes(board)
    #обработка дыр
    boards_to_remove = []
    for i, boar in enumerate(boards):
        if boar[5] > current_holes_number:
            boards_to_remove.append(i)

    if len(boards_to_remove) == len(boards):
        print("\n\nНЕВОЗМОЖНО СЫГРАТЬ БЕЗ УВЕЛИЧЕНИЯ ЧИСЛА ДЫР\n\n")
    else:
        boards_to_remove.reverse()
        for i in boards_to_remove:
            boards.pop(i)
    # обработка веса
    min_weight = boards[0][4] + boards[0][3]
    min_weight_i = 0
    for i, boar in enumerate(boards):
        if boar[4] + boar[3] < min_weight:
            min_weight_i = i
            min_weight = boar[4] + boar[3]

    action_numbers = boards[min_weight_i][0:2]

    finish_time = datetime.datetime.now()
    print("\n\n", "TIME =", finish_time - start_time, "\n\n")
    return create_actions_list(action_numbers)