Y
Y
Yura Khlyan2015-06-12 17:45:03
Python
Yura Khlyan, 2015-06-12 17:45:03

What's wrong with the game of life?

Good time of the day.
I recently sat down to learn Python and so I decided to create a game "Life" (link Wiki ). But something does not work, or rather everything works, but it is not true. If someone has the time and desire to look at my code, you are welcome.
I will be very grateful for the help, and also for constructive criticism of the code.
Here is my code:

def neighbors(row, col, matrix):
    """returns all neighbors of the cell as a list"""
    
    n = len(matrix)
    m = len(matrix[0])
    return [matrix[r][c] for r in range(max(row - 1, 0), min(n, row + 2)) for c in range(max(col - 1, 0), min(m, col + 2)) if r != row or c != col]


def add_zero_frame(matrix):
    """adds frame of zeros around matrix"""
    
    n = len(matrix)
    m = len(matrix[0])
    res = 


def game_life(cells, generations):
    start = add_zero_frame(cells) 
    
    for gen in range(generations):
        end = [row[:] for row in start[:]]
        for i in range(len(start)):
            for j in range(len(start[0])):
                neighb = sum(neighbors(i, j, start))
                if start[i][j]:
                    if  2 <= neighb <= 3:
                        end[i][j] = 1
                    else:
                        end[i][j] = 0
                else:
                    if neighb == 3:
                        end[i][j] = 1
        start = add_zero_frame(find_matrix(end))
    
    return find_matrix(start)

P.S. Sorry for my bad Russian and Python)
=========================UPDATE============ ==============
An error was found in the line:
return  for row in matrix[min_row:max_row + 1]]

This line returned the wrong data structure. It should be like this:
return [row[min_col:max_col + 1] for row in matrix[min_row:max_row + 1]].

Answer the question

In order to leave comments, you need to log in

2 answer(s)
O
Oxoron, 2015-06-12
@Oxoron

Не совсем понял Ваш набор методов (функций).
По факту, вся игра на поле nxn состоит из следующих этапов
1. Создаем матрицу (n+2, n+2), все элементы нулевые.
2. Заполняем некоторые клетки (не крайние) единицами, создавая начальную популяцию.
3. Делаем ходы по следующему алгоритму:
3.1 Сначала для каждой не крайней клетки считаем кол-во соседей (результаты сохраняем в отдельную матрицу).
3.2 В зависимости от числа соседей обращаем клетку в ноль или единицу.
То есть, Вам нужны методы:
1. Заполнить всё поле нулями.
2. Проверка поля на "крайность".
3. Метод создания начальной популяции.
4. Метод подсчета числа соседей.
5. Метод изменения значения клетки в зависимости от числа соседей.
Методы 2, 3, 4, 5 покрываем модульными тестами (Unit-tests)
Самая частая ошибка в реализации заключается в том, что клетку изменяют сразу после подсчета её соседей. Если не ошибаюсь, она у Вас есть.
Плюс, в методе find_matrix вы max_col присваиваете 0, а min_col присваиваете размер массива. Наверное, стоило сделать наоборот.
Непонятно, чего Вы пытаетесь добиться строкой res[i][j] = matrix[i-1][j-1] в Add_zero_frame.

B
bobrovskyserg, 2015-06-12
@bobrovskyserg

Неудачные структуры данных, всё громоздкое.
Поле обязательно растёт каждый шаг - плохо.

from collections import Counter

def display(t, gen):
    sz = 10
    sz2 = sz * 2
    space = [["  "] * sz2 for i in range(sz2)]
    for x, y in gen:
        if sz > x >= -sz <= y < sz:
            space[y + sz][x + sz] = "()"
    for row in space:
        print(''.join(row))
    print("{:>3n}".format(t), "--" * sz2)

def game_life(cells, generations):
    gen = set((x, y) for y, row in enumerate(cells) for x, cell in enumerate(row) if cell)
    for t in range(generations):
        display(t, gen)
        ngh = Counter((x + i, y + j) for x, y in gen for i in range(-1, 2) for j in range(-1, 2))
        gen = set(xy for xy, cnt in ngh.items() if cnt == 3 or cnt == 4 and xy in gen)

# game_life([[1, 1, 1]], 5) # палка
# game_life([[1, 1], [1, 1]], 5) # квадрат
game_life([[1, 1, 1], [0, 0, 1], [0, 1, 0]], 40)  # планер

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question