def __init__(self, channel):

        self.server = SnakePost(channel, "server")

        self.players = {}
        self.apples = []

        self.clock = pygame.time.Clock()
        self.current_time = 0
        self.new_apple_timer = Timer(Constants.NEW_APPLE_PERIOD * 1000,
                                     self.current_time,
                                     periodic=True)
        self.update_snakes_timer = Timer(0.1 * 1000,
                                         self.current_time,
                                         periodic=True)
    def __init__(self, channel):

        self.server = SnakePost(channel, "server")

        self.players = {}
        self.apples = []

        self.clock = pygame.time.Clock()
        self.current_time = 0
        self.new_apple_timer=Timer(Constants.NEW_APPLE_PERIOD*1000,self.current_time,periodic=True)
        self.update_snakes_timer = Timer(0.1 * 1000, self.current_time, periodic=True)
   YELLOW = '\033[93m'
   RED = '\033[91m'
   BOLD = '\033[1m'
   UNDERLINE = '\033[4m'
   END = '\033[0m'

print color.BOLD+"SnakeChan connection"+color.END, 

p = subprocess.Popen("python gameServer.py &", shell=True)

time.sleep(1)

client = SnakeChan()
client.connect(("127.0.0.1", 3100))

post = SnakePost(client, "client")

post.send("ping", ("127.0.0.1", 3100))
while 1:
   data = post.listen()
   if data != None:
      if data[0] == "ok":
         post.send("re", data[1])
      if data[0] == "caca":
         post.send("kill", data[1])
      if data[0] == "killed":
         post.send("finished", data[1])
      if data[0]=="bo":
         post.send("boa", data[1])
         break
