Python Forum
conway's game of life / Single Responsibility Principle
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
conway's game of life / Single Responsibility Principle
#1
While i've finished my homework : write a simple game in less than 80 lines (see my previous topic, for which I got a C Dodgy , with comment that the key binding solution was ingenious, thnx Mekire )
The suggestions I got from both this forum and my instructor was to write the program logic up into more functions. Every function should have a single job. Although beyond my current homework goal, I've now added Class Square and Class Neighbours to the program. Does the program now seems logical ? (two while loops and break from first) or should it be broken up in even more classes/definitions ?
HCVL


( python 3.5 ; tkinter)
##################### GENERAL ############################
import time ; import random
from tkinter import *
window = Tk(); window.title("Conway's Game of Life")
canvas = Canvas(window, width=1200, height=900,bd=0, highlightthickness=0);canvas.pack() 
text_ = Text(window, height=3, width=30); text_.pack() 
text_.insert(END, "To MOVE use arrow keys. Press x to seed. r for random seeds.  f to finish")
##################### VARIABLES ###########################
keypressed = ""; SQident = 1; doublelist=[]    
Neighb=([-50,-50,-50,-50],[0,-50,0,-50],[+50,-50,+50,-50],[-50,0,-50,0],[+50,0,+50,0],[-50,+50,-50,+50],[0,+50,0,+50],[+50,+50,+50,+50])
moves={"Up":(0, -50),"Down":(0,50), "Left":(-50,0), "Right":(50,0)} 
sq = canvas.create_rectangle(50, 50, 100, 100, fill="grey")
##################### CLASS/DEF ###########################
def movesquare(event): # detect movement keys
    x,y=moves[event.keysym]
    canvas.move(SQident,x,y)         
def otherkey(event): #detect other keys pressed
    global keypressed 
    keypressed = event.keysym
    if keypressed == "x": # make new square
        Square(canvas.coords(SQident),"green")

class Square:#Sqa
    def __init__(self,x1y1x2y2,color):
        self.x1y1x2y2=x1y1x2y2
        self.color=color
        if (self.x1y1x2y2) not in doublelist:#create only if there is not one already
            canvas.create_rectangle(self.x1y1x2y2, fill = self.color)
            doublelist.append(self.x1y1x2y2)            
class Neighbours: #Nb
    def __init__(self,squarecoordinates):
        self.squarecoordinates=squarecoordinates
    def numberofneighbours(self):#CN
        return len(canvas.find_overlapping(self.squarecoordinates[0],self.squarecoordinates[1],self.squarecoordinates[2],self.squarecoordinates[3]))-1 # Number of objects surrounding
#################### Bind Keys ###########################        
bindings = {"<KeyPress-Up>" : movesquare, "<KeyPress-Down>": movesquare,
            "<KeyPress-Left>": movesquare, "<KeyPress-Right>": movesquare,
            "x": otherkey, "f": otherkey, "r": otherkey}
for binding in bindings:
    canvas.bind_all(binding, bindings[binding])    
#################### Create field #########################    
while 1:
    window.update();window.update_idletasks()
    if keypressed == "f": #finished
        canvas.delete(SQident)
        break 
    if keypressed == "r": #create 15 random squares
        canvas.delete(SQident)
        for x in range(15):
            x1=(random.randint(0,13)+random.randint(0,13))*50 # between 0-1200 is width
            y1=(random.randint(0,10)+random.randint(0,10))*50 # between 0-900 is height
            x2=x1+50; y2=y1+50
            Sqa = Square([x1,y1,x2,y2],"yellow");
            for y in range(3):#add 3 squares surrounding the previous 15
                ra=random.randint(0,7)
                x1ne=(Neighb[ra][0]);y1ne=(Neighb[ra][1]);x2ne=(Neighb[ra][2]);y2ne=(Neighb[ra][3])
                Sqa = Square([x1+x1ne,y1+y1ne,x2+x2ne,y2+y2ne],"pink")
        break
################### Start animation #########################
color=0; colsel=["Light Pink","Pale Violet Red","Deep Pink","Medium Violet Red","Orchid","Medium Orchid","Medium Purple","Dark Violet","Blue Violet","Purple"]
while 1:
    window.update();window.update_idletasks()
    livelist = canvas.find_all();createlist=[];killlist=[]
    if color == 10:
        color = 1
    for live in livelist: 
        x1=(canvas.coords(live)[0]); y1=(canvas.coords(live)[1]); x2=(canvas.coords(live)[2]); y2=(canvas.coords(live)[3]) 
        Nb=Neighbours([x1,y1,x2,y2]);CN=Nb.numberofneighbours()
        if (CN < 2) or (CN > 3): #dead too few/many neighbours
            killlist.append (canvas.find_enclosed(x1-10,y1-10,x2+10,y2+10)) 
        for Ne in Neighb:
            Encl=len(canvas.find_enclosed(x1+Ne[0]-10,y1+Ne[1]-10,x2+Ne[2]+10,y2+Ne[3]+10)) # enclosed=0 Neighbour is empty; =1 is present
            if Encl == 0: # Neighbour is empty. Possible new life->
                Coo=([x1+Ne[0],y1+Ne[1],x2+Ne[2],y2+Ne[3]])
                Nb=Neighbours(Coo);CN=Nb.numberofneighbours()+1
                if CN == 3: # has 3 neighbours thus new life
                    if Coo not in createlist: # prevent creating twice
                        createlist.append (Coo)                       
    for create in createlist:    #Start creating
        sq=canvas.create_rectangle(create, fill=(colsel[color]))           
    for kill in killlist:        #Start killling
        canvas.delete(kill)        
    for TI in range(0,4):        #Slow down:
        time.sleep(0.1) 
    color +=1
mainloop()
Reply


Messages In This Thread
conway's game of life / Single Responsibility Principle - by hanscvanleeuwen - Dec-11-2016, 12:18 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  While loop/half-life Miraclefruit 6 8,598 Mar-06-2017, 05:24 PM
Last Post: nilamo
  conway's game of life hanscvanleeuwen 17 18,158 Dec-09-2016, 04:05 PM
Last Post: hanscvanleeuwen
  Game of life using IDLE Informatics109 4 5,213 Oct-29-2016, 01:39 PM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020