Attributes not inherited via tkinter.button - python

I am writing the number of step-by-step participants within the framework of the classical one. In normal code in def move function I try to reset attributes from one button to unexpected but when I use get_info I get nothing. I've been sitting for 5 hours, I can not figure out how to fix it.
I tried to remake all classes into 1, but even after that it didn't inherit the attributes I needed.
import random
import tkinter as tk
from PIL import Image, ImageTk
import threading
class Color(object):
EMPTY = 0
BLACK = 1
WHITE = 2
class Move:
xstart = -1
ystart = 0
xdest = 0
ydest = 0
class Button(tk.Button, object):
IMG = None
PlayStatus = None
Getstatus = 0
MovementPointsStart = 0
MovementPoints = 0
Heatl = 0
def __init__(self, color, master, x, y, *args, **kwargs):
self.color = color
super(Button, self).__init__(master, width=6, height=3, *args, **kwargs)
self.x = x
self.y = y
self.color = color
def __str__(self):
return f'Юнит {self.x} {self.y} {self.PlayStatus}'
def __repr__(self):
return f'Юнит {self.x} {self.y} {self.PlayStatus}'
def nextturn(self):
if self.MovementPointsStart > self.MovementPoints:
print(self.MovementPointsStart)
self.MovementPoints = self.MovementPointsStart
print('sosnul')
else:
pass
def get_info(self, Button, x, y):
info = 0
if self.color == Color.BLACK:
info = (type(self), self.PlayStatus, self.MovementPointsStart, str('/'), self.MovementPoints, 'Black')
else:
info = (type(self), self.PlayStatus, self.MovementPointsStart, str('/'), self.MovementPoints,'White')
return info
def get_moves(self, Button, turn):
print(turn)
i = 1
while i==1:
print('zestko')
if turn % 2 == 0 and self.color == Color.WHITE:
print('sosnul')
if self.MovementPoints > 0:
print('huiza')
if Button.get_color(Move.xstart, Move.ystart) == Color.WHITE or Button.get_color(Move.xdest, Move.ydest) == Color.EMPTY:
if Move.xdest < Move.xstart:
xend = Move.xstart - Move.xdest
else:
xend = Move.xdest - Move.xstart
if Move.ydest < Move.ystart:
yend = Move.ystart - Move.ydest
else:
yend = Move.ydest - Move.ystart
self.MovementPoints = self.MovementPoints - (xend + yend)
break
break
else:
print("У вас нет очков перемещения")
break
else:
if turn % 2 == 0:
print("Сейчас не ваш ход")
if turn % 2 == 1 and self.color == Color.BLACK:
print('sosnul')
if self.MovementPoints > 0:
print('huiza')
if Button.get_color(Move.xstart, Move.ystart) == Color.BLACK or Button.get_color(Move.xdest, Move.ydest) == Color.EMPTY:
if Move.xdest < Move.xstart:
xend = Move.xstart - Move.xdest
else:
xend = Move.xdest - Move.xstart
if Move.ydest < Move.ystart:
yend = Move.ystart - Move.ydest
else:
yend = Move.ydest - Move.ystart
self.MovementPoints = self.MovementPoints - (xend + yend)
break
else:
print("У вас нет очков перемещения")
break
else:
print("Сейчас не ваш ход")
break
class Game:
turn = 0
ROW = 10
COLUMNS = 10
win = tk.Tk()
win.title('Eve Offline')
win.geometry("900x560")
x=0
y=0
def __init__(self):
self.Button = []
for x in range(Game.ROW):
temp = []
for y in range(Game.COLUMNS):
btn = Button(Color.EMPTY, Game.win, bg='green', x=x, y=y, text='bebra')
temp.append(btn)
self.Button.append(temp)
def set_Button(self):
self.Button[1][2] = Button(Color.BLACK, Game.win, x=1, y=2, text='Suck')
self.Button[1][2].PlayStatus = 1
for x in range (Game.ROW):
for y in range (Game.COLUMNS):
self.Button[x][y].config(command=lambda button=self.Button[x][y]: self.get_click(button))
def create_window(self):
for x in range(Game.ROW):
for y in range(Game.COLUMNS):
btn = self.Button[x][y]
btn.grid(row=x, column=y)
Muvprikaz = tk.Button(bg='green', width=20, height=4, text='MOVE', activebackground='blue')
Muvprikaz.config(command=lambda button=self.Muvprikaz: self.Muvprikaz())
Muvprikaz.place(x=550, y=300)
NextturnB = tk.Button(bg='gray', width=20, height=4, text='Next Turn')
NextturnB.config(command=lambda button=self.nextturn(Game.turn): self.nextturn(button))
NextturnB.place(x=700, y=300)
def start(self):
self.set_Button()
self.create_window()
self.print_button()
self.win.mainloop()
def print_button(self):
for row_btn in self.Button:
print(row_btn)
def get_color(self, x, y):
return self.Button[y][x].color
def get_info(self, x, y):
return self.Button[y][x].get_info(self, x, y)
def move(self):
print(Move.xdest, Move.ydest)
print('sukablat')
print([Move.xdest],[Move.ydest])
self.Button[Move.xdest][Move.ydest].config(background='gray', text='SS')
self.Button[Move.xdest][Move.ydest].config(command=lambda button=self.Button[Move.xdest][Move.ydest]: self.get_click(button))
self.Button[Move.xdest][Move.ydest] = self.Button[Move.xdest][Move.ydest]
self.Button[Move.xstart][Move.ystart] = Button(Color.EMPTY, Game.win, bg='green', x=Move.xstart, y=Move.ystart, text='bebra')
for x in range (Game.ROW):
for y in range (Game.COLUMNS):
self.Button[x][y].config(command=lambda button=self.Button[x][y]: self.get_click(button))
self.create_window()
self.Button[Move.xstart][Move.ystart].Getstatus = 0
print('blatsuka')
self.Button[Move.xstart][Move.ystart].config(bg='green', text='bebra')
self.Update()
def nextturn(self, turn):
self.turn +=1
print(self.turn)
for x in range(Game.ROW):
for y in range(Game.COLUMNS):
if self.Button[x][y] == self.Button[x][y]:
self.Button[x][y].nextturn()
print("hui")
return turn
def get_click(self, clicked_button):
if Button.Getstatus == 0:
print(Button.Getstatus)
x = (clicked_button.x)
y = (clicked_button.y)
Button.Getstatus = Button.Getstatus+1
clicked_button.config(bg='red')
self.print_button()
print(self.get_info(x, y))
print(Button.Getstatus)
Move.xstart = x
Move.ystart = y
Button.Getstatus == 0
elif Button.Getstatus == 1:
Button.Getstatus = 0
print(Button.Getstatus)
clicked_button.config(bg='green')
def dest_click(self, clicked_button):
x = (clicked_button.x)
y = (clicked_button.y)
clicked_button.config(bg='blue')
Move.xdest = x
Move.ydest = y
print(Move.ydest, Move.xdest)
print('eblan')
self.Move()
def Move(self):
self.Button[Move.xstart][Move.ystart].get_moves(self, self.turn)
self.move()
def Muvprikaz(self):
if Move.xstart>-1:
self.print_button()
print(Move.xstart, Move.ystart)
for x in range (Game.ROW):
for y in range (Game.COLUMNS):
self.Button[x][y].config(command=lambda button=self.Button[x][y]: self.dest_click(button))
else:
pass
def Update(self):
for x in range (Game.ROW):
for y in range (Game.COLUMNS):
self.Button[x][y].config(command=lambda button=self.Button[x][y]: self.get_click(button))
Move.xstart = -1
Move.ystart = 0
Move.xdest = 0
Move.ydest = 0
g = 1
game = Game()
game.start()

