class GameController: def __init__(self, mode, dinos_per_gen = 10): #can be either a train or a game self.mode = mode self.master = Tk() self.width = 800 self.height = 800 self.canvas = Canvas(self.master, width=800, height=800, bg='#fff') self.infoPanel = Frame(self.master, bg='#fff') self.colisionMonitor = ColisionMonitor(self.master, self.canvas, self.stopGround) self.dinos = [] self.dinosOnScreen = 0 self.obstacles = [] self.colisionMonitor = None self.obstacleGenerator = None self.initialDinoNum = dinos_per_gen self.game_params = {'distance': 100, 'speed': 25, 'height': 0, 'width': 50} self.master.bind('<r>', self.restart) self.scoresCheckPoint = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 80, 110, 140, 200, 250] self.imgs_pil_ground = [ Image.open("./assets/ground.png"), Image.open("./assets/ground-1.png")] self.ground = ImageTk.PhotoImage(self.imgs_pil_ground[0]) self.ground_1 = ImageTk.PhotoImage(self.imgs_pil_ground[1]) # display image on canvas self.ground_id = self.canvas.create_image(0, 695, image=self.ground, anchor=NW) self.ground_id_1 = self.canvas.create_image(400, 695, image=self.ground_1, anchor=NW) self.ground_id_2 = self.canvas.create_image(800, 695, image=self.ground, anchor=NW) self.ground_animation_id = None self.interfaceObject = {} self.score = 0 self.record = 0 try: general_data = np.load('data/general/game.npy') self.general_record = general_data[0] except IOError as err: self.general_record = 0 np.save('data/general/game.npy', np.array([0])) self.n_generations = 0 self.game_modes = { "train": "train", "game": "game", "simulation": "simulation" } self.nn_elements = { 'neurons': [], 'connections': [] } def saveGeneralRecord(self): if(self.general_record<=self.score): print(self.general_record) np.save('data/general/game.npy', np.array([self.general_record])) def prepareInterface(self): #l1.grid(row = 0, column = 0, sticky = W, pady = 2) self.infoPanel.pack(fill='x') speedLabel = Label(self.infoPanel, text="Speed: "+str(self.game_params['speed'])+"/"+str(len(self.scoresCheckPoint)), bg='#fff') speedLabel.grid(row=0, column=0, pady=10, sticky = W) self.interfaceObject['speedLabel'] = speedLabel dinosAlive = Label(self.infoPanel, text="Dinos: "+str(self.initialDinoNum), bg='#fff') dinosAlive.grid(row=1, column=0, pady=10, sticky = W) self.interfaceObject['dinosAlive'] = dinosAlive scoreLabel = Label(self.infoPanel, text="Score: "+str(self.score), bg='#fff') scoreLabel.grid(row=2, column=0, pady=10, sticky = W) self.interfaceObject['score'] = scoreLabel record = Label(self.infoPanel, text="Record: "+str(self.record), bg='#fff') record.grid(row=0, column=1, padx=20, pady=10, sticky = W) self.interfaceObject['record'] = record n_generation = Label(self.infoPanel, text="Generation: "+str(self.n_generations), bg='#fff') n_generation.grid(row=1, column=1, padx=20, pady=10, sticky = W) self.interfaceObject['n_generation'] = n_generation general_record = Label(self.infoPanel, text="General record: "+str(self.general_record), bg='#fff') general_record.grid(row=2, column=1, padx=20, pady=10, sticky = W) self.interfaceObject['general_record'] = general_record weights = np.load('data/brain/best_w.npy') weights_flatten = weights.flatten() biases = np.load('data/brain/best_b.npy').flatten() self.nn_elements = draw_nn(width=self.width, height = self.height, nn_shape=[5, 2], weights = weights, weights_flatten = weights_flatten,biases = biases, canvas = self.canvas, padding=[50, 10, 400, 300], neuron_size=10) def animateGround(self): self.canvas.move(self.ground_id, -9, 0) self.canvas.move(self.ground_id_1, -9, 0) self.canvas.move(self.ground_id_2, -9, 0) #[left top right bottom] if(self.canvas.coords(self.ground_id)[0]<-400): self.canvas.move(self.ground_id, 1200, 0) if(self.canvas.coords(self.ground_id_1)[0]<-400): self.canvas.move(self.ground_id_1, 1200, 0) if(self.canvas.coords(self.ground_id_2)[0]<-400): self.canvas.move(self.ground_id_2, 1200, 0) self.ground_animation_id = self.canvas.after(20, self.animateGround) def run(self): if(self.mode == self.game_modes["game"]): self.prepareInterface() self.canvas.pack() self.prepareGame() self.animateGround() mainloop() elif(self.mode == self.game_modes["train"]): self.prepareInterface() self.canvas.pack() self.prepareTrain() self.animateGround() mainloop() elif(self.mode == self.game_modes["simulation"]): self.prepareInterface() self.canvas.pack() self.prepareSimulation() self.animateGround() mainloop() def decreaseDinos(self): self.dinosOnScreen-=1 self.colisionMonitor.dinosOnScreen = self.dinosOnScreen self.updateLabels() def updateGameParams(self, distance=None, speed=None, height=None, width=None): if(not distance is None): self.game_params['distance'] = distance if(not speed is None): self.game_params['speed'] = speed if(not height is None): self.game_params['height'] = height if(not width is None): self.game_params['width'] = width #print(self.game_params) def updateLabels(self): self.interfaceObject['speedLabel'].config(text="Speed: "+str(25 - self.game_params['speed'])+"/"+str(len(self.scoresCheckPoint))) self.interfaceObject['dinosAlive'].config(text="Dinos: "+str(self.dinosOnScreen)+"/"+str(self.initialDinoNum)) self.interfaceObject['score'].config(text="Score: "+str(self.score)) self.interfaceObject['record'].config(text="Record: "+str(self.record)) self.interfaceObject['n_generation'].config(text="Generation: "+str(self.n_generations)) self.interfaceObject['general_record'].config(text="General record: "+str(self.general_record)) # create game elements def prepareGame(self): self.dinos.append(Dino(self.master, self.canvas, DinoBrain(), self.game_params, self.decreaseDinos, mode=self.mode, game_modes=self.game_modes, color="black")) self.dinos.append(Dino(self.master, self.canvas, DinoBrain(), self.game_params, self.decreaseDinos, mode="train", game_modes=self.game_modes, color="red")) self.dinos[-1].brain.load() self.dinosOnScreen = 2 self.obstacleGenerator = ObstacleGenerator(self.master, self.canvas, self.updateGameParams, self.increaseScore) self.obstacleGenerator.updateObstaclesSpeed(self.game_params['speed']) self.obstacleGenerator.run() self.colisionMonitor = ColisionMonitor(self.master, self.canvas, self.stopGround, self.dinos, self.obstacleGenerator.obstacles, self.dinosOnScreen) self.colisionMonitor.run() # create train elements def prepareTrain(self): for i in range(self.initialDinoNum): self.dinosOnScreen+=1 dino = Dino(self.master, self.canvas, DinoBrain(), self.game_params, self.decreaseDinos, mode=self.mode, game_modes=self.game_modes) dino.brain.load() self.dinos.append(dino) for dino in self.dinos[1:]: dino.brain.mutate() self.obstacleGenerator = ObstacleGenerator(self.master, self.canvas, self.updateGameParams, self.increaseScore) self.obstacleGenerator.updateObstaclesSpeed(self.game_params['speed']) self.obstacleGenerator.run() self.colisionMonitor = ColisionMonitor(self.master, self.canvas, self.stopGround, self.dinos, self.obstacleGenerator.obstacles, self.dinosOnScreen) self.colisionMonitor.run() # create simulation elements def prepareSimulation(self): for i in range(self.initialDinoNum): self.dinosOnScreen+=1 dino = Dino(self.master, self.canvas, DinoBrain(), self.game_params, self.decreaseDinos, mode=self.mode, game_modes=self.game_modes) self.dinos.append(dino) self.obstacleGenerator = ObstacleGenerator(self.master, self.canvas, self.updateGameParams, self.increaseScore) self.obstacleGenerator.updateObstaclesSpeed(self.game_params['speed']) self.obstacleGenerator.run() self.colisionMonitor = ColisionMonitor(self.master, self.canvas, self.stopGround, self.dinos, self.obstacleGenerator.obstacles, self.dinosOnScreen) self.colisionMonitor.run() def stopGround(self): print("New gen") if(self.general_record<=self.score): self.general_record = self.score np.save('data/general/game.npy', np.array([self.general_record])) self.n_generations+=1 if(self.record<self.score): self.record = self.score self.resetGameParams() self.canvas.after_cancel(self.ground_animation_id) brain_index = None for i, dino in enumerate(self.dinos): if(dino.best): brain_index = i print("best: ", brain_index) if(self.mode == "train"): dino.brain.save() self.obstacleGenerator.updateObstaclesSpeed(self.game_params['speed']) self.obstacleGenerator.reset() for i, dino in enumerate(self.dinos): dino.reset() if(i != brain_index): dino.setBrain(self.dinos[brain_index].brain.getClone(True)) for i, dino in enumerate(self.dinos): dino.game_params = self.game_params dino.animate() dino.run() self.score = 0 self.dinosOnScreen = len(self.dinos) self.colisionMonitor.dinosOnScreen = self.dinosOnScreen self.updateLabels() self.animateGround() self.colisionMonitor.run() self.obstacleGenerator.run() def increaseScore(self, score): self.score+=score if(self.score in self.scoresCheckPoint): self.game_params['speed']-=1 self.obstacleGenerator.updateObstaclesSpeed(self.game_params['speed']) if(self.score==350 and self.mode == self.game_modes['train']): for dino in self.dinos: if(dino.onScreen): dino.brain.save() if(self.general_record<self.score): self.general_record = self.score self.updateLabels() def resetGameParams(self): self.game_params = {'distance': 100, 'speed': 25, 'height': 0, 'width': 50} def restart(self, event): for dino in self.dinos: dino.reset() self.resetGameParams() self.animateGround() self.obstacleGenerator.reset() self.obstacleGenerator.run()
class Main(object): def __init__(self, master): self.master = master self.master.title('CONWAY\'S GAME OF LIFE') self.wid = 910 self.hei = 680 smw = self.master.winfo_screenwidth() // 2 smh = self.master.winfo_screenheight() // 2 tplft = (smw - self.wid // 2, smh - self.hei // 2) self.master.geometry(f'{self.wid}x{self.hei}+{tplft[0]}+{tplft[1]}') self.master.resizable(width=False, height=False) # create a main field self.can_width = 800 self.can_height = 640 # variable to continue with right number generation after stop game self.global_gen = None # start self.cell = 4 self.start_cell = 0 self.live = set() # trick for rigth after_cancel self.game_on = (0, 0) # population self.score = 0 # variable for max cells self.max_score = 0 # for change speed self.timer = 15 # cursor for place ships self.cur = None self.invert = None self.on = (0, 0) self.sample = {'1': 10, '2': 5, '4': 3} # erase seeds self.erase = True # images for ships self.glider = PhotoImage(file='data/1_ship.gif') self.glider_in = PhotoImage(file='data/1_ship_in.gif') self.lss = PhotoImage(file='data/2_lss.gif') self.lss_in = PhotoImage(file='data/2_lss_in.gif') self.sui = PhotoImage(file='data/3_sucide.gif') self.sui_in = PhotoImage(file='data/3_sucide_in.gif') self.f5 = PhotoImage(file='data/4_f5.gif') self.f5_in = PhotoImage(file='data/4_f5_in.gif') self.penta = PhotoImage(file='data/5_penta.gif') self.penta_in = PhotoImage(file='data/5_penta_in.gif') self.patern = PhotoImage(file='data/6_patern.gif') self.patern_in = PhotoImage(file='data/6_patern_in.gif') self.fireship = PhotoImage(file='data/7_fireship.gif') self.fireship_in = PhotoImage(file='data/7_fireship_in.gif') # GUI frameWin = Frame(master, bg='white', borderwidth=0) frameWin.pack(side=TOP, fill=BOTH) frameCanv = Frame(frameWin, bg='white', borderwidth=0) frameCanv.pack(side=RIGHT, fill=BOTH) # main canvas self.window = Canvas(frameCanv, width=self.can_width, height=self.can_height, cursor='plus', bg='white', bd=0, highlightthickness=0) self.window.pack(side=TOP) self.w_field = self.can_width // self.cell self.h_field = self.can_height // self.cell print(self.w_field, self.h_field) self.cell_matrix = PhotoImage(width=self.can_width, height=self.can_height) hor_line = '{' + ' '.join(['#EEEEEE'] * self.can_width) + '}' self.cell_matrix.put(' '.join([hor_line] * self.can_height)) # make copy self.original = self.cell_matrix.copy() self.cell_img = self.window.create_image(0, 0, image=self.cell_matrix, anchor=NW) # side menu for images frameBorderCr = Frame(frameWin, bg='white', bd=3) frameBorderCr.pack(side=LEFT, fill=BOTH) mes_creat = Label(frameBorderCr, text='CREATURE', height=2, bg='white') mes_creat.pack(side=TOP, fill=X) frameCreat = Frame(frameBorderCr, bg='#CCCCCC', bd=2) frameCreat.pack(side=TOP, fill=BOTH) self.creat = Canvas(frameCreat, height=596, bg='white', highlightthickness=0) self.creat.pack(side=TOP, expand=YES, fill=Y) # images for ships self.creat.create_image(48, 25, image=self.glider) self.creat.create_image(48, 73, image=self.lss) self.creat.create_image(48, 126, image=self.sui) self.creat.create_image(48, 175, image=self.f5) self.creat.create_image(48, 256, image=self.penta) self.creat.create_image(48, 349, image=self.patern) self.creat.create_image(49, 485, image=self.fireship) # menu for counters frameMB = Frame(frameCanv, bg='white', borderwidth=0) frameMB.pack(side=BOTTOM, fill=BOTH) message = Label(frameMB, text='SQUARE UNIVERSUM ', height=2, bg='white') message.pack(side=LEFT, fill=X) # cell part frameBor1 = Frame(frameMB, bg='#CCCCCC', borderwidth=2) frameBor1.pack(side=LEFT) name_pop = Label(frameBor1, text='CELL') name_pop.pack(side=LEFT) self.scrPop = Label(frameBor1, text=0, width=7) self.scrPop.pack(side=RIGHT) # separator sep = Frame(frameMB, width=4) sep.pack(side=LEFT) # cycle part frameBor2 = Frame(frameMB, bg='#CCCCCC', borderwidth=2) frameBor2.pack(side=LEFT) name_gen = Label(frameBor2, text='CYCLE') name_gen.pack(side=LEFT) self.scrGen = Label(frameBor2, text=0, width=6) self.scrGen.pack(side=RIGHT) # buttons self.button_Start = Button(frameMB, text='START', width=6, command=self.start_game) self.button_Start.pack(side=RIGHT, padx=3) self.button_Stop = Button(frameMB, text='STOP', width=6, command=self.stop_game) self.button_Stop.pack(side=RIGHT, padx=3) self.button_Clear = Button(frameMB, text='CLEAR', width=6, command=self.clear) self.button_Clear.pack(side=RIGHT, padx=3) blockSpeed = Frame(frameMB, padx=25) blockSpeed.pack(side=RIGHT) button_Fast = Button(blockSpeed, text='>>', width=3, command=self.fast) button_Fast.pack(side=RIGHT, padx=3) butSpeedFrame = Frame(blockSpeed, bg='#CCCCCC', bd=2) butSpeedFrame.pack(side=RIGHT) self.speedVal = Label(butSpeedFrame, text=int(self.timer), width=3) self.speedVal.pack(side=RIGHT) button_Slow = Button(blockSpeed, text='<<', width=3, command=self.slow) button_Slow.pack(side=RIGHT, padx=3) self.window.bind('<B1-Motion>', self.motion_paint) self.window.bind('<ButtonPress-1>', self.start_paint) self.window.bind('<ButtonPress-2>', self.clear_side_menu) self.window.bind('<Leave>', self.clear_side_menu) self.creat.bind('<ButtonPress-1>', self.creatures) self.master.mainloop() def motion_paint(self, event): self.erase = False xcell = int(event.x) ycell = int(event.y) xcell = int(xcell // self.cell) ycell = int(ycell // self.cell) self.black_cell(ycell, xcell) def start_paint(self, event): self.erase = True self.fir_x = event.x // self.cell self.fir_y = event.y // self.cell self.black_cell(self.fir_y, self.fir_x) def creatures(self, event): # I can realize with standart buttons and compound x = int(event.x) y = int(event.y) if self.invert: # clear menu with figures self.clear_side_menu() else: self.on = (0, 0) if x in range(32, 65) and y in range(10, 45): self.creat_but(x, y, 32, 65, 10, 45, 48, 25, self.glider_in, self.glider, self.ship_1, SE) if x in range(20, 75) and y in range(54, 96): self.creat_but(x, y, 20, 75, 54, 96, 48, 73, self.lss_in, self.lss, self.ship_2, SE) if x in range(32, 65) and y in range(107, 149): self.creat_but(x, y, 32, 65, 107, 149, 48, 126, self.sui_in, self.sui, self.fig_1, S) if x in range(32, 65) and y in range(161, 192): self.creat_but(x, y, 32, 65, 161, 192, 48, 175, self.f5_in, self.f5, self.fig_2, CENTER) if x in range(32, 65) and y in range(203, 313): self.creat_but(x, y, 32, 65, 203, 313, 48, 256, self.penta_in, self.penta, self.fig_3, S) if x in range(21, 75) and y in range(323, 377): self.creat_but(x, y, 21, 75, 323, 377, 48, 349, self.patern_in, self.patern, self.fig_4, SE) if x in range(6, 93) and y in range(388, 588): self.creat_but(x, y, 6, 93, 388, 588, 48, 485, self.fireship_in, self.fireship, self.ship_3, S) def creat_but(self, x, y, fnx, lnx, fny, lny, x_im, y_im, img_in, img, bind, al): self.window.unbind('<B1-Motion>') if self.cur: self.window.delete(self.cur) self.cur = None if (self.on[0] not in range(fnx, lnx) or self.on[1] not in range(fny, lny)): self.invert = self.creat.create_image(x_im, y_im, image=img_in) self.window.bind('<ButtonPress-1>', bind) self.on = (x, y) # size of pictures depend of self.cell size = self.sample[str(self.cell)] img = img.subsample(size, size) self.window.bind( '<Motion>', lambda event, i=img, a=al: self.cursor(event, i, a)) def cursor(self, event, img, align): self.erase = False self.window.configure(cursor='none') if not self.cur: self.cur = self.window.create_image(event.x, event.y, image=img, anchor=align) self.window.coords(self.cur, (event.x, event.y)) def ship_1(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) pack = [(xcell, ycell), (xcell - 1, ycell), (xcell, ycell - 1), (xcell, ycell - 2), (xcell - 2, ycell - 1)] for i in pack: self.black_cell(i[0], i[1]) def ship_2(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 3, ycell - 1) self.black_cell(xcell, ycell - 1) self.black_cell(xcell, ycell - 2) self.black_cell(xcell, ycell - 3) self.black_cell(xcell - 1, ycell - 4) self.black_cell(xcell - 3, ycell - 4) def fig_1(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell, ycell - 1) self.black_cell(xcell - 1, ycell - 1) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 3, ycell - 1) self.black_cell(xcell - 3, ycell - 2) def fig_2(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 1, ycell - 1) self.black_cell(xcell - 2, ycell + 1) def fig_3(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 2, ycell + 1) self.black_cell(xcell - 3, ycell) self.black_cell(xcell - 4, ycell) self.black_cell(xcell - 5, ycell) self.black_cell(xcell - 6, ycell) self.black_cell(xcell - 7, ycell - 1) self.black_cell(xcell - 7, ycell + 1) self.black_cell(xcell - 8, ycell) self.black_cell(xcell - 9, ycell) def fig_4(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 4, ycell) self.black_cell(xcell - 4, ycell - 2) self.black_cell(xcell - 4, ycell - 3) self.black_cell(xcell - 4, ycell - 4) self.black_cell(xcell - 3, ycell - 4) self.black_cell(xcell - 1, ycell - 3) self.black_cell(xcell - 1, ycell - 2) self.black_cell(xcell, ycell - 2) self.black_cell(xcell, ycell - 4) def ship_3(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 1, ycell + 1) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 2, ycell + 2) self.black_cell(xcell - 3, ycell + 2) self.black_cell(xcell - 4, ycell + 2) self.black_cell(xcell - 3, ycell + 3) self.black_cell(xcell - 6, ycell + 1) self.black_cell(xcell - 7, ycell) self.black_cell(xcell - 9, ycell) self.black_cell(xcell - 9, ycell + 1) self.black_cell(xcell - 10, ycell + 1) self.black_cell(xcell - 10, ycell + 2) self.black_cell(xcell - 11, ycell + 3) self.black_cell(xcell - 13, ycell + 3) self.black_cell(xcell - 14, ycell + 3) self.black_cell(xcell - 14, ycell + 1) self.black_cell(xcell - 15, ycell) self.black_cell(xcell - 16, ycell) self.black_cell(xcell - 17, ycell + 1) self.black_cell(xcell - 17, ycell + 2) self.black_cell(xcell, ycell - 1) self.black_cell(xcell - 1, ycell - 1) self.black_cell(xcell - 1, ycell - 2) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 2, ycell - 3) self.black_cell(xcell - 3, ycell - 3) self.black_cell(xcell - 3, ycell - 4) self.black_cell(xcell - 4, ycell - 3) self.black_cell(xcell - 6, ycell - 2) self.black_cell(xcell - 7, ycell - 1) self.black_cell(xcell - 9, ycell - 1) self.black_cell(xcell - 9, ycell - 2) self.black_cell(xcell - 10, ycell - 2) self.black_cell(xcell - 10, ycell - 3) self.black_cell(xcell - 11, ycell - 4) self.black_cell(xcell - 13, ycell - 4) self.black_cell(xcell - 14, ycell - 4) self.black_cell(xcell - 14, ycell - 2) self.black_cell(xcell - 15, ycell - 1) self.black_cell(xcell - 16, ycell - 1) self.black_cell(xcell - 17, ycell - 2) self.black_cell(xcell - 17, ycell - 3) def black_cell(self, y, x): x = x % self.w_field y = y % self.h_field x = x * self.cell + self.cell // 2 y = y * self.cell + self.cell // 2 if self.cell_matrix.get(x, y) == (238, 238, 238): self.fill_black(x, y, '#000000') self.start_cell += 1 self.live.add((x, y)) else: if self.erase: if self.cell_matrix.get(x, y) == (0, 0, 0): self.fill_black(x, y, '#EEEEEE') self.start_cell -= 1 self.live.remove((x, y)) def fill_black(self, x, y, color): # leave some borders for 4 px but it is to heavy task for i in range((-self.cell // 2) - 1, (self.cell // 2) - 1): for j in range((-self.cell // 2) - 1, (self.cell // 2) - 1): xx = (x + i) % self.can_width yy = (y + j) % self.can_height self.cell_matrix.put(color, (xx, yy)) def check_black(self, x, y, color): total = 8 for i in [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]: xi = (x + i[0] * self.cell) % self.can_width yi = (y + i[1] * self.cell) % self.can_height if self.cell_matrix.get(xi, yi) == color: total -= 1 return total def start_game(self): self.button_Start.configure(state='disabled') self.button_Clear.configure(state='disabled') self.start_cycle() def start_cycle(self): if self.global_gen: gen = self.global_gen else: gen = 1 tot = len(self.live) # clean self.born = [] self.dead = [] for i, j in self.live: total = self.check_black(i, j, (238, 238, 238)) if total < 2: self.dead.append((i, j)) if total > 3: self.dead.append((i, j)) # check if new cell wass born for xy in [(i - self.cell, j - self.cell), (i, j - self.cell), (i + self.cell, j - self.cell), (i - self.cell, j), (i + self.cell, j), (i - self.cell, j + self.cell), (i, j + self.cell), (i + self.cell, j + self.cell)]: total = self.check_black(xy[0], xy[1], (0, 0, 0)) # invert rule need 3 cells to born new if total == 5: xy0 = xy[0] % self.can_width xy1 = xy[1] % self.can_height self.born.append((xy0, xy1)) self.scrPop.configure(text=tot) self.scrGen.configure(text=gen) for i in self.dead: self.live.remove(i) xd, yd = i self.fill_black(xd, yd, '#EEEEEE') for i in self.born: self.live.add(i) xb, yb = i self.fill_black(xb, yb, '#000000') # counters for maximum population if self.max_score is False: self.max_score = tot elif tot > self.max_score: self.max_score = tot else: self.max_score = self.max_score # for generation gen += 1 self.global_gen = gen # after dead cells need to check how many stay alive tot += len(self.born) - len(self.dead) # count population self.score += tot # start goal for end message if tot == 0: self.game_over(tot, gen) # for stop button else: self.game_on = self.window.after(self.timer, self.start_cycle) def stop_game(self): self.window.after_cancel(self.game_on) self.button_Start.configure(state='normal') self.button_Clear.configure(state='normal') def clear_side_menu(self, event=None): self.window.unbind('<Motion>') self.creat.delete(self.invert) self.invert = None self.window.bind('<ButtonPress-1>', self.start_paint) self.window.bind('<B1-Motion>', self.motion_paint) self.window.configure(cursor='plus') if self.cur: self.window.delete(self.cur) def clear(self): self.cell_matrix = self.original.copy() self.window.itemconfigure(self.cell_img, image=self.cell_matrix) self.scrPop.configure(text=0) self.scrGen.configure(text=0) # clear menu with figures self.clear_side_menu() self.start_cell = 0 self.live = set() self.score = 0 self.max_score = 0 self.global_gen = None def fast(self): self.timer -= 1 if self.timer < 1: self.timer = 1 self.speedVal.configure(text=int(self.timer)) def slow(self): self.timer += 1 if self.timer > 15: self.timer = 15 self.speedVal.configure(text=int(self.timer)) def game_over(self, tot, gen): self.window.after_cancel(self.game_on) self.global_gen = 0 self.scrPop.configure(text=tot) self.scrGen.configure(text=self.global_gen) self.creat.delete(self.invert) self.button_Stop.configure(state='disabled') end_menu = End(self.master, gen, self.start_cell, self.score, self.max_score) self.window.configure(cursor='left_ptr') ans = end_menu.answer() if ans is True: self.button_Start.configure(state='normal') self.button_Clear.configure(state='normal') self.button_Stop.configure(state='normal') self.window.configure(cursor='plus') self.clear() elif ans is False: self.exit_life() def exit_life(self): self.master.quit()
class Gem: def __init__(self): self.frame = Tk(); self.frame.resizable(False, False) self.status = 1 self.scorePlayerA = 0 self.scorePlayerB = 0 self.scoreRoundA = 0 self.scoreRoundB = 0 self.countRound = 0 self.quitMatch = 0 self.isQuitRound = 0 self.canvas_after_2 = 0 self.canvas_after_1 = 0 self.isPause = 0 #register event self.frame.bind("<F4>", self.quitGame) self.frame.bind("<F5>", self.pauseGame) self.frame.protocol("WM_DELETE_WINDOW", self.on_closing) self.registerKeyboard() def setName(self, title): self.frame.title(title) def setBall(self, ball): self.ball = ball def setLeftBar(self, bar): self.leftBar = bar def setRightBar(self, bar): self.rightBar = bar def run(self): self.frame.mainloop() def getFrame(self): return self.frame; def getCanvas(self): return self.canvas def setSize(self, size): self.frame.geometry(("%dx%d")%(size[0], size[1])) self.frame.update() def getSize(self): return (self.frame.winfo_width(), self.frame.winfo_height()) def setBackground(self, color): self.background = color def setPlayers(self, players): self.players = players def setScoreBoard(self): players = self.players size = self.getSize() mid = round(size[0]/2) # Board self.canvas.create_rectangle(mid - 100, 0, mid + 100, 35, fill="grey58", outline="white", tag="boarda") # Player name 1 self.canvas.create_text(mid - 80, 15, text=players[0], fill="magenta2", tag="boardb") # Round score 1 r1 = players[0]+"a" self.canvas.create_text(mid - 80, 28, text="0", fill="pale green", tag="scoreplayera") # Player name 2 self.canvas.create_text(mid + 80, 15, text=players[1], fill="magenta2", tag="boardc") # Round score 2 self.canvas.create_text(mid + 80, 28, text="0", fill="pale green", tag="scoreplayerb") # Box score 1 self.canvas.create_rectangle(mid - 50, 5, mid - 10, 25, fill="thistle3", outline="white", tag="boardd") # Score 1 self.canvas.create_text(mid - 30, 15, text="000", fill="cyan", tag=players[0]) # Box score 2 self.canvas.create_rectangle(mid + 10, 5, mid + 50, 25, fill="thistle3", outline="white", tag="boarde") # Score 2 self.canvas.create_text(mid + 30, 15, text="000", fill="cyan", tag=players[1]) self.canvas.pack() self.frame.update() def clearScoreBoard(self): self.canvas.delete(self.players[0]) self.canvas.delete(self.players[1]) self.canvas.delete("boarda") self.canvas.delete("boardb") self.canvas.delete("boardc") self.canvas.delete("boardd") self.canvas.delete("boarde") self.canvas.delete("scoreplayera") self.canvas.delete("scoreplayerb") self.canvas.update() def initCanvas(self): canvas_width = self.frame.winfo_width() canvas_height = self.frame.winfo_height() self.canvas = Canvas(self.frame, width=canvas_width, height=canvas_height, bg=self.background) self.frame.update() def setDashboard(self): size = self.getSize(); midw = round(size[0]/2) midh = round(size[1]/2) self.canvas.create_oval(midw - 120, midh - 70, midw + 120, midh+70, fill="alice blue", outline="white", tag="dash1") self.canvas.create_text(midw, midh - 35, text="F1: Machine Vs Machine", fill="blue violet", tag="dash2") self.canvas.create_text(midw, midh - 10, text="F2: Human Vs Machine ", fill="blue violet", tag="dash3") self.canvas.create_text(midw, midh + 15, text="F3: Human Vs Human ", fill="blue violet", tag="dash4") self.canvas.create_text(midw, midh + 38, text="F4: Quit Game ", fill="blue violet", tag="dash5") self.canvas.pack() def clearDashboard(self): self.canvas.delete("dash1") self.canvas.delete("dash2") self.canvas.delete("dash3") self.canvas.delete("dash4") self.canvas.delete("dash5") self.canvas.update() def setWinter(self, status = -1): size = self.getSize(); midw = round(size[0]/2) midh = round(size[1]/2) if status == 1: textstr = self.players[0] + " Win" elif status == 2: textstr = self.players[1] + " Win" elif self == 3 and self.scorePlayerA != self.scorePlayerB: if self.scoreRoundB > self.scorePlayerA: textstr = self.players[1] + " Win" else: textstr = self.players[0] + " Win" else: textstr = "Not Match" self.canvas.create_oval(midw - 50, midh - 20, midw + 50, midh+20, fill="alice blue", outline="white", tag="wintera") self.canvas.create_text(midw, midh, text=textstr, fill="blue violet", tag="winterb") self.canvas.pack() self.canvas.update(); def clearWinter(self): self.canvas.delete("wintera") self.canvas.delete("winterb") self.canvas.update() def quitRound(self, status): if self.scorePlayerA >= self.maxRoundScore and self.scorePlayerB >= self.maxRoundScore: self.isQuitRound = 1 if status == 1 or status == 2 or self.isQuitRound == 1 or self.quitMatch == 1: if self.isQuitRound == 0: self.updateScoreRound(status - 1) self.isQuitRound = 1 self.ball.quit(self.canvas) self.leftBar.quit(self.canvas) self.rightBar.quit(self.canvas) return self.isQuitRound def nextRound(self, status): self.canvas.after_cancel(self.canvas_after_2) if status == 2 or status == 1: if self.maxRound > self.countRound: #self.ball.quit(self.canvas) #self.leftBar.quit(self.canvas) #self.rightBar.quit(self.canvas) self.resetRound() self.countRound += 1 self.leftBar.reset(self.canvas) self.rightBar.reset(self.canvas) if status == 1: self.leftBar.transferBall(self.canvas, self.ball) else: self.leftBar.transferBall(self.canvas, self.ball) #print(self.canvas.find_withtag(self.ball.name)) else: self.stopMatch() def play(self, event): self.clearDashboard() self.unRegisterKeyboard() if event.keycode == 112: self.isPause = 4 self.startMatch() self.machineVSmachine() elif event.keycode == 113: self.isPause = 5 self.leftBar.registerKeyboard(self.frame) self.startMatch() self.machineVShuman() elif event.keycode == 114: self.isPause = 6 self.leftBar.registerKeyboard(self.frame) self.rightBar.registerKeyboard(self.frame) self.startMatch() self.humanVShuman() def machineVSmachine(self): try: if self.ball.exists == False: self.isQuitRound = 0 if self.isQuitRound == 0: rs = self.ball.move(self.canvas) self.leftBar.autoMove(self.canvas) self.rightBar.autoMove(self.canvas) rs = self.update(rs) if rs == 1: return ; self.canvas_after_1 = self.canvas.after(10, self.machineVSmachine) except: print("I am so sorry!") self.stopMatch(0) def machineVShuman(self): try: if self.ball.exists == False: self.isQuitRound = 0 if self.isQuitRound == 0: rs = self.ball.move(self.canvas) self.leftBar.move(self.canvas) self.rightBar.autoMove(self.canvas) rs = self.update(rs) if rs == 1: return ; self.canvas_after_1 = self.canvas.after(10, self.machineVShuman) except: print("I am so sorry!") self.stopMatch(0) def humanVShuman(self): try: if self.ball.exists == False: self.isQuitRound = 0 if self.isQuitRound == 0: rs = self.ball.move(self.canvas) self.leftBar.move(self.canvas) self.rightBar.move(self.canvas) rs = self.update(rs) if rs == 1: return ; self.canvas_after_1 = self.canvas.after(10, self.humanVShuman) except: print("I am so sorry!") self.stopMatch(0) def startMatch(self): self.setScoreBoard() self.quitMatch = 0 self.isQuitRound = 0 self.countRound = 0 self.nextRound(1) def resetRound(self): self.scorePlayerA = 0 self.scorePlayerB = 0 self.isQuitRound = 0 self.updateScorePlayer() self.leftBar.registerKeyboard(self.frame) self.rightBar.registerKeyboard(self.frame) def update(self, status): self.updateScorePlayer(status-3) self.canvas.update() if self.quitRound(status) == 1 and self.quitMatch == 0: self.leftBar.unRegisterKeyboard(self.frame) self.rightBar.unRegisterKeyboard(self.frame) self.canvas_after_2 = self.canvas.after(800, self.nextRound, status) if self.quitMatch == 1: self.leftBar.unRegisterKeyboard(self.frame) self.rightBar.unRegisterKeyboard(self.frame) self.isQuitRound == 1 return self.quitMatch def updateScoreRound(self, status): if self.scorePlayerB == 0 and self.scorePlayerA == 0: return if status == 0: self.scoreRoundA += 1 self.canvas.itemconfig("scoreplayera", text=self.scoreRoundA) elif status == 1: self.scoreRoundB += 1 self.canvas.itemconfig("scoreplayerb", text=self.scoreRoundB) def updateScorePlayer(self, status = 5): if status == 0: self.scorePlayerA += 1 self.canvas.itemconfig(self.players[0], text=self.__countScore(self.scorePlayerA)) if self.scorePlayerA != 0 and self.scorePlayerA % 5 == 0: self.ball.speed +=1 elif status == 1: self.scorePlayerB += 1 self.canvas.itemconfig(self.players[1], text=self.__countScore(self.scorePlayerB)) elif status == 5: self.canvas.itemconfig(self.players[0], text=self.__countScore(self.scorePlayerA)) self.canvas.itemconfig(self.players[1], text=self.__countScore(self.scorePlayerB)) self.canvas.update() def __countScore(self, score): if score < 10: scorestr = "00" + str(score); elif score < 100: scorestr = "0" + str(score) else: scorestr = str(score) return scorestr def stopMatch(self, event = 0): self.isQuitRound = 1 self.quitMatch = 1 self.leftBar.unRegisterKeyboard(self.frame) self.rightBar.unRegisterKeyboard(self.frame) self.canvas.after_cancel(self.canvas_after_1); self.canvas_after_3 = self.canvas.after(500, self.returnMenu) def quitGame(self, event): self.isQuitRound = 1 self.quitMatch = 1 self.leftBar.unRegisterKeyboard(self.frame) self.rightBar.unRegisterKeyboard(self.frame) self.canvas.after_cancel(self.canvas_after_1); self.canvas_after_3 = self.canvas.after(200, self.destroy) def destroy(self): self.canvas.after_cancel(self.canvas_after_3) self.frame.destroy() def returnMenu(self): self.canvas.after_cancel(self.canvas_after_3) self.ball.quit(self.canvas) self.leftBar.quit(self.canvas) self.rightBar.quit(self.canvas) self.clearScoreBoard() self.clearWinter() self.setDashboard() self.registerKeyboard() def setMaxRound(self, max): self.maxRound = max def setMaxRoundScore(self, max): self.maxRoundScore = max def registerKeyboard(self): self.frame.bind("<F1>", self.play) self.frame.bind("<F2>", self.play) self.frame.bind("<F3>", self.play) self.frame.unbind("<Escape>") def unRegisterKeyboard(self): self.frame.unbind("<F1>") self.frame.unbind("<F2>") self.frame.unbind("<F3>") self.frame.bind("<Escape>", self.stopMatch) def on_closing(self): self.quitGame(0) def pauseGame(self, event): if self.isPause == 1: self.isPause += 3 self.machineVSmachine() elif self.isPause == 2: self.isPause += 3 self.machineVShuman() elif self.isPause == 3: self.isPause += 3 self.humanVShuman() elif self.isPause > 3: self.canvas.after_cancel(self.canvas_after_1) self.isPause -= 3
class Main(object): def __init__(self, master): self.master = master self.master.title('CONWAY\'S GAME OF LIFE') self.wid = 910 self.hei = 680 smw = self.master.winfo_screenwidth() // 2 smh = self.master.winfo_screenheight() // 2 tplft = (smw - self.wid // 2, smh - self.hei // 2) self.master.geometry(f'{self.wid}x{self.hei}+{tplft[0]}+{tplft[1]}') self.master.resizable(width=False, height=False) # create a main field can_width = 801 can_height = 641 # variable to continue with right number generation after stop game self.global_gen = None # start self.start_cell = 0 self.live = set() # trick for rigth after_cancel self.game_on = (0, 0) # population self.score = 0 # variable for max cells self.max_score = 0 # for change speed self.timer = 50 # cursor for place ships self.cur = None self.invert = None self.on = (0, 0) # erase seeds self.erase = True # images for ships self.glider = PhotoImage(file='data/1_ship.gif') self.glider_in = PhotoImage(file='data/1_ship_in.gif') self.lss = PhotoImage(file='data/2_lss.gif') self.lss_in = PhotoImage(file='data/2_lss_in.gif') self.sui = PhotoImage(file='data/3_sucide.gif') self.sui_in = PhotoImage(file='data/3_sucide_in.gif') self.f5 = PhotoImage(file='data/4_f5.gif') self.f5_in = PhotoImage(file='data/4_f5_in.gif') self.penta = PhotoImage(file='data/5_penta.gif') self.penta_in = PhotoImage(file='data/5_penta_in.gif') self.patern = PhotoImage(file='data/6_patern.gif') self.patern_in = PhotoImage(file='data/6_patern_in.gif') self.fireship = PhotoImage(file='data/7_fireship.gif') self.fireship_in = PhotoImage(file='data/7_fireship_in.gif') # GUI frameWin = Frame(master, bg='white', borderwidth=0) frameWin.pack(side=TOP, fill=BOTH) frameCanv = Frame(frameWin, bg='white', borderwidth=0) frameCanv.pack(side=RIGHT, fill=BOTH) # main canvas self.window = Canvas( frameCanv, width=can_width, height=can_height, cursor='plus', bg='#EEEEEE', # bg='white', bd=0, highlightthickness=0) self.window.pack(side=TOP) self.cell = 10 self.w_field = can_width // self.cell self.h_field = can_height // self.cell # create a examples of class square self.cell_matrix = [] for i in range(0, self.h_field): x = 0 y = 0 + i * self.cell rows = [] for i in range(0, self.w_field): rows.append( Square(self.window, x + i * self.cell, y, self.cell, self)) self.cell_matrix.append(rows) # side menu for images frameBorderCr = Frame(frameWin, bg='white', bd=3) frameBorderCr.pack(side=LEFT, fill=BOTH) mes_creat = Label(frameBorderCr, text='CREATURE', height=2, bg='white') mes_creat.pack(side=TOP, fill=X) frameCreat = Frame(frameBorderCr, bg='gray', bd=2) frameCreat.pack(side=TOP, fill=BOTH) self.creat = Canvas(frameCreat, height=596, bg='white', highlightthickness=0) self.creat.pack(side=TOP, expand=YES, fill=Y) # images for ships self.creat.create_image(48, 25, image=self.glider) self.creat.create_image(48, 73, image=self.lss) self.creat.create_image(48, 126, image=self.sui) self.creat.create_image(48, 175, image=self.f5) self.creat.create_image(48, 256, image=self.penta) self.creat.create_image(48, 349, image=self.patern) self.creat.create_image(49, 485, image=self.fireship) # menu for counters frameMB = Frame(frameCanv, bg='white', borderwidth=0) frameMB.pack(side=BOTTOM, fill=BOTH) message = Label(frameMB, text='SQUARE UNIVERSUM ', height=2, bg='white') message.pack(side=LEFT, fill=X) # cell part frameBor1 = Frame(frameMB, bg='gray', borderwidth=2) frameBor1.pack(side=LEFT) name_pop = Label(frameBor1, text='CELL') name_pop.pack(side=LEFT) self.scrPop = Label(frameBor1, text=0, width=7) self.scrPop.pack(side=RIGHT) # separator sep = Frame(frameMB, width=4) sep.pack(side=LEFT) # cycle part frameBor2 = Frame(frameMB, bg='gray', borderwidth=2) frameBor2.pack(side=LEFT) name_gen = Label(frameBor2, text='CYCLE') name_gen.pack(side=LEFT) self.scrGen = Label(frameBor2, text=0, width=6) self.scrGen.pack(side=RIGHT) # buttons self.button_Start = Button(frameMB, text='START', width=6, command=self.start_game) self.button_Start.pack(side=RIGHT, padx=3) self.button_Stop = Button(frameMB, text='STOP', width=6, command=self.stop_game) self.button_Stop.pack(side=RIGHT, padx=3) self.button_Clear = Button(frameMB, text='CLEAR', width=6, command=self.clear) self.button_Clear.pack(side=RIGHT, padx=3) blockSpeed = Frame(frameMB, padx=25) blockSpeed.pack(side=RIGHT) button_Fast = Button(blockSpeed, text='>>', width=3, command=self.fast) button_Fast.pack(side=RIGHT, padx=3) butSpeedFrame = Frame(blockSpeed, bg='gray', bd=2) butSpeedFrame.pack(side=RIGHT) self.speedVal = Label(butSpeedFrame, text=int(self.timer), width=3) self.speedVal.pack(side=RIGHT) button_Slow = Button(blockSpeed, text='<<', width=3, command=self.slow) button_Slow.pack(side=RIGHT, padx=3) self.window.bind('<B1-Motion>', self.motion_paint) self.window.bind('<ButtonPress-1>', self.start_paint) self.window.bind('<ButtonPress-2>', self.clear_side_menu) self.window.bind('<Leave>', self.clear_side_menu) self.creat.bind('<ButtonPress-1>', self.creatures) self.master.mainloop() def motion_paint(self, event): self.erase = False x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) def start_paint(self, event): self.erase = True xcell = event.y // self.cell ycell = event.x // self.cell self.black_cell(xcell, ycell) def creatures(self, event): # I can realize with standart buttons and compound x = int(event.x) y = int(event.y) if self.invert: # clear menu with figures self.clear_side_menu() else: self.on = (0, 0) if x in range(32, 65) and y in range(10, 45): self.creat_but(x, y, 32, 65, 10, 45, 48, 25, self.glider_in, self.glider, self.ship_1, SE) if x in range(20, 75) and y in range(54, 96): self.creat_but(x, y, 20, 75, 54, 96, 48, 73, self.lss_in, self.lss, self.ship_2, SE) if x in range(32, 65) and y in range(107, 149): self.creat_but(x, y, 32, 65, 107, 149, 48, 126, self.sui_in, self.sui, self.fig_1, S) if x in range(32, 65) and y in range(161, 192): self.creat_but(x, y, 32, 65, 161, 192, 48, 175, self.f5_in, self.f5, self.fig_2, CENTER) if x in range(32, 65) and y in range(203, 313): self.creat_but(x, y, 32, 65, 203, 313, 48, 256, self.penta_in, self.penta, self.fig_3, S) if x in range(21, 75) and y in range(323, 377): self.creat_but(x, y, 21, 75, 323, 377, 48, 349, self.patern_in, self.patern, self.fig_4, SE) if x in range(6, 93) and y in range(388, 588): self.creat_but(x, y, 6, 93, 388, 588, 48, 485, self.fireship_in, self.fireship, self.ship_3, S) def creat_but(self, x, y, fnx, lnx, fny, lny, x_im, y_im, img_in, img, bind, al): self.window.unbind('<B1-Motion>') if self.cur: self.window.delete(self.cur) self.cur = None if (self.on[0] not in range(fnx, lnx) or self.on[1] not in range(fny, lny)): self.invert = self.creat.create_image(x_im, y_im, image=img_in) self.window.bind('<ButtonPress-1>', bind) self.on = (x, y) self.window.bind( '<Motion>', lambda event, i=img, a=al: self.cursor(event, i, a)) def cursor(self, event, img, align): self.erase = False self.window.configure(cursor='none') if not self.cur: self.cur = self.window.create_image(event.x, event.y, image=img, anchor=align) self.window.coords(self.cur, (event.x, event.y)) def ship_1(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell, ycell - 1) self.black_cell(xcell, ycell - 2) self.black_cell(xcell - 2, ycell - 1) def ship_2(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 3, ycell - 1) self.black_cell(xcell, ycell - 1) self.black_cell(xcell, ycell - 2) self.black_cell(xcell, ycell - 3) self.black_cell(xcell - 1, ycell - 4) self.black_cell(xcell - 3, ycell - 4) def fig_1(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell, ycell - 1) self.black_cell(xcell - 1, ycell - 1) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 3, ycell - 1) self.black_cell(xcell - 3, ycell - 2) def fig_2(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 1, ycell - 1) self.black_cell(xcell - 2, ycell + 1) def fig_3(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 2, ycell + 1) self.black_cell(xcell - 3, ycell) self.black_cell(xcell - 4, ycell) self.black_cell(xcell - 5, ycell) self.black_cell(xcell - 6, ycell) self.black_cell(xcell - 7, ycell - 1) self.black_cell(xcell - 7, ycell + 1) self.black_cell(xcell - 8, ycell) self.black_cell(xcell - 9, ycell) def fig_4(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 4, ycell) self.black_cell(xcell - 4, ycell - 2) self.black_cell(xcell - 4, ycell - 3) self.black_cell(xcell - 4, ycell - 4) self.black_cell(xcell - 3, ycell - 4) self.black_cell(xcell - 1, ycell - 3) self.black_cell(xcell - 1, ycell - 2) self.black_cell(xcell, ycell - 2) self.black_cell(xcell, ycell - 4) def ship_3(self, event): x = int(event.x) y = int(event.y) xcell = int(y / self.cell) ycell = int(x / self.cell) self.black_cell(xcell, ycell) self.black_cell(xcell - 1, ycell) self.black_cell(xcell - 1, ycell + 1) self.black_cell(xcell - 2, ycell) self.black_cell(xcell - 2, ycell + 2) self.black_cell(xcell - 3, ycell + 2) self.black_cell(xcell - 4, ycell + 2) self.black_cell(xcell - 3, ycell + 3) self.black_cell(xcell - 6, ycell + 1) self.black_cell(xcell - 7, ycell) self.black_cell(xcell - 9, ycell) self.black_cell(xcell - 9, ycell + 1) self.black_cell(xcell - 10, ycell + 1) self.black_cell(xcell - 10, ycell + 2) self.black_cell(xcell - 11, ycell + 3) self.black_cell(xcell - 13, ycell + 3) self.black_cell(xcell - 14, ycell + 3) self.black_cell(xcell - 14, ycell + 1) self.black_cell(xcell - 15, ycell) self.black_cell(xcell - 16, ycell) self.black_cell(xcell - 17, ycell + 1) self.black_cell(xcell - 17, ycell + 2) self.black_cell(xcell, ycell - 1) self.black_cell(xcell - 1, ycell - 1) self.black_cell(xcell - 1, ycell - 2) self.black_cell(xcell - 2, ycell - 1) self.black_cell(xcell - 2, ycell - 3) self.black_cell(xcell - 3, ycell - 3) self.black_cell(xcell - 3, ycell - 4) self.black_cell(xcell - 4, ycell - 3) self.black_cell(xcell - 6, ycell - 2) self.black_cell(xcell - 7, ycell - 1) self.black_cell(xcell - 9, ycell - 1) self.black_cell(xcell - 9, ycell - 2) self.black_cell(xcell - 10, ycell - 2) self.black_cell(xcell - 10, ycell - 3) self.black_cell(xcell - 11, ycell - 4) self.black_cell(xcell - 13, ycell - 4) self.black_cell(xcell - 14, ycell - 4) self.black_cell(xcell - 14, ycell - 2) self.black_cell(xcell - 15, ycell - 1) self.black_cell(xcell - 16, ycell - 1) self.black_cell(xcell - 17, ycell - 2) self.black_cell(xcell - 17, ycell - 3) def black_cell(self, x, y): # could be an answer x = x % self.h_field y = y % self.w_field if self.cell_matrix[x][y].color_change: self.live.add((x, y)) self.start_cell += 1 self.cell_matrix[x][y].flip() else: if self.erase: self.live.remove((x, y)) self.start_cell -= 1 self.cell_matrix[x][y].flip() def check_black(self, x, y, color): total = 8 for i in [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]: xi = (x + i[0]) % self.h_field yi = (y + i[1]) % self.w_field if self.cell_matrix[xi][yi].color_change == color: total -= 1 return total def start_game(self): self.button_Start.configure(state='disabled') self.button_Clear.configure(state='disabled') self.start_cycle() def start_cycle(self): if self.global_gen: gen = self.global_gen else: gen = 1 tot = len(self.live) dead = [] born = [] for i in self.live: x, y = i total = self.check_black(x, y, True) if total < 2: dead.append((x, y)) if total > 3: dead.append((x, y)) # check if new cell wass born for xy in [(x - 1, y - 1), (x, y - 1), (x + 1, y - 1), (x - 1, y), (x + 1, y), (x - 1, y + 1), (x, y + 1), (x + 1, y + 1)]: total = self.check_black(xy[0], xy[1], False) if total == 5: xy0 = xy[0] % self.h_field xy1 = xy[1] % self.w_field born.append((xy0, xy1)) self.scrPop.configure(text=tot) self.scrGen.configure(text=gen) for i in dead: x, y = i self.live.remove(i) self.cell_matrix[x][y].flip() for i in born: x, y = i self.live.add(i) # because born include old born self.cell_matrix[x][y].color_change = True self.cell_matrix[x][y].flip() # counters for maximum population if self.max_score is False: self.max_score = tot elif tot > self.max_score: self.max_score = tot else: self.max_score = self.max_score # for generation gen += 1 self.global_gen = gen # after dead cells need to check how many stay alive tot += len(born) - len(dead) # count population self.score += tot # start goal for end message if tot == 0: self.game_over(tot, gen) else: # for stop button self.game_on = self.window.after(self.timer, self.start_cycle) def stop_game(self): self.window.after_cancel(self.game_on) self.button_Start.configure(state='normal') self.button_Clear.configure(state='normal') def clear_side_menu(self, event=None): self.window.unbind('<Motion>') self.creat.delete(self.invert) self.invert = None self.window.bind('<ButtonPress-1>', self.start_paint) self.window.bind('<B1-Motion>', self.motion_paint) self.window.configure(cursor='plus') if self.cur: self.window.delete(self.cur) def clear(self): for i in self.cell_matrix: for j in i: j.canvas.itemconfigure(j.cel, fill='#EEEEEE') j.color_change = True self.scrPop.configure(text=0) self.scrGen.configure(text=0) # clear menu with figures self.clear_side_menu() self.start_cell = 0 self.live = set() self.score = 0 self.max_score = 0 self.global_gen = None def fast(self): self.timer -= 10 if self.timer < 10: self.timer = 10 self.speedVal.configure(text=int(self.timer)) def slow(self): self.timer += 10 if self.timer > 150: self.timer = 150 self.speedVal.configure(text=int(self.timer)) def game_over(self, tot, gen): self.window.after_cancel(self.game_on) self.global_gen = 0 self.scrPop.configure(text=tot) self.scrGen.configure(text=self.global_gen) self.creat.delete(self.invert) self.button_Stop.configure(state='disabled') end_menu = End(self.master, gen, self.start_cell, self.score, self.max_score) self.window.configure(cursor='left_ptr') ans = end_menu.answer() if ans is True: self.button_Start.configure(state='normal') self.button_Clear.configure(state='normal') self.button_Stop.configure(state='normal') self.window.configure(cursor='plus') self.clear() elif ans is False: self.exit_life() def exit_life(self): self.master.quit()