The problem I have is trying to make my shape files have random locations and size, without having to put the definitions in a for loop. Here are my classes.
# Module imports
import math
import turtle as t
# Class Definitions
class Circle:
def __init__(self,x=0,y=0,r=0):
self.center = Point(x,y)
self.radius = r
def circumference(self):
result = (self.radius * 2) * math.pi
return result
def area(self):
result = (self.radius ** 2) * math.pi
return result
def draw(self,fill_color,pen_color,pen_width):
t.color(pen_color)
t.fillcolor(fill_color)
t.pensize(pen_width)
t.penup()
t.goto(self.center.x,self.center.y)
t.pendown()
t.begin_fill()
t.circle(self.radius)
t.end_fill()
t.penup()
class Point:
"""Represents a point with an x and y coordinate"""
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def show(self):
print "(%d, %d)" % (self.x, self.y)
def move_to(self,x,y):
self.x = x
self.y = y
def distance(self,p):
dx = self.x - p.x
dy = self.y - p.y
dist = math.sqrt(dx**2 + dy**2)
return dist
class Rectangle:
"represented with upper left corner as a Point, width, height"""
def __init__(self,x=0,y=0,width=100,height=100):
self.corner = Point(x,y)
self.width = width
self.height = height
def go_to(self,x,y):
self.corner.move_to(x,y)
def area(self):
result = self.width * self.height
return result
def perimeter(self):
result = 2*self.width + 2*self.height
return result
def draw(self,fill_color,pen_color,pen_width):
t.color(pen_color)
t.fillcolor(fill_color)
t.pensize(pen_width)
t.penup()
t.goto(self.corner.x,self.corner.y)
t.pendown()
t.begin_fill()
t.goto(self.corner.x + self.width,self.corner.y)
t.goto(self.corner.x + self.width,self.corner.y - self.height)
t.goto(self.corner.x,self.corner.y - self.height)
t.goto(self.corner.x,self.corner.y)
t.end_fill()
t.penup()
class Segment:
def __init__(self,x1=0,y1=0,x2=100,y2=0):
self.start = Point(x1,y1)
self.end = Point(x2,y2)
def length(self):
return self.start.distance(self.end)
def draw(self,pen_color,pen_width):
t.color(pen_color)
t.pensize(pen_width)
t.penup()
t.goto(self.start.x,self.start.y)
t.pendown()
t.goto(self.end.x,self.end.y)
t.penup()
class Triangle:
def __init__(self,x1=0,y1=0,x2=0,y2=0,x3=0,y3=0):
self.start = Point(x1,y1)
self.second = Point(x2,y2)
self.third = Point(x3,y3)
self.segmentf = Segment(x1,y1,x2,y2)
self.segments = Segment(x2,y2,x3,y3)
self.segmentt = Segment(x3,y3,x1,y1)
def area(self):
a = self.segmentf.length()
b = self.segments.length()
c = self.segmentt.length()
s = (a + b + c) / 2
result = (s*(s-a)*(s-b)*(s-c)) ** 0.5
return result
def perimeter(self):
a = self.segmentf.length()
b = self.segments.length()
c = self.segmentt.length()
result = a + b + c
return result
def draw(self,fill_color,pen_color,pen_width):
t.color(pen_color)
t.fillcolor(fill_color)
t.pensize(pen_width)
t.penup()
t.goto(self.start.x,self.start.y)
t.pendown()
t.begin_fill()
t.goto(self.second.x,self.second.y)
t.goto(self.third.x,self.third.y)
t.goto(self.start.x,self.start.y)
t.end_fill()
t.penup()
And here is my main function:
# Module imports
import math
import turtle
import random
from Suter_Andrew_shapesfinal import *
# Globals
MAX_S = 50
# List Definitions
r = Rectangle(random.randint(-100,100),random.randint(-100,100),random.randint(0,100),random.randint(0,100))
t = Triangle(random.randint(-100,100),random.randint(-100,100),random.randint(-100,100),random.randint(-100,100),random.randint(-100,100),random.randint(-100,100))
c = Circle(random.randint(-100,100),random.randint(-100,100),random.randint(0,100))
shapes = [r,t,c]
colors = ["blue","green","red","purple","pink","yellow","orange","black","white"]
# Main body
for i in range(MAX_S):
s_choice = random.choice(shapes)
c_choice = random.choice(colors)
if s_choice == r:
r.draw(c_choice,c_choice,random.randint(0,10))
elif s_choice == t:
t.draw(c_choice,c_choice,random.randint(0,10))
elif s_choice == c:
c.draw(c_choice,c_choice,random.randint(0,10))
turtle.mainloop()
The function works fine, but the problem is the definitions at the top. Thanks for reading!
If you want to have random definition of a shape for each time through the loop, you're going to have to put the instantiation of it inside the for loop. There's no way around this. If you create the instantiation outside the loop, then there'll only be one and you'll end up reusing the same one in all cases (as you've seen).
# Module imports
import math
import turtle
import random
from Suter_Andrew_shapesfinal import *
randint = random.randint
# Globals
MAX_S = 50
# List Definitions
shapes = [Rectangle, Triangle, Circle]
colors = ["blue", "green", "red", "purple", "pink", "yellow", "orange", "black", "white"]
# Main body
for i in range(MAX_S):
s_choice = random.choice(shapes)
c_choice = random.choice(colors)
if s_choice == Rectangle:
r = Rectangle(*([randint(-100, 100) for x in range(2)] + [randint(0, 100) for x in range(2)]))
r.draw(c_choice, c_choice, random.randint(0, 10))
elif s_choice == Triangle:
t = Triangle(*[randint(-100, 100) for x in range(6)])
t.draw(c_choice, c_choice, random.randint(0, 10))
elif s_choice == Circle:
c = Circle(*([randint(-100, 100) for x in range(2)] + [randint(0, 100)]))
c.draw(c_choice, c_choice, random.randint(0, 10))
turtle.mainloop()
I've also simplified the arguments bit of this a bit using list comprehension to generate a list of random.randints and then using the * in front of a list when passing it to a function unpacks the list into each parameter automatically.
Related
I'm trying to make a very simple game with my son in Kivy and Python. We are trying to make our viewport (camera) centered over the player as they move around our map that is self generating. We get the initial view, then as the player moves the initial chunk is shown in the correct place, but new chunks aren't being drawn at all.
By debugging, we can tell that we are creating chunks, that they have good values, and that our draw_chunks function knows to grab more chunks and to draw them. They just aren't being drawn. We think that our code for drawing the rectangles is probably wrong, but works for the initial load of the game. We've spent a couple hours trying to fix it. We've adjusted the viewport position a couple different ways as well as the rectangle code, but nothing seems to work. I'm hoping someone can point out what we missed. It is probably something very obvious or silly that we are overlooking. Does anyone have any ideas?
import kivy
import random
from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color, Ellipse, Line, Rectangle
from kivy.uix.widget import Widget
from kivy.config import Config
from kivy.core.window import Window
import enum
# Constants for the chunk size and map dimensions
CHUNK_SIZE = 48
TILE_SIZE = 16
MAP_WIDTH = 256
MAP_HEIGHT = 256
#**************************
#* Tile Int Enum Class *
#**************************
class TileEnum(enum.IntEnum):
GRASS = 0
DIRT = 1
CONCRETE = 2
ASPHALT = 3
# Class to represent the game map
class GameMap:
def __init__(self, seed=None):
self.seed = seed
if seed is not None:
random.seed(seed)
self.chunks = {}
self.first_chunk = False
def generate_chunk(self, chunk_x, chunk_y):
# Use the RNG to generate the terrain for this chunk
terrain = []
for x in range(0, CHUNK_SIZE):
column = []
for y in range(0, CHUNK_SIZE):
column.append(random.randint(0, 3))
terrain.append(column)
return terrain
def get_chunk(self, chunk_x, chunk_y):
# Check if the chunk has already been generated
if (chunk_x, chunk_y) in self.chunks:
print("found it",chunk_x, chunk_y)
return self.chunks[(chunk_x, chunk_y)]
else:
# Generate the chunk and store it in the chunk cache
chunk = self.generate_chunk(chunk_x, chunk_y)
self.chunks[(chunk_x, chunk_y)] = chunk
print("made it",chunk_x,chunk_y)
return chunk
# Class to represent the player
class Player:
def __init__(self, pos=(0, 0)):
self.x, self.y = pos
self.speed = TILE_SIZE/2
def move_left(self):
self.x += self.speed
def move_right(self):
self.x -= self.speed
def move_up(self):
self.y -= self.speed
def move_down(self):
self.y += self.speed
class GameScreen(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.viewport_size = (TILE_SIZE*CHUNK_SIZE, TILE_SIZE*CHUNK_SIZE)
self.viewport_pos = (0, 0)
self.size = self.viewport_size
self.map = GameMap(seed=123)
self.player = Player((self.viewport_size[0]/2, self.viewport_size[1]/2))
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
def draw_chunks(self):
# Determine the chunks that are currently in view
viewport_left = int(self.viewport_pos[0] // (CHUNK_SIZE * TILE_SIZE))
viewport_top = int(self.viewport_pos[1] // (CHUNK_SIZE * TILE_SIZE))
viewport_right = int((self.viewport_pos[0] + self.viewport_size[0]) // (CHUNK_SIZE * TILE_SIZE))
viewport_bottom = int((self.viewport_pos[1] + self.viewport_size[1]) // (CHUNK_SIZE * TILE_SIZE))
print(viewport_left, viewport_top, viewport_right, viewport_bottom)
# Iterate over the visible chunks and draw them
for x in range(viewport_left, viewport_right + 1):
for y in range(viewport_top, viewport_bottom + 1):
chunk = self.map.get_chunk(x, y)
#print(chunk)
for i in range(len(chunk)):
for j in range(len(chunk[i])):
if chunk[i][j] == TileEnum.GRASS:
# Draw a green square for grass
with self.canvas:
Color(0.25, 0.75, 0.25)
elif chunk[i][j] == TileEnum.DIRT:
# Draw a brown square for dirt
with self.canvas:
Color(0.75, 0.5, 0.25)
elif chunk[i][j] == TileEnum.CONCRETE:
# Draw a gray square for concrete
with self.canvas:
Color(0.5, 0.5, 0.75)
elif chunk[i][j] == TileEnum.ASPHALT:
# Draw a black square for asphalt
with self.canvas:
Color(0.25, 0.25, 0.5)
with self.canvas:
Rectangle(pos=(
(x * CHUNK_SIZE + i) * TILE_SIZE + self.viewport_pos[0],
(y * CHUNK_SIZE + j) * TILE_SIZE + self.viewport_pos[1]),
size=(TILE_SIZE, TILE_SIZE))
def draw_player(self):
# Draw a circle for the player
with self.canvas:
Color(0, 0.5, 0)
Ellipse(pos=(self.viewport_size[0]/2 - (TILE_SIZE/2), self.viewport_size[0]/2 - (TILE_SIZE/2)), size=(TILE_SIZE, TILE_SIZE))
def update(self, dt):
# Update the viewport position to keep the player centered
self.viewport_pos = (self.player.x - self.viewport_size[0]/2, self.player.y - self.viewport_size[1]/2)
print(self.viewport_pos)
# Redraw the chunks and player
self.canvas.clear()
self.draw_chunks()
self.draw_player()
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
#print(keycode)
if keycode[1] == 'left':
self.player.move_left()
elif keycode[1] == 'right':
self.player.move_right()
elif keycode[1] == 'up':
self.player.move_up()
elif keycode[1] == 'down':
self.player.move_down()
# Main application class
class ProceduralGenerationGameApp(App):
def build(self):
self.title = "Procedural Generation Game"
Config.set("graphics", "width", "768")
Config.set("graphics", "height", "768")
Config.set("graphics", "resizable", False)
Config.set("graphics", "borderless", False)
Config.set("graphics", "fullscreen", False)
Config.set("graphics", "window_state", "normal")
Config.set("graphics", "show_cursor", True)
Config.write()
window_width = Config.getint("graphics", "width")
window_height = Config.getint("graphics", "height")
# Create the game screen and schedule the update function to be called every frame
game_screen = GameScreen()
Window.size = (window_width, window_height)
Clock.schedule_interval(game_screen.update, 1)# 1.0 / 60.0)
return game_screen
if __name__ == "__main__":
ProceduralGenerationGameApp().run()
We updated the Rectangle code to this and reversed the players direction in his move functions:
with self.canvas:
x_chunk_offset = (x * CHUNK_SIZE * TILE_SIZE)
y_chunk_offset = (y * CHUNK_SIZE * TILE_SIZE)
x_tile_offset = (i * TILE_SIZE)
y_tile_offset = (j * TILE_SIZE)
actual_x = x_chunk_offset + x_tile_offset - self.viewport_pos[0]
actual_y = y_chunk_offset + y_tile_offset - self.viewport_pos[1]
Rectangle(pos=(actual_x, actual_y), size=(TILE_SIZE, TILE_SIZE))
I want to visualize an algorithm (Graham scan) in python with tkinter.
I want to animate the algorithm and I am stuck.
I basically want to draw and delete lines but I don't understand canvas.after() well enough to make it work.
draw_line() returns the line object but when I call it in canvas.after(..., draw_line, ...) I don't see a way to get the return value or how to call another canvas.after() to change the color/delete that line if the function draw_line() hasn't been called yet because of the delay.
Thanks in advance.
from tkinter import *
import math
import random
class Point:
def __init__(self, _x, _y, _a=0):
self.x = _x
self.y = _y
self.angle = _a
def get_co(self):
return self.x, self.y
def draw_hull(hull):
for i in range(len(hull) - 1):
canvas.create_line(hull[i][0], hull[i][1], hull[i + 1][0], hull[i + 1][1], fill="red", width=2)
def draw_line(p1, p2, color="yellow"):
return canvas.create_line(p1.x, p1.y, p2.x, p2.y, fill=color, width=2)
def convex_hull(list_points):
# find bottom point
bottom_point = Point(math.inf, math.inf)
for point in list_points:
if point[1] < bottom_point.y:
bottom_point = Point(point[0], point[1])
# calculate angles between the bottom point and the other points
points = []
for point in list_points:
if point != bottom_point.get_co():
new_point = Point(point[0], point[1])
angle = calculate_angle(bottom_point, new_point)
new_point.angle = angle
points.append(new_point)
# sort the points by angle
swaps = None
while swaps != 0:
swaps = 0
for i in range(len(points) - 1):
point1 = points[i]
point2 = points[i + 1]
if point1.angle > point2.angle:
points[i], points[i + 1] = points[i + 1], points[i]
swaps += 1
# go through the points and add them to the convex hull
# if the angle between 3 points ever exeeds 180 degrees, discard the middle point
hull = [bottom_point, points[0]]
i = 1
while i < len(points):
####### DRAW LINE #######
canvas.after(i*500, draw_line, hull[-2], hull[-1])
##############
# check angle
angle = calculate_angle(hull[-2], hull[-1], points[i])
if angle == -1:
########## DELETE LINE ##########
# change color of line to red and delete it a bit later
# canvas.itemconfig(line, fill="red")
# canvas.after(i*500+250, canvas.delete, line)
####################
# pop the point of the stack
hull.pop()
else:
########## CHANGE COLOR OF LINE ##########
# change color of line to green
# canvas.itemconfig(line, fill="green")
####################
# move to the next point
hull.append(points[i])
i += 1
# add bottom point again for loop
hull.append(bottom_point)
# give easy return list (with coordinate-tupels not class objects)
output = []
for point in hull:
output.append(point.get_co())
return output
def calculate_angle(point1, point2, point3=None):
if point3 is None:
if point2.x - point1.x == 0:
return 90
elif point2.x - point1.x > 0:
return math.degrees(math.atan((point2.y - point1.y)/(point2.x - point1.x)))
else:
return 180 - math.degrees(math.atan((point2.y - point1.y)/(point1.x - point2.x)))
else:
v1 = Point(point1.x - point2.x, point1.y - point2.y)
v2 = Point(point3.x - point2.x, point3.y - point2.y)
det = (v1.x * v2.y) - (v2.x * v1.y)
if det < 0:
return 1
else:
return -1
window = Tk()
window.geometry("1000x600")
canvas = Canvas(window, width=1000, height=600)
canvas.pack()
POINTSIZE = 2
points = []
for i in range(100):
x = random.randint(50, 950)
y = random.randint(50, 550)
points.append((x, y))
canvas.create_oval(x - POINTSIZE, y - POINTSIZE, x + POINTSIZE, y + POINTSIZE, fill="black")
hull = convex_hull(points)
# draw_hull(hull)
window.mainloop()
If you have questions about the code, let me know. Because I dont know where to start to explain, since I made major changes to your code.
Anyway, I would be glad if you share your code again, once you are done with, on CodeReview and please do let me know. Because it was fun to work with and your code seems incomplete to me.
Happy Coding:
import tkinter as tk
import random
import math
class Point:
def __init__(self, _x, _y, _a=0):
self.x = _x
self.y = _y
self.angle = _a
return None
def get_co(self):
return self.x, self.y
class Window(tk.Tk):
def __init__(self,_w,_h):
super().__init__()
self.POINTSIZE = 2
self.points = []
self.swaps = None
self.count = 1
self.delay = 200
self.title('Graham scan simulation')
self.toolbar = tk.Frame(self,background='grey')
self.refresh_button = tk.Button(self.toolbar,text='Refresh',
command=self.refresh)
self.start_button = tk.Button(self.toolbar,text='Start',
command = self.convex_hull)
self.canvas = tk.Canvas(self,width=_w,height=_h)
self.toolbar.pack(side=tk.TOP,fill=tk.BOTH,expand=True)
self.refresh_button.pack(side=tk.LEFT)
self.start_button.pack(side=tk.LEFT)
self.canvas.pack(side=tk.BOTTOM,fill=tk.BOTH,expand=True)
def generate_points(self):
for point_instance in self.points:
yield point_instance
def find_bottom_point(self):
bottom_point = Point(math.inf,math.inf)
for point in self.generate_points():
if point.y < bottom_point.y:
bottom_point = point
return bottom_point
def calculate_angle(self,point1, point2):
if point2.x - point1.x == 0:
return 90
elif point2.x - point1.x > 0:
return math.degrees(math.atan((point2.y - point1.y)/(point2.x - point1.x)))
else:
return 180 - math.degrees(math.atan((point2.y - point1.y)/(point1.x - point2.x)))
def calculate_angels_by_bottom_point(self,bottom_point):
for point in self.generate_points():
if point != bottom_point:
angle = self.calculate_angle(bottom_point,point)
point.angle = angle
def sort_points(self,event_variable):
if self.swaps != 0:
self.swaps = 0
for i in range(len(self.points)-1):
point1 = self.points[i]
point2 = self.points[i + 1]
if point1.angle > point2.angle:
self.points[i], self.points[i + 1] = self.points[i + 1], self.points[i]
self.swaps += 1
if self.swaps == 0:
event_variable.set(1)
self.after(20,self.sort_points,event_variable)
def check_angle(self,point1,point2,point3):
v1 = Point(point1.x - point2.x, point1.y - point2.y)
v2 = Point(point3.x - point2.x, point3.y - point2.y)
det = (v1.x * v2.y) - (v2.x * v1.y)
if det < 0:
return 1
else:
return -1
def draw_line(self,p1,p2,color='yellow'):
return self.canvas.create_line(p1.x,p1.y, p2.x,p2.y, fill='yellow',tags='line')
def clear_red_lines(self,p1,p2):
shapes = self.canvas.find_withtag('line')
for shape in shapes:
if self.canvas.itemcget(shape,'fill') == 'red':
coords = self.canvas.coords(shape)
overlapped = self.canvas.find_overlapping(*coords)
for i in overlapped:
coords2 = self.canvas.coords(i)
if coords == coords2:
self.canvas.delete(i)
self.canvas.delete(shape)
def animated_draw(self,hull):
if self.count != len(self.points):
line = self.draw_line(hull[-2],hull[-1])
check_mark = self.check_angle(hull[-2],hull[-1],self.points[self.count])
if check_mark == -1:
self.canvas.itemconfig(line,fill='red')
self.after(self.delay-100,lambda:self.clear_red_lines(hull[-2],hull[-1]))
hull.pop()
else:
self.canvas.itemconfig(line,fill='green')
hull.append(self.points[self.count])
self.count += 1
self.after(self.delay,self.animated_draw,hull)
def convex_hull(self):
bottom_point = self.find_bottom_point()
self.calculate_angels_by_bottom_point(bottom_point)
event_variable = tk.IntVar(self,value=0)
self.sort_points(event_variable)
self.wait_variable(event_variable)
self.points.pop(0)
self.animated_draw(hull = [bottom_point, self.points[0]])
def generate_listpoints(self,_amount):
'''using a generator for memory purpose'''
for i in range(_amount):
x = random.randint(50, 950)
y = random.randint(50, 550)
yield x,y
def refresh(self):
self.swaps = None
self.count = 1
self.points= []
self.populate_canvas()
def populate_canvas(self):
self.canvas.delete('all')
for x,y in self.generate_listpoints(100):
self.points.append(Point(x, y))#instead of creating throwing instances away.
self.canvas.create_oval(x - self.POINTSIZE,
y - self.POINTSIZE,
x + self.POINTSIZE,
y + self.POINTSIZE,
fill="black")
root = Window(1000,600)
root.mainloop()
I'm new baby in Python and having the following error can you guys look into it........................................
AttributeError: 'area' object has no attribute 'radius'. So, I'm facing error in any cases. Thank for help
import math, random
class area:
def __init__(self, radius, length, breath, height, base):
if radius == 0 and breath != 0:
self.radius = random.uniform(1.1, 9.5)
self.length = random.uniform(10.5, 15.5)
self.breath = random.uniform(15, 20)
self.height = random.uniform(20, 25)
self.base = random.uniform(26, 32)
elif length == 0 and heigh != 0:
self.radius = random.uniform(1.1, 9.5)
self.length = length
self.breath = random.uniform(15, 20)
self.height = height
self.base = base
elif height == 0 and base != 0:
self.radius = radius
self.length = random.uniform(1.1, 9.5)
self.breath = breath
self.height = random.uniform(1.1, 9.5)
self.base = base
def areaofcircle(self):
return (self.radius ** 2) * math.pi
def areaoftriangl(self):
return 0.5 * (self.height) * (self.base)
def areaofrectangle(self):
return (self.length) * (self.breath)
areas = []
for i in range(0, 10):
v = area(1, 3, 5, 0, 0)
areas.append(v)
for v in areas:
print(
"Area of Circle:",
v.areaofcircle(),
"Area of Triangle:",
v.areaoftriangl(),
"Area of Rectangle:",
v.areaofrectangle(),
)
You may need to remove radius from this function arguments
def areaofcircle(self, radius):
return (self.radius ** 2) * math.pi
to be:
def areaofcircle(self):
return (self.radius ** 2) * math.pi
By defining the function as
def areaofcircle(self, radius)
Your function expect two inputs, but in your case you only give one. As far as I understand 'radius' is a datafield of the area class. Therefore, you can call it with "self.radius". In this case if you remove the radius parameter from the function, it should all work out.
def areaofcircle(self)
Is is possible to have a while loop in Python with no expressions?
I know in other languages you can do something like:
while(flag) {};
I'm trying to do something similar in Python but cannot find an answer.
Here is what I have so far:
import turtle
from random import randrange
def is_in_screen(t, w): #CHECKS TO SEE IF STILL IN SCREEN
flag = True
r = w.window_width() / 2
l = r * -1
u = w.window_height() / 2
d = u * -1
x_cor = t.xcor()
y_cor = t.ycor()
if (x_cor < l or x_cor > r or y_cor < d or y_cor > u):
flag = False
return flag
def move_to(t, w): #MOVE IN RANDOM DIRECTION AND RANDOM DISTANCE
t.forward(randrange(1, 100))
if (randrange(1, 2) == 1):
t.left(randrange(1, 180))
else:
t.right(randrange(1, 180))
return is_in_screen(t, w)
def random_movement(t1, t2, w):
while (move_to(t1, w) and move_to(t2, w)): #<<<<<<<<LOOP IN QUESTION
i = 0
def main():
t1 = turtle.Turtle()
t2 = turtle.Turtle()
w = turtle.Screen()
t1.color("green")
t2.color("purple")
random_movement(t1, t2, w)
w.exitonclick()
main()
The reason I'm trying to do no expressions is because I want the second turtle to not move if the first turtle goes out of bounds. Also, I do not want return statements in the function.
You're looking for the pass keyword.
while (flag):
pass
Below is a rework of your code with the while expr: pass that everyone's suggesting along with some other style and idiom changes to tighten up the code:
from turtle import Screen, Turtle
from random import randrange
def is_in_screen(turtle, screen):
r = screen.window_width() / 2
u = screen.window_height() / 2
x, y = turtle.position()
return -r < x < r and -u < y < u
def move_to(turtle, screen):
turtle.forward(randrange(1, 100))
turtle.left(randrange(-180, 180)) # negative left turn is a right turn
return is_in_screen(turtle, screen)
def random_movement(turtle_1, turtle_2, screen):
while move_to(turtle_1, screen) and move_to(turtle_2, screen): pass
screen = Screen()
t1 = Turtle()
t1.color("green")
t2 = Turtle()
t2.color("purple")
random_movement(t1, t2, screen)
screen.exitonclick()
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
I have a compiler error “not defined” although there is a definition
from gasp import *
GRID_SIZE = 30
MARGIN = GRID_SIZE
BACKGROUND_COLOR = color.BLACK # Colors we use
WALL_COLOR = (0.6 * 255, 0.9 * 255, 0.9 * 255)
# The shape of the maze. Each character
# represents a different type of object
# % - Wall
# . - Food
# o - Capsule
# G - Ghost
# P - Chomp
# Other characters are ignored
the_layout = [
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
"%.....%.................%.....%",
"%o%%%.%.%%%.%%%%%%%.%%%.%.%%%o%",
"%.%.....%......%......%.....%.%",
"%...%%%.%.%%%%.%.%%%%.%.%%%...%",
"%%%.%...%.%.........%.%...%.%%%",
"%...%.%%%.%.%%% %%%.%.%%%.%...%",
"%.%%%.......%GG GG%.......%%%.%",
"%...%.%%%.%.%%%%%%%.%.%%%.%...%",
"%%%.%...%.%.........%.%...%.%%%",
"%...%%%.%.%%%%.%.%%%%.%.%%%...%",
"%.%.....%......%......%.....%.%",
"%o%%%.%.%%%.%%%%%%%.%%%.%.%%%o%",
"%.....%........P........%.....%",
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"]
class Immovable:
def is_a_wall(self):
return False
class Nothing(Immovable):
pass
class Maze:
def __init__(self):
self.have_window = False
self.game_over = False
self.set_layout(the_layout)
set_speed(20)
def set_layout(self, layout):
height = len(layout)
width = len(layout[0])
self.make_window(width, height)
self.make_map(width, height)
max_y = height - 1
for x in range( width ):
for y in range(height):
char = layout[max_y - y][x]
self.make_object((x, y), char)
def make_window(self, width, height):
grid_width = (width -1) * GRID_SIZE
grid_height = (height - 1) * GRID_SIZE
screen_width = 2 * MARGIN + grid_width
screen_height = 2 * MARGIN + grid_height
begin_graphics(screen_width, screen_height,"Chomp",BACKGROUND_COLOR)
def to_screen(self, point):
(x,y) = point
x = x * GRID_SIZE + MARGIN
y = y * GRID_SIZE + MARGIN
return(x,y)
def make_map(self, width, height):
self.width = width
self.height = height
self.map = []
for y in range(width):
new_row = []
for x in range(width):
new_row.append(Nothing())
self.map.append(new_row)
def make_object(self,point,charactor):
(x,y) = point
if charactor == "%":
self.map[y][x] = Wall(self,point)
def finished(self):
return self.game_over
def play(self):
update_when('next_tick')
def done(self):
end_graphics()
self.map = []
def object_at(self,point):
(x,y) = point
if y < 0 or y >= self.height:
return Nothing()
if x < 0 or x >= self.width:
return Nothing()
return self.map[y][x]
class Wall(Immovable):
def __init__(self, maze, point):
self.place = point # Store our position
self.screen_point = maze.to_screen(point)
self.maze = maze # Keep hold of Maze
self.draw()
def draw(self):
(screen_x, screen_y) = self.screen_point
dot_size = GRID_SIZE * 0.2
Circle(self.screen_point, dot_size,
color = WALL_COLOR, filled = 1)
(x, y) = self.place
neighbors = [ (x+1, y), (x-1, y)]
for neighbor in neighbors:
self.check_neighbor(neighbor)
def check_neighbor(self,neighbor):
maze = self.maze
object = maze.object_at(neighbor)
if object.is_a_wall():
here = self.screen_point
there = maze.to_screen(neighbor)
Line(here, there, color = WALL_COLOR,thickness = 2)
def is_a_wall(self):
return True
the_maze = Maze()
while not the_maze.finished():
the_maze.play()
the_maze.done()
I got this error..
Traceback (most recent call last): File "chomp.py", line 110, in
class Wall(Immovable): File "chomp.py", line 124, in Wall
for neighbor in neighbors: NameError: name '
neighbors' is not defined
I spent lot of time still can't find what's wrong, need some help
You never close the function call to Circle() two lines about line 122, that's probably it. You're probably missing an argument based on the trailing comma.
dot_size = GRID_SIZE * 0.2
Circle(self.screen_point, dot_size, # No closing parentheses
(x, y) = self.place
neighbors = [ (x+1, y), (x-1, y)]
for neighbor in neighbors:
self.check_neighbor(neighbor)
Circle(self.screen_point, dot_size,
missing something at the end of that line