Related

Unable to detect mouse clicks for randomly generated buttons

I created a program that allows the user to randomly generate buttons on a grid, but I cannot detect if the user presses them or not. Here is what I have so far:
from graphics import *
from time import *
from random import *
class Button:
def __init__(self, win, center, width, height, label):
w,h = width/2.0, height/2.0
x,y = center.getX(), center.getY()
self.xmax, self.xmin = x+w, x-w
self.ymax, self.ymin = y+h, y-h
p1 = Point(self.xmin, self.ymin)
p2 = Point(self.xmax, self.ymax)
self.rect = Rectangle(p1,p2)
self.rect.setFill("blue")
self.rect.draw(win)
self.label = Text(center, label)
self.label.draw(win)
self.label.setSize(8)
self.activate()
def clicked(self, p):
#print("clicked", p.getX(), p.getY(), self.xmin, self.xmax)
return (self.active and
self.xmin <= p.getX() <= self.xmax and
self.ymin <= p.getY() <= self.ymax)
def getLabel(self):
return self.label.getText()
def activate(self):
self.label.setFill("black")
self.rect.setWidth(2)
self.active = True
def deactivate(self):
self.label.setFill("darkgray")
self.rect.setWidth(1)
self.active = False
def setColor(self, color):
self.rect.setFill(color)
class Grid:
def __init__(self, win, startX, startY, numCols, numRows, squareWidth, squareHeight):
self.ButtonMatrix = []
self.numCols = numCols
self.numRows = numRows
for y in range(startY, numRows):
buttonList = []
for x in range(startX,numCols):
label = str(x) + str(y)
buttonList.append(Button(win,Point(x,y), squareWidth, squareHeight, label))
self.ButtonMatrix.append(buttonList)
sleep(0.03)
def getClickPos(self, clickPt):
for y in range(self.numRows):
for x in range(self.numCols):
if self.ButtonMatrix[y][x].clicked(clickPt):
return y,x
def GenerateRandomColor(self, X,Y, color):
self.ButtonMatrix[X][Y].setColor(color)
#def insideBox(x,y):
def setSquareColor(self,r,c,color):
self.ButtonMatrix[r][c].setColor(color)
def setRowColor(self,rowNum,color):
for c in range(15):
self.ButtonMatrix[rowNum][c].setColor(color)
def main():
SIZE = 15
#application window
win = GraphWin("Memory Game", 600, 600)
win.setBackground(color_rgb(45,59,57))
win.setCoords(-3, -3, SIZE + 2, SIZE + 2)
grid = Grid(win, 0, 1, SIZE, SIZE, 1, 1)
quitButton = Button(win, Point(SIZE, SIZE+1), 2, 1, "Quit")
for i in range(10):
X = randrange(13)
Y = randrange(13)
grid.GenerateRandomColor(X,Y, "white")
Coords = X,Y
sleep(0.1)
print(Coords) #checking to see if each button coord will be printed out
pt = win.getMouse()
if grid.getClickPos(pt) == Coords:
print("pressed random button")
else:
print("did not press a random button")
if __name__ == "__main__":
main()

I made a minesweeper game with tkinter

