forked from AllenDowney/ThinkPython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTagger.py
149 lines (113 loc) · 3.67 KB
/
Tagger.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""This module contains code from
Think Python by Allen B. Downey
http://thinkpython.com
Copyright 2012 Allen B. Downey
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
"""
import math
from Wobbler import *
class Missed(Exception):
"""Exception raised when a turtle tries to tag someone too far away."""
class Tagger(Wobbler):
"""Represents a Turtle that plays tag."""
def __init__(self, world, speed=1, clumsiness=60, color='red'):
Wobbler.__init__(self, world, speed, clumsiness, color)
self.it = 0
self.sulking = 0
def steer(self):
"""Steers the Wobbler in the general direction it should go.
Postcondition: the Wobbler's heading may be changed, but
its position may not.
"""
# if sulking, decrement the sulking clock
if self.sulking > 0:
self.sulking -= 1
if self.sulking == 0:
self.color = 'red'
self.speed = self.old_speed
return
# if out of bounds, turn toward the center
if self.distance() > 200:
self.turn_toward(0, 0)
return
# if not it, just wander
if not self.it:
return
# if it, chase the closest player
target = self.closest(self.world.animals)
try:
self.apply_tag(target)
except Missed:
self.chase(target)
def turn_toward(self, x=0, y=0):
"""Turns to face the given point.
x, y: point to turn toward
"""
self.heading = self.away(x, y) + 180
self.redraw()
def away(self, x=0, y=0):
"""Computes the heading away from the given point.
x, y: point to face away from
"""
dx = self.x - x
dy = self.y - y
heading = math.atan2(dy, dx)
return heading * 180 / math.pi
def distance(self, x=0, y=0):
"""Computes the distance from this turtle to the given point.
x, y: point to find distance to
"""
dx = self.x - x
dy = self.y - y
return math.sqrt(dx**2 + dy**2)
def distance_from(self, other):
"""Computes the distance between turtles.
other: Turtle object
"""
return self.distance(other.x, other.y)
def youre_it(self):
"""Makes this turtle it."""
self.it = 1
self.old_speed = self.speed
self.old_color = self.color
self.speed = 0
self.color = 'blue'
self.sulking = 200
self.redraw()
def not_it(self):
"""Makes this turtle not it."""
self.it = 0
self.color = self.old_color
self.redraw()
def flee(self, other):
"""Faces away from the other turtle.
other: Turtle object
"""
self.heading = self.away(other.x, other.y)
def chase(self, other):
"""Faces the other turtle.
other: Turtle object
"""
self.turn_toward(other.x, other.y)
def closest(self, others):
"""Return closest animal in the list (other than self).
others: list of Animals
"""
t = [(self.distance_from(animal), animal)
for animal in others if animal is not self]
(distance, animal) = min(t)
return animal
def apply_tag(self, other):
"""Tried to tag the other turtle.
If it is too far away, raises an exception.
other: Turtle object
"""
if self.distance_from(other) < 10:
self.not_it()
other.youre_it()
else:
raise Missed
if __name__ == '__main__':
world = make_world(Tagger)
world.animals[0].youre_it()
world.mainloop()