time.sleep(1)
class Server:
    def __init__(self, channel):

        self.server = SnakePost(channel, "server")

        self.players = {}
        self.apples = []

        self.clock = pygame.time.Clock()
        self.current_time = 0
        self.new_apple_timer = Timer(Constants.NEW_APPLE_PERIOD * 1000,
                                     self.current_time,
                                     periodic=True)
        self.update_snakes_timer = Timer(0.1 * 1000,
                                         self.current_time,
                                         periodic=True)

    #Envoie un message a tous les clients
    def broadcast(self, message, sec=False):
        for player in self.players:
            if sec:
                self.server.sendSecure(message, player)
            else:
                self.server.send(message, player)

    # Broadcast les scores et etats de tous les joueurs
    def sendPlayerInfo(self):
        obj = "{\"players_info\": ["
        for player in self.players:
            obj += "[\"" + str(self.players[player].nickname) + "\",\"" + str(self.players[player].color) + \
                       "\"," + str(self.players[player].score) + "," + str(self.players[player].ready).lower() + "],"
        obj = obj[:-1]
        obj += "]}"
        self.broadcast(obj, True)

    # Broadcast la position de tous les snakes, et regarde si un joueur a timeout
    def sendSnakesPositions(self):
        obj = "{\"snakes\": ["
        disconnect = []
        for player in self.players:
            obj += "[\"" + str(self.players[player].nickname) + "\"," + str(
                self.players[player].positions) + "],"
            if self.players[player].last_message > (
                    Constants.PLAYER_TIMEOUT * 1000
            ) and self.current_time - self.players[player].last_message > (
                    Constants.PLAYER_TIMEOUT * 1000):
                #Le joueur n'a pas envoye de messages depuis plus de 2 secondes
                print color.RED + "Le joueur " + self.players[
                    player].nickname + " s'est deconnecte" + color.END
                disconnect.append(player)
        for p in disconnect:
            del self.players[p]
            del self.server.commDict[p]
        obj = obj[:-1]
        obj += "]}"
        self.broadcast(obj, False)

    # Broadcast les pommes
    def sendFood(self):
        obj = "{\"foods\": " + str(self.apples) + "}"
        self.broadcast(obj, True)

    # Broadcast un message pour l'agrandissement d'un serpent
    def growPlayer(self, name):
        self.broadcast("{\"grow\": \"" + name + "\"}", False)

    # Broadcast le game over d'un serpent
    def gameOver(self, name):
        print color.YELLOW + "Game over for " + name + color.END
        obj = "{\"game_over\": \"" + name + "\"}"
        self.broadcast(obj, True)

    # Routine du serveur
    def serve(self):

        while True:

            # La clock du jeu
            self.current_time += self.clock.tick(Constants.FPS)

            pieces = None  # Variable qui contiendra les donnees de connexion
            data, addr = self.server.listen()  # Attend un message d'un client

            if data is not None and not self.players.get(addr):
                #Nouveau joueur, on attrappe son username et sa couleur
                pieces = data.split('\\')
                if pieces[
                        6] is not None:  # Si on a un message du format de connexion, pieces[6] sera le username
                    # On enregistre le nouveau player
                    self.players[addr] = Player(pieces[8], pieces[6])
                    print color.GREEN + "Nouveau joueur " + pieces[
                        8] + color.END

                    #On notifie tout le monde
                    self.sendPlayerInfo()

            elif data is not None:  # On a de la donnee utilisable
                self.players[addr].last_message = self.current_time
                # On convertit le json
                dat = json.loads(data)
                for key in dat:  # Une boucle qui sera de un pas, mais qui nous permet d'avoir la cle
                    if key == "body_p":
                        # on update la position des snakes et on calcule si ils ont mange
                        self.players[addr].positions = dat[key]

                        if not self.players[
                                addr].ready:  # si le player n'est pas ready, on se fiche des pommes ou collisions.
                            continue

                        for player in self.players:  # Checkons les collisions
                            if not self.players[
                                    player].ready:  # on s'en fiche si le player n'est pas ready
                                continue
                            for position in self.players[
                                    player].positions:  # On regarde dans ses positions
                                if player == addr:  # Si on est en train de regarder le meme player que celui qui envoie body_p
                                    same = self.players[player].positions.count(
                                        self.players[player].positions[0]
                                    )  # on regarde si sa tete se confond avec son corps
                                    if (
                                            same > 1
                                    ):  # La tete est a la meme position qu'une autre case du serpent
                                        #un joueur s'est mange la queue -> game over
                                        self.gameOver(
                                            self.players[player].nickname)
                                        self.players[player].score -= 1
                                        self.players[player].ready = False
                                        self.sendPlayerInfo()
                                        break
                                else:  # Sinon on regarde si il touche un autre serpent
                                    if self.players[addr].positions[
                                            0] == position:  # il touche une autre position
                                        self.gameOver(
                                            self.players[addr].nickname)
                                        self.players[addr].score -= 1
                                        self.players[player].score += 1
                                        self.players[addr].ready = False
                                        self.sendPlayerInfo()
                                        break

                        for apple in self.apples:  # On check si le joueur a mange une pomme
                            if self.players[addr].positions[
                                    0] == apple:  # la tete est sur une pomme
                                self.apples.remove(apple)  # on enleve la pomme
                                print color.CYAN + "An apple has been eaten by " + self.players[
                                    addr].nickname + color.END
                                self.growPlayer(self.players[addr].nickname
                                                )  # le serpent grandit
                                self.players[addr].score += 1  # le score aussi
                                self.sendFood(
                                )  # On avise tout le monde que la pomme a ete mangee
                                self.sendPlayerInfo(
                                )  # On avise tout le monde des scores
                                break

                    if key == "ready":
                        print color.BOLD + self.players[
                            addr].nickname + " is now ready to play" + color.END
                        self.players[addr].ready = dat[key]
                        self.sendPlayerInfo()

            # Envoi perdiodique des positions de chacun
            if self.update_snakes_timer.expired(self.current_time):
                self.sendSnakesPositions()
            # Envoi periodique des pommes, on ne le fait pas tant que personne n'est ingame
            if self.new_apple_timer.expired(
                    self.current_time) and len(self.players) > 0:
                self.apples.append([
                    random.randint(0, Constants.UNITS - 1),
                    random.randint(0, Constants.UNITS - 1)
                ])
                self.sendFood()