I'm a total beginner who just started learning to code with the book "Head First Learn to Code". I've just finished the book and coded a minesweeper game with python3 on my mac. I hope to get some advice on the game I made. If you feel like the code is too long to read, here are some specific questions I'd like to ask:
What does this: flag = flag.resize((12, 12), Image.ANTIALIAS) actually do, why do I need to assign it a variable instead of just doing this: flag.resize((12, 12), Image.ANTIALIAS) as I'd do with other objects
Is there a better way to create a stopwatch? Mine is the function update_time.
Did I make any mistake regarding the conventions of python? Please point out some for me.
Any help would be much appreciated!
Here's my code:
from tkinter import *
import random as rd
from tkinter import messagebox
from PIL import ImageTk, Image
import sys
class GameGrid(Frame): #the game
def __init__(self, master, height, width, mines_count, player):
Frame.__init__(self, master)
self.grid(row=0)
self.master = master
if sys.platform == 'win32': #checking os
self.platform = 'windows'
else:
self.platform = 'macos'
self.height = height #storing height, width, mines_count, and player's name
self.width = width
self.mines_count = mines_count
self.player_name = player
self.play_time = 0 #initiating play_time and other values
self.lost = False
self.won = False
self.notmine = height * width - mines_count #calculate the number of tiles that are not mines
flag = Image.open('flag.png') #creating and storing flag and bomb images
flag = flag.resize((12, 12), Image.ANTIALIAS)
bomb = Image.open('bomb.png')
bomb = bomb.resize((12, 12), Image.ANTIALIAS)
self.flag = ImageTk.PhotoImage(flag)
self.bomb = ImageTk.PhotoImage(bomb)
grid_model = [[0]*width for item in [0]*height] #creating a list to hold 1's and 0's
while mines_count > 0: #1 is mine, 0 is normal
randi = rd.randint(0, height-1) #putting mines into the list by generating random coordinates
randj = rd.randint(0, width-1) #and storing mine in the corresponding place
if grid_model[randi][randj] == 0:
grid_model[randi][randj] = 1
mines_count -= 1
self.tiles = {} #creating Tiles and storing them using dictionary
for i in range(height):
for j in range(width):
if grid_model[i][j] == 1:
self.tiles[i, j] = Tile(self, i, j, True)
else:
mine_neighbors = 0 #counting nearby mines if Tile in creation is not a mine
if i - 1 >= 0:
if grid_model[i-1][j] == 1:
mine_neighbors += 1
if i - 1 >= 0 and j - 1 >= 0:
if grid_model[i-1][j-1] == 1:
mine_neighbors += 1
if i - 1 >= 0 and j + 1 < width:
if grid_model[i-1][j+1] == 1:
mine_neighbors += 1
if j - 1 >= 0:
if grid_model[i][j-1] == 1:
mine_neighbors += 1
if j + 1 < width:
if grid_model[i][j+1] == 1:
mine_neighbors += 1
if i + 1 < height:
if grid_model[i+1][j] == 1:
mine_neighbors += 1
if i + 1 < height and j - 1 >= 0:
if grid_model[i+1][j-1] == 1:
mine_neighbors += 1
if i + 1 < height and j + 1 < width:
if grid_model[i+1][j+1] == 1:
mine_neighbors += 1
self.tiles[i, j] = Tile(self, i, j, False, mine_neighbors)
def reveal_surroundings(self, i, j): #reveal nearby tiles
revealing = []
width = self.width
height = self.height
if i - 1 >= 0:
revealing.append(self.tiles[i-1, j])
if i - 1 >= 0 and j - 1 >= 0:
revealing.append(self.tiles[i-1, j-1])
if i - 1 >= 0 and j + 1 < width:
revealing.append(self.tiles[i-1, j+1])
if j - 1 >= 0:
revealing.append(self.tiles[i, j-1])
if j + 1 < width:
revealing.append(self.tiles[i, j+1])
if i + 1 < height:
revealing.append(self.tiles[i+1, j])
if i + 1 < height and j - 1 >= 0:
revealing.append(self.tiles[i+1, j-1])
if i + 1 < height and j + 1 < width:
revealing.append(self.tiles[i+1, j+1])
for tile in revealing:
tile.reveal()
def lose(self): #show if lost, stop the clock
global stp
stp = True
self.lost = True
if self.platform == 'windows':
for tile in self.tiles:
if self.tiles[tile].mine:
self.tiles[tile].config(bg='red')
else:
for tile in self.tiles:
if self.tiles[tile].mine:
self.tiles[tile].config(image=self.bomb, padx=9, pady=4, bg='red')
self.tiles[tile].unbind('<Button-1>')
self.tiles[tile].unbind('<Button-2>')
messagebox.showerror(message='Boom, Game Over!!')
self.score = ScoreBoard(self.master)
def win(self): #show if won, stop the clock, creating a window recording scores
global mn, sc, stp
stp = True
self.won = True
for tile in self.tiles:
if self.tiles[tile].mine:
self.tiles[tile].config(image=self.bomb, padx=9, pady=4, bg='red')
self.tiles[tile].unbind('<Button-1>')
self.tiles[tile].unbind('<Button-2>')
messagebox.showinfo(message='Congrats, You Survived ;)')
play_time = str(m) + ' mins, ' + str(s) + ' secs'
self.score = ScoreBoard(self.master, self.player_name, play_time)
class ScoreBoard(Toplevel): #for score recording
def __init__(self, master, name=None, time=None):
Toplevel.__init__(self, master)
self.title('Hall of Fame')
fin_text = ''
if name != None: #writing in the record if there is one
self.board = open('ScoreBoard.txt', 'r') #assigning the text inside ScoreBoard.txt to board_text
board_text = '' #and writing it into ScoreBoard.txt
for line in self.board:
board_text = board_text + line
self.board = open('ScoreBoard.txt', 'w')
self.record = name + ' ' + time
self.board.write(board_text + '\n' + self.record)
self.board = open('ScoreBoard.txt', 'r') #reading text in ScoreBoard and put it on the window
for line in self.board:
fin_text = fin_text + line
self.lbl = Label(self, text=fin_text)
self.lbl.pack()
self.geometry('300x300')
self.board.close()
class Tile(Label): #the Tile
def __init__(self, master, i, j, mine, mine_neighbors=None):
Label.__init__(self, master, width=2, relief=RAISED)
self.grid(row=i, column=j)
self.game = master #storing row, column, is mine or not, count of nearby mines
self.mine = mine
self.row = i
self.col = j
self.mine_neighbors = mine_neighbors
self.revealed = False
self.marked = False
self.bind('<Button-1>', self.reveal) #bind Tile: reveal(left click), mark(right click)
self.bind('<Button-2>', self.mark)
def reveal(self, event=None): #revealing tile
if self.mine:
self.game.lose()
return
else:
if not self.revealed:
self.revealed = True
self.mark()
self.unbind('<Button-1>')
self.unbind('<Button-2>')
if self.mine_neighbors == 0: #if no nearby mines, reveal nearby tiles
self.config(text='', relief=SUNKEN, bg='lightgrey', image='', padx=1, pady=1)
self.game.reveal_surroundings(self.row, self.col)
else:
self.config(text=self.mine_neighbors, relief=SUNKEN, bg='lightgrey', image='', padx=1, pady=1)
self.game.notmine -= 1
if self.game.notmine == 0:
self.game.win()
def mark(self,event=None): #marking tile
if self.game.platform == 'windows':
if not self.marked:
self.config(text='*')
self.marked = True
else:
self.config(text='')
self.marked = False
else:
if not self.marked:
self.config(image=self.game.flag, padx=9, pady=4)
self.marked = True
else:
self.config(image='', padx=1, pady=1)
self.marked = False
stp = False #used to stop the clock when lost or won
def update_time(): #a stopwatch
global m, s, timer, stp
if stp != True:
s = s + 1
if s == 60:
m = m + 1
s = 0
mn = str(m) #making the clock look better by adding a 0 when the number
sc = str(s) #of second or minute is just one digit, e.g. 01, 06, 09..
if len(sc) == 1 and len(mn) == 1:
sc = '0' + sc
mn = '0' + mn
timer.config(text=mn+':'+sc)
elif len(mn) == 1 and len(sc) != 1:
mn = '0' + str(m)
timer.config(text=mn+':'+str(s))
elif len(sc) == 1 and len(mn) != 1:
sc = '0' + sc
timer.config(text=mn+':'+sc)
timer.after(1000, update_time)
def play(height, width, mines_count, player): #initiating the game
global s, m, timer
m = 0
s = -1
time = str(m) + ':' + str(s)
root = Tk()
root.title('MineSweeper')
root.resizable(False, False)
timer = Label(root, text='%i:%i'%(m,s)) #creating stopwatch and update it every second
timer.grid(row=1)
update_time()
game = GameGrid(root, height, width, mines_count, player)
root.mainloop()
if __name__ == '__main__':
play(10, 10, 10, 'Harley')

Genetic algorithm for "smart dots" in python doesn't work

