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_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
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
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)