class Server:

    def __init__(self, channel):

        self.server = SnakePost(channel, "server")

        self.players = {}
        self.apples = []

        self.clock = pygame.time.Clock()
        self.current_time = 0
        self.new_apple_timer=Timer(Constants.NEW_APPLE_PERIOD*1000,self.current_time,periodic=True)
        self.update_snakes_timer = Timer(0.1 * 1000, self.current_time, periodic=True)

    #Envoie un message a tous les clients
    def broadcast(self, message, sec=False):
        for player in self.players:
            if sec:
                self.server.sendSecure(message, player)
            else:
                self.server.send(message, player)

    # Broadcast les scores et etats de tous les joueurs
    def sendPlayerInfo(self):
        obj = "{\"players_info\": ["
        for player in self.players:
            obj += "[\"" + str(self.players[player].nickname) + "\",\"" + str(self.players[player].color) + \
                       "\"," + str(self.players[player].score) + "," + str(self.players[player].ready).lower() + "],"
        obj = obj[:-1]
        obj += "]}"
        self.broadcast(obj, True)

    # Broadcast la position de tous les snakes, et regarde si un joueur a timeout
    def sendSnakesPositions(self):
        obj = "{\"snakes\": ["
        disconnect = []
        for player in self.players:
            obj += "[\"" + str(self.players[player].nickname) + "\"," + str(self.players[player].positions) + "],"
            if self.players[player].last_message > (Constants.PLAYER_TIMEOUT * 1000) and self.current_time - self.players[player].last_message > (Constants.PLAYER_TIMEOUT * 1000) :
                #Le joueur n'a pas envoye de messages depuis plus de 2 secondes
                print color.RED + "Le joueur " + self.players[player].nickname + " s'est deconnecte" + color.END
                disconnect.append(player)
        for p in disconnect:
            del self.players[p]
            del self.server.commDict[p]
        obj = obj[:-1]
        obj += "]}"
        self.broadcast(obj, False)

    # Broadcast les pommes
    def sendFood(self):
        obj = "{\"foods\": " + str(self.apples) + "}"
        self.broadcast(obj, True)

    # Broadcast un message pour l'agrandissement d'un serpent
    def growPlayer(self, name):
        self.broadcast("{\"grow\": \"" + name + "\"}", False)

    # Broadcast le game over d'un serpent
    def gameOver(self, name):
        print color.YELLOW + "Game over for " + name + color.END
        obj = "{\"game_over\": \"" + name + "\"}"
        self.broadcast(obj, True)

    # Routine du serveur
    def serve(self):

        while True:

            # La clock du jeu
            self.current_time += self.clock.tick(Constants.FPS)

            pieces = None # Variable qui contiendra les donnees de connexion
            data, addr = self.server.listen() # Attend un message d'un client

            if data is not None and not self.players.get(addr):
                #Nouveau joueur, on attrappe son username et sa couleur
                pieces = data.split('\\')
                if pieces[6] is not None: # Si on a un message du format de connexion, pieces[6] sera le username
                    # On enregistre le nouveau player
                    self.players[addr] = Player(pieces[8], pieces[6])
                    print color.GREEN + "Nouveau joueur " + pieces[8] + color.END

                    #On notifie tout le monde
                    self.sendPlayerInfo()


            elif data is not None: # On a de la donnee utilisable
                self.players[addr].last_message = self.current_time
                # On convertit le json
                dat = json.loads(data)
                for key in dat: # Une boucle qui sera de un pas, mais qui nous permet d'avoir la cle
                    if key == "body_p":
                        # on update la position des snakes et on calcule si ils ont mange
                        self.players[addr].positions = dat[key]

                        if not self.players[addr].ready: # si le player n'est pas ready, on se fiche des pommes ou collisions.
                            continue

                        for player in self.players: # Checkons les collisions
                            if not self.players[player].ready: # on s'en fiche si le player n'est pas ready
                                continue
                            for position in self.players[player].positions: # On regarde dans ses positions
                                if player == addr: # Si on est en train de regarder le meme player que celui qui envoie body_p
                                    same = self.players[player].positions.count(self.players[player].positions[0]) # on regarde si sa tete se confond avec son corps
                                    if(same > 1): # La tete est a la meme position qu'une autre case du serpent
                                        #un joueur s'est mange la queue -> game over
                                        self.gameOver(self.players[player].nickname)
                                        self.players[player].score -= 1
                                        self.players[player].ready = False
                                        self.sendPlayerInfo()
                                        break
                                else: # Sinon on regarde si il touche un autre serpent
                                    if self.players[addr].positions[0] == position: # il touche une autre position
                                        self.gameOver(self.players[addr].nickname)
                                        self.players[addr].score -= 1
                                        self.players[player].score += 1
                                        self.players[addr].ready = False
                                        self.sendPlayerInfo()
                                        break

                        for apple in self.apples: # On check si le joueur a mange une pomme
                            if self.players[addr].positions[0] == apple: # la tete est sur une pomme
                                self.apples.remove(apple) # on enleve la pomme
                                print color.CYAN +  "An apple has been eaten by " + self.players[addr].nickname + color.END
                                self.growPlayer(self.players[addr].nickname) # le serpent grandit
                                self.players[addr].score += 1 # le score aussi
                                self.sendFood() # On avise tout le monde que la pomme a ete mangee
                                self.sendPlayerInfo() # On avise tout le monde des scores
                                break


                    if key == "ready":
                        print color.BOLD + self.players[addr].nickname + " is now ready to play" + color.END
                        self.players[addr].ready = dat[key]
                        self.sendPlayerInfo()

            # Envoi perdiodique des positions de chacun
            if self.update_snakes_timer.expired(self.current_time):
                self.sendSnakesPositions()
            # Envoi periodique des pommes, on ne le fait pas tant que personne n'est ingame
            if self.new_apple_timer.expired(self.current_time) and len(self.players) > 0:
                self.apples.append([random.randint(0, Constants.UNITS - 1), random.randint(0, Constants.UNITS - 1)])
                self.sendFood()