For the past few days I've been trying to implement the so called "Smart dots" game. I first saw it on Code Bullet youtube channel: https://www.youtube.com/watch?v=BOZfhUcNiqk. Unfortunately it was coded in Processing language, while the only language I barely know is Python. I finished my python version of the game but some bugs have appeared.
The problem is that on the second generation dots that are selected to be the best just stop moving almost instantly. I think that it has something to do with me being bad at OOP and copying the Brain class wrong. Steps(which i use for movement) Jump from zero(that is set at the beginning) to max value(200) at the first or second looping of the main loop. But the problems don't stop there. At the next generation, when i try to set brain step to zero, it just breaks with:
AttributeError: 'NoneType' object has no attribute 'brain'
I tried setting up the new brain manually but i still get the same errors. If anyone who already made this or has time to spare can help me with this error or even project i would appreciate it.
I know the code has a lot of unused things but that's just the product of me trying to fix it
:(
The commented out code is some of the old code i used.
main2.py(main loop):
import pygame
import klase2
pygame.init()
def main():
win = pygame.display.set_mode((klase2.WIN_W, klase2.WIN_H))
clock = pygame.time.Clock()
population = klase2.Population()
dots = population.return_dots(1000)
goal = klase2.Goal()
run = True
while run:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
win.fill((255, 255, 255))
goal.draw_goal(win)
for dot in dots:
dot.draw_dot(win)
dot.update_dot()
if population.all_dots_dead():
# natural selection
population.natural_selection()
# mutation
dots = population.mutate_dots()
population.gen += 1
print(population.gen)
pygame.display.update()
main()
kase2(handles all the functions and classes):
import pygame
import numpy as np
from pygame import gfxdraw
import math
import random
pygame.init()
WIN_W = 500
WIN_H = 500
class Brain:
def __init__(self, size):
self.step = 0
self.size = size
self.directionsx = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.size / 2)))
self.directionsy = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.size / 2)))
def clone(self):
self.size = self.size
self.directionsx = self.directionsx
self.directionsy = self.directionsy
self.step = 0
class Goal:
def __init__(self):
self.x = WIN_W / 2
self.y = 10
self.color = (255, 20, 20)
self.r = 5
def draw_goal(self, win):
pygame.gfxdraw.aacircle(win, int(self.x), int(self.y), self.r, self.color)
pygame.gfxdraw.filled_circle(win, int(self.x), int(self.y), self.r, self.color)
class Dot:
goal = Goal()
def __init__(self):
self.tick = 0
self.goal = Goal()
self.brain = Brain(400)
self.velx = 0
self.vely = 0
self.accx = 0
self.accy = 0
self.x = WIN_W / 2
self.y = WIN_H - 10
self.r = 3
self.color = (0, 0, 0)
self.alive = True
self.velLimit = 5
self.fitness = 0
def draw_dot(self, win):
pygame.gfxdraw.aacircle(win, int(self.x), int(self.y), self.r, self.color)
pygame.gfxdraw.filled_circle(win, int(self.x), int(self.y), self.r, self.color)
def move_dot(self):
if self.brain.size / 2 > self.brain.step:
self.accx = self.brain.directionsx[self.brain.step]
self.accy = self.brain.directionsy[self.brain.step]
self.brain.step += 1
else:
self.alive = False
self.velx += self.accx
self.vely += self.accy
if self.velx > self.velLimit:
self.velx = self.velLimit
elif self.velx < -self.velLimit:
self.velx = -self.velLimit
if self.vely > self.velLimit:
self.vely = self.velLimit
elif self.vely < -self.velLimit:
self.vely = -self.velLimit
self.x += self.velx
self.y += self.vely
def update_dot(self):
if not self.reached_goal():
self.tick += 1
if self.alive:
self.move_dot()
if self.x < 0 + self.r or self.x > WIN_W - self.r or self.y < 0 + self.r or self.y > WIN_H - self.r or self.reached_goal():
self.alive = False
def distance_to_goal(self):
a = abs(self.x - self.goal.x)
b = abs(self.y - self.goal.y)
return math.sqrt(a**2 + b**2)
def reached_goal(self):
if self.distance_to_goal() <= self.r + self.goal.r:
return True
return False
def fitness_dot(self):
if self.reached_goal():
self.fitness = 1 / (self.brain.step)
else:
self.fitness = 1 / (self.distance_to_goal()**2)
return self.fitness
class Population:
def __init__(self):
self.dots = []
self.newDots = []
self.gen = 0
self.mutateChance = 800
self.size = 0
self.fitness_sum = 0
def return_dots(self, size):
self.size = size
for _ in range(size):
self.dots.append(Dot())
return self.dots
def all_dots_dead(self):
for i in range(len(self.dots)):
if self.dots[i].alive:
return False
return True
def sort_dots(self):
self.dots = sorted(self.dots, key=lambda dot: dot.fitness, reverse=True)
def sum_fitness(self):
for dot in self.dots:
self.fitness_sum += dot.fitness_dot()
return self.fitness_sum
def get_parent(self):
rand = random.uniform(0, self.fitness_sum)
running_sum = 0
for dot in self.dots:
running_sum += dot.fitness
if running_sum >= rand:
return dot
def natural_selection(self):
for dot in self.dots:
dot.fitness_dot()
self.sort_dots()
self.newDots.append(self.dots[0])
self.sum_fitness()
for i in range(1, len(self.dots)):
parent = self.get_parent()
self.newDots.append(Dot())
self.newDots[i].brain = parent.brain
self.newDots[i].brain.step = 0
self.dots = self.newDots
def mutate_dots(self):
for i in range(1, len(self.dots)):
rand = random.randint(0, 1000)
if rand > self.mutateChance:
self.dots[i].brain.directionsx = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.dots[i].brain.size / 2)))
self.dots[i].brain.directionsy = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.dots[i].brain.size / 2)))
return self.dots
# def natural_selection(self):
# self.selectedDots = []
# for dot in self.dots:
# dot.fitness_dot()
# self.sort_dots()
# for i in range(0, int(len(self.dots) / 3)):
# self.selectedDots.append(self.dots[i])
# self.selectedDots[i].tick = 0
# self.selectedDots[i].velx = 0
# self.selectedDots[i].vely = 0
# self.selectedDots[i].accx = 0
# self.selectedDots[i].accy = 0
# self.selectedDots[i].x = WIN_W / 2
# self.selectedDots[i].y = WIN_H - 10
# self.selectedDots[i].alive = True
# self.selectedDots[i].fitness = 0
# self.selectedDots[i].brain.step = 0
# self.selectedDots[i].goal = Goal()
#
# def new_dots(self):
# for i in range(len(self.selectedDots), len(self.dots)):
# self.selectedDots.append(Dot())
# self.dots = self.selectedDots
#
# def mutate_dots(self):
# for i, dot in enumerate(self.dots):
# isMutating = random.randint(0, 1000)
# if self.mutateChance > isMutating and i > int(len(self.dots) / 3) and i < (2 * int((len(self.dots) / 3))):
# for j in range(len(dot.brain.directionsx)):
# isMutatingDir = random.randint(0, 1000)
# if isMutatingDir >= 800:
# dot.brain.directionsx[j] = np.random.uniform(low=-2.5, high=2.5, size=1)
# for j in range(len(dot.brain.directionsy)):
# isMutatingDir = random.randint(0, 1000)
# if isMutatingDir >= 800:
# dot.brain.directionsy[j] = np.random.uniform(low=-2.5, high=2.5, size=1)
# return self.dots
'''
def natural_selection(self):
self.selectedDots = []
for dot in self.dots:
dot.fitness_dot()
self.sort_dots()
self.selectedDots = self.dots[0:int(0.3 * len(self.dots))]
def new_dots(self):
for i in range(len(self.dots) - int(0.3 * len(self.dots))):
self.selectedDots.append(self.dots[i])
self.dots = []
def mutate_dots(self):
for i, selectedDot in enumerate(self.selectedDots):
self.tick = 0
self.x = WIN_W / 2
self.y = WIN_H - 10
self.r = 3
self.alive = True
self.velLimit = 5
self.fitness = 0
self.dots = self.selectedDots
return self.dots
'''
'''
def mutate_dots(self):
for i, selectedDot in enumerate(self.selectedDots):
selectedDot.alive = True
if i >= 1:
isMutating = random.randint(0, 1000)
if isMutating <= self.mutateChance:
for j in range(len(selectedDot.brain.directionsx)):
isMutatingDir = random.randint(0, 1000)
if isMutatingDir >= 800:
selectedDot.brain.directionsx[j] = np.random.uniform(low=-2.5, high=2.5, size=1)
for j in range(len(selectedDot.brain.directionsy)):
isMutatingDir = random.randint(0, 1000)
if isMutatingDir >= 800:
selectedDot.brain.directionsy[j] = np.random.uniform(low=-2.5, high=2.5, size=1)
elif isMutating <= 800:
selectedDot.brain.directionsx = np.array(np.random.uniform(low=-2.5, high=2.5, size=200))
selectedDot.brain.directionsy = np.array(np.random.uniform(low=-2.5, high=2.5, size=200))
self.newDots.append(selectedDot)
return self.newDots
'''
The NoneType error is caused by the get_parent method. It searches for a child dot, but has no return value if the search fails (same effect as return None). This code will get past that error
def get_parent(self):
rand = random.uniform(0, self.fitness_sum)
running_sum = 0
for dot in self.dots:
running_sum += dot.fitness
if running_sum >= rand:
return dot
return self.dots[0] # search failed, return 1st dot

