# L-34 MCS 260 Wed 6 Apr 2016 : game.py
"""
This script gives a plain implementation of Conway's game of life.
"""

from random import randint

def random_grid(rows, cols):
    """
    Returns a list of rows.
    Every row has as many random booleans
    as the value of cols.
    """
    result = []
    for _ in range(rows):
        result.append([bool(randint(0, 1)) \
           for _ in range(cols)]) 
    return result

def write(grid):
    """
    Writes the lists of lists of booleans
    in grid using 0 for False and 1 for True.
    """
    for row in grid:
        for item in row:
            print(' %d' % item, end='') 
        print('')

def neighbors(grid, i, j):
    """
    Returns the number of live cells 
    next to grid[i][j].
    """
    cnt = 0
    if i > 0:
        if grid[i-1][j]:
            cnt = cnt + 1
        if j > 0:
            if grid[i-1][j-1]:
                cnt = cnt + 1
        if j < len(grid[i-1])-1:
            if grid[i-1][j+1]:
                cnt = cnt + 1
    if i < len(grid)-1:
        if grid[i+1][j]:
            cnt = cnt + 1
        if j > 0:
            if grid[i+1][j-1]:
                cnt = cnt + 1
        if j < len(grid[i+1])-1:
            if grid[i+1][j+1]:
                cnt = cnt + 1
    if j > 0:
        if grid[i][j-1]:
            cnt = cnt + 1
    if j < len(grid[i])-1:
        if grid[i][j+1]:
            cnt = cnt + 1
    return cnt

def write_neighbors(grid):
    """
    Writes the number of neighbors for each cell in mat.
    """
    print('neighbors :')
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            print(' %d' % neighbors(grid, i, j), end='')
        print('')

def update(grid):
    """
    Applies the rule of the game of life to grid
    and returns a new grid.
    """
    result = [[False for _ in row] for row in grid]
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            nbr = neighbors(grid, i, j)
            if grid[i][j]:
                if nbr < 2 or nbr > 3:
                    result[i][j] = False
                else:
                    result[i][j] = True
            else:
                if nbr == 3:
                    result[i][j] = True
    return result

def main():
    """
    Prompts for dimensions and runs the game of life
    as long as the user wants to continue.
    """
    nrows = int(input('give the number of rows : '))
    ncols = int(input('give the number of columns : '))
    grid = random_grid(nrows, ncols)
    print('Initial State :')
    write(grid)
    cnt = 0
    while True:
        ans = input('continue ? (y/n) ')
        if ans != 'y':
            break
        grid = update(grid)
        cnt = cnt + 1
        print('State %d of Grid :' % cnt)
        write(grid)

if __name__ == "__main__":
    main()
