我必须编写一个程序来实现Turtle Graphics的使用。我已经编写了大部分程序,其中包括网格和创建多个乌龟,但是一旦乌龟到达我创建的网格的边缘,我就很难结束游戏。这是我到目前为止的内容:
import turtle
import random
# Setting up Turtle Graphics Window
turtle.setup(800,600)
window = turtle.Screen()
window.title("Turtles Walking through Grid")
window.bgcolor("black")
# Making the turtle
grid = turtle.getturtle()
grid.shape("classic")
grid.color("white")
grid.speed(10)
# Creating the Grid (Relative Positioning)
grid.penup()
grid.setposition(-300,200)
grid.pendown()
grid.forward(600)
grid.right(90)
grid.forward(400)
grid.right(90)
grid.forward(600)
grid.right(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(400)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(400)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(600)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(600)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(600)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(600)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(600)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(600)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(600)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(600)
grid.right(90)
grid.forward(40)
grid.right(90)
grid.forward(600)
grid.left(90)
grid.forward(40)
grid.left(90)
grid.forward(600)
# User Input for Speed
speed = int(input("Enter the speed of the turtles (1-10): "))
# Variable for choosing colors
all_colors = ["red","white","blue","hotpink","purple","lightgreen","yellow"]
# Creating the turtles
def createTurtles(turtle_count):
count = []
for k in range(0, turtle_count):
lil_guys = turtle.Turtle()
lil_guys.shape("turtle")
colors = random.choice(all_colors)
lil_guys.color(colors)
lil_guys.speed(speed)
lil_guys.pendown()
count.append(lil_guys)
return count
# Determine where the Turtle should stop
def off_board(self):
x = self.turtle.xcor()
y = self.turtle.ycor()
return x < -160 or 160 < x or y < -160 or 160 < y
# Set Turtle Amount to 5
count = createTurtles(5)
fun = True
while fun:
for k in range(5):
coin = random.randrange(0, 2)
if coin == 0:
count[k].left(90)
else:
count[k].right(90)
count[k].forward(40)
# Exit on close window
turtle.exitonclick()
一旦五只乌龟之一到达我创建的网格的边缘,程序就应该结束。
答案 0 :(得分:1)
当乌龟到达网格边缘时,您可以退出,如下所示:
while fun:
for k in range(5):
coin = random.randrange(0, 2)
if coin == 0:
count[k].left(90)
else:
count[k].right(90)
count[k].forward(40)
x = count[k].xcor() # new lines
y = count[k].ycor() # |
# |
if x < -300 or 300 < x or \ # |
y < -200 or 200 < y: # |
fun = False # |
break # |
通过将此逻辑放入off_grid
函数中,您将走上正确的道路,但是此函数不应将self
作为参数(它不是类的实例)。
我有一些一般的设计建议(原谅即兴代码审查):
count
实际上不是任何事物的count
,而是turtle
的列表。有意义的名称使您更容易遵循自己的逻辑,避免出现错误和误解。变量fun
可以更清楚地表示为running
。 k
中的变量for k in range(0, turtle_count):
未使用,在Python中通常写为_
。snake_case
首选为function names in Python(CamelCase
用于类)。使用循环来绘制网格并保留代码DRY(而不是重复自己),而不是依次执行多行命令。例如:
for _ in range(0, height + 1, grid_size):
turtle.pendown()
turtle.forward(width)
turtle.penup()
turtle.right(90)
turtle.forward(grid_size)
turtle.right(90)
turtle.forward(width)
turtle.right(180)
避免使用hardcoding数字和字符串;将所有这些变量放在main
程序的顶部,并在整个过程中使用它们。具体来说,在此程序中,您需要height
,width
和grid_size
参数,这些参数将在一个位置中定义并控制整个程序的操作(包括确定何时乌龟已离开网格)。现在,例如,如果我决定要使栅格大小为30,高度为200,宽度为400,则可以在一处更改这些数字,一切都将正常工作。
main
分开。注释不错,但是当代码很明显时注释通常会增加噪音:
# Exit on close window
turtle.exitonclick()
请记住用户:我不知道在绘制网格后我必须回到终端输入乌龟速度。我希望提示用户输入乌龟速度,然后运行程序的可视部分。
将所有内容放在一起,这是一个建议的第一个重构(仍有很多改进设计的空间,但这应该为我们提供一些思考的机会):
import turtle
import random
def create_turtles(
turtle, turtle_count, colors, speed=10, shape="turtle"
):
turtles = []
for _ in range(turtle_count):
tur = turtle.Turtle()
tur.shape(shape)
tur.color(random.choice(colors))
tur.speed(speed)
tur.pendown()
turtles.append(tur)
return turtles
def draw_lines(turtle, turn, length_a, length_b, grid_size):
for _ in range(0, length_a + 1, grid_size):
turtle.pendown()
turtle.forward(length_b)
turtle.penup()
turn(90)
turtle.forward(grid_size)
turn(90)
turtle.forward(length_b)
turn(180)
def draw_grid(
turtle, width=600, height=400, grid_size=40,
speed=100, shape="classic", color="white"
):
tur = turtle.getturtle()
tur.shape(shape)
tur.color(color)
tur.speed(speed)
tur.penup()
tur.setposition(-width // 2, height // 2)
draw_lines(tur, tur.right, height, width, grid_size)
tur.setposition(-width // 2, height // 2)
tur.right(90)
draw_lines(tur, tur.left, width, height, grid_size)
turtle.penup()
turtle.ht()
def off_grid(turtle, width, height):
x = turtle.xcor()
y = turtle.ycor()
return x < -width // 2 or x > width // 2 or \
y < -height // 2or y > height // 2
if __name__ == "__main__":
grid_size = 40
height = 400
width = 600
all_colors = [
"red", "white", "blue", "hotpink",
"purple", "lightgreen", "yellow"
]
speed = int(input("Enter the speed of the turtles (1-10): "))
turtle.setup(800, 600)
window = turtle.Screen()
window.title("Turtles Walking through Grid")
window.bgcolor("black")
draw_grid(turtle, width, height, grid_size)
turtles = create_turtles(turtle, 5, all_colors, speed)
running = True
while running:
for tur in turtles:
random.choice([tur.left, tur.right])(90)
tur.forward(grid_size)
if off_grid(tur, width, height):
running = False
break
turtle.exitonclick()
答案 1 :(得分:1)
我不会重复@ggorlen的所有出色建议(+1),而是指出其他一些问题:
您的海龟在一个维度上在网格线上行走,在另一个维度上在网格线之间行走。在我下面的修改中,他们在网格线上 行走。这需要根据您为网格选择的(奇偶性)大小进行计算。
在我的返工中,当海龟到达网格的边缘时,运动停止了,因为它们在网格线上行走,因此更加清晰。
如果要使用笔向下和白色网格线,请避免使用“白色”作为乌龟色!同为乌龟颜色的“黑色”。
如果可以的话,请避免让用户走出程序来输入参数。如@ggorlen所述,在调用乌龟之前先进行input()
会有所帮助。但是在我的返工中,我使用了Python 3中新增的numinput()
,将其全部保留在GUI中。
有很多算法可以在乌龟中绘制网格,然后选择其中一个并使用它!
重做的代码:
from turtle import Screen, Turtle
from random import choice
TURTLE_COUNT = 5
# Variable for choosing colors
ALL_COLORS = ['red', 'green', 'blue', 'magenta', 'yellow', 'cyan', 'purple']
WINDOW_WIDTH, WINDOW_HEIGHT = 800, 600
GRID_WIDTH, GRID_HEIGHT = 600, 400
CELL_SIZE = 40 # should be a divisor of GRID_WIDTH and GRID_HEIGHT, and probably no smaller than CURSOR_SIZE
CURSOR_SIZE = 20
# Creating the turtles
def create_turtles(turtle_count, speed):
turtles = []
for index in range(turtle_count):
lil_guy = Turtle('turtle')
lil_guy.color(ALL_COLORS[index % TURTLE_COUNT])
lil_guy.speed(speed)
lil_guy.penup()
# to place a turtle cleanly on the grid lines, we have to consider the parity of the grid size
lil_guy.goto((GRID_WIDTH / CELL_SIZE % 2) * CELL_SIZE/2, (GRID_HEIGHT / CELL_SIZE % 2) * CELL_SIZE/2)
lil_guy.pendown()
turtles.append(lil_guy)
return turtles
# Determine where the Turtle should stop
def on_edge(turtle):
x, y = turtle.position()
return abs(x) >= (GRID_WIDTH/2 - CELL_SIZE/2) or abs(y) >= (GRID_HEIGHT/2 - CELL_SIZE/2)
# Setting up Turtle Graphics Window
window = Screen()
window.setup(WINDOW_WIDTH, WINDOW_HEIGHT)
window.title("Turtles Walking through Grid")
window.bgcolor('black')
# Create the grid via stamping
grid = Turtle(visible=False)
grid.speed('fastest')
grid.color('white')
grid.penup()
grid.setx(-GRID_WIDTH/2)
grid.shapesize(GRID_HEIGHT*2 / CURSOR_SIZE, 1/CURSOR_SIZE)
for _ in range(GRID_WIDTH // CELL_SIZE + 1):
grid.stamp()
grid.forward(CELL_SIZE)
grid.setheading(90)
grid.setposition(0, -GRID_HEIGHT/2)
grid.shapesize(GRID_WIDTH*2 / CURSOR_SIZE, 1/CURSOR_SIZE)
for _ in range(GRID_HEIGHT // CELL_SIZE + 1):
grid.stamp()
grid.forward(CELL_SIZE)
# User Input for Speed
user_speed = window.numinput("Turtle Speed", "Enter a value (1-10)", default=5, minval=1, maxval=10)
# Set Turtle Amount
turtles = create_turtles(TURTLE_COUNT, user_speed)
finished = False
while not finished:
for k in range(5):
angle = choice([90, -90])
turtles[k].left(angle)
turtles[k].forward(CELL_SIZE)
finished = on_edge(turtles[k])
if finished:
break
# Exit on close window
window.exitonclick()