【问题标题】:Turtle racing game - unable to keep turtle on square海龟赛车游戏 - 无法让海龟保持原状
【发布时间】:2017-04-09 13:31:26
【问题描述】:

我和我的朋友目前正在学校编写一个练习,我们遇到了如何让海龟保持正轨的困难。举例来说,在广场的第一边,有 2 只海龟在边上赛跑。但是,当他们转身 90 度时,其中有 1 或 2 人会从侧面脱离,这在运动要求方面是不正确的。

这是我们的代码:

import turtle
from random import randint
def read_int(prompt,first,last):
    x = int(input(prompt))
    while x < first or x > last:
        print("Not in range. Try Again!!!")
        x= int(input(prompt))
    return x

square_count = read_int("Enter your laps between 1 and 10: ",1,10)
print(square_count)
#def t():

window = turtle.Screen()
window.bgcolor('lightblue')
def draw_square(turtle, center, size):
    xPt, yPt = center
    xPt -= size / 2
    yPt += size / 2
    side = 4
    size = 300
    angle = 90
    turtle.speed(0)
    turtle.up()
    turtle.goto(xPt, yPt)
    turtle.down()
    for i in range(side):
        turtle.forward(size)
        turtle.right(angle)

t = turtle.Turtle()
draw_square(t,(0,0),300)
t.shape('turtle')
t.color("red")
t.pensize(5)
t.up()
t.goto(-150, 150)

#def r():
r = turtle.Turtle()
draw_square(r,(0,0),300)
r.shape('turtle')
r.color("yellow")
r.up()
r.pensize(5)
r.goto(-150, 150)

sides = 4
size = 300


count_int = int(square_count)* sides
if count_int > 1:
    for sides in range(count_int):
            i = 0
            e = 0
            while i in range(0, size) or e in range(0, size):
                t_step = randint(1, 5)
                t.forward(t_step)
                i = i + t_step
                r_step = randint(1, 5)
                r.forward(r_step)
                e = e + r_step

            t.right(90)
            r.right(90)





window.exitonclick()

