Skip to content

Commit 9541aa9

Browse files
committed
Initial commit.
0 parents  commit 9541aa9

37 files changed

+3559
-0
lines changed

AI/DumbAI.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from Robots import *
2+
import Move
3+
4+
class AI(RobotAI):
5+
def getMove(self, robotstate, worldstate):
6+
return Move.TURN_RIGHT

AI/ExampleAI.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from Robots import *
2+
import Move
3+
4+
class AI(RobotAI):
5+
def __init__(self):
6+
self.firedMissileAgo = 0
7+
def getMove(self, robotstate, worldstate):
8+
# Get up to speed
9+
if(robotstate.speed < robotstate.maxspeed):
10+
return Move.SPEED_UP
11+
# If just fired missile, evade so don't shoot missile
12+
if(self.firedMissileAgo < 10):
13+
self.firedMissileAgo += 1
14+
return Move.TURN_RIGHT
15+
# Track missiles and robots in view
16+
objects = worldstate.objectsInView
17+
if( len(objects)>0 and ( (objects[0].isARobot and objects[0].colour != robotstate.colour) or objects[0].isAMissile) ):
18+
targetPos = worldstate.objectsInView[0].relativePosition
19+
alpha = robotstate.direction.angleBetween(targetPos)
20+
if(alpha > 0.1):
21+
return Move.TURN_RIGHT
22+
elif(alpha < -0.1):
23+
return Move.TURN_LEFT
24+
if(robotstate.missilesLeft<=0 or abs(alpha) < 0.05 or objects[0].isAMissile):
25+
return Move.FIRE_LASER
26+
else:
27+
self.firedMissileAgo = 0
28+
return Move.FIRE_MISSILE
29+
# Otherwise move randomly
30+
else:
31+
i = random.randint(0, 100)
32+
if(i<30):
33+
return Move.TURN_LEFT
34+
elif(i<60):
35+
return Move.TURN_RIGHT
36+
else:
37+
38+
return Move.NONE

AI/Human.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from Robots import *
2+
import Move
3+
4+
import Tkinter as tk
5+
root = tk.Tk()
6+
move = -4
7+
def keypress(event):
8+
global move
9+
if event.keysym == 'Escape':
10+
move = Move.RESIGN
11+
root.destroy()
12+
x = event.char
13+
if x == "w":
14+
move = Move.SPEED_UP
15+
elif x == "a":
16+
move = Move.TURN_LEFT
17+
elif x == "s":
18+
move = Move.SLOW_DOWN
19+
elif x == "d":
20+
move = Move.TURN_RIGHT
21+
elif x == " ":
22+
move = Move.FIRE_LASER
23+
elif x == "m":
24+
move = Move.FIRE_MISSILE
25+
else:
26+
print x
27+
root.quit()
28+
29+
class AI(RobotAI):
30+
def __init__(self):
31+
print "Press a key (Escape key to exit):"
32+
root.bind_all('<Key>', keypress)
33+
# don't show the tk window
34+
#root.withdraw()
35+
#root.mainloop()
36+
def getMove(self, robotstate, worldstate):
37+
root.mainloop()
38+
return move
39+
# respond to a key without the need to press enter

