Возможно, я бы начал с упрощения работы с сеткой. Взгляните на этот код, например:
grid_width = 6
grid_height = 6
grid_dimensions_product = (grid_width * grid_height)
if grid_dimensions_product % 2 != 0:
raise ValueError("Product of grid dimensions must be divisible by two!")
number_of_pairs = grid_dimensions_product // 2
print(f"For a {grid_width}x{grid_height} grid, you'll have {number_of_pairs} pairs.")
Вывод:
For a 6x6 grid, you'll have 18 pairs.
При такой настройке мы можем изменять размеры нашей сетки в любое время, когда мы хотим внести больше разнообразияв игру. Количество пар будет вычисляться на лету, что желательно, так как нам не нравятся жесткие настройки. Однако размеры сетки всегда должны умножаться вместе, чтобы получить продукт, который делится на два. Это требование, потому что в противном случае мы могли бы получить недостаточно пар (позиция в сетке, у которой нет подходящей пары) - например, сетка 5 x 5 будет иметь 12 пар, поэтому всего 24 числа. Вот почему здесь есть if-выражение. Здесь снова тот же код, но с недопустимыми размерами сетки:
grid_width = 5
grid_height = 5
grid_dimensions_product = (grid_width * grid_height)
if grid_dimensions_product % 2 != 0:
raise ValueError("Product of grid dimensions must be divisible by two!")
number_of_pairs = grid_dimensions_product // 2
print(f"For a {grid_width}x{grid_height} grid, you'll have {number_of_pairs} pairs.")
Вывод:
ValueError: Product of grid dimensions must be divisible by two!
Как только мы получим number_of_pairs
, мы можем сгенерировать список скрытых чисел,который мы позже будем использовать для заполнения нашей сетки:
hidden_numbers = list(range(1, number_of_pairs + 1)) * 2
print(hidden_numbers)
Помните, range
является эксклюзивным. Если мы хотим, чтобы числа 1-18 включительно, мы должны добавить +1 к эксклюзивному концу нашего диапазона. Мы превращаем диапазон в список и умножаем список на два, чтобы получить числа 1-18, дважды:
output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Теперь нам нужноперетасовать скрытые номера. В верхней части кода напишите:
from random import shuffle
Чтобы импортировать функцию shuffle
. Он принимает список в качестве аргумента и перетасовывает его содержимое на место.
hidden_numbers = list(range(1, number_of_pairs + 1)) * 2
shuffle(hidden_numbers)
hidden_number_iter = iter(hidden_numbers)
grid = []
# Generate the grid
for y in range(grid_height):
row = [next(hidden_number_iter) for x in range(grid_width)]
grid.append(row)
# Print the grid
for y in range(grid_height):
print(grid[y])
После перемешивания мы создаем итератор нашего списка hidden_numbers
. Это позволит нам легко получить «следующий» скрытый номер из нашего перемешанного списка. Если вы не знакомы с итераторами, вот краткий пример поведения итератора:
>>> my_list = ["A", "B", "C"]
>>> my_list_iterator = iter(my_list)
>>> next(my_list_iterator)
'A'
>>> next(my_list_iterator)
'B'
>>> next(my_list_iterator)
'C'
>>> next(my_list_iterator)
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
next(my_list_iterator)
StopIteration
>>>
Когда мы наконец напечатаем нашу сетку, она будет выглядеть примерно так:
[9, 1, 2, 14, 18, 8]
[15, 4, 3, 16, 16, 2]
[12, 11, 6, 1, 17, 13]
[17, 7, 5, 5, 13, 4]
[6, 12, 10, 14, 18, 7]
[3, 15, 10, 9, 11, 8]
КаждыйПри перезапуске сценария список скрытых номеров будет отображаться в другом порядке. Вот еще раз весь сценарий:
from random import shuffle
grid_width = 6
grid_height = 6
grid_dimensions_product = (grid_width * grid_height)
if grid_dimensions_product % 2 != 0:
raise ValueError("Product of grid dimensions must be divisible by two!")
number_of_pairs = grid_dimensions_product // 2
hidden_numbers = list(range(1, number_of_pairs + 1)) * 2
shuffle(hidden_numbers)
hidden_number_iter = iter(hidden_numbers)
grid = []
# Generate the grid
for y in range(grid_height):
row = [next(hidden_number_iter) for x in range(grid_width)]
grid.append(row)
# Print the grid
for y in range(grid_height):
print(grid[y])