【问题讨论】:

    标签: python turtle-graphics


    【解决方案1】:

    你的错误在于你的程序快要结束了。

    while i in range(0, size) or e in range(0, size):
                    t_step = randint(1, 5)
                    t.forward(t_step)
                    i = i + t_step
                    r_step = randint(1, 5)
                    r.forward(r_step)
                    e = e + r_step
    

    假设 i = 298,并且 t_step 选择一个随机整数作为 3。海龟最终会移动到大于 300 的范围,因此它会移动到绘制的框之外。 循环不会停止,因为它只在所有代码运行后才意识到 i 超出范围。 (即当循环被打破时,乌龟已经移到了盒子外面。) 这就是乌龟跑到外面的原因。您可以尝试使用“如果”条件来防止这种情况发生。

    【讨论】:

      【解决方案2】:

      你有两种问题。
      首先,你应该注意你的海龟走了多少步。因为如果一个正方形的大小为 300,它可能会发生乌龟采取的步数总和不等于 300。我建议您将随机步数的生成更改为:

      steps = random.randrange(0, 4, 2)
      

      这样一来,一只乌龟只需要走 0 或 2 步,而您确信总和会达到 300。
      第二点可能更重要。如果像你那样构建race loop,只有当另一只海龟到达行尾时,一只海龟才会转向,你应该重新组织你的代码,使两只海龟彼此独立。

      【讨论】:

      • 好的!谢谢你的建议:)
      【解决方案3】:

      我会采取稍微不同的方法——不是硬编码两只海龟,而是为任意数量的海龟设计,然后只让两只海龟比赛。这是基于任意数量的海龟的重写,包括样式代码的一些重写,以及@Claudio 的一些代码建议:

      from random import randint
      from turtle import Turtle, Screen
      from collections import defaultdict
      
      SIZE = 300
      SIDES = 4
      ANGLE = 90
      MAXIMUM_STRIDE = 5
      
      COLORS = ('red', 'gold', 'green', 'orange', 'blue')
      
      MAX_RACERS = len(COLORS)
      
      def read_int(prompt, first, last):
          x = int(input(prompt))
      
          while not first <= x <= last:
              print('Not in range! Try Again.')
              x = int(input(prompt))
      
          return x
      
      def draw_square(turtle, center, size):
          xPt, yPt = center
      
          xPt -= size / 2
          yPt += size / 2
      
          turtle.up()
          turtle.goto(xPt, yPt)
          turtle.down()
      
          for _ in range(SIDES):
              turtle.forward(SIZE)
              turtle.right(ANGLE)
      
      lap_count = read_int('Enter number of laps (between 1 and 10): ', 1, 10)
      no_racers = read_int('Enter number of racers (between 2 and {}): '.format(MAX_RACERS), 2, MAX_RACERS)
      
      jockey_colors = COLORS[0:no_racers]
      
      window = Screen()
      window.bgcolor('lightblue')
      
      racers = defaultdict(dict)
      
      draw_square(Turtle(visible=False), (0, 0), SIZE)
      
      for color in jockey_colors:
          jockey = Turtle('turtle', visible=False)
          jockey.speed('fastest')
          jockey.color(color)
      
          jockey.up()
          jockey.goto(-SIZE/2, SIZE/2)
          jockey.showturtle()
      
          racers[color]['jockey'] = jockey
          racers[color]['sides'] = 0
          racers[color]['position'] = 0
      
      finished = False
      
      while not finished:
          for racer in racers.values():
              jockey = racer['jockey']
      
              step = randint(1, MAXIMUM_STRIDE + 1)
      
              if racer['position'] + step > SIZE:
      
                  racer['sides'] += 1
      
                  if racer['sides'] == lap_count * SIDES:
                      finished = True
                      break
      
                  baby_step = SIZE - racer['position']
                  jockey.forward(baby_step)
                  jockey.right(ANGLE)
                  racer['position'] = 0
      
                  step -= baby_step
      
              jockey.forward(step)
              racer['position'] += step
      
      window.exitonclick()
      

      【讨论】:

      • 因为我的练习需要 2 只乌龟跑在同一个方格上。因此,我无法应用此解决方案。不过,感谢您的支持。对我帮助很大!!!
      • @davidmechin,我已将代码简化为使用单个共享方块。
      • 最初提供的代码(请参阅 Claudio 的答案中的代码 - 它不关心它)有两个随机源。第一个目的是使步长随机化。另一个,在创建算法的热度中监督,缩短步骤取决于到拐点处广场角落的距离。它在那里是因为算法正在跳过以将赛车手向前移动剩余距离(如果有的话)。由于此答案倾向于提供“更好”的海龟游戏,因此我建议在此答案中列出一个改进版本。
      • @Claudio,我已经采纳了您的建议。我不能说“随机性”问题有很大的不同,但最好把它说清楚。选择赛车手的数量,因为代码可以处理它,是一个不错的选择。
      【解决方案4】:

      你在这里:

      import turtle
      
      from random import randint
      
      def read_int(prompt,first,last):
          x = int(input(prompt))
          while x < first or x > last:
              print("Not in range. Try Again!!!")
              x= int(input(prompt))
          return x
      
      no_of_laps = read_int("Enter your laps between 1 and 10: ",1 , 10)
      print(no_of_laps)
      
      window = turtle.Screen()
      
      window.bgcolor('lightblue')
      
      def draw_square(turtle, center, size):
          xPt, yPt = center
          xPt -= size / 2
          yPt += size / 2
          side = 4
          size = 300
          angle = 90
          turtle.speed(0)
          turtle.up()
          turtle.goto(xPt, yPt)
          turtle.down()
          for i in range(side):
              turtle.forward(size)
              turtle.right(angle)
      
      t = turtle.Turtle()
      draw_square(t,(0,0),300)
      
      t.shape('turtle')
      t.color("red")
      t.pensize(5)
      t.up()
      t.goto(-150, 150)
      
      #def r():
      r = turtle.Turtle()
      draw_square(r,(0,0),300)
      r.shape('turtle')
      r.color("yellow")
      r.up()
      r.pensize(5)
      r.goto(-150, 150)
      
      sides = 4
      size  = 300
      
      no_of_turns = int(no_of_laps) * sides
      
      countTurns_t = 0
      countTurns_r = 0
      t_i = 0
      r_i = 0
      
      while countTurns_t < no_of_turns and countTurns_r < no_of_turns: 
      
      
          t_step = randint(1, 5)
          if t_i + t_step > size:
              t_step = size - t_i
              t.forward(t_step)
              t_i = 0
              t.right(90)
              countTurns_t += 1
          else:
              t.forward(t_step)
              t_i += t_step
      
          r_step = randint(1, 5)
          if r_i + r_step > size:
              r_step = size - r_i
              r.forward(r_step)
              r_i = 0
              r.right(90)
              countTurns_r += 1
          else:
              r.forward(r_step)
              r_i += r_step
      
      window.exitonclick()
      

      附:希望您能看到上面提供的代码如何以及为什么按预期工作。仔细阅读其他答案,它们指出了您在编写代码时遗漏的重要问题。

      【讨论】:

      • 如何将其标记为已接受的答案,以便任何人都可以直接看到该问题已被回答,并且它不会出现在未回答问题的列表中?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      • 2021-08-26
      • 2018-05-30
      相关资源
      最近更新 更多