Grid Generation for minesweeper

Hi so I am making a minesweeper game and I am a bit stuck with the grid generation part. This is my code so far:
from random import randint
import pygame
def MineGen():
mineamount = 100
grid_across = 40
grid_up = 25
mine_list = []
my2dthatlist = []
numacoss = 0
for i in range (mineamount):
numacoss = randint(1,40)
my2dthatlist.append(numacoss)
numup = randint(1,25)
my2dthatlist.append(numup)
mine_list.append(my2dthatlist)
my2dthatlist = []
return mine_list
def GridGen():
grid_across = 40
grid_up = 25
GRIDD = [[0]* grid_across for i in range(grid_up)]
return GRIDD
def MineGrid(GridOutMine, mine_list):
mineplace = 0
placeX = 0
placeY = 0
for i in range(100):
mineplace = mine_list[i]
placeX = mineplace[0]
placeY = mineplace[1]
GridOutMine[placeX][placeY] = 1
print(GridOutMine)
mine_list = MineGen()
GridOutMine = GridGen()
MineGrid(GridOutMine, mine_list)
My issue is that i am getting a list index out of range for the
GridOutMine[placeX][placeY] = 1
part. I don't really know why this is. If you could give me some assistance in what to do, or just some general comments on my code, I would really appreciate it thanks.
That's because, unlike range, random.randint outputs numbers within the specified bounds inclusively. That is, randint(1, 25) could output 25, which is not a valid index for a list that's only 25 elements long (since the last index is 24).
In MineGen, you need to change randint(1, 25) to randint(1, 25-1) or randint(1, 24), and likewise for randint(1, 40) which needs to be randint(1, 39). I'd actually suggest randint(0, 24) and (0, 39), but I don't know if that's intentional.
There are many other things that could/should be improved about this code, but I'd suggest you ask for that kind of input over on CodeReview instead of here once your code is working (they don't fix broken code).
EDIT:
Also, you're indexing your grid in the wrong order. It's a list (25-long) of rows (40-long), so you need to index it in the Y dimension first, then X: GridOutMine[placeY][placeX] = 1
If you are trying to build a grid for the game and want to display buttons in a GUI your users can interact with, you may want to start with the following code as a basic framework for the rest of the code you will be writing.
import tkinter
import functools
class MineSweep(tkinter.Frame):
#classmethod
def main(cls, width, height):
root = tkinter.Tk()
window = cls(root, width, height)
root.mainloop()
def __init__(self, master, width, height):
super().__init__(master)
self.__width = width
self.__height = height
self.__build_buttons()
self.grid()
def __build_buttons(self):
self.__buttons = []
for y in range(self.__height):
row = []
for x in range(self.__width):
button = tkinter.Button(self)
button.grid(column=x, row=y)
button['text'] = '?'
command = functools.partial(self.__push, x, y)
button['command'] = command
row.append(button)
self.__buttons.append(row)
def __push(self, x, y):
print('Column = {}\nRow = {}'.format(x, y))
if __name__ == '__main__':
MineSweep.main(10, 10)
If you want a more complete example of a minesweeper game to either borrow ideas from or adapt for your own needs, the following program implements much of the functionality you might want from a finished game.
import tkinter
import functools
import random
from tkinter.simpledialog import askstring, Dialog
from tkinter.messagebox import showinfo
import os.path
################################################################################
class MineSweep(tkinter.Frame):
#classmethod
def main(cls, width, height, mines, scores):
root = tkinter.Tk()
root.resizable(False, False)
root.title('MineSweep')
window = cls(root, width, height, mines, scores)
root.protocol('WM_DELETE_WINDOW', window.close)
root.mainloop()
################################################################################
def __init__(self, master, width, height, mines, scores):
super().__init__(master)
self.__width = width
self.__height = height
self.__mines = mines
self.__wondering = width * height
self.__started = False
self.__playing = True
self.__scores = ScoreTable()
self.__record_file = scores
if os.path.isfile(scores):
self.__scores.load(scores)
self.__build_timer()
self.__build_buttons()
self.grid()
def close(self):
self.__scores.save(self.__record_file)
self.quit()
def __build_timer(self):
self.__secs = tkinter.IntVar()
self.__timer = tkinter.Label(textvariable=self.__secs)
self.__timer.grid(columnspan=self.__width, sticky=tkinter.EW)
self.__after_handle = None
def __build_buttons(self):
self.__reset_button = tkinter.Button(self)
self.__reset_button['text'] = 'Reset'
self.__reset_button['command'] = self.__reset
self.__reset_button.grid(column=0, row=1,
columnspan=self.__width, sticky=tkinter.EW)
self.__reset_button.blink_handle = None
self.__buttons = []
for y in range(self.__height):
row = []
for x in range(self.__width):
button = tkinter.Button(self, width=2, height=1,
text='?', fg='red')
button.grid(column=x, row=y+2)
command = functools.partial(self.__push, x, y)
button['command'] = command
row.append(button)
self.__buttons.append(row)
def __reset(self):
for row in self.__buttons:
for button in row:
button.config(text='?', fg='red')
self.__started = False
self.__playing = True
self.__wondering = self.__width * self.__height
if self.__after_handle is not None:
self.after_cancel(self.__after_handle)
self.__after_handle = None
self.__secs.set(0)
def __push(self, x, y, real=True):
button = self.__buttons[y][x]
if self.__playing:
if not self.__started:
self.__build_mines()
while self.__buttons[y][x].mine:
self.__build_mines()
self.__started = True
self.__after_handle = self.after(1000, self.__tick)
if not button.pushed:
self.__push_button(button, x, y)
elif real:
self.__blink(button, button['bg'], 'red')
elif real:
self.__blink(button, button['bg'], 'red')
def __blink(self, button, from_bg, to_bg, times=8):
if button.blink_handle is not None and times == 8:
return
button['bg'] = (to_bg, from_bg)[times & 1]
times -= 1
if times:
blinker = functools.partial(self.__blink, button,
from_bg, to_bg, times)
button.blink_handle = self.after(250, blinker)
else:
button.blink_handle = None
def __tick(self):
self.__after_handle = self.after(1000, self.__tick)
self.__secs.set(self.__secs.get() + 1)
def __push_button(self, button, x, y):
button.pushed = True
if button.mine:
button['text'] = 'X'
self.__playing = False
self.after_cancel(self.__after_handle)
self.__after_handle = None
self.__blink(self.__reset_button, button['bg'], 'red')
else:
button['fg'] = 'SystemButtonText'
count = self.__total(x, y)
button['text'] = count and str(count) or ' '
self.__wondering -= 1
if self.__wondering == self.__mines:
self.after_cancel(self.__after_handle)
self.__after_handle = None
self.__finish_game()
def __finish_game(self):
self.__playing = False
score = self.__secs.get()
for row in self.__buttons:
for button in row:
if button.mine:
button['text'] = 'X'
if self.__scores.eligible(score):
name = askstring('New Record', 'What is your name?')
if name is None:
name = 'Anonymous'
self.__scores.add(name, score)
else:
showinfo('You did not get on the high score table.')
HighScoreView(self, 'High Scores', self.__scores.listing())
def __total(self, x, y):
count = 0
for x_offset in range(-1, 2):
x_index = x + x_offset
for y_offset in range(-1, 2):
y_index = y + y_offset
if 0 <= x_index < self.__width and 0 <= y_index < self.__height:
count += self.__buttons[y_index][x_index].mine
if not count:
self.__propagate(x, y)
return count
def __propagate(self, x, y):
for x_offset in range(-1, 2):
x_index = x + x_offset
for y_offset in range(-1, 2):
y_index = y + y_offset
if 0 <= x_index < self.__width and 0 <= y_index < self.__height:
self.__push(x_index, y_index, False)
def __build_mines(self):
mines = [True] * self.__mines
empty = [False] * (self.__width * self.__height - self.__mines)
total = mines + empty
random.shuffle(total)
iterator = iter(total)
for row in self.__buttons:
for button in row:
button.mine = next(iterator)
button.pushed = False
button.blink_handle = None
################################################################################
class ScoreTable:
def __init__(self, size=10):
self.__data = {999: [''] * size}
def add(self, name, score):
assert self.eligible(score)
if score in self.__data:
self.__data[score].insert(0, name)
else:
self.__data[score] = [name]
if len(self.__data[max(self.__data)]) == 1:
del self.__data[max(self.__data)]
else:
del self.__data[max(self.__data)][-1]
def eligible(self, score):
return score <= max(self.__data)
def listing(self):
for key in sorted(self.__data.keys()):
for name in self.__data[key]:
yield name, key
def load(self, filename):
self.__data = eval(open(filename, 'r').read())
def save(self, filename):
open(filename, 'w').write(repr(self.__data))
################################################################################
class HighScoreView(Dialog):
def __init__(self, parent, title, generator):
self.__scores = generator
super().__init__(parent, title)
def body(self, master):
self.__labels = []
for row, (name, score) in enumerate(self.__scores):
label = tkinter.Label(master, text=name)
self.__labels.append(label)
label.grid(row=row, column=0)
label = tkinter.Label(master, text=str(score))
self.__labels.append(label)
label.grid(row=row, column=1)
self.__okay = tkinter.Button(master, command=self.ok, text='Okay')
self.__okay.grid(ipadx=100, columnspan=2, column=0, row=row+1)
return self.__okay
def buttonbox(self):
pass
################################################################################
if __name__ == '__main__':
MineSweep.main(10, 10, 10, 'scores.txt')
Reference: ActiveState Code » Recipes » MineSweep