AI/Hunter.py

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
from Robots import *
2+
import Move
3+
4+
class AI(RobotAI):
5+
def __init__(self):
6+
self.firedMissileAgo = 0
7+
8+
def steerTowards(self, robotstate, relpos):
9+
alpha = robotstate.direction.angleBetween(relpos)
10+
if(alpha > 0.0):
11+
return Move.TURN_LEFT
12+
else:
13+
return Move.TURN_RIGHT
14+
def steerAway(self, robotstate, relpos):
15+
alpha = robotstate.direction.angleBetween(relpos)
16+
if(alpha > 0.0):
17+
return Move.TURN_RIGHT
18+
else:
19+
return Move.TURN_LEFT
20+
21+
def getMove(self, robotstate, worldstate):
22+
23+
# Get up to speed
24+
if(robotstate.speed < robotstate.maxspeed):
25+
return Move.SPEED_UP
26+
27+
# If just fired missile, evade so don't shoot missile
28+
if(self.firedMissileAgo < 20):
29+
self.firedMissileAgo += 1
30+
return Move.TURN_RIGHT
31+
32+
objects = worldstate.objectsInView
33+
34+
# Friendly robots in view
35+
friends = [r for r in objects if (r.isARobot and r.colour==robotstate.colour)]
36+
# Enemy robots in view
37+
enemies = [r for r in objects if (r.isARobot and r.colour!=robotstate.colour)]
38+
# Missiles in view
39+
missiles = [r for r in objects if r.isAMissile]
40+
41+
# If friend directly in front and close, nudge left
42+
if(len(friends)>0):
43+
friendangles = [ robotstate.direction.angleBetween(f.relativePosition) for f in friends if f.relativePosition.length()<60]
44+
critangles = [a for a in friendangles if abs(a)<0.2]
45+
if(len(critangles)>0):
46+
if critangles[0]>0:
47+
return Move.TURN_LEFT
48+
else:
49+
return Move.TURN_RIGHT
50+
51+
52+
53+
# If friend in view signalling red, signal green and go towards him
54+
redfriends = [r for r in friends if r.signal==Move.Signals.RED]
55+
if len(redfriends)>0 and len(enemies)==0:
56+
if robotstate.signal!=Move.Signals.GREEN: return Move.SIGNAL_GREEN
57+
return self.steerTowards(robotstate, redfriends[0].relativePosition)
58+
59+
# Turn off signal if no enemies or red friends in view
60+
if len(enemies)==0 and len(redfriends)==0 and robotstate.signal!=Move.Signals.NONE: return Move.SIGNAL_NONE
61+
62+
# If friend in view signalling green, go towards him
63+
greenfriends = [r for r in friends if r.signal==Move.Signals.GREEN]
64+
if len(greenfriends)>0 and len(enemies)==0:
65+
return self.steerTowards(robotstate, greenfriends[0].relativePosition)
66+
67+
# Signal red iff enemy in view
68+
if len(enemies)!=0 and robotstate.signal!=Move.Signals.RED: return Move.SIGNAL_RED
69+
70+
71+
# Flock
72+
if(len(friends)>0 and len(enemies)==0):
73+
# Min distance to a friend
74+
minfriend = None
75+
mindist = 999999
76+
for f in friends:
77+
if(f.relativePosition.norm() < mindist):
78+
minfriend = f
79+
mindist = f.relativePosition.norm()
80+
# Separation
81+
if(mindist<50):
82+
return self.steerAway(robotstate, f.relativePosition)
83+
# Average heading of friends
84+
heading = Vec2d(0,0)
85+
for f in friends:
86+
heading += f.direction
87+
heading.normalise()
88+
# Average position of friends
89+
relposition = Vec2d(0,0)
90+
for f in friends:
91+
relposition += f.relativePosition
92+
93+
if(random.random()<0.5):
94+
# Alignment
95+
return self.steerTowards(robotstate, heading)
96+
else:
97+
# Cohesion
98+
return self.steerTowards(robotstate, relposition)
99+
100+
101+
# Track missiles and robots in view
102+
# TODO track missiles
103+
if( len(enemies)>0 or len(missiles)>0 ):
104+
# Prioritise enemies
105+
if(len(enemies)>0):
106+
target = enemies[0]
107+
for e in enemies:
108+
if(e.relativePosition.length()<target.relativePosition.length()):
109+
target = e
110+
else:
111+
target = missiles[0]
112+
113+
targetPos = target.relativePosition
114+
# Track target
115+
alpha = robotstate.direction.angleBetween(targetPos)
116+
if(alpha > 0.05):
117+
return Move.TURN_RIGHT
118+
elif(alpha < -0.05):
119+
return Move.TURN_LEFT
120+
121+
# Target far away
122+
if(targetPos.length()>400):
123+
return Move.NONE
124+
125+
# Fire
126+
if(robotstate.missilesLeft<=0 or target.isAMissile):
127+
return Move.FIRE_LASER
128+
else:
129+
self.firedMissileAgo = 0
130+
return Move.FIRE_MISSILE
131+
# Nothing in view. Move randomly
132+
else:
133+
i = random.randint(0, 100)
134+
if(i<30):
135+
return Move.TURN_LEFT
136+
elif(i<60):
137+
return Move.TURN_RIGHT
138+
else:
139+
140+
return Move.NONE

AI/__init__.py

Whitespace-only changes.

