Skip to content

Instantly share code, notes, and snippets.

@cecyurbina
Created May 21, 2013 08:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cecyurbina/5618420 to your computer and use it in GitHub Desktop.
Save cecyurbina/5618420 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
#Autor
#Sandra Cecilia Urbina Coronado
#----------------------------------------------------------
import pygame
from pygame.locals import *
import random, math, sys
import time
import random
import numpy
import threading
# ==================================================
# -------- CONSTANTES ---------
PARTICULAS_DEFAULT = 100
PROPORCION_DEFAULT = 20
NODOS = list()
BLANCOS = list()
# --------- PANTALLA ----------
PANTALLA = {
'ANCHO': 800,
'ALTO': 600,
'RESOLUCION': (800, 600),
'FPS': 30
}
# --------- COLORES ----------
COLORES = {
'NEGRO': (0,0,0),
'BLANCO': (255,255,255)
}
# --------- PYGAME ----------
pygame.init()
fpsClock = pygame.time.Clock()
VENTANA = pygame.display.set_mode(PANTALLA['RESOLUCION'])
pygame.display.set_caption('simulacion')
# ==================================================
def creaVector((ang1, len1), (ang2, len2)):
x = math.sin(ang1) * len1 + math.sin(ang2) * len2
y = math.cos(ang1) * len1 + math.cos(ang2) * len2
len = math.hypot(x, y)
ang = 0.5 * math.pi - math.atan2(y, x)
return (ang, len)
def exp(lamb):
return (-1*math.log(random.random( ))/lamb)
class Nodo:
def __init__(self, ID, radio, color):
self.id = ID
self.x = random.randint(10,PANTALLA['ANCHO'])
self.y = random.randint(10,PANTALLA['ALTO'])
self.radio = radio
self.color = color
self.ang = 0
self.vel = 0
self.bateria = 120
self.ttl = 3
self.visitado = False
self.papa = None
self.hijo = None
self.tiempo = time.time()
self.mueves = True
def mueve(self):
"""obtiene las nuevas posiciones
"""
global NODOS
(self.ang, self.vel) = creaVector((self.ang, self.vel), (random.uniform(0,math.pi*2), numpy.random.poisson(4)*.01))
self.x += math.sin(self.ang) * self.vel
self.y -= math.cos(self.ang) * self.vel
self.bounce()
self.dibuja()
def dibuja(self):
"""actualiza el canvas
"""
global VENTANA, COLORES
pygame.draw.circle(VENTANA, self.color, (int(self.x), int(PANTALLA['ALTO'] - self.y)), int(round(self.radio)))
def bounce(self):
"""para que no se salgan de la pantalla
"""
largo = 800
ancho = 600
if self.x > largo - self.radio:
self.x = 2*(largo - self.radio) - self.x
self.ang = - self.ang
elif self.x < self.radio:
self.x = 2*self.radio - self.x
self.ang = - self.ang
if self.y > ancho - self.radio:
self.y = 2*(ancho - self.radio) - self.y
self.ang = math.pi - self.ang
elif self.y < self.radio:
self.y = 2*self.radio - self.y
self.ang = math.pi - self.ang
def getInput():
"""para terminar la animacion adecuadamente
"""
presiona = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == QUIT or presiona[K_ESCAPE]:
pygame.quit()
sys.exit()
class agrega(threading.Thread):
"""agrega el numero de nodos indicado
"""
def __init__(self):
threading.Thread.__init__(self)
self.id = 0
def run(self):
while True:
global NODOS
if self.id > PARTICULAS_DEFAULT:
color = (255, 0, 0)
radio = 30
nodo = Nodo(self.id, radio,color)
NODOS.append(nodo)
print 'enemigo %d' %nodo.id
break
color = (random.randint(100,200), random.randint(100,200), random.randint(100,200))
radio = 20
nodo = Nodo(self.id, radio,color)
NODOS.append(nodo)
print 'Se creo el nodo %d' %nodo.id
time.sleep(exp(5))
self.id += 1
class mueve(threading.Thread):
"""mueve todos los nodos que estan en la pantalla
"""
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global VENTANA
global NODOS
while True:
VENTANA.fill(COLORES['NEGRO'])
for p in NODOS:
getInput()
if p.mueves:
p.mueve()
pygame.display.update()
class elimina(threading.Thread):
"""elimina los nodos
ya sea por bateria o por tiempo cumplido
"""
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global PARTICULAS_DEFAULT, NODOS
while True:
for i in NODOS:
if (time.time() - i.tiempo)>30:
i.mueves = False
print "Nodo %s muere" %i.id
class avisa(threading.Thread):
"""manda mensajes a sus nodos dentro
del rando de su senal
"""
def __init__(self, elegido):
threading.Thread.__init__(self)
self.ele = elegido
def run(self):
global NODOS, BLANCOS
print self.ele.id
lock = threading.Lock()
global VENTANA
v = True
while True:
for i in range(len(NODOS)):
if (NODOS[i].id in BLANCOS) == False:
x = self.ele.x
y = self.ele.y
x2 = NODOS[i].x
y2 = NODOS[i].y
dist = math.hypot(x-x2, y-y2)
if dist <= self.ele.radio+100 and NODOS[i].radio != 30:
BLANCOS.append(NODOS[i].id)
pygame.draw.line(VENTANA, (255, 255, 255), (x, y), (x2, y2))
NODOS[i].ttl = self.ele.ttl - 1
NODOS[i].bateria -= NODOS[i].bateria - 40
if NODOS[i].bateria >= 0:
"El nodo %s tiene una bateria de %s" %(NODOS[i].id, NODOS[i].bateria)
if NODOS[i].ttl == 0:
print "El nodo %s ya deja de transmitir" %NODOS[i].id
break
NODOS[i].color =(255,255,255)
NODOS[i].papa = self.ele
self.ele.hijo = NODOS[i]
j = avisa(NODOS[i])
j.start()
elif NODOS[i].radio == 30:
if v:
print "Ya se vio al ENEMIGO!!"
v = False
for s in NODOS:
if s.id in BLANCOS:
s.color = (100,100,100)
if len(BLANCOS) == len(NODOS):
for n in NODOS:
n.mueves = False
else:
pass
def main():
cantidadNodos = PARTICULAS_DEFAULT
proporcion = PROPORCION_DEFAULT
print 'Se dibujaran [%d] nodos' % cantidadNodos
t = agrega()
t.start()
x = mueve()
x.start()
time.sleep(5)
pos = random.randint(0, len(NODOS)-1)
NODOS[pos].color = (255,255,255)
s = avisa(NODOS[pos])
s.start()
e = elimina()
e.start()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment