-
Notifications
You must be signed in to change notification settings - Fork 0
/
ai_controllers.py
150 lines (114 loc) · 4.65 KB
/
ai_controllers.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
150
class AIController():
"""Abstract/Base controller for AI."""
def __init__ (self, mission_model, entity_id):
""" Constructor. pass in the id of the entity to control."""
self.mission_model = mission_model
self._init_entities(entity_id)
self.next_moves_by_entity_id = {}
def _init_entities(self,entity_id):
"""Internal method to set the internal entity ids. Can be overwritten."""
self.entity_id = entity_id
def determine_next_moves(self):
"""Process the AI to figure out and store the next moves for the entities in controlled.
"""
pass
def get_next_moves(self):
"""Return the already stored moves.
"""
return self.next_moves_by_entity_id
def clear_all_ai_moves(self):
"""Clear all of the moves.
"""
self.next_moves_by_entity_id = {}
def delete_entities(self, entity_ids_to_delete):
"""Remove the given entities from consideration.
Subclasses should overwrite this.
"""
pass
class AlwaysWait(AIController):
"""AI will always wait.
"""
def determine_next_moves(self):
self.next_moves_by_entity_id[self.entity_id] = 'W'
class ChaseTheFox(AIController):
"""AI will try to move one step closer to the fox.
"""
def _init_entities(self, entity_id):
"""Internal method to set the internal entity ids. Can be overwritten."""
# If entity_ids is a single item, put it in a list
if isinstance(entity_id, basestring):
entity_id = [entity_id]
self.entity_ids = entity_id
def determine_next_moves(self):
# Clear out previous round's instructions
self.next_moves_by_entity_id = {}
# Because you can move in eight directions, move towards the fox.
fox_entity = self.mission_model.all_entities_by_id['fox']
# Get the fox's position
fox_position_x = fox_entity.position_x
fox_position_y = fox_entity.position_y
# For each entity
for entity_id in self.entity_ids:
entity = self.mission_model.all_entities_by_id[entity_id]
# Get the entity's position
entity_position_x = entity.position_x
entity_position_y = entity.position_y
entity_direction_x = ""
entity_direction_y = ""
# Move towards the fox
if fox_position_x < entity_position_x:
entity_direction_x = 'L'
elif fox_position_x > entity_position_x:
entity_direction_x = 'R'
if fox_position_y < entity_position_y:
entity_direction_y = 'D'
elif fox_position_y > entity_position_y:
entity_direction_y = 'U'
final_direction = entity_direction_y + entity_direction_x
if final_direction == "":
final_direction = 'W'
# Store this result for later.
self.next_moves_by_entity_id[entity_id] = final_direction
def delete_entities(self, entity_ids_to_delete):
"""Remove the given entities from consideration.
Subclasses should overwrite this.
"""
for id in entity_ids_to_delete:
self.entity_ids.remove(id)
class ManualInstructions(AIController):
"""AI waits for an instruction.
"""
def __init__(self, *args, **kwargs):
AIController.__init__(self, *args, **kwargs)
self.next_instruction = None
def add_instruction(self, instruction):
"""Changes the next input to be consumed.
"""
self.next_instruction = instruction
def determine_next_moves(self):
"""Consume the next_instruction.
"""
next_instruction = 'W'
if self.next_instruction:
next_instruction = self.next_instruction
self.next_instruction = None
# Store the id for this unit.
self.next_moves_by_entity_id[self.entity_id] = next_instruction
class ReplayInstructions(AIController):
"""AI maintains a queue of instructions and processes one per turn.
"""
def __init__(self, *args, **kwargs):
AIController.__init__(self, *args, **kwargs)
self.next_instructions = []
def add_instructions(self, instructions):
"""Changes the next input to be consumed.
"""
self.next_instructions += instructions
def determine_next_moves(self):
"""Consume the next_instruction.
"""
next_instruction = 'W'
if len(self.next_instructions) > 0:
next_instruction = self.next_instructions.pop(0)
# Store the id for this unit.
self.next_moves_by_entity_id[self.entity_id] = next_instruction