# jmiz.py
# coded by: joel lieske
# b00516890
# april 8, 2010
import numpy
import random; random.seed()
import cgolf
import scipy
class Golfer(object):
def __init__(self, id, x, z, friends = [], foes = [], Vmin = 0., Vmax = 85.,
rpm_min = 2000., rpm_max = 10000., *args, **kwargs):
"""Initialization code for this golfer.
id: Name of this golfer.
x,z: Position assigned to this golfer.
friends: List of (name,x,z) tuples for friends.
foes: List of (name,x,z) tuples for friends.
Vmin, Vmax: The min and max launch speeds (m/s) allowed.
rpm_min, rpm_max: The min and max rotation rates (rpms) allowed.
args,kwargs: Extra positional and keyword arguments.
"""
# attatch local variables to 'self' so they can be accessed
# from swing function
self.Vmin = Vmin
self.Vmax = Vmax
self.rpm_min = rpm_min
self.rpm_max = rpm_max
self.x = x
self.z = z
self.foes = foes
self.increm = 0
# define default value for theta0
self.theta = 10
# create 3 empty lists to filter through while swinging
self.under_comp = []
self.over_comp = []
# create a list of dictionaries to store all the foes
self.dictionaries = []
self.living_foes = []
# function to simulate trajectory to a foe, and minimize error
def dist_to_foe(v0, theta0 = self.theta, rpm0 = 2000):
x_vals, z_vals = cgolf.get_trajectory(v0, theta0, rpm0, x0 = self.x, z0 = self.z)
x_rol, z_rol = cgolf.get_roll(x_vals, z_vals, get_zground=cgolf.get_zground_default, alpha=1)
x_f = cgolf.get_carry_distance(x_vals, z_vals) + cgolf.get_roll_distance(x_rol, z_rol)
distance = numpy.sqrt((x_f)**2 + (cgolf.get_zground_default(x_f))**2) - numpy.sqrt((d_x)**2 + (cgolf.get_zground_default(d_x))**2)
return distance
# returns the distance between self and a given foe
# brent optimization below will minimize this distance
# and solve for the most accurate velocity,
# while keeping theta and rpm constant
# populate self.dictionaries with locations, ids, v0s, and thetas
i=0
for j in foes:
nam = j[0]
d_x = j[1] - self.x
d_z = j[2] - self.z
# invert theta if foe is to the left
if d_x < 0:
self.theta = 180 - 10
# otherwise keep default theta = 10 deg
else:
self.theta = 10
# optimize dist_to_foe function to find optimum
# velocity to current target within foes
#
# then fill in dictionary with according values
#----------------------------------------------------------
v0 = scipy.optimize.brentq(dist_to_foe, 5., 75., xtol = .01)
dictionary = {
'nam' : nam,
'd_x' : d_x,
'd_z' : d_z,
'v0' : v0,
'theta' : self.theta
}
self.dictionaries.append(dictionary)
# define comparison function to sort dictionaries according
# to distance of foe from self, shortest to longest
def cmp(a,b):
if numpy.abs(a['d_x'])numpy.abs(['d_x']):
return 1
else:
return 0
# sort list of dictionaries using above function
self.dictionaries.sort(cmp = cmp)
def swing(self, friend_ids = [], foe_ids = [], data = [], *args, **kwargs):
"""Returns launch parameters.
friend_ids: Names of active friends.
foe_ids: Names of active foes.
data: A list of recently landed projectiles. The data for each
projectile are contained in dictionaries with the following
keys:
id - the player's name who launched this projectile
N - the shot number for this projectile
xend - the final resting ponosition of the projectile
carry - the absolute carry (m) of the projectile
roll - the absolute roll (m) of the projectile
args,kwargs: Extra positional and keyword arguments.
The launch parameters should be returned as (V0,theta0,rpm0),
or None to pass up this opportunity.
"""
# increment self.iterator to indicate which shot to take next
self.increm += 1
# this is a loop used to extract deceased foes
# and maintain the order of living foes, from closest
# to farthes from my location
liv_foes=[]
for still_alive in self.dictionaries:
for fool in foe_ids:
# print
# print fool[0]
# print still_alive['nam']
# print
if fool == still_alive['nam']:
dictionary={
'nam':still_alive['nam'],
'd_x':still_alive['d_x'],
'd_z':still_alive['d_z'],
'v0':still_alive['v0'],
'theta':still_alive['theta']
}
liv_foes.append(dictionary)
continue
# this function re-orders foe list each time it is called
# the shots start with the closest foe, and work their
# way out from there.
times=0
while times1:
liv_foes.append(liv_foes.pop(0))
times+=1
# i had a function to optimize trajectory, while compensating
# for wind, but my module was running too slow, and i died
# every time before i could get a second shot off,
# so i took it out, and my golfer seems to be doing
# much better.
# this loop 'generates' or 'looks up' previously 'optimized'
# parameters to send the golf ball projectile as close to
# foes as possible, without external interference.
for first_check in liv_foes:
if first_check:
print first_check['nam']
V0 = first_check['v0']
theta0 = first_check['theta']
rpm0 = 2000.
print 'v0'+str(self.increm)
print V0
print 'theta0'+str(self.increm)
print theta0
print
return V0, theta0, rpm0
else:
continue