2016-01-30 2 views
1

Я начал программировать и пробовал «игру жизни», и все хорошо на досках 20x20, но если я беру размеры до 100 или более, то после 100 поколений программа нуждается в 500 мб RAM и 25% моего процессора (и для каждого поколения требуется больше), что, я думаю, плохо. поэтому я думаю, у меня есть логическая ошибка, которая занимает больше ОЗУ каждого поколения. разместить код нижеИгра жизни python - слишком много ресурсов

import time 
from tkinter import * 

class cell(object): 
    def __init__(self,lives): 
     self.lives = lives 

    def set(self, alive): 
     self.lives=alive 


class grid(object): 
    gen = 0 
    def __init__(self,height,width,file=None): 
     if(file is None): 
      self.root=Tk() 
      self.root.title("Game of Life") 
      self.canvas=Canvas(self.root,height =height*6, width=width*6) 
      self.canvas.grid(row=0,column=0) 
      self.matrix=[[cell(False) for x in range(width)] for y in range(height)] 
      self.next_grid = [[cell(False) for x in range(width)] for y in range(height)] 
      self.width= width 
      self.height=height 
     else: 
      pass 
      #comes later with fileinput 

    def print_grid(self): 
     for i in range(self.height): 
      for j in range(self.width): 
       if(self.matrix[i][j].lives): 
        pass 
        self.canvas.create_rectangle(j*6,i*6,j*6+4,i*6 + 4,fill="black") 
       elif(not self.matrix[i][j].lives): 
        self.canvas.create_rectangle(j*6,i*6,j*6+5,i*6 + 5,fill="white",width=0)#invalid command name ".9727696"?! 

    def set_cell(self, height,width,live): 
     self.matrix[height][width].set(live) 

    def count_neighbours(self,height,width): 
     counter = 0 
     for hi in range(height-1,height+2): 
      for wi in range(width -1,width+2): 
       if(hi < self.height and hi > -1 and wi < self.width and wi > -1): 
        if(self.matrix[hi][wi].lives): 
         counter = counter +1 

     if(self.matrix[height][width].lives): 
      counter = counter -1 
     return counter 

    def does_survive(self,i,j): 
     neighbours = self.count_neighbours(i,j) 
     result =False 
     if(self.matrix[i][j].lives): 
      if(neighbours == 2 or neighbours == 3): 
       result = True 
     elif (neighbours == 3): 
      result = True 
     return result 


    def next_gen(self): 

    self.next_grid = [[cell(False) for x in range(self.width)] for y in range(self.height)] 
     self.gen = self.gen +1 
     for i in range(self.height): 
      for j in range(self.width): 
       self.next_grid[i][j].set(self.does_survive(i,j)) 
     self.matrix = self.next_grid 


def test(): 
    cell1=cell(True) 
    cell2=cell(False) 
    cell2.set(True) 
    place=grid(150,150) 
    place.set_cell(50,60,True) 
    place.set_cell(51,60,True) 
    place.set_cell(51,59,True) 
    place.set_cell(52,60,True) 
    place.set_cell(50,61,True) 
    for i in range(1000): 
     place.print_grid() 
     #time.sleep(0.01) 
     place.next_gen() 
     place.canvas.update() 
    place.root.mainloop() 
    test() 

это первый раз я использую графики в целом, и да ... я надеюсь, что вы можете мне помочь: D

редактировать: я нашел ошибку и тружусь на лучшую производительность, но теперь у меня проблема, что поколения странны, если я не очистку сетки next_gen в ... вы можете мне помочь?

+8

Ваш код print_grid создает прямоугольники, и они никогда не удаляются, вы просто складываете новые поверх старых. Рассмотрим скорее наличие массива прямоугольников (константу) и только изменение их цветов (или удаление старых на каждой итерации). – lejlot

+0

@lejlot: Это уже может быть ответ. – Haini

+0

Спасибо, я использовал self.canvas.delete («все») перед печатью новой сетки, и это помогает, но теперь поколения выглядят немного странно ... вы могли бы посмотреть, правильно ли написаны мои правила в do_survive? – KuSpa

ответ

0

Когда вы создаете сетку размером 150x150, вы создаете 22 500 элементов холста. Каждый раз, когда вы звоните print_grid, вы создаете другой 22,500 элементов на холсте. Поскольку вы звоните print_grid 1000 раз, вы создаете более 22 миллионов элементы на холсте. Хотя холст довольно мощный, он не может справиться с этим множеством элементов.

Вы должны создать сетку ровно один раз, а затем каждый раз, когда вы вызываете print_grid, вы должны просто изменить уже созданные прямоугольники. Когда вы создаете прямоугольник, он возвращает id. Затем вы можете передать этот id в canvas itemconfigure метод изменения свойств этих элементов.

Смежные вопросы