Правильно распечатайте содержимое игрового поля в шестнадцатеричном формате

Недавно я работал над проектом шестигранной настольной игры https://en.wikipedia.org/wiki/Hex_(board_game), который я нашел на Python. Однако из-за моих ржавых навыков кодирования у меня возникли серьезные проблемы с определением функции, которая принимает содержимое платы (которое хранится внутри массива N * N) и печатает их в правильном формате. Вывод должен выглядеть так:

Размер варьируется от 4 до 21, но с этим я справлюсь. Однако, учитывая, что в конечном итоге содержимое доски должно быть внутри шестиугольников (W для белой фигуры и B для черной), мне нужен был способ динамической печати содержимого доски. Для этого я использовал список (board_print), инициализированный в начале игры, который содержит строку для каждой строки и динамически изменяет свое содержимое в зависимости от сделанного хода (A3, B2 и т. д.):

# Function to change and print board after a move is played
def play(move, whose_turn):
    global turn
    color_string = 'W' if whose_turn == 0 else 'B'
    column = " ".join(re.findall("[a-zA-Z]+", move))
    row = int(re.findall(r'\d+', move)[0])
    # Check if there is a piece already placed there and move is in bounds
    if 0 <= row <= board_size and 0 <= col_index[column] <= board_size:
        if board[row - 1][col_index[column]] != 0:
            print('Error! There is a piece already placed there')
            return False
        else:
            board[row - 1][col_index[column]] = 1 if color_string == 'W' else 2
            moves.append((row, col_index[column]))
            # Modify board_print contents
            # 4-3 4-7 4-11 4-15...
            # 6-5 6-9 6-13    ...
            # A is 0 etc, board index to print index mapping is 1->4 2->6 3->8..,,

            for index, row_string in enumerate(board_print):
                if index == 2 * row + 2:
                    # Handle A differently because index starts from 0
                    if column == 'A':
                        new_string = row_string[:index] + color_string + row_string[index + 1:]
                    else:
                        # Because col_index starts from 0 , add 1 . then multiply the result by col index to match the
                        # print format
                        new_string = row_string[
                                 :index + (col_index[column] + 1) * col_index[
                                     column] + 2] + color_string + row_string[
                                                                   index + (
                                                                           col_index[
                                                                               column] + 1) *
                                                                   col_index[
                                                                       column] + 3:]
                    board_print[index] = new_string

        # Print board
        for row in board_print:
            print(row)
        print('Move played: ', move)
        moves_print.append(board_print)
        return True
    else:
        print('Error!Move is out of bounds')
        return False  # Don't change turn if move was illegal

который работал нормально:

Но потом я понял, что мне нужно реализовать функции undo() и load() (списки moves и move_print содержат все ходы, сделанные с соответствующими строками board_print), а это означает, что этот глупый подход больше не может работать. Мне нужен способ правильно сопоставить содержимое доски с шестнадцатеричной сеткой, которая печатается на консоли. Для справки: доска представлена ​​в виде списка списков длиной N, где каждый подсписок представляет собой строку (board[i][j] = 0 (нет фигуры), 1 (белый) или 2 (черный)). В настоящее время я инициализирую вывод и список board_print следующим образом:

column_names = '    A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T'
def start_board(n, load_game):
    # Append each row to the board print array
    rows_index = 0  # to index rows
    number_index = 0  # For printing out the row numbers in the board
    if not load_game: print(' ' * (n + 3) + 'W H I T E')
    board_print.append(' ' * (n + 3) + 'W H I T E')
    # Format the top rows properly with spaces
    if not load_game: print(column_names[:(4 + (3 * n + 4))])
    board_print.append(column_names[:(4 + (3 * n + 4))])
    if not load_game: print('    ' + '-   ' * n)
    board_print.append('    ' + '-   ' * n)
    if not load_game: print('   ' + '/ \\_' * (n - 1) + '/ \\')
    board_print.append('   ' + '/ \\_' * (n - 1) + '/ \\')
    # Loop enough times to print entire board. That is, 2 * n times
    for i in range(2 * n):
        if i == 0 or i % 2 == 0:
        # Even pattern
            if not load_game: print(
            ' ' * number_index + (str(rows_index + 1) + ' ' + '|   ' * n + '| ' + str(rows_index + 1)))
            board_print.append(
            ' ' * number_index + (str(rows_index + 1) + ' ' + '|   ' * n + '| ' + str(rows_index + 1)))
            rows_index += 1
        else:
            # Odd pattern
            # Check if it's final row for proper formatting
            if i == (2 * n) - 1:
                if not load_game: print(' ' * (number_index + 2) + '\\_/ ' * n)
                board_print.append(
                ' ' * (number_index + 2) + '\\_/ ' * n)
            else:
                if not load_game: print(' ' * (number_index + 2) + '\\_/ ' * n + '\\')
                board_print.append(
                ' ' * (number_index + 2) + '\\_/ ' * n + '\\')

        number_index += 1
    # Print final row (column names and BLACK)
    if not load_game: print(' ' * 2 * (n - 1) + column_names[:(4 + (3 * n + 4))])
    board_print.append(
    ' ' * 2 * (n - 1) + column_names[:(4 + (3 * n + 4))])
    moves_print.append(board_print)

Извините за плохое форматирование/отступ, это черновик, и у меня возникли проблемы с копированием кода из PyCharm.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
469
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, это веселое небольшое упражнение. Вот что я придумал

column_names = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

def print_board(board):
    rows = len(board)
    cols = len(board[0])
    indent = 0
    headings = " "*5+(" "*3).join(column_names[:cols])
    print(headings)
    tops = " "*5+(" "*3).join("-"*cols)
    print(tops)
    roof = " "*4+"/ \\"+"_/ \\"*(cols-1)
    print(roof)
    color_mapping = lambda i : " WB"[i]
    for r in range(rows):
        row_mid = " "*indent
        row_mid += " {} | ".format(r+1)
        row_mid += " | ".join(map(color_mapping,board[r]))
        row_mid += " | {} ".format(r+1)
        print(row_mid)
        row_bottom = " "*indent
        row_bottom += " "*3+" \\_/"*cols
        if r<rows-1:
            row_bottom += " \\"
        print(row_bottom)
        indent += 2
    headings = " "*(indent-2)+headings
    print(headings)

Это просто для печати доски в соответствии с вашими требованиями (0 для пустых ячеек, 1 для белых, 2 для черных).

board=[[0,0,0,0],[0,0,0,1],[0,0,0,2],[1,2,0,0],[0,2,1,0]]
print_board(board)

Дает следующий вывод

     A   B   C   D     
     -   -   -   -     
    / \_/ \_/ \_/ \    
 1 |   |   |   |   | 1 
    \_/ \_/ \_/ \_/ \  
   2 |   |   |   | W | 2
      \_/ \_/ \_/ \_/ \
     3 |   |   |   | B | 3 
        \_/ \_/ \_/ \_/ \
       4 | W | B |   |   | 4
          \_/ \_/ \_/ \_/ \
         5 |   | B | W |   | 5
            \_/ \_/ \_/ \_/
             A   B   C   D

Дайте мне знать, если что-то неясно

Работает нормально, спасибо! Можете ли вы уточнить, что делает строка «color_mapping = lambda i: «WB» [i]»? Я знаю, что делают лямбды, но меня смущает индекс

Tatami 22.12.2020 00:57

О да, это просто индексация строки «WB» в позиции i, что фактически дает вам символ, соответствующий содержимому ячейки (0 соответствует « », 1 соответствует «W», 2 соответствует «B»). Честно говоря, [' ','W','B'][i], вероятно, было бы немного более читабельно.

Cereal 22.12.2020 01:08

Другие вопросы по теме