改进我的 Python 海龟游戏,使其更紧凑

Improve my Python Turtle game to make it more compact

我是编程初学者,我开始使用 Python Turtle 制作游戏。游戏运行良好,但我觉得它有很多不必要的代码,我想让它更紧凑。有人可以给我一些提高效率的建议吗?

在这个游戏中有 3 只乌龟:红绿蓝。你选择其中一个(蓝色是通过单击 b 来选择,绿色是通过单击 g 和红色通过单击 r)并且如果你的乌龟排名第一,你将赢得 1 分,如果第二名你没有得到任何积分,但如果你排名第三你失去一分。您可以按 h 重新开始游戏。分数保存在名为 "database.txt".

的文件中
import turtle
import random
import time

global score

file = open('database.txt','r+')

score = file.read()

playing = True

global n
n = 0

turtle.setup(500, 400)

win = turtle.Screen()
win.title("Gamble on Turtles")

screen = turtle.Screen()

global x1
x1 = 0
global x2
x2 = 0
global x3
x3 = 0

def red_turtle():
    global turtle1
    turtle1 = turtle.Turtle()
    turtle1.shape("turtle")
    turtle1.color("red")
    turtle1.penup()
    turtle1.setpos(-180, 100)
    turtle1.pendown()

def green_turtle():
    global turtle2
    turtle2 = turtle.Turtle()
    turtle2.shape("turtle")
    turtle2.color("green")
    turtle2.penup()
    turtle2.setpos(-180, 0)
    turtle2.pendown()

def blue_turtle():
    global turtle3
    turtle3 = turtle.Turtle()
    turtle3.shape("turtle")
    turtle3.color("blue")
    turtle3.penup()
    turtle3.setpos(-180, -100)
    turtle3.pendown()

def track():
    i = 30
    track = turtle.Turtle()
    track.hideturtle()
    track.speed(100)

    track.penup()
    track.setpos(-150, 150)
    track.pendown()
    track.right(90)
    track.write(i)
    track.forward(300)

    track.penup()
    track.setpos(-120, 150)
    track.pendown()
    track.write(i*2)
    track.forward(300)

    track.penup()
    track.setpos(-90, 150)
    track.pendown()
    track.write(i*3)
    track.forward(300)

    track.penup()
    track.setpos(-60, 150)
    track.pendown()
    track.write(i*4)
    track.forward(300)

    track.penup()
    track.setpos(-30, 150)
    track.pendown()
    track.write(i*5)
    track.forward(300)

    track.penup()
    track.setpos(0, 150)
    track.pendown()
    track.write(i*6)
    track.forward(300)

    track.penup()
    track.setpos(30, 150)
    track.pendown()
    track.write(i*7)
    track.forward(300)

    track.penup()
    track.setpos(60, 150)
    track.pendown()
    track.write(i*8)
    track.forward(300)

    track.penup()
    track.setpos(90, 150)
    track.pendown()
    track.write(i*9)
    track.forward(300)

    track.penup()
    track.setpos(120, 150)
    track.pendown()
    track.write(i*10)
    track.forward(300)

    track.penup()
    track.setpos(150, 150)
    track.pendown()
    track.write(i*11)
    track.forward(300)

def bet_red():
    global n
    global x1
    global x2
    global x3
    global score

    message = turtle.Turtle()
    message.hideturtle()
    message.penup()
    message.forward(180)

    n = 3
    move()
    if n == 3:
        keys_deactivate()
        if x1 > x2 and x1 > x3:
            file = open('database.txt','r+')
            score = int(score) + 1
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('+1 point')
            file.close()

        elif x1 > x3 and x1 < x2 or x1 < x3 and x1 > x2:
            file = open('database.txt','r+')
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('+0 point')
            file.close()
        else:
            file = open('database.txt','r+')
            score = int(score) - 1
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('-1 point')
            file.close()

def bet_green():
    global n
    global x1
    global x2
    global x3
    global score

    message = turtle.Turtle()
    message.hideturtle()
    message.penup()
    message.forward(180)

    n = 3
    move()
    if n == 3:
        keys_deactivate()
        if x2 > x1 and x2 > x3:
            file = open('database.txt','r+')
            score = int(score) + 1
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('+1 point')
            file.close()

        elif x2 > x1 and x2 < x3 or x2 < x1 and x2 > x3:
            file = open('database.txt','r+')
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('+0 point')
            file.close()
        else:
            file = open('database.txt','r+')
            score = int(score) - 1
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('-1 point')
            file.close()

def bet_blue():
    global n
    global x1
    global x2
    global x3
    global score

    message = turtle.Turtle()
    message.hideturtle()
    message.penup()
    message.forward(180)

    n = 3
    move()
    if n == 3:
        keys_deactivate()
        if x3 > x1 and x3 > x2:
            file = open('database.txt','r+')
            score = int(score) + 1
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('+1 point')
            file.close()

        elif x3 > x1 and x3 < x2 or x3 < x1 and x3 > x2:
            file = open('database.txt','r+')
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('+0 point')
            file.close()
        else:
            file = open('database.txt','r+')
            score = int(score) - 1
            file.write(str(score))
            message.write(score)
            message.left(90)
            message.forward(20)
            message.write('-1 point')
            file.close()


