康威的生命游戏问题

时间:2015-03-28 12:55:33

标签: python tkinter

这是我对Conway的生命游戏模拟的粗略实现。

LIVE = 1
DEAD = 0

def board(canvas, width, height, n):
    for row in range(n+1):
        for col in range(n+1):
            canvas.create_rectangle(row*height/n,col*width/n,(row+1)*height/n,(col+1)*width/n,width=1,fill='black',outline='green')                      

n = int(raw_input("Enter the dimensions of the board: "))
width = n*25
height = n*25

from Tkinter import *
import math

window=Tk()
window.title('Game of Life')

canvas=Canvas(window,width=width,height=height,highlightthickness=0)
canvas.grid(row=0,column=0,columnspan=5)

board = [[DEAD for row in range(n)] for col in range(n)]

rect = [[None for row in range(n)] for col in range(n)]


for row in range(n):
    for col in range(n):      
        rect[row][col] = canvas.create_rectangle(row*height/n,col*width/n,(row+1)*height/n,(col+1)*width/n,width=1,fill='black',outline='green') 

#canvas.itemconfigure(rect[2][3], fill='red') #rect[2][3] is rectangle ID

#print rect

f = open('filename','r') #filename is whatever configuration file is chosen that gives the step() function to work off of for the first time
for line in f:
    parsed = line.split()
    print parsed
    if len(parsed)>1:
        row = int(parsed[0].strip())
        col = int(parsed[1].strip())
        board[row][col] = LIVE
        board[row][col] = canvas.itemconfigure(rlist[row][col], fill='red')        

def surrounding(row,col):
    count = 0
    if board[(row-1) % n][(col-1) % n] == LIVE:
        count += 1
    if board[(row-1) % n][col % n] == LIVE:
        count += 1
    if board[(row-1) % n][(col+1) % n] == LIVE:
        count += 1
    if board[row % n][(col-1) % n] == LIVE:
        count += 1
    if board[row % n][(col+1) % n] == LIVE:
        count += 1
    if board[(row+1) % n][(col-1) % n] == LIVE:
        count +=1
    if board[(row+1) % n ][col % n] == LIVE:
        count += 1
    if board[(row+1) % n][(col+1) % n] == LIVE:
        count += 1
    print count
    return count

surrounding(1,1)


def round():
    board_copy = board
    for row in range(n):
        for col in range(n):
            if surrounding(row,col) == 3:
                board_copy[row][col] = LIVE
                board_copy[row][col] = canvas.itemconfigure(rect[row][col],fill='red')
            elif surrounding(row,col) > 3 or getNeighbors(row,col) < 2:
                board_copy[row][col] = DEAD
                board_copy[row][col] = canvas.itemconfigure(rect[row][col],fill='black')
    board = board_copy

def start():
    global alarm
    alarm = window.after(500,round)

def stop():
    window.after.cancel(alarm)

所以我有一个函数可以计算某个方格周围的平方数有多少LIVELIVE = 1)。

最初,所有方块都被初始化为DEAD。配置文件确定为哪个方块分配值LIVE。制作一个配置文件,使1,1处方形周围的8个方块返回值8,但无论配置或测试方块如何,我都会一致地返回值0。

更新:更改计数器从1开始,返回值为1.我猜我的功能实际上并没有计数(或读取板上周围方块的值),但我看不到为什么不会。

另外,对于我的step()功能,我需要一个能够制作电路板副本的功能,然后根据在原始电路板上执行的计数更改副本上的填充。如果原始板上的矩形具有3个具有LIVE值的矩形,则板复制上具有相同索引的矩形将具有LIVE值并变为红色。 DEAD也是如此,除了不同的情况。最后,复制的板(带有更改)替换原来的板,这样当我们再次运行该功能时,它将基于副本。

我假设board_copy = board足以制作副本;我该怎么写,以便在Tkinter窗口中执行该功能后,出现board_copy?

配置文件的格式为

rownum colnum
rownum colnum

所以我使用的配置文件,如果我想在第一轮中获得countNeighbors函数中的8(如果有效)将是:

0 0
0 1
0 2
1 0
1 2
2 0
2 1
2 2

1 个答案:

答案 0 :(得分:0)

  

我假设board_copy = board足以制作副本;

不,board_copy = board是不够的。这只是将名称board_copy绑定到与board完全相同的列表列表,即您在board_copy中更改的所有内容也会在board中更改。

相反,您可以使用copy模块中的deepcopy函数:

import copy
board_copy = copy.deepcopy(board)

或使用list-comprehension创建嵌套列表的深层副本:

board_copy = [[x for x in row] for row in board]

在方法结束时使用board = board_copy是可以的,因为在这里你只想将新板绑定到board。但请注意,您还需要在方法顶部添加global board以访问全局定义的board

另外,请注意您定义了一个函数boarddef board(...):和一个全局变量boardboard = [...])。后者将影响第一个,即您将无法使用board函数。您应该将函数重命名为def draw_board(...)

您的代码可能存在更多问题,但我无法执行它,因为它似乎不完整(start在哪里调用?)而且我不知道'filename'的内容。