Updating a Turtle.write Function as a Counter

So in this simulation I have bears, fish, and plants doing various things on a grid. Once the simulation starts I have variables from the simulation function update the number of bears and fish in the world class constructor under fishCount and bearCount. I have another method in the World class that turtle.writes the amount of bears and turtles as a counter. Two problems. The initial count number for each creature is wrong on startup and when the counts are updated via breeding the showCounts method keeps writing over the previous count, making it hard to read. I want it to update the counts on the screen each time a new bear/fish is made or when one dies.
Here is my code:
from math import *
from turtle import *
from random import *
import turtle
import random
import math
def mainSimulation():
numberOfBears = 5
numberOfFish = 5
numberOfPlants = 5
worldLifeTime = 2500
worldWidth = 30
worldHeight = 25
myworld = World(worldWidth,worldHeight,numberOfBears,numberOfFish)
myworld.draw()
myworld.getBearStarvePass()
myworld.getBearBreedPass()
myworld.setBearStarvePass(25)
myworld.setBreedPass(3)
myworld.getFishOvercrowdNum()
myworld.getFishBreedPass()
myworld.setFishOvercrowdNum(5)
myworld.setFishBreedPass(2)
for i in range(numberOfFish):
newfish = Fish(myworld)
x = random.randrange(myworld.getMaxX())
y = random.randrange(myworld.getMaxY())
while not myworld.emptyLocation(x,y):
x = random.randrange(myworld.getMaxX())
y = random.randrange(myworld.getMaxY())
myworld.addThing(newfish,x,y)
for i in range(numberOfBears):
newbear = Bear(myworld)
x = random.randrange(myworld.getMaxX())
y = random.randrange(myworld.getMaxY())
while not myworld.emptyLocation(x,y):
x = random.randrange(myworld.getMaxX())
y = random.randrange(myworld.getMaxY())
myworld.addThing(newbear,x,y)
for i in range(numberOfPlants):
newplant = Plant()
x = random.randrange(myworld.getMaxX())
y = random.randrange(myworld.getMaxY())
while not myworld.emptyLocation(x,y):
x = random.randrange(myworld.getMaxX())
y = random.randrange(myworld.getMaxY())
myworld.addThing(newplant,x,y)
for i in range(worldLifeTime):
myworld.liveALittle()
myworld.showCounts()
myworld.freezeWorld()
THIS IS THE WORLD CLASS
class World:
def __init__(self,mx,my,bear,fish):
self.maxX = mx
self.maxY = my
self.thingList = []
self.grid = []
self.bearCount = bear
self.fishCount = fish
self.fishOvercrowdNum = 0
self.fishBreedNum =0
self.bearStarvePass = 0
self.bearBreedPass = 0
for arow in range(self.maxY):
row=[]
for acol in range (self.maxX):
row.append(None)
self.grid.append(row)
self.wturtle = turtle.Turtle()
self.wscreen = turtle.Screen()
self.wscreen.setworldcoordinates(0,0,self.maxX-1,self.maxY-1)
self.wscreen.addshape("E:/Python/Lib/idlelib/Bear.gif")
self.wscreen.addshape("E:/Python/Lib/idlelib/Fish.gif")
self.wscreen.addshape("E:/Python/Lib/idlelib/Plant.gif")
self.wturtle.hideturtle()
def getBearStarvePass(self):
return self.bearStarvePass
def getBearBreedPass(self):
return self.bearBreedPass
def setBearStarvePass(self, newNum):
self.bearStarvePass = newNum
def setBreedPass(self, newNum):
self.bearBreedPass = newNum
def getFishOvercrowdNum(self):
return self.fishOvercrowdNum
def getFishBreedPass(self):
return self.fishBreedNum
def setFishOvercrowdNum(self, newNum):
self.fishOvercrowdNum = newNum
def setFishBreedPass(self, newNum):
self.fishBreedNum = newNum
def showCounts(self):
bearCount = self.bearCount
fishCount = self.fishCount
self.wturtle.write("Bear: %d Fish: %d " % (bearCount, fishCount), move = False)
def getNumBears(self):
return self.bearCount
def getNumFish(self):
return self.fishCount
def incBear(self):
self.bearCount = self.bearCount + 1
def incFish(self):
self.fishCount = self.fishCount + 1
def decBear(self):
self.bearCount = self.bearCount - 1
def decFish(self):
self.fishCount = self.fishCount - 1
def draw(self):
self.wscreen.tracer(0)
self.wturtle.forward(self.maxX-1)
self.wturtle.left(90)
self.wturtle.forward(self.maxY-1)
self.wturtle.left(90)
self.wturtle.forward(self.maxX-1)
self.wturtle.left(90)
self.wturtle.forward(self.maxY-1)
self.wturtle.left(90)
for i in range(self.maxY-1):
self.wturtle.forward(self.maxX-1)
self.wturtle.backward(self.maxX-1)
self.wturtle.left(90)
self.wturtle.forward(1)
self.wturtle.right(90)
self.wturtle.forward(1)
self.wturtle.right(90)
for i in range(self.maxX-2):
self.wturtle.forward(self.maxY-1)
self.wturtle.backward(self.maxY-1)
self.wturtle.left(90)
self.wturtle.forward(1)
self.wturtle.right(90)
self.wscreen.tracer(1)
def freezeWorld(self):
self.wscreen.exitonclick()
def addThing(self,athing,x,y):
a = 0
athing.setX(x)
athing.setY(y)
self.grid[y][x] = athing
athing.setWorld(self)
self.thingList.append(athing)
athing.appear()
if isinstance(athing, Bear):
self.bearCount = self.bearCount + 1
elif isinstance(athing, Fish):
self.fishCount = self.fishCount + 1
def delThing (self, athing):
athing.hide()
self.grid[athing.getY()][athing.getX()] = None
self.thingList.remove(athing)
def moveThing(self,oldx,oldy,newx,newy):
self.grid[newy][newx] = self.grid[oldy][oldx]
self.grid[oldy][oldx] = None
def getMaxX(self):
return self.maxX
def getMaxY(self):
return self.maxY
def liveALittle(self):
if self.thingList != [ ]:
athing = random.randrange(len(self.thingList))
randomthing = self.thingList[athing]
randomthing.liveALittle()
def emptyLocation(self,x,y):
if self.grid[y][x] == None:
return True
else:
return False
def lookAtLocation(self,x,y):
return self.grid[y][x]
This is the Bear Class
class Bear:
def __init__(self, theWorld):
self.turtle=turtle.Turtle()
self.turtle.up()
self.turtle.hideturtle()
self.turtle.shape("E:/Python/Lib/idlelib/Bear.gif")
self.offsetList = [(-1,1) ,(0,1) ,(1,1),
(-1,0) ,(1,0),
(-1,-1),(0,-1),(1,-1)]
self.theWorld = theWorld
self.bearStarvePass = self.theWorld.bearStarvePass
self.bearBreedPass = self.theWorld.bearBreedPass
self.xpos=0
self.ypos=0
self.world=None
self.starveTick=0
self.breedTick=0
def setX(self, newx):
self.xpos = newx
def setY(self, newy):
self.ypos = newy
def getX(self):
return self.xpos
def getY(self):
return self.ypos
def setWorld(self, aworld):
self.world = aworld
def appear(self):
self.turtle.goto(self.xpos, self.ypos)
self.turtle.showturtle()
def hide(self):
self.turtle.hideturtle()
def move(self, newx, newy):
self.world.moveThing(self.xpos, self.ypos, newx, newy)
self.xpos = newx
self.ypos = newy
self.turtle.goto(self.xpos, self.ypos)
def liveALittle(self):
self.breedTick = self.breedTick + 1
if self.breedTick >= self.bearBreedPass:
self.tryToBreed()
self.tryToEat()
if self.starveTick == self.bearStarvePass:
self.world.delThing(self)
else:
self.tryToMove()
def tryToMove(self):
randomOffsetIndex = random.randrange(len(self.offsetList))
randomOffset = self.offsetList[randomOffsetIndex]
nextx=self.xpos + randomOffset[0]
nexty=self.ypos + randomOffset[1]
while not(0 <= nextx < self.world.getMaxX() and
0 <= nexty < self.world.getMaxY() ):
randomOffsetIndex = random.randrange(len(self.offsetList))
randomOffset = self.offsetList[randomOffsetIndex]
nextx=self.xpos + randomOffset[0]
nexty=self.ypos + randomOffset[1]
if self.world.emptyLocation(nextx,nexty):
self.move(nextx,nexty)
def tryToBreed(self):
randomOffsetIndex = random.randrange(len(self.offsetList))
randomOffset = self.offsetList[randomOffsetIndex]
nextx = self.xpos + randomOffset[0]
nexty = self.ypos + randomOffset[1]
while not(0 <= nextx < self.world.getMaxX() and 0 <= nexty < self.world.getMaxY()):
randomOffsetIndex = random.randrange(len(self.offsetList))
randomOffset = self.offsetList[randomOffsetIndex]
nextx = self.xpos + randomOffset[0]
nexty = self.ypos + randomOffset[1]
if self.world.emptyLocation(nextx, nexty):
childThing = Bear(self.theWorld)
self.world.addThing(childThing, nextx, nexty)
self.breedTick = 0
def tryToEat(self):
adjprey = []
for offset in self.offsetList:
newx = self.xpos + offset[0]
newy = self.ypos + offset[1]
if 0 <= newx < self.world.getMaxX() and 0 <= newy < self.world.getMaxY():
if (not self.world.emptyLocation(newx,newy)) and isinstance(self.world.lookAtLocation(newx,newy),Fish):
adjprey.append(self.world.lookAtLocation(newx,newy))
if len(adjprey)>0:
randomprey = adjprey[random.randrange(len(adjprey))]
preyx = randomprey.getX()
preyy = randomprey.getY()
self.world.delThing(randomprey)
self.move(preyx,preyy)
self.starveTrick = 0
else:
self.starveTick = self.starveTick + 1
This is the CLass Fish
class Fish:
def __init__(self, theworld):
self.turtle = turtle.Turtle()
self.turtle.up()
self.turtle.hideturtle()
self.turtle.shape("E:/Python/Lib/idlelib/Fish.gif")
self.offsetList = [(-1, 1), (0, 1), (1, 1),
(-1, 0) , (1, 0),
(-1, -1), (0, -1), (1, -1)]
self.theWorld = theworld
self.overcrowd = self.theWorld.fishOvercrowdNum
self.breed = self.theWorld.fishBreedNum
self.xpos = 0
self.ypos = 0
self.world = None
self.breedTick = 0
def setX(self, newx):
self.xpos = newx
def setY(self, newy):
self.ypos = newy
def getX(self):
return self.xpos
def getY(self):
return self.ypos
def setWorld(self, aworld):
self.world = aworld
def appear(self):
self.turtle.goto(self.xpos, self.ypos)
self.turtle.showturtle()
def hide(self):
self.turtle.hideturtle()
def move(self, newx, newy):
self.world.moveThing(self.xpos, self.ypos, newx, newy)
self.xpos = newx
self.ypos = newy
self.turtle.goto(self.xpos, self.ypos)
def liveALittle(self):
adjfish = 0
for offset in self.offsetList:
newx = self.xpos + offset[0]
newy = self.ypos + offset[1]
if 0 <= newx < self.world.getMaxX() and 0 <= newy < self.world.getMaxY():
if (not self.world.emptyLocation(newx, newy)) and isinstance(self.world.lookAtLocation(newx, newy), Fish):
adjfish = adjfish + 1
if adjfish >= self.overcrowd:
self.world.delThing(self)
else:
self.breedTick = self.breedTick + 1
if self.breedTick >= self.breed:
self.tryToBreed()
self.tryToMove()
def tryToBreed(self):
offsetList = [(-1, 1), (0, 1), (1, 1),
(-1, 0) , (1, 0),
(-1, -1), (0, -1), (1, -1)]
randomOffsetIndex = random.randrange(len(offsetList))
randomOffset = offsetList[randomOffsetIndex]
nextx = self.xpos + randomOffset[0]
nexty = self.ypos + randomOffset[1]
while not(0 <= nextx < self.world.getMaxX() and 0 <= nexty < self.world.getMaxY()):
randomOffsetIndex = random.randrange(len(offsetList))
randomOffset = offsetList[randomOffsetIndex]
nextx = self.xpos + randomOffset[0]
nexty = self.ypos + randomOffset[1]
if self.world.emptyLocation(nextx, nexty):
childThing = Fish(self.theWorld)
self.world.addThing(childThing, nextx, nexty)
self.breedTick = 0
def tryToMove(self):
offsetList = [(-1, 1), (0, 1), (1, 1),
(-1, 0) , (1, 0),
(-1, -1), (0, -1), (1, -1)]
randomOffsetIndex = random.randrange(len(offsetList))
randomOffset = offsetList[randomOffsetIndex]
nextx = self.xpos + randomOffset[0]
nexty = self.ypos + randomOffset[1]
while not(0 <= nextx < self.world.getMaxX() and 0 <= nexty < self.world.getMaxY()):
randomOffsetIndex = random.randrange(len(offsetList))
randomOffset = offsetList[randomOffsetIndex]
nextx = self.xpos + randomOffset[0]
nexty = self.ypos + randomOffset[1]
if self.world.emptyLocation(nextx, nexty):
self.move(nextx, nexty)
This is the Class Plant
class Plant:
def __init__(self):
self.turtle = turtle.Turtle()
self.turtle.up()
self.turtle.hideturtle()
self.turtle.shape("E:/Python/Lib/idlelib/Plant.gif")
self.xpos = 0
self.ypos = 0
self.world = None
self.breedTick = 0
#accessor and mutators
def setX(self, newx):
self.xpos = newx
def setY(self, newy):
self.ypos = newy
def getX(self):
return self.xpos
def getY(self):
return self.ypos
def setWorld(self, aworld):
self.world = aworld
def appear(self):
self.turtle.goto(self.xpos, self.ypos)
self.turtle.showturtle()
def hide(self):
self.turtle.hideturtle()
def tryToBreed(self):
offsetList=[(-1,1),(0,1),(1,1),
(-1,0) ,(1,0),
(-1,-1),(0,-1),(1,-1)]
randomOffsetIndex=random.randrange(len(offsetList))
randomOffset=offsetList[randomOffsetIndex]
nextx=self.xpos+randomOffset[0]
nexty=self.ypos+randomOffset[1]
while not(0<=nextx<self.world.getMaxX()and
0<=nexty<self.world.getMaxY() ):
randomOffsetIndex=random.randrange(len(offsetList))
randomOffset=offsetList[randomOffsetIndex]
nextx=self.xpos+randomOffset[0]
nexty=self.ypos+randomOffset[1]
if self.world.emptyLocation(nextx,nexty):
childThing=Plant()
self.world.addThing(childThing,nextx,nexty)
self.breedTick=0
def liveALittle(self):
offsetList = [(-1, 1), (0, 1), (1, 1),
(-1, 0) , (1, 0),
(-1, -1), (0, -1), (1, -1)]
self.breedTick = self.breedTick + 1
if self.breedTick >= 5:
self.tryToBreed()
adjplant = 0
for offset in offsetList:
newx = self.xpos + offset[0]
newy = self.ypos + offset[1]
if 0 <= newx < self.world.getMaxX() and 0 <= newy < self.world.getMaxY():
if (not self.world.emptyLocation(newx, newy)) and isinstance(self.world.lookAtLocation(newx, newy), Plant):
adjplant = adjplant + 1
if adjplant >= 2:
self.world.delThing(self)
else:
self.breedTick = self.breedTick + 1
if self.breedTick >= 12:
self.tryToBreed()
if __name__ == '__main__':
mainSimulation()
The problem with #Tankobot's wturtle.clear() suggestion is that it wipes everything wturtle may have done. So, you'll want a separate turtle just for drawing the text. A related approach is not to clear, but to undo the last write command, if you're using a current Python 3 turtle module:
The scenario for the undo approach is:
Initial Setup:
Create a separate turtle, make it invisible (hideturtle) and pen up.
(You don't need to have the pen down to do turtle.write())
Move your turtle to where you want the counters to appear.
Write out an initial (zero'd) set of counters.
Runtime:
Before you call turtle.write(), call turtle.undo() to remove the previous counters.
Call turtle.write() to display the updated counters. You don't need to move the turtle into position first if it was located correctly for the previous write.
An example I wrote for a turtle user who wanted to know How to output variable on turtle screen

Categories