def gamble():
    global screen
    screen.onkey(bet_red, "r")
    screen.onkey(bet_green, "g")
    screen.onkey(bet_blue, "b")
    screen.listen()

def keys_deactivate():
    screen.onkey(None, "r")
    screen.onkey(None, "g")
    screen.onkey(None, "b")

def move():
    global x1
    global x2
    global x3

    x1 = random.randint(30, 330)
    x2 = random.randint(30, 330)
    x3 = random.randint(30, 330)

    global turtle1
    global turtle2
    global turtle3

    turtle1.forward(x1)
    turtle2.forward(x2)
    turtle3.forward(x3)

def restart():
    global screen
    screen.clear()
    game()

def game():
    red_turtle()
    green_turtle()
    blue_turtle()
    track()
    gamble()
    global screen
    screen.onkey(restart, 'h')

game()

screen.mainloop()

下面是你的代码的返工,其中有 60% 是错误的。重新考虑一下,它可能会更小:

from turtle import Screen, Turtle
from random import randint

FONT = ('Arial', 16, 'normal')
STARTING_LINE = -180

def make_turtle(color, y_offset):
    turtle = Turtle("turtle")
    turtle.color(color)
    turtle.penup()
    turtle.setpos(STARTING_LINE, y_offset)
    turtle.pendown()

    return turtle

def track():
    track = Turtle(visible=False)
    track.speed('fastest')
    track.right(90)

    for i in range(30, 360, 30):
        track.penup()
        track.setpos(STARTING_LINE + i, 150)
        track.pendown()
        track.write(i)
        track.forward(300)

def bet_red():
    keys_deactivate()
    move()
    bet_race(turtles['red'].xcor(), turtles['green'].xcor(), turtles['blue'].xcor())

def bet_green():
    keys_deactivate()
    move()
    bet_race(turtles['green'].xcor(), turtles['blue'].xcor(), turtles['red'].xcor())

def bet_blue():
    keys_deactivate()
    move()
    bet_race(turtles['blue'].xcor(), turtles['red'].xcor(), turtles['green'].xcor())

def bet_race(x1, x2, x3):
    global score

    if x1 > x2 and x1 > x3:
        score += 1

        message.write(score, font=FONT)
        message.left(90)
        message.forward(20)
        message.write('+1 point', font=FONT)

    elif x1 < x2 and x1 < x3:
        score -= 1

        message.write(score, font=FONT)
        message.left(90)
        message.forward(20)
        message.write('-1 point', font=FONT)

    else:
        message.write(score, font=FONT)
        message.left(90)
        message.forward(20)
        message.write('+0 point', font=FONT)

    with open('database.txt', 'w') as file:
        print(score, file=file)

def gamble():
    screen.onkey(bet_red, "r")
    screen.onkey(bet_green, "g")
    screen.onkey(bet_blue, "b")

def keys_deactivate():
    screen.onkey(None, "r")
    screen.onkey(None, "g")
    screen.onkey(None, "b")

def move():
    for turtle in turtles.values():
        turtle.forward(randint(30, 330))

def restart():
    message.clear()
    message.home()
    message.forward(180)

    for turtle in turtles.values():
        turtle.clear()
        turtle.penup()
        turtle.setx(STARTING_LINE)
        turtle.pendown()

    gamble()

score = 0

try:
    with open('database.txt') as file:
        score = int(file.read())
except FileNotFoundError:
    pass

screen = Screen()
screen.setup(500, 400)
screen.title("Gamble on Turtles")

turtles = {
    'red': make_turtle('red', 100),
    'green': make_turtle('green', 0),
    'blue': make_turtle('blue', -100)
}

message = Turtle(visible=False)
message.speed('fastest')
message.penup()
message.forward(180)

track()

gamble()

screen.onkey(restart, 'h')
screen.listen()
screen.mainloop()

主要注意事项:

  • 你不明白global,花点时间(重新)阅读一下。 您的代码使用了 32 个 global 语句,返工只有 一个.

  • 同样,您应该重新考虑您对全球实体的管理和 避免创建这么多。需要牢记的一个关键概念 编程这将是,“再添加一个有多难 乌龟去比赛?”。如果很难,你需要重新考虑 你的代码。

  • 当您第一次 运行 时,您不能假设 database.txt 存在 代码 -- 相应的程序。

  • 海龟作为一种资源不会被垃圾回收,因此请避免创建 比你需要的更多。目前你每次创造五只新海龟 比赛重新运行。重新编写的代码重用了相同的海龟 再次避免重新绘制轨道。

  • 令人惊讶的是,您的代码没有循环和数据结构。如果你 想要紧凑高效的代码,你会想了解这些。