import time
from snakeChan import SnakeChan
from snakePost import SnakePost

serveur = SnakePost(SnakeChan('127.0.0.1', 3100), "serveur")
while 1:
	data = serveur.listen()
	if data[0] != None:
		if data[0] == "ping":
			serveur.sendSecure("ok", data[1])
		if data[0] == "re":
			serveur.sendSecure("caca", data[1])
		if data[0] == "kill":
			serveur.sendSecure("killed", data[1])
		if data[0] == "finished":
			serveur.sendSecure("bo", data[1])
		if data[0] == "boa":
			break
    def run(self):

        self.address = (self.preferences.get("server"), self.preferences.get("port"))

        #initialisation du snakePost
        self.client = SnakeChan()

        self.client.connect(self.address, self.preferences.get("color"), self.preferences.get("nickname"))
        self.com = SnakePost(self.client, self.preferences.get("nickname"))


        whole_second=0
        self.running=True
        while self.running:
            #time tracking
            self.current_time+=self.clock.tick(Constants.FPS)

            #check if the snake is still alive
            if not self.me.alive:
                self.me.alive=True
                self.me.restart()

            #check if game need more food
            # if self.new_apple_timer.expired(self.current_time):
            #     self.f.make()

            #check if we need to move our own snake's state
            #if we do, send an update of our position to
            #the server
            if self.move_snake_timer.expired(self.current_time):
                self.me.move()
                pos = self.me.netinfo()
                self.com.send(pos, self.address)

            #check if we need to blink the unready snakes (unready state)
            if self.blink_snake_timer.expired(self.current_time):
                for snake in self.others:
                    self.others[snake].blink()

            #cleanup background
            self.gamescreen.fill(Constants.COLOR_BG)

            #draw scores
            self.scores.draw(self.screen)

            #draw all snakes positions as last seen by the server
            #we do not compute their positions ourselves!

            for snake in self.others:
                self.others[snake].draw(self.gamescreen)

            #draw food
            self.f.draw(self.gamescreen)

            #process external events (keyboard,...)
            self.process_events()

            #then update display
            #update game area on screen container
            self.screen.blit(self.gamescreen,(self.score_width,0))

            pygame.display.update()

            # Sur message du serveur...
            data, addr = self.com.listen()

            if data is not None:

                dat = json.loads(data)

                for key in dat:

                    if key == 'players_info':
                        #On met a jour les scores et les etats des joueurs
                        for player in dat[key]:

                            if not self.others.get(player[0]): # Si on a pas de joueur de ce nom, on l'ajoute
                                self.others[player[0]] = Snake(color=pygame.color.THECOLORS[player[1]], nickname=player[0])
                                self.scores.new_score(player[0], self.others.get(player[0]).color)

                            else: # On a deja le joueur, on update son etat
                                if player[3]:
                                    self.others[player[0]].set_ready()
                                else:
                                    self.others[player[0]].set_unready()
                            # on update les scores
                            self.scores.set_score(player[0], player[2])

                    elif key == "snakes": # message de position des joueurs

                        # on regarde si il y a des serpents a enlever
                        if len(dat[key]) != len(self.others):
                            for nickname in self.others.keys():
                                connected = False
                                for val in dat[key]:
                                    if val[0] == nickname:
                                        connected = True
                                if not connected:
                                    del self.others[nickname]
                                    self.scores.del_score(nickname)

                        for val in dat[key]:
                            # si on a ce joeur et que ses positions ne sont pas vides (premier message)
                            if len(val[1]) > 0 and self.others[val[0]]:
                                self.others[val[0]].setBody(val[1])

                    elif key == "foods": # les pommes envoyees par le serveur
                        self.f.set_positions(dat[key])

                    elif key == "grow": # Un serpent a mange une pomme !
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.grow(Constants.GROW)

                    elif key == "game_over": # Desole, c'est perdu
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.restart()
class Game:
    def __init__(self):
        pygame.init()

        #get preferences
        self.preferences = Preferences()
        # self.nickname = raw_input('Choose a username: '******'Choose a color (red, green, blue, yellow, white): ')
        #resolution, flags, depth, display
        self.unit=Constants.RESOLUTION[0]/Constants.UNITS
        self.banner = Banner()
        self.score_width=self.unit*15

        if self.preferences.fullscreen:
            self.screen = pygame.display.set_mode((Constants.RESOLUTION[0]+self.score_width,\
                                               Constants.RESOLUTION[1]),pygame.FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode((Constants.RESOLUTION[0]+self.score_width,\
                                               Constants.RESOLUTION[1]),0,32)

        pygame.display.set_caption(Constants.CAPTION)

        #game area surface
        self.gamescreen = pygame.Surface(Constants.RESOLUTION)
        #score area rectangle surface
        self.scorescreen = pygame.Surface((self.score_width,Constants.RESOLUTION[1]))

        #Snake and foods manager
        self.me=Snake(color=pygame.color.THECOLORS[self.preferences.get("color")],\
                    nickname=self.preferences.get("nickname"))


        self.f=Foods()

        self.others = {}

        #Score manager
        self.scores=Scores((self.score_width,Constants.RESOLUTION[1]))

        #add our own score, the server will send us the remaining one at connection
        self.scores.new_score(self.preferences.get("nickname"),\
                        pygame.color.THECOLORS[self.preferences.get("color")])

	#game area background color
        self.gamescreen.fill(Constants.COLOR_BG)
        self.scorescreen.fill((100,100,100))

        #timers
        self.clock=pygame.time.Clock();
        self.current_time=0

        self.move_snake_timer=Timer(1.0/Constants.SNAKE_SPEED*1000,self.current_time,periodic=True)
        self.blink_snake_timer=Timer(1.0/Constants.SNAKE_BLINKING_SPEED*1000,self.current_time,periodic=True)
        self.blink_banner_timer=Timer(500,self.current_time,periodic=True)
        self.new_apple_timer=Timer(Constants.NEW_APPLE_PERIOD*1000,self.current_time,periodic=True)



    def process_events(self):
        #key handling
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                   self.running=False
                if event.key == pygame.K_UP:
                   self.me.action(1)
                if event.key == pygame.K_DOWN:
                   self.me.action(2)
                if event.key == pygame.K_LEFT:
                   self.me.action(3)
                if event.key == pygame.K_RIGHT:
                   self.me.action(4)
                if event.key == pygame.K_SPACE:
                   #self.me.set_ready()
                   self.com.sendSecure("{\"ready\": true}", self.address)
    def run(self):

        self.address = (self.preferences.get("server"), self.preferences.get("port"))

        #initialisation du snakePost
        self.client = SnakeChan()

        self.client.connect(self.address, self.preferences.get("color"), self.preferences.get("nickname"))
        self.com = SnakePost(self.client, self.preferences.get("nickname"))


        whole_second=0
        self.running=True
        while self.running:
            #time tracking
            self.current_time+=self.clock.tick(Constants.FPS)

            #check if the snake is still alive
            if not self.me.alive:
                self.me.alive=True
                self.me.restart()

            #check if game need more food
            # if self.new_apple_timer.expired(self.current_time):
            #     self.f.make()

            #check if we need to move our own snake's state
            #if we do, send an update of our position to
            #the server
            if self.move_snake_timer.expired(self.current_time):
                self.me.move()
                pos = self.me.netinfo()
                self.com.send(pos, self.address)

            #check if we need to blink the unready snakes (unready state)
            if self.blink_snake_timer.expired(self.current_time):
                for snake in self.others:
                    self.others[snake].blink()

            #cleanup background
            self.gamescreen.fill(Constants.COLOR_BG)

            #draw scores
            self.scores.draw(self.screen)

            #draw all snakes positions as last seen by the server
            #we do not compute their positions ourselves!

            for snake in self.others:
                self.others[snake].draw(self.gamescreen)

            #draw food
            self.f.draw(self.gamescreen)

            #process external events (keyboard,...)
            self.process_events()

            #then update display
            #update game area on screen container
            self.screen.blit(self.gamescreen,(self.score_width,0))

            pygame.display.update()

            # Sur message du serveur...
            data, addr = self.com.listen()

            if data is not None:

                dat = json.loads(data)

                for key in dat:

                    if key == 'players_info':
                        #On met a jour les scores et les etats des joueurs
                        for player in dat[key]:

                            if not self.others.get(player[0]): # Si on a pas de joueur de ce nom, on l'ajoute
                                self.others[player[0]] = Snake(color=pygame.color.THECOLORS[player[1]], nickname=player[0])
                                self.scores.new_score(player[0], self.others.get(player[0]).color)

                            else: # On a deja le joueur, on update son etat
                                if player[3]:
                                    self.others[player[0]].set_ready()
                                else:
                                    self.others[player[0]].set_unready()
                            # on update les scores
                            self.scores.set_score(player[0], player[2])

                    elif key == "snakes": # message de position des joueurs

                        # on regarde si il y a des serpents a enlever
                        if len(dat[key]) != len(self.others):
                            for nickname in self.others.keys():
                                connected = False
                                for val in dat[key]:
                                    if val[0] == nickname:
                                        connected = True
                                if not connected:
                                    del self.others[nickname]
                                    self.scores.del_score(nickname)

                        for val in dat[key]:
                            # si on a ce joeur et que ses positions ne sont pas vides (premier message)
                            if len(val[1]) > 0 and self.others[val[0]]:
                                self.others[val[0]].setBody(val[1])

                    elif key == "foods": # les pommes envoyees par le serveur
                        self.f.set_positions(dat[key])

                    elif key == "grow": # Un serpent a mange une pomme !
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.grow(Constants.GROW)

                    elif key == "game_over": # Desole, c'est perdu
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.restart()
    def run(self):

        self.address = (self.preferences.get("server"),
                        self.preferences.get("port"))

        #initialisation du snakePost
        self.client = SnakeChan()

        self.client.connect(self.address, self.preferences.get("color"),
                            self.preferences.get("nickname"))
        self.com = SnakePost(self.client, self.preferences.get("nickname"))

        whole_second = 0
        self.running = True
        while self.running:
            #time tracking
            self.current_time += self.clock.tick(Constants.FPS)

            #check if the snake is still alive
            if not self.me.alive:
                self.me.alive = True
                self.me.restart()

            #check if game need more food
            # if self.new_apple_timer.expired(self.current_time):
            #     self.f.make()

            #check if we need to move our own snake's state
            #if we do, send an update of our position to
            #the server
            if self.move_snake_timer.expired(self.current_time):
                self.me.move()
                pos = self.me.netinfo()
                self.com.send(pos, self.address)

            #check if we need to blink the unready snakes (unready state)
            if self.blink_snake_timer.expired(self.current_time):
                for snake in self.others:
                    self.others[snake].blink()

            #cleanup background
            self.gamescreen.fill(Constants.COLOR_BG)

            #draw scores
            self.scores.draw(self.screen)

            #draw all snakes positions as last seen by the server
            #we do not compute their positions ourselves!

            for snake in self.others:
                self.others[snake].draw(self.gamescreen)

            #draw food
            self.f.draw(self.gamescreen)

            #process external events (keyboard,...)
            self.process_events()

            #then update display
            #update game area on screen container
            self.screen.blit(self.gamescreen, (self.score_width, 0))

            pygame.display.update()

            # Sur message du serveur...
            data, addr = self.com.listen()

            if data is not None:

                dat = json.loads(data)

                for key in dat:

                    if key == 'players_info':
                        #On met a jour les scores et les etats des joueurs
                        for player in dat[key]:

                            if not self.others.get(
                                    player[0]
                            ):  # Si on a pas de joueur de ce nom, on l'ajoute
                                self.others[player[0]] = Snake(
                                    color=pygame.color.THECOLORS[player[1]],
                                    nickname=player[0])
                                self.scores.new_score(
                                    player[0],
                                    self.others.get(player[0]).color)

                            else:  # On a deja le joueur, on update son etat
                                if player[3]:
                                    self.others[player[0]].set_ready()
                                else:
                                    self.others[player[0]].set_unready()
                            # on update les scores
                            self.scores.set_score(player[0], player[2])

                    elif key == "snakes":  # message de position des joueurs

                        # on regarde si il y a des serpents a enlever
                        if len(dat[key]) != len(self.others):
                            for nickname in self.others.keys():
                                connected = False
                                for val in dat[key]:
                                    if val[0] == nickname:
                                        connected = True
                                if not connected:
                                    del self.others[nickname]
                                    self.scores.del_score(nickname)

                        for val in dat[key]:
                            # si on a ce joeur et que ses positions ne sont pas vides (premier message)
                            if len(val[1]) > 0 and self.others[val[0]]:
                                self.others[val[0]].setBody(val[1])

                    elif key == "foods":  # les pommes envoyees par le serveur
                        self.f.set_positions(dat[key])

                    elif key == "grow":  # Un serpent a mange une pomme !
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.grow(Constants.GROW)

                    elif key == "game_over":  # Desole, c'est perdu
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.restart()
class Game:
    def __init__(self):
        pygame.init()

        #get preferences
        self.preferences = Preferences()
        # self.nickname = raw_input('Choose a username: '******'Choose a color (red, green, blue, yellow, white): ')
        #resolution, flags, depth, display
        self.unit = Constants.RESOLUTION[0] / Constants.UNITS
        self.banner = Banner()
        self.score_width = self.unit * 15

        if self.preferences.fullscreen:
            self.screen = pygame.display.set_mode((Constants.RESOLUTION[0]+self.score_width,\
                                               Constants.RESOLUTION[1]),pygame.FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode((Constants.RESOLUTION[0]+self.score_width,\
                                               Constants.RESOLUTION[1]),0,32)

        pygame.display.set_caption(Constants.CAPTION)

        #game area surface
        self.gamescreen = pygame.Surface(Constants.RESOLUTION)
        #score area rectangle surface
        self.scorescreen = pygame.Surface(
            (self.score_width, Constants.RESOLUTION[1]))

        #Snake and foods manager
        self.me=Snake(color=pygame.color.THECOLORS[self.preferences.get("color")],\
                    nickname=self.preferences.get("nickname"))

        self.f = Foods()

        self.others = {}

        #Score manager
        self.scores = Scores((self.score_width, Constants.RESOLUTION[1]))

        #add our own score, the server will send us the remaining one at connection
        self.scores.new_score(self.preferences.get("nickname"),\
                        pygame.color.THECOLORS[self.preferences.get("color")])

        #game area background color
        self.gamescreen.fill(Constants.COLOR_BG)
        self.scorescreen.fill((100, 100, 100))

        #timers
        self.clock = pygame.time.Clock()
        self.current_time = 0

        self.move_snake_timer = Timer(1.0 / Constants.SNAKE_SPEED * 1000,
                                      self.current_time,
                                      periodic=True)
        self.blink_snake_timer = Timer(1.0 / Constants.SNAKE_BLINKING_SPEED *
                                       1000,
                                       self.current_time,
                                       periodic=True)
        self.blink_banner_timer = Timer(500, self.current_time, periodic=True)
        self.new_apple_timer = Timer(Constants.NEW_APPLE_PERIOD * 1000,
                                     self.current_time,
                                     periodic=True)

    def process_events(self):
        #key handling
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                if event.key == pygame.K_UP:
                    self.me.action(1)
                if event.key == pygame.K_DOWN:
                    self.me.action(2)
                if event.key == pygame.K_LEFT:
                    self.me.action(3)
                if event.key == pygame.K_RIGHT:
                    self.me.action(4)
                if event.key == pygame.K_SPACE:
                    #self.me.set_ready()
                    self.com.sendSecure("{\"ready\": true}", self.address)

    def run(self):

        self.address = (self.preferences.get("server"),
                        self.preferences.get("port"))

        #initialisation du snakePost
        self.client = SnakeChan()

        self.client.connect(self.address, self.preferences.get("color"),
                            self.preferences.get("nickname"))
        self.com = SnakePost(self.client, self.preferences.get("nickname"))

        whole_second = 0
        self.running = True
        while self.running:
            #time tracking
            self.current_time += self.clock.tick(Constants.FPS)

            #check if the snake is still alive
            if not self.me.alive:
                self.me.alive = True
                self.me.restart()

            #check if game need more food
            # if self.new_apple_timer.expired(self.current_time):
            #     self.f.make()

            #check if we need to move our own snake's state
            #if we do, send an update of our position to
            #the server
            if self.move_snake_timer.expired(self.current_time):
                self.me.move()
                pos = self.me.netinfo()
                self.com.send(pos, self.address)

            #check if we need to blink the unready snakes (unready state)
            if self.blink_snake_timer.expired(self.current_time):
                for snake in self.others:
                    self.others[snake].blink()

            #cleanup background
            self.gamescreen.fill(Constants.COLOR_BG)

            #draw scores
            self.scores.draw(self.screen)

            #draw all snakes positions as last seen by the server
            #we do not compute their positions ourselves!

            for snake in self.others:
                self.others[snake].draw(self.gamescreen)

            #draw food
            self.f.draw(self.gamescreen)

            #process external events (keyboard,...)
            self.process_events()

            #then update display
            #update game area on screen container
            self.screen.blit(self.gamescreen, (self.score_width, 0))

            pygame.display.update()

            # Sur message du serveur...
            data, addr = self.com.listen()

            if data is not None:

                dat = json.loads(data)

                for key in dat:

                    if key == 'players_info':
                        #On met a jour les scores et les etats des joueurs
                        for player in dat[key]:

                            if not self.others.get(
                                    player[0]
                            ):  # Si on a pas de joueur de ce nom, on l'ajoute
                                self.others[player[0]] = Snake(
                                    color=pygame.color.THECOLORS[player[1]],
                                    nickname=player[0])
                                self.scores.new_score(
                                    player[0],
                                    self.others.get(player[0]).color)

                            else:  # On a deja le joueur, on update son etat
                                if player[3]:
                                    self.others[player[0]].set_ready()
                                else:
                                    self.others[player[0]].set_unready()
                            # on update les scores
                            self.scores.set_score(player[0], player[2])

                    elif key == "snakes":  # message de position des joueurs

                        # on regarde si il y a des serpents a enlever
                        if len(dat[key]) != len(self.others):
                            for nickname in self.others.keys():
                                connected = False
                                for val in dat[key]:
                                    if val[0] == nickname:
                                        connected = True
                                if not connected:
                                    del self.others[nickname]
                                    self.scores.del_score(nickname)

                        for val in dat[key]:
                            # si on a ce joeur et que ses positions ne sont pas vides (premier message)
                            if len(val[1]) > 0 and self.others[val[0]]:
                                self.others[val[0]].setBody(val[1])

                    elif key == "foods":  # les pommes envoyees par le serveur
                        self.f.set_positions(dat[key])

                    elif key == "grow":  # Un serpent a mange une pomme !
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.grow(Constants.GROW)

                    elif key == "game_over":  # Desole, c'est perdu
                        if dat[key] == self.preferences.get("nickname"):
                            self.me.restart()