def __init__(self, position, velocity, identifier=None, **kwargs): """ Initialize a particle by assigning a position and velocity to it. Optional parameters include assigning an idx value (a unique way to identify the particle) and the world it belongs to, so that it can be bound to discover its own neighborhood. """ self.params = kwargs.get('params', world_parameters) self.pos = Vector.arr(position) # Init vectors here? self.vel = Vector.arr(velocity) # Init vectors here? self.idx = identifier self.world = kwargs.get('world', None) # Initialize in world self.state = kwargs.get('state', SPREADING) # Set initial state... self.team = kwargs.get('team', 'ally') # Set the team self.home = kwargs.get('home', None) # Remember where home is self.memory = [] # Initialize the memory self.target = None # Initialize target self.loaded = False # Are we carrying minerals or not? self.enemy = "enemy" if self.team == "ally" else ("ally" if self.team == "enemy" else None) self.stun_cooldown = 0 # Hidden variables to reduce computation complexity self._pos = None # Holder for new position self._vel = None # Holder for new velocity self._state = None # Holder for new state self._target = None # Holder for new target self._loaded = None # Holder for loaded state self._neighbors = None # Holder for neighbors in RMAX
def test_mineral_init(self): """ Check that minerals can be instantiated irregularly """ stash = parameters.get('stash_size') mineral = ResourceParticle(Vector.arrp(15,15)) self.assertEqual(mineral.stash, stash) self.assertEqual(mineral.vel, Vector.arrp(0,1))
def test_bound(self): """ Test bound vs unbound Particles """ particle = Particle(Vector.rand(12), Vector.rand(12), 'test') self.assertFalse(particle.is_bound()) self.assertIn('unbound', repr(particle)) world = World(agents=[]) world.add_agent(particle) self.assertTrue(particle.is_bound()) self.assertIn('world', repr(particle))
def __init__(self, pos, **kwargs): # Create the stash that the minerals contain self.stash = kwargs.get('stash_size', world_parameters.get('stash_size')) # Pass everything else back to super kwargs['team'] = kwargs.get('team', 'mineral') # Add the default team super(ResourceParticle, self).__init__(pos, Vector.arrp(0,1), **kwargs)
def test_cohesion(self): """ Test the cohesion computation """ expected = Vector.arr(np.array([ 0.26094689, 0.37837299])) velocity = self.particle.cohesion() msg = "expected vector: %s does not match computed vector: %s" % (expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_homing(self): """ Test the homing computation """ expected = Vector.arr(np.array([ 70.71067812, -70.71067812])) velocity = self.particle.homing() msg = "expected vector: %s does not match computed vector: %s" % (expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_alignment(self): """ Test the alignment computation """ expected = Vector.arr(np.array([ 1.11143669, 0.55571835])) velocity = self.particle.alignment() msg = "expected vector: %s does not match computed vector: %s" % (expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_avoidance(self): """ Test the avoidance computation """ expected = Vector.arr(np.array([-35.35533906, 35.35533906])) velocity = self.particle.avoidance() msg = "expected vector: %s does not match computed vector: %s" % (expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_separation(self): """ Test the separation computation """ expected = Vector.arr(np.array([-3.73398612, -5.43125254])) velocity = self.particle.separation() msg = "expected vector: %s does not match computed vector: %s" % (expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_clearance(self): """ Test the clearance computation """ expected = Vector.arr(np.array([ 9.83078305, -6.88154813])) velocity = self.particle.clearance() msg = "expected vector: %s does not match computed vector: %s" % (expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_avoidance(self): """ Test the avoidance computation """ expected = Vector.arr(np.array([-35.35533906, 35.35533906])) velocity = self.particle.avoidance() msg = "expected vector: %s does not match computed vector: %s" % ( expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def __init__(self, pos, **kwargs): # Create the stash that the minerals contain self.stash = kwargs.get('stash_size', world_parameters.get('stash_size')) # Pass everything else back to super kwargs['team'] = kwargs.get('team', 'mineral') # Add the default team super(ResourceParticle, self).__init__(pos, Vector.arrp(0, 1), **kwargs)
def test_separation(self): """ Test the separation computation """ expected = Vector.arr(np.array([-3.73398612, -5.43125254])) velocity = self.particle.separation() msg = "expected vector: %s does not match computed vector: %s" % ( expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_seeking(self): """ Test the seeking computation """ expected = Vector.arr(np.array([70.71067812, -70.71067812])) velocity = self.particle.seeking() msg = "expected vector: %s does not match computed vector: %s" % ( expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def test_alignment(self): """ Test the alignment computation """ expected = Vector.arr(np.array([1.11143669, 0.55571835])) velocity = self.particle.alignment() msg = "expected vector: %s does not match computed vector: %s" % ( expected, velocity) self.assertTrue(np.allclose(expected, velocity), msg=msg)
def relative_pos(self, point): size_x = self.world.size[0] size_y = self.world.size[1] rel_x = self.pos.x rel_y = self.pos.y if (abs(self.pos.x - point.x) > size_x / 2): rel_x += (-1 if (self.pos.x - point.x) > 0 else 1) * size_x if (abs(self.pos.y - point.y) > size_y / 2): rel_y += (-1 if (self.pos.y - point.y) > 0 else 1) * size_y return Vector.arrp(rel_x, rel_y)
def alignment(self): """ Reports the alignment velocity from an array of neighbors """ r = self.components['alignment'].radius a = self.components['alignment'].alpha neighbors = [x for x in list(self.neighbors(r,a, team=self.team)) if (x.state == SEEKING or x.state == SPREADING)] if not neighbors: return Vector.zero() center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) deltap = center - self.pos scale = deltap.length2 / (r*r) avgvel = np.average(list(n.vel for n in neighbors), axis=0) deltav = Vector.arr(avgvel) return VMAX * deltav.unit * scale
def relative_pos(self, point): size_x = self.world.size[0] size_y = self.world.size[1] rel_x = self.pos.x rel_y = self.pos.y if (abs(self.pos.x - point.x) > size_x / 2): rel_x += (-1 if (self.pos.x - point.x) > 0 else 1) * size_x if (abs(self.pos.y - point.y) > size_y/ 2): rel_y += (-1 if (self.pos.y - point.y) > 0 else 1) * size_y return Vector.arrp(rel_x, rel_y)
def test_mineral_mine(self): """ Test mineral mining """ stash = parameters.get('stash_size') mineral = ResourceParticle(Vector.arrp(15,15)) self.assertEqual(mineral.stash, stash) for i in xrange(0, stash): self.assertTrue(mineral.mine()) self.assertFalse(mineral.mine()) self.assertFalse(mineral)
def test_mineral_mine(self): """ Test mineral mining """ stash = parameters.get('stash_size') mineral = ResourceParticle(Vector.arrp(15, 15)) self.assertEqual(mineral.stash, stash) for i in xrange(0, stash): self.assertTrue(mineral.mine()) self.assertFalse(mineral.mine()) self.assertFalse(mineral)
def test_periodic_find_closest(self): """ Test that the find nearest can see periodic boundaries """ agents = [ Particle(Vector.arrp(10, 10), Vector.rand(6), 'a'), Particle(Vector.arrp(10, 990), Vector.rand(6), 'b'), Particle(Vector.arrp(990, 10), Vector.rand(6), 'c'), Particle(Vector.arrp(990, 990), Vector.rand(6), 'd'), ] world = World(agents=agents, world_size=1000) expected = world.agents[1] observed = world.agents[0].find_nearest(100, 360) self.assertEqual(expected, observed)
def alignment(self): """ Reports the alignment velocity from an array of neighbors """ r = self.components['alignment'].radius a = self.components['alignment'].alpha neighbors = [ x for x in list(self.neighbors(r, a, team=self.team)) if (x.state == SEEKING or x.state == SPREADING) ] if not neighbors: return Vector.zero() center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) deltap = center - self.pos scale = deltap.length2 / (r * r) avgvel = np.average(list(n.vel for n in neighbors), axis=0) deltav = Vector.arr(avgvel) return VMAX * deltav.unit * scale
def update_position(self): """ Adds the velocity to get a new position, also ensures a periodic world by using modulo against the width and height of the world. """ if self.state == STUNNED: self._pos = self.pos return newpos = self.pos + self._vel x = newpos.x % self.world.size[0] y = newpos.y % self.world.size[1] self._pos = Vector.arrp(x, y)
def update_position(self): """ Adds the velocity to get a new position, also ensures a periodic world by using modulo against the width and height of the world. """ if self.state == STUNNED: self._pos = self.pos return newpos = self.pos + self._vel x = newpos.x % self.world.size[0] y = newpos.y % self.world.size[1] self._pos = Vector.arrp(x,y)
def test_periodic_neighborhood(self): """ Test that the neighborhood can see periodic boundaries """ agents = [ Particle(Vector.arrp(10, 10), Vector.rand(6), 'a'), Particle(Vector.arrp(10, 990), Vector.rand(6), 'b'), Particle(Vector.arrp(990, 10), Vector.rand(6), 'c'), Particle(Vector.arrp(990, 990), Vector.rand(6), 'd'), ] world = World(agents=agents, world_size=1000) expected = {'b', 'c', 'd'} observed = set([]) for neighbor in world.agents[0].neighbors(100, 360): observed.add(neighbor.idx) self.assertEqual(expected, observed)
def test_periodic_neighborhood(self): """ Test that the neighborhood can see periodic boundaries """ agents = [ Particle(Vector.arrp(10, 10), Vector.rand(6), 'a'), Particle(Vector.arrp(10, 990), Vector.rand(6), 'b'), Particle(Vector.arrp(990, 10), Vector.rand(6), 'c'), Particle(Vector.arrp(990, 990), Vector.rand(6), 'd'), ] world = World(agents=agents, world_size=1000) expected = {'b','c','d'} observed = set([]) for neighbor in world.agents[0].neighbors(100, 360): observed.add(neighbor.idx) self.assertEqual(expected, observed)
def clearance(self): """ Reports the clearance velocity orthogonal to current velocity """ r = self.components['clearance'].radius a = self.components['clearance'].alpha neighbors = list(n for n in self.neighbors(r,a, team=self.team) if (n.state != GUARDING and n.state != STUNNED)) if neighbors: center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) delta = center - self.pos if (np.cross(delta, self.vel) < 0): delta *= -1 return VMAX * delta.orthogonal return Vector.zero()
def cohesion(self): """ Reports cohesion velocity from an array of neighbors """ r = self.components['cohesion'].radius a = self.components['cohesion'].alpha neighbors = [n for n in self.neighbors(r,a, team=self.team) if (n.state != GUARDING and n.state != STUNNED)] if not neighbors: return Vector.zero() center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) delta = center - self.pos scale = (delta.length / r) ** 2 vmaxrt = VMAX * delta.unit return vmaxrt * scale
def clearance(self): """ Reports the clearance velocity orthogonal to current velocity """ r = self.components['clearance'].radius a = self.components['clearance'].alpha neighbors = list(n for n in self.neighbors(r, a, team=self.team) if (n.state != GUARDING and n.state != STUNNED)) if neighbors: center = np.average(list( n.relative_pos(self.pos) for n in neighbors), axis=0) delta = center - self.pos if (np.cross(delta, self.vel) < 0): delta *= -1 return VMAX * delta.orthogonal return Vector.zero()
def avoidance(self): """ Reports the avoidance velocity from an array of agents on the opposing team. Changed the formula to (r - dp.length /r) """ r = self.components['avoidance'].radius a = self.components['avoidance'].alpha neighbors = [x for x in list(self.neighbors(r,a, team=self.enemy)) if x.state != STUNNED] arr = np.zeros(2) for n in neighbors: delta = self.pos - n.relative_pos(self.pos) scale = (r - delta.length) / r arr += scale * delta.unit * VMAX return Vector.arr(arr)
def separation(self): """ Reports the separation velocity from an array of neighbors Changed the formula to (r-dp.length /r)**2 """ r = self.components['separation'].radius a = self.components['separation'].alpha neighbors = list(self.neighbors(r,a, team=self.team)) if not neighbors: return Vector.zero() center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) delta = center - self.pos scale = ((r - delta.length) / r) ** 2 vmaxrt = VMAX * delta.unit return -1 * vmaxrt * scale
def cohesion(self): """ Reports cohesion velocity from an array of neighbors """ r = self.components['cohesion'].radius a = self.components['cohesion'].alpha neighbors = [ n for n in self.neighbors(r, a, team=self.team) if (n.state != GUARDING and n.state != STUNNED) ] if not neighbors: return Vector.zero() center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) delta = center - self.pos scale = (delta.length / r)**2 vmaxrt = VMAX * delta.unit return vmaxrt * scale
def separation(self): """ Reports the separation velocity from an array of neighbors Changed the formula to (r-dp.length /r)**2 """ r = self.components['separation'].radius a = self.components['separation'].alpha neighbors = list(self.neighbors(r, a, team=self.team)) if not neighbors: return Vector.zero() center = np.average(list(n.relative_pos(self.pos) for n in neighbors), axis=0) delta = center - self.pos scale = ((r - delta.length) / r)**2 vmaxrt = VMAX * delta.unit return -1 * vmaxrt * scale
def avoidance(self): """ Reports the avoidance velocity from an array of agents on the opposing team. Changed the formula to (r - dp.length /r) """ r = self.components['avoidance'].radius a = self.components['avoidance'].alpha neighbors = [ x for x in list(self.neighbors(r, a, team=self.enemy)) if x.state != STUNNED ] arr = np.zeros(2) for n in neighbors: delta = self.pos - n.relative_pos(self.pos) scale = (r - delta.length) / r arr += scale * delta.unit * VMAX return Vector.arr(arr)
def setUp(self): agents = [ Particle(Vector.arrp(90, 90), Vector.arrp(10, 10), 'a'), Particle(Vector.arrp(100, 140), Vector.arrp(10, 0), 'b'), Particle(Vector.arrp(120, 160), Vector.arrp(10, 0), 'c'), Particle(Vector.arrp(140, 140), Vector.arrp(0, 10), 'd'), Particle(Vector.arrp(140, 120), Vector.arrp(10, 10), 'e'), Particle(Vector.arrp(180, 220), Vector.arrp(10, 0), 'f'), Particle(Vector.arrp(60, 50), Vector.arrp(-10, -10), 'g'), ] self.world = World(agents=agents) self.particle = self.world.agents[0] assert self.particle.idx == 'a'
def setUp(self): agents = [ Particle(Vector.arrp( 90 ,90 ), Vector.arrp( 10, 10), 'a'), Particle(Vector.arrp( 100,140), Vector.arrp( 10, 0 ), 'b'), Particle(Vector.arrp( 120,160), Vector.arrp( 10, 0 ), 'c'), Particle(Vector.arrp( 140,140), Vector.arrp( 0 , 10), 'd'), Particle(Vector.arrp( 140,120), Vector.arrp( 10, 10), 'e'), Particle(Vector.arrp( 180,220), Vector.arrp( 10, 0 ), 'f'), Particle(Vector.arrp( 60 ,50 ), Vector.arrp(-10,-10), 'g'), ] self.world = World(agents=agents) self.particle = self.world.agents[0] assert self.particle.idx == 'a'
def setUp(self): agents = [ Particle(Vector.arrp(90, 90), Vector.arrp(10, 10), 'a', team='blue'), Particle(Vector.arrp(50, 50), Vector.arrp(10, 0), 'b', team='blue'), Particle(Vector.arrp(130, 130), Vector.arrp(10, 0), 'c', team='blue'), Particle(Vector.arrp(90, 50), Vector.arrp(0, 10), 'd', team='blue'), Particle(Vector.arrp(90, 130), Vector.arrp(10, 10), 'e', team='blue'), Particle(Vector.arrp(50, 90), Vector.arrp(10, 0), 'f', team='gold'), Particle(Vector.arrp(130, 90), Vector.arrp(-10, -10), 'g', team='gold'), Particle(Vector.arrp(130, 50), Vector.arrp(10, 0), 'h', team='gold'), Particle(Vector.arrp(50, 130), Vector.arrp(10, -10), 'i', team='gold'), Particle(Vector.arrp(50, 70), Vector.arrp(-10, 10), 'j', team='gold'), Particle(Vector.arrp(80, 75), Vector.arrp(-10, -10), 'k', team='enemy'), ] self.world = World(agents=agents) self.particle = self.world.agents[0] assert self.particle.idx == 'a'
def setUp(self): agents = [ Particle(Vector.arrp(90,90), Vector.arrp(10, 10), 'a', team='blue'), Particle(Vector.arrp(50,50), Vector.arrp(10, 0), 'b', team='blue'), Particle(Vector.arrp(130,130), Vector.arrp(10, 0), 'c', team='blue'), Particle(Vector.arrp(90, 50), Vector.arrp(0 , 10), 'd', team='blue'), Particle(Vector.arrp(90, 130), Vector.arrp(10, 10), 'e', team='blue'), Particle(Vector.arrp(50, 90), Vector.arrp(10, 0), 'f', team='gold'), Particle(Vector.arrp(130, 90), Vector.arrp(-10,-10), 'g', team='gold'), Particle(Vector.arrp(130, 50), Vector.arrp(10, 0), 'h', team='gold'), Particle(Vector.arrp(50, 130), Vector.arrp(10, -10), 'i', team='gold'), Particle(Vector.arrp(50, 70), Vector.arrp( -10, 10), 'j', team='gold'), Particle(Vector.arrp(80, 75), Vector.arrp(-10,-10), 'k', team='enemy'), ] self.world = World(agents=agents) self.particle = self.world.agents[0] assert self.particle.idx == 'a'