Client.py

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/usr/bin/python
2+
from lib.PodSixNet.PodSixNet.Connection import connection, ConnectionListener
3+
import time
4+
import WorldStates
5+
import Robots
6+
import Move
7+
import sys
8+
import signal
9+
import getopt
10+
11+
class Client(ConnectionListener):
12+
def __init__(self, ai, colour, addr=("127.0.0.1", 12345), verbose=True):
13+
self.ai = ai
14+
self.colour = colour
15+
self.verbose = verbose
16+
self.Connect(addr)
17+
self.speak("Client connecting to " + addr[0] + ":" + str(addr[1]))
18+
self.speak("Ctrl-C to exit")
19+
self.sendRobot()
20+
signal.signal(signal.SIGINT, self.resign)
21+
22+
def speak(self, text):
23+
if self.verbose:
24+
print "[client]", text
25+
26+
def Network(self, data):
27+
pass
28+
def Network_chat(self, data):
29+
if self.verbose: print "[server]", data["text"]
30+
# Called when server requests a move
31+
def Network_requestMove(self, data):
32+
worldstatepacked = data["worldstate"]
33+
robotstatepacked = data["robotstate"]
34+
robotstate = Robots.RobotState.unpack( robotstatepacked )
35+
worldstate = WorldStates.WorldState.unpack( worldstatepacked )
36+
move = self.ai.getMove(robotstate, worldstate)
37+
self.sendMove(move)
38+
if move==Move.RESIGN:
39+
time.sleep(0.1)
40+
sys.exit(0)
41+
# Called when dead / game over
42+
def Network_kick(self, data):
43+
self.speak("Got kicked (" + data["reason"] + ")")
44+
sys.exit(0)
45+
def Network_informRobotUID(self, data):
46+
self.speak("Got robot UID " + str(data["uid"]))
47+
48+
49+
# Send a move to the server
50+
def sendMove(self, move):
51+
connection.Send({"action": "move", "move": move})
52+
connection.Pump()
53+
self.Pump()
54+
# Send my robot to the server
55+
def sendRobot(self):
56+
connection.Send({"action": "placeRobot", "colour": self.colour})
57+
self.Pump()
58+
connection.Pump()
59+
# Send my resignation (and wait for kick message)
60+
def resign(self, handler, frame):
61+
self.speak("Sending resignation.")
62+
connection.Send({"action": "resign"})
63+
self.Pump()
64+
connection.Pump()
65+
# Sleep for a small amount of time
66+
# to allow server to process request,
67+
# so it doesn't try to write to closed connection
68+
time.sleep(0.1)
69+
sys.exit(0)
70+
71+
def Loop(self):
72+
while True:
73+
self.Pump()
74+
connection.Pump()
75+
time.sleep(0.0001)
76+
77+
# Get around __import__ only importing top-level module
78+
def my_import(name):
79+
mod = __import__(name)
80+
components = name.split('.')
81+
for comp in components[1:]:
82+
mod = getattr(mod, comp)
83+
return mod
84+
85+
def usage():
86+
print "Usage: " + sys.argv[0] + " [-a AIname, --ai=AIname] [-t team, --team=team] [-s host:port, --server=host:port]"
87+
88+
if __name__ == "__main__":
89+
try:
90+
opts, args = getopt.getopt(sys.argv[1:], "hva:t:s:", ["help", "ai=", "team=", "server="])
91+
except getopt.GetoptError, err:
92+
# print help information and exit:
93+
print str(err) # will print something like "option -a not recognized"
94+
usage()
95+
sys.exit(2)
96+
aiName = "ExampleAI"
97+
verbose = False
98+
team = 0
99+
server = "localhost:12345"
100+
for o, a in opts:
101+
if o == "-v":
102+
verbose = True
103+
elif o in ("-h", "--help"):
104+
usage()
105+
sys.exit()
106+
elif o in ("-a", "--ai"):
107+
aiName = a
108+
elif o in ("-t", "--team"):
109+
team = int(a) % Robots.Teams.num
110+
elif o in ("-s", "--server"):
111+
server = a
112+
else:
113+
assert False, "unhandled option"
114+
115+
aiString = "AI." + aiName
116+
aiModule = my_import(aiString)
117+
ai = aiModule.AI()
118+
119+
host, port = server.split(":")
120+
addr = (host, int(port))
121+
122+
print "Using AI module", aiModule
123+
print "Joining " + Robots.Teams.Name[team] + " team on " + server
124+
125+
client = Client(ai, team, addr, verbose)
126+
client.Loop()
127+
128+
129+

0 commit comments

Comments
 (0)