Python turtle.ontimer(func,time)有多次?

时间:2017-10-19 02:12:31

标签: python-3.x turtle-graphics

问题:您的红绿灯控制器程序已获得专利,您即将变得非常富有。但是你的新客户需要改变。他们希望状态机中有四个状态:绿色,然后是绿色和橙色,然后是橙色,然后是红色。此外,他们希望在每个州花费不同的时间。机器应该在绿色状态下花费3秒钟,然后在绿色+橙色状态下花费一秒钟,然后在橙色状态下花费一秒钟,然后在红色状态下花费2秒钟。更改状态机中的逻辑。

import turtle           # Tess becomes a traffic light.


wn = turtle.Screen()
wn.title("Tess becomes a traffic light!")
wn.bgcolor("lightgreen")
tess = turtle.Turtle()
alexis = turtle.Turtle()


def draw_housing2():
    """ Draw a nice housing to hold the traffic lights """
    alexis.pensize(3)
    alexis.color("black", "darkgrey")
    alexis.penup()
    alexis.backward(180)
    alexis.pendown()
    alexis.begin_fill()
    alexis.forward(80)
    alexis.left(90)
    alexis.forward(275)
    alexis.circle(40, 180)
    alexis.forward(275)
    alexis.left(90)
    alexis.end_fill()

def draw_housing():
    """ Draw a nice housing to hold the traffic lights """
    tess.pensize(3)
    tess.color("black", "darkgrey")
    tess.begin_fill()
    tess.forward(80)
    tess.left(90)
    tess.forward(200)
    tess.circle(40, 180)
    tess.forward(200)
    tess.left(90)
    tess.end_fill()



draw_housing()
draw_housing2()

tess.penup()
# Position tess onto the place where the green light should be
tess.forward(40)
tess.left(90)
tess.forward(50)
# Turn tess into a big green circle
tess.shape("circle")
tess.shapesize(3)
tess.fillcolor("green")
alexis.penup()
alexis.forward(40)
alexis.left(90)
alexis.forward(50)
alexis.shape("circle")
alexis.shapesize(3)
alexis.fillcolor("gray")
bob = turtle.Turtle()
bob.penup()
bob.goto(alexis.position()[0], (alexis.position()[1] + 75))
bob.shape('circle')
bob.shapesize(3)
bob.fillcolor("gray")
chris = turtle.Turtle()
chris.penup()
chris.goto(bob.position()[0], (bob.position()[1] + 75))
chris.shape('circle')
chris.shapesize(3)
chris.fillcolor('gray')
jeff = turtle.Turtle()
jeff.penup()
jeff.goto(chris.position()[0], (chris.position()[1] + 75))
jeff.shape('circle')
jeff.shapesize(3)
jeff.fillcolor('gray')

# A traffic light is a kind of state machine with three states,
# Green, Orange, Red.  We number these states  0, 1, 2
# When the machine changes state, we change tess' position and
# her fillcolor.

# This variable holds the current state of the machine
state_num = 0
state_num_1 = 0

def advance_state_machine():
    global state_num
    if state_num == 0:       # Transition from state 0 to state 1
        tess.forward(70)
        tess.fillcolor("orange")
        state_num = 1
    elif state_num == 1:     # Transition from state 1 to state 2
        tess.forward(70)
        tess.fillcolor("red")
        state_num = 2
    else:                     # Transition from state 2 to state 0
        tess.back(140)
        tess.fillcolor("green")
        state_num = 0
    wn.ontimer(advance_state_machine, "5000")

def advance_state_machine2():
    global state_num_1
    if state_num_1 == 0:       # Transition from state 0 to state 1
        jeff.fillcolor('gray')
        alexis.fillcolor('green')
        state_num_1 = 1
    elif state_num_1 == 1:     # Transition from state 1 to state 2
        alexis.fillcolor('gray')
        bob.fillcolor('green')
        chris.fillcolor('orange')
        state_num_1 = 2
    elif state_num_1 == 2:
        bob.fillcolor('gray')
        chris.fillcolor('gray')
        jeff.fillcolor('red')
        state_num_1 = 0
    wn.ontimer(advance_state_machine2, "5000")

advance_state_machine()
advance_state_machine2()

wn.mainloop()

除了改变计时器的部分外,我已经完成了所有工作。看来我只能在wn.ontimer(advanced_state_machine2,timer)语句中使用一个整数,当我尝试使用列表时,它失败了。

1 个答案:

答案 0 :(得分:0)

只看第二种,四种颜色的光,而不是让你的状态机都是基于代码的,你可以使它成为一个数据结构,包括保持在该状态的时间量:

from turtle import Turtle, Screen

def draw_housing():
    ''' Draw a nice housing to hold the traffic lights '''
    alexis.pensize(3)
    alexis.color('black', 'darkgrey')
    alexis.penup()
    alexis.backward(180)
    alexis.pendown()
    alexis.begin_fill()
    alexis.forward(80)
    alexis.left(90)
    alexis.forward(275)
    alexis.circle(40, 180)
    alexis.forward(275)
    alexis.left(90)
    alexis.end_fill()

wn = Screen()
wn.title('Alex becomes a traffic light!')
wn.bgcolor('lightgreen')

alexis = Turtle()

draw_housing()

alexis.shape('circle')
alexis.penup()
alexis.forward(40)
alexis.left(90)
alexis.forward(50)
alexis.shapesize(3)
alexis.fillcolor('gray')

bob = Turtle('circle')
bob.penup()
bob.goto(alexis.xcor(), alexis.ycor() + 75)
bob.shapesize(3)
bob.fillcolor('gray')

chris = Turtle('circle')
chris.penup()
chris.goto(bob.xcor(), bob.ycor() + 75)
chris.shapesize(3)
chris.fillcolor('gray')

jeff = Turtle('circle')
jeff.penup()
jeff.goto(chris.xcor(), chris.ycor() + 75)
jeff.shapesize(3)
jeff.fillcolor('gray')

state_num = 0

state_machine = { \
    0: ('green', None, None, 'gray', 3), \
    1: ('gray', 'green', 'orange', None, 1), \
    2: (None, 'gray', None, None, 1), \
    3: (None, None, 'gray', 'red', 2), \
}

def advance_state_machine():
    global state_num

    *colors, time = state_machine[state_num]

    for i, light in enumerate([alexis, bob, chris, jeff]):
        if colors[i] is not None:
            light.fillcolor(colors[i])

    state_num = (state_num + 1) % len(state_machine)

    wn.ontimer(advance_state_machine, time * 1000)

advance_state_machine()

wn.mainloop()

None的颜色表示没有变化。一个稍微好一点的实现将是一个海龟/灯阵列,而不是单独命名的海龟,这将清理逻辑。