Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Pygame][Mini-projet] jeu surprise

    1 novembre 2010 à 0:02:07

    Aleetheia, tu utilises draw.lines() pour le hightlight
    pygame.draw.lines(surf_tile, WHITE, True, list, 2)
    

    tu dois pouvoir avoir le même résultat avec
    pygame.draw.rect(surf_tile, WHITE,(0,0,self.tile_w-3,self.tile_h-3) , 2)
    

    en supprimant 'list'
    • Partager sur Facebook
    • Partager sur Twitter

    Python c'est bon, mangez-en. 

      5 novembre 2010 à 16:06:42

      Citation : josmiley

      Aleetheia, tu utilises draw.lines() pour le hightlight

      pygame.draw.lines(surf_tile, WHITE, True, list, 2)
      


      tu dois pouvoir avoir le même résultat avec

      pygame.draw.rect(surf_tile, WHITE,(0,0,self.tile_w-3,self.tile_h-3) , 2)
      


      en supprimant 'list'



      Oui, merci :) je pensais que draw.rect allait me remplir ma surface mais j'ai lu trop vite et j'ai enchainé avec draw.lines, mais là c'est bien mieux.

      Donc voici mon code final, j'ai un peu honte de la dernière étape de mon code, c'est long, surtout par rapport au tien josmiley :

      #!/usr/bin/env python
      
      from random import choice
      import pygame
      from pygame.locals import *
      
      WIN_TITLE = "Samegame"
      TILE_W = 30
      TILE_H = 30
      WIDTH, HEIGHT = 12, 6
      WIN_W = WIDTH * TILE_W
      WIN_H = HEIGHT * TILE_H
      COLORS = [(182, 97, 73), \
      		(219, 168, 102), \
      		(76, 123, 169), \
      		(151, 161, 145), \
      		]
      WHITE = (255, 255, 255)
      BLACK = (0, 0, 0)
      
      
      class Tile:
      	def __init__(self, color, dead=False):
      		self.color = color
      		self.dead = dead
      
      
      class Grid:
      	def __init__(self):
      		self.grid = []
      		self.tile_w = TILE_W
      		self.tile_h = TILE_H
      		self.mouse_tile = (0, 0)
      		self.hl_tiles = []
      		self.visited = []
      		self.mask = pygame.image.load('mask.png').convert_alpha()
      
      	def populate(self, width=TILE_W, height=TILE_H):
      		self.grid = []
      		self.grid = [[Tile(choice(COLORS)) for x in range(width)] for y in range(height)]
      
      	def display(self, win):
      		for y, row in enumerate(self.grid):
      			for x, cell in enumerate(row):
      				surf_tile = pygame.Surface((self.tile_w, self.tile_h))
      				surf_tile.fill(cell.color)
      				if cell.color != BLACK:
      					surf_tile.blit(self.mask, (0,0))
      					if (x,y) in self.hl_tiles and len(self.hl_tiles) > 1 :
      						pygame.draw.rect(surf_tile, WHITE, ( 0, 0, self.tile_w-2, self.tile_h-2 ), 2)
      				win.blit(surf_tile, (x * self.tile_w, y * self.tile_h))
      
      	def onMouseHover(self, coord):
      		mouse_tile = (coord[0] / self.tile_w, coord[1] / self.tile_h)
      		self.mouse_tile = mouse_tile
      		self.hl_tiles = self.highlight(mouse_tile) + [self.mouse_tile]
      		self.visited = []
      	
      	def highlight(self, start):
      		self.visited.append(start)
      		pos = start
      		hl_tiles = []
      		close_tiles = self.__getCloseTiles(start)
      		for x, y in close_tiles:
      			if self.__getTileColor( start ) == self.__getTileColor( (x, y) ) and (x, y) not in self.visited and self.__getTileColor(start) != BLACK:
      				hl_tiles.append( (x, y) )
      				hl_tiles += self.highlight( (x, y) )
      		return hl_tiles
      
      	def delete(self):
      		if len(self.hl_tiles) < 2:
      			return
      		# set highlighted tiles color to black
      		# and count the number of black tiles per col
      		l = [0 for x in range(WIDTH)]
      		for el in self.hl_tiles:
      			x, y = el
      			self.grid[y][x].color = BLACK
      			l[x] += 1
      
      		# move tiles down when empty tiles
      		for col in list(set(x[0] for x in self.hl_tiles)):
      			y = HEIGHT - 1
      			num = l[col]
      			self.__moveDownTiles(col, num)	
      		
      		# move left when empty cols
      		numCols = self.__countEmptyCols()
      		for c in range(numCols):
      			for x in range(WIDTH):
      				if self.__isEmptyCol(x):
      					self.__delCol(x)
      					self.__addCol()
      
      	def __moveDownTiles(self, col, num):
      		for i in range(num):
      			for y in range(HEIGHT - 1, -1, -1):
      				if self.grid[y][col].color == BLACK:
      					if y > 0:
      						self.grid[y][col].color = self.grid[y-1][col].color
      						self.grid[y-1][col].color = BLACK
      
      	def __addCol(self):
      		for y in range(HEIGHT):
      			self.grid[y].append(Tile(BLACK, True))
      
      	def __delCol(self, col):
      		for y in range(HEIGHT):
      			del(self.grid[y][col])
      
      	def __isEmptyCol(self, col):
      		count = 0
      		for y in range(HEIGHT):
      			if self.grid[y][col].color == BLACK and not self.grid[y][col].dead:
      				count += 1
      		if count - 1 == HEIGHT - 1:	return True
      		else: return False
      
      	def __countEmptyCols(self):
      		count = 0
      		for x in range(WIDTH):
      			if self.__isEmptyCol(x):
      				count += 1
      		return count
      
      	def __getCloseTiles(self, pos):
      		x, y = pos
      		close_tiles = []
      		if x - 1 >= 0:
      			close_tiles.append( (x - 1, y) )
      		if x + 1 < WIDTH:
      			close_tiles.append( (x + 1, y) )
      		if y - 1 >= 0:
      			close_tiles.append( (x, y - 1) )
      		if y + 1 < HEIGHT:
      			close_tiles.append( (x, y + 1) )
      		return close_tiles
      
      	def __getTileColor(self, id):
      		x, y = id
      		return self.grid[y][x].color
      
      
      class Game:
      	def __init__(self):
      		pygame.init()
      		pygame.font.init()
      		self.font = pygame.font.Font(pygame.font.get_default_font(), 25)
      		self.screen = pygame.display.set_mode(( WIN_W, WIN_H ))
      		self.grid = Grid()
      		self.grid.populate(WIDTH, HEIGHT)
      		self.score = 0
      		self.caption = lambda: "["+WIN_TITLE+"] Score : "+str(self.score)
      		self.onLoop = True
      		self.gameover = False
      
      	def run(self):
      		while self.isGameOver(): self.grid.populate(WIDTH, HEIGHT)
      		while self.onLoop:
      			pygame.time.Clock().tick(30)
      			for event in pygame.event.get():
      				if event.type == QUIT:
      					self.onLoop = False
      				if event.type == KEYDOWN:
      					if event.key == K_ESCAPE:
      						self.onLoop = False
      				if event.type == MOUSEMOTION:
      					self.grid.onMouseHover(pygame.mouse.get_pos())
      				if event.type == MOUSEBUTTONDOWN:
      					self.score += (len(self.grid.hl_tiles) - 1)**2
      					self.grid.delete()
      					self.grid.onMouseHover(pygame.mouse.get_pos())
      					self.gameover = self.isGameOver()
      
      			self.grid.display(self.screen)
      			pygame.display.flip()
      			pygame.display.set_caption(self.caption())
      			if self.gameover:
      				self.onLoop = False
      				self.displayScore()
      
      	def displayScore(self):
      		msg = self.font.render("Final score: "+str(self.score), True, WHITE)
      		rmsg = msg.get_rect()
      		rmsg.center = self.screen.get_rect().center
      		self.screen.blit(msg, rmsg)
      		pygame.display.flip()
      		while pygame.event.wait().type != any((QUIT, KEYDOWN, MOUSEBUTTONDOWN)): pass
      
      	def isGameOver(self):
      		adj_tiles = []
      		for x in range(WIDTH):
      			for y in range(HEIGHT):
      				pos = (x, y)
      				adj_tiles = self.grid.highlight(pos)
      				self.grid.visited = []
      				if len(adj_tiles) > 0:
      					return False
      		return True
      				
      
      samegame = Game()
      samegame.run()
      


      J'ai pas cherché à donné un bonus si le joueur arrive à vider le tableau, pareil pour l'image je t'ai pris la tienne josmiley. J'ai fait pas mal de tests et priori le jeu est complètement fonctionnel avec toutes les features demandés dans l'énoncé.

      J'ai fait une archive aussi : samegame-sdz.tar.gz

      Bon je m'attends pas à ce que quelqu'un arrive à me relire, j'essaierai de mieux faire au prochain sujet.
      • Partager sur Facebook
      • Partager sur Twitter
        5 novembre 2010 à 21:46:47

        ouais, ça le fait et j'aime bien les couleurs pastels, bravo!
        je me suis permis de modifier un peu.
        pour chaque tile tu recrées une surface que tu colories, sur laquelle tu blit et que tu blit ensuite sur win.
        là, on travaille directement sur win ...
        def display(self, win):
                for y, row in enumerate(self.grid):
                    for x, cell in enumerate(row):
                        win.fill(cell.color,(x * self.tile_w, y * self.tile_h, self.tile_w, self.tile_h))
                        if cell.color != BLACK:
                            win.blit(self.mask,(x * self.tile_w, y * self.tile_h))
                            if (x,y) in self.hl_tiles and len(self.hl_tiles) > 1 :
                                pygame.draw.rect(win, WHITE, (x * self.tile_w, y * self.tile_h , self.tile_w-2, self.tile_h-2 ), 2)
        



        • Partager sur Facebook
        • Partager sur Twitter

        Python c'est bon, mangez-en. 

          6 novembre 2010 à 23:45:16

          Moi je viens de programmer un Puissance 4 !

          import jeux
          from Tkinter import *
          fen = Tk()
          fen.title("Puissance 4")
          puissance = jeux.Puissance4(fen)
          puissance.pack()
          fen.mainloop()
          


          Ok je sors
          • Partager sur Facebook
          • Partager sur Twitter
            7 février 2011 à 13:37:42

            Salut Josmiley,

            Est-ce que tu pourrais me dire quelles sont les notions à connaitre en python pour aborder cet exercice (ce projet)?
            Comme ça je peux les rajouter dans le tableau de synthèse des exercices. :)
            • Partager sur Facebook
            • Partager sur Twitter
              7 février 2011 à 23:02:13

              les matrices et parcours en profondeur; je pense ...
              • Partager sur Facebook
              • Partager sur Twitter

              Python c'est bon, mangez-en. 

                9 août 2011 à 17:53:15

                J'ai tenté de faire la partie 1, ça a l'air de fonctionner. :)
                Dites moi ce que je pourrais faire pour plus programmer 'python'. :lol:
                Est-ce que ma fonction 'fill_case' est correcte ? j'ai essayé de faire un truc, ça a l'air de fonctionner... :-°

                # -*- coding: UTF-8 -*-
                
                from random import randint
                
                import pygame
                from pygame.locals import *
                
                ## Constantes
                SZ_CASE = 30
                TAB_W   = 40
                TAB_H   = 30
                SCR_W   = TAB_W * SZ_CASE
                SCR_H   = TAB_H * SZ_CASE
                
                ## Variables
                col = [(0xD8, 0xD8, 0x00),
                       (0x50, 0xD2, 0x50),
                       (0xFD, 0x80, 0x30),
                       (0x5C, 0x74, 0xD3),
                       (0xE9, 0xE9, 0xE9)]
                
                ## Fonctions
                def col_rand():
                    return col[randint(0, 4)]
                
                def fill_case():
                    return [[col_rand() for i in xrange(TAB_W)] for j in xrange(TAB_H)]
                
                def draw_screen(screen, tab):
                    screen.fill((0, 0, 0))
                    for i in xrange(TAB_H):
                        for j in xrange(TAB_W):
                            screen.fill(tab[i][j], (j * SZ_CASE + 1, i * SZ_CASE + 1, SZ_CASE - 2, SZ_CASE - 2))
                
                def main():
                    pygame.init()
                    screen = pygame.display.set_mode((SCR_W, SCR_H))
                    tab = fill_case()
                    draw_screen(screen, tab)
                    pygame.display.flip()
                    
                    done = 0
                    while not done:
                	   for event in pygame.event.get():
                	           if event.type == QUIT:
                	               done = 1
                
                main()
                
                • Partager sur Facebook
                • Partager sur Twitter
                  9 août 2011 à 21:42:24

                  Bonjour,

                  J'ai décidé moi aussi de me lancer dans cet exo. Je suis donc en train d'apprendre pygame en parallèle. ^^

                  Voici ma version pour la partie 1 :
                  import pygame
                  from pygame.locals import *
                  import random
                  
                  Case_size = 30
                  Tab_width, Tab_height = 20, 15
                  
                  
                  class Case(object):
                      _cases_colors = ['red','yellow','cyan','green','blue']
                      def __init__(self):
                          self.color = random.choice(Case._cases_colors)
                      def available_colors():
                          return Case._cases_colors
                  
                  
                  def display(screen, mat):
                      # initialise les surfaces dans un dictionnaire
                      srf = { colorname: pygame.Surface((Case_size, Case_size)) for colorname in Case.available_colors() }
                      for colorname in srf:
                          srf[colorname].fill(pygame.Color(colorname))
                      # blitte les surfaces sur l'ecran. commence depuis le bas
                      for x,col in enumerate(mat):
                          h = len(col)
                          for y,case in enumerate(col):
                              pos = x * Case_size, (h - (1+y)) * Case_size
                              print(pos[0], pos[1])
                              screen.blit(srf[case.color], pos)
                      pygame.display.flip()
                  
                  
                  # initialise aléatoirement un tableau 2D
                  Mat = [[Case() for i in range(Tab_height)] for j in range(Tab_width)]
                  
                  
                  pygame.init()
                  Screen = pygame.display.set_mode((Case_size * Tab_width, Case_size * Tab_height))
                  
                  display(Screen, Mat)
                  
                  while int(input()):
                      pass
                  


                  Au passage, si quelqu'un sait comment télécharger la doc de pygame, ce serait sympa de donner un lien, parce que c'est assez casse-pieds de devoir se connecter pour lire la doc, et je n'ai pas trouvé d'autre solution. Merci.

                  _______________________

                  Citation : Pouet_forever

                  J'ai tenté de faire la partie 1, ça a l'air de fonctionner. :)


                  Ah, tiens, bienvenue au club ! ;)

                  Citation : Pouet_forever

                  Dites moi ce que je pourrais faire pour plus programmer 'python'. :lol:


                  Tout faire pour qu'un codeur C ne puisse pas comprendre ton code. :lol:

                  Plus sérieusement et en général (c.a.d pas vis à vis de ton code que je n'ai pas trop regardé), AMHA, utiliser les outils et paradigmes à ta disposition : fonctions built-ins (comme reverse, enumerate, zip, etc.), dictionnaires, compréhensions (tu t'en sers déjà :) ), générateurs, iterateurs, decorateurs (parfois), et en général éviter une approche trop "C" (ex. utiliser des index à la place de enumerate, utiliser une liste à la place d'un set dans certains cas).

                  Enfin bon, c'est l'avis de quelqu'un qui débute et qui se pose les mêmes questions...
                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 août 2011 à 23:17:56

                    Citation : yoch

                    Ah, tiens, bienvenue au club ! ;)


                    Merci. ^^

                    Citation : yoch

                    Tout faire pour qu'un codeur C ne puisse pas comprendre ton code. :lol:


                    Aïe, je vais ptete changer de langage alors ! :D
                    Je vais essayer de suivre ce que t'as dit, mais bon il y a des trucs que je connais pas encore et d'autres où je sais pas trop comment l'appliquer. :-°
                    • Partager sur Facebook
                    • Partager sur Twitter
                      9 août 2011 à 23:30:42

                      @yoch
                      j'ai une erreur avec ton code:
                      TypeError: unbound method available_colors() must be called with Case instance as first argument (got nothing instead)

                      que j'ai corrigé comme ça
                      class Case(object):
                          _cases_colors = ['red','yellow','cyan','green','blue']
                          def __init__(self):
                              self.color = random.choice(Case._cases_colors)
                          @staticmethod
                          def available_colors():
                              return Case._cases_colors
                      
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Python c'est bon, mangez-en. 

                        10 août 2011 à 0:47:13

                        Citation : josmiley

                        @yoch
                        j'ai une erreur avec ton code:


                        Ah bon ? Aucun problème chez moi (python 3.2).
                        C'est légal, ce que je fais, ou on doit faire comme toi ?

                        De toutes façons, je crois que je vais virer cette classe, son utilisation telle quelle est totalement artificielle.


                        EDIT :
                        Bon, avant d'aller me coucher :-° , voici une version "jouable".

                        2e partie (sauf highlighting) : fait
                        3e partie : effacement des groupes réalisé

                        Mon code n'est absolument plus orienté objet, je ne sais pas si c'est bien ou pas. (en tous cas, mon approche orientée performance m’empêche de coder objet trop naïvement, et faire les choses comme il faut me demanderait actuellement un surplus d'efforts non négligeable)

                        import pygame
                        from pygame.locals import *
                        import random
                        from collections import deque
                        
                        Case_size = 30
                        Tab_width, Tab_height = 20, 15
                        Screen_width, Screen_height = 1 + Case_size * Tab_width, 1 + Case_size * Tab_height
                        Cases_colors = ['red','yellow','cyan','green','blue']
                        Cases_srf = {}
                        
                        def init_srf():
                            global Cases_srf
                            # initialise les surfaces dans un dictionnaire
                            Cases_srf = { colorname: pygame.Surface((Case_size - 1, Case_size - 1)) for colorname in Cases_colors }
                            for colorname in Cases_srf:
                                Cases_srf[colorname].fill(pygame.Color(colorname))
                        
                        def display(screen, mat):
                            screen.fill(pygame.Color('black'))
                            # blitte les surfaces sur l'ecran. commence depuis le bas
                            for x,col in enumerate(mat):
                                for y,color in enumerate(col):
                                    pos = x * Case_size + 1, (Tab_height - (y + 1)) * Case_size + 1
                                    screen.blit(Cases_srf[color], pos)
                            pygame.display.flip()
                        
                        # suppression des colonnes vides
                        def del_empty_cols(mat):
                            n = 0
                            for col in mat:
                                if len(col) == 0:
                                    del mat[n]
                                else:
                                    n += 1
                        
                        def suppr_group(mat, x, y):
                            if not (len(mat) > x and len(mat[x]) > y):
                                return 0
                            counter = 1
                            color = mat[x][y]
                            del mat[x][y]
                            fifo = deque([(x,y)])
                            while len(fifo) != 0:
                                x,y = fifo.popleft()
                                for i,j in ((-1,0),(1,0),(0,-1),(0,0)):  # hack : le dernier est à zero car on supprime un élément
                                    _x,_y = x + i, y + j
                                    if _x >= 0 and _x < len(mat) and _y >= 0 and _y < len(mat[_x]) and mat[_x][_y] == color:
                                        del mat[_x][_y]
                                        counter += 1
                                        fifo.append((_x,_y))
                            del_empty_cols(mat)
                            return counter
                        
                        
                        if __name__ == "__main__":
                            # initialise aléatoirement un tableau 2D
                            mat = [[random.choice(Cases_colors) for i in range(Tab_height)] for j in range(Tab_width)]
                        
                            pygame.init()
                            screen = pygame.display.set_mode((Screen_width, Screen_height))
                        
                            init_srf()
                            
                            draw = True
                            while True:
                                if draw:
                                    display(screen, mat)
                                    draw = False
                                event = pygame.event.wait()
                                if event.type == QUIT:
                                    exit()
                                elif event.type == MOUSEBUTTONDOWN and event.button == 1:
                                    x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                    # print(x,y)
                                    suppr_group(mat, x, y)
                                    draw = True
                                elif event.type == MOUSEMOTION:
                                    pass
                        
                        • Partager sur Facebook
                        • Partager sur Twitter
                          10 août 2011 à 10:09:32

                          @yoch,
                          pas mal du tout mais:

                          Citation

                          soit une variable 'Zone', liste de toutes coordonnées des cases de même couleur en contact entre elles(de bord à bord); la case de référence étant, évidement, celle pointée par la souris.
                          - Coder une fonction 'memes_cases' qui tiens à jour cette liste et qui 'hightlight' la zone obtenue lorsque 'Zone' contient au moins 2 coordonnées.


                          sous-entend qu'un groupe de cases éliminable contient au moins 2 cases.
                          dans ton code je peux éliminer des cases seules.
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Python c'est bon, mangez-en. 

                            10 août 2011 à 12:19:33

                            Citation : josmiley

                            Citation

                            soit une variable 'Zone', liste de toutes coordonnées des cases de même couleur en contact entre elles(de bord à bord); la case de référence étant, évidement, celle pointée par la souris.
                            - Coder une fonction 'memes_cases' qui tiens à jour cette liste et qui 'hightlight' la zone obtenue lorsque 'Zone' contient au moins 2 coordonnées.


                            sous-entend qu'un groupe de cases éliminable contient au moins 2 cases.
                            dans ton code je peux éliminer des cases seules.



                            Oui, je m'en suis rendu compte aussi (j'ai déja joué à ce jeu ;) ).

                            Sinon, mon algo était faux, j'ai du le modifier... :-°

                            Voici mon code final (remplit pratiquement toutes les reccomandations) :
                            import pygame
                            from pygame.locals import *
                            import random
                            from collections import deque, defaultdict
                            
                            # variables globales
                            Case_size = 30
                            Tab_width, Tab_height = 20, 15
                            Screen_width, Screen_height = 1 + Case_size * Tab_width, 1 + Case_size * Tab_height
                            Cases_colors = ['red','yellow','cyan','green','blue']
                            Cases_srf = {}
                            H_srf = None
                            
                            
                            # initialise les surfaces à blitter
                            def init_surfaces():
                                global Cases_srf, H_srf
                                # initialise les surfaces dans un dictionnaire
                                Cases_srf = { colorname: pygame.Surface((Case_size - 1, Case_size - 1)) for colorname in Cases_colors }
                                for colorname in Cases_srf:
                                    Cases_srf[colorname].fill(pygame.Color(colorname))
                                # prepare une surface spéciale pour le highlighting
                                H_srf = pygame.Surface((Case_size - 1, Case_size - 1))
                                H_srf.fill(pygame.Color('white'))
                                pygame.draw.rect(H_srf, pygame.Color('black'), pygame.Rect(2,2,Case_size-5,Case_size-5) )
                                H_srf.set_colorkey((0,0,0))
                            
                            # affichage
                            def display(screen, mat, paint_region = None):
                                screen.fill(pygame.Color('black'))
                                # blitte les surfaces sur l'ecran. commence depuis le bas
                                for x,col in enumerate(mat):
                                    for y,color in enumerate(col):
                                        pos = x * Case_size + 1, (Tab_height - (y + 1)) * Case_size + 1
                                        screen.blit(Cases_srf[color], pos)
                                if paint_region != None:
                                    for x,y in paint_region:
                                        pos = x * Case_size + 1, (Tab_height - (y + 1)) * Case_size + 1
                                        screen.blit(H_srf, pos)
                                pygame.display.flip()
                            
                            # suppression des colonnes vides
                            def del_empty_cols(mat):
                                n = 0
                                for k in range(len(mat)):
                                    if mat[k-n] == []:
                                        del mat[k-n]
                                        n += 1
                            
                            # suppression d'une region
                            def suppr_region(mat, region):
                                d = defaultdict(list)
                                for x,y in region:
                                    d[x].append(y)
                                for x,lst in d.items():
                                    lst.sort()
                                    n = 0
                                    for y in lst:
                                        del mat[x][y-n]
                                        n += 1
                                del_empty_cols(mat)
                                return len(region)
                            
                            # comptage et enregistrement des regions
                            def count_regions(mat):
                                registered_cases = {}
                                for X,col in enumerate(mat):
                                    for Y,color in enumerate(col):
                                        if (X,Y) not in registered_cases:
                                            region = []
                                            registered_cases[(X,Y)] = region
                                            fifo = deque([(X,Y)])
                                            while len(fifo) != 0:
                                                x,y = fifo.popleft()
                                                region.append((x,y))
                                                for i,j in ((-1,0),(1,0),(0,-1),(0,1)):
                                                    _x,_y = x + i, y + j
                                                    if (_x >= 0 and _x < len(mat) and _y >= 0 and _y < len(mat[_x])
                                                    and (_x,_y) not in registered_cases and mat[_x][_y] == color):
                                                        registered_cases[(_x,_y)] = region
                                                        fifo.append((_x,_y))
                                return registered_cases
                            
                            # teste s'il reste des regions à supprimer
                            def continuer_jeu(regions):
                                return max({len(reg) for reg in regions.values()}) > 1
                            
                            # main
                            if __name__ == "__main__":
                                # initialise aléatoirement un tableau 2D
                                mat = [[random.choice(Cases_colors) for i in range(Tab_height)] for j in range(Tab_width)]
                                regions = count_regions(mat)
                            
                                pygame.init()
                                screen = pygame.display.set_mode((Screen_width, Screen_height))
                            
                                init_surfaces()
                                score = 0
                                
                                display(screen, mat)
                                while continuer_jeu(regions):
                                    event = pygame.event.wait()
                                    if event.type == QUIT:
                                        exit()
                                    elif event.type == MOUSEBUTTONDOWN and event.button == 1:
                                        x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                        if (x,y) in regions and len(regions[(x,y)]) > 1:
                                            n = suppr_region(mat, regions[(x,y)])
                                            score += (n-1) ** 2
                                            print(n, ' elements supprimes, score : ', score)
                                            regions = count_regions(mat)
                                            display(screen, mat)
                                    elif event.type == MOUSEMOTION:
                                        x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                        if (x,y) in regions:
                                            display(screen, mat, regions[(x,y)] if len(regions[(x,y)]) > 1 else None)
                                print('Fin de la partie,\n votre score est de ', score, ' points')
                            



                            screenshot :
                            Image utilisateur


                            Quelques explications sur ma démarche :
                            - Concernant la suppression de régions, tout se passe directement dans le tableau2d contenant les cases. En fait, chaque sous-liste représente une pile d'éléments, ce qui correspond bien à la gravité dans le jeu : lorsqu'on supprime un élément, ceux du dessus descendent. Si une pile est vide, on la supprime du tableau.
                            - Concernant le highlighting, voici comment je procède : je calcule une seule fois à chaque modification du tableau toutes les régions et les associer avec chaque cases, ensuite il suffit de récupérer à chaque mouvement de souris directement la région voulue et le mettre en surbrillance. Ca m'a semblé nettement plus efficace que refaire le parcours en profondeur à chaque déplacement de souris.
                            - Je n'ai finalement pas utilisé de POO.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              10 août 2011 à 13:13:53

                              117 lignes ... je suis jaloux là, bravo :)
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Python c'est bon, mangez-en. 

                                12 août 2011 à 11:31:41

                                Citation : josmiley

                                117 lignes ... je suis jaloux là, bravo :)



                                Merci !

                                J'ai encore raccourci en remplaçant cette portion du code :
                                # suppression des colonnes vides
                                def del_empty_cols(mat):
                                    n = 0
                                    for k in range(len(mat)):
                                        if mat[k-n] == []:
                                            del mat[k-n]
                                            n += 1
                                
                                # suppression d'une region
                                def suppr_region(mat, region):
                                    d = defaultdict(list)
                                    for x,y in region:
                                        d[x].append(y)
                                    for x,lst in d.items():
                                        lst.sort()
                                        n = 0
                                        for y in lst:
                                            del mat[x][y-n]
                                            n += 1
                                    del_empty_cols(mat)
                                    return len(region)
                                


                                par ce code plus court (ça devrait te plaire ;) ) :
                                # suppression d'une region
                                def suppr_region(mat, region):
                                    d = defaultdict(set)
                                    for x,y in region:
                                        d[x].append(y)
                                    for x in d.keys():
                                        mat[x][:] = [color for y,color in enumerate(mat[x]) if y not in d[x]]
                                    # ensuite, suppression des colonnes vides
                                    mat[:] = [pile for pile in mat if pile != []]
                                    return len(region)
                                
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  12 août 2011 à 11:44:44

                                  haaaaa, d'où la question sur l'autre post ^^
                                  héhé, toi tu vas devenir un byte-cruncher
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Python c'est bon, mangez-en. 

                                    12 août 2011 à 12:09:58

                                    Citation : josmiley

                                    haaaaa, d'où la question sur l'autre post ^^
                                    héhé, toi tu vas devenir un byte-cruncher


                                    Bien vu. ;)

                                    Mais il ne s'agissait pas seulement de gagner des lignes, c’était surtout que j'avais fait plutôt un sale bricolage... :-°

                                    edit [15/08/2011] :
                                    Version complète (encore légèrement modifiée, j'ai aussi viré la fonction continuer_jeu() qui ne servait à rien) :

                                    import pygame
                                    from pygame.locals import *
                                    import random
                                    from collections import deque, defaultdict
                                    
                                    # variables globales
                                    Case_size = 30
                                    Tab_width, Tab_height = 20, 15
                                    Screen_width, Screen_height = 1 + Case_size * Tab_width, 1 + Case_size * Tab_height
                                    Cases_colors = ['red','yellow','cyan','green','blue']
                                    Cases_srf = {}
                                    H_srf = None
                                    
                                    
                                    # initialise les surfaces à blitter
                                    def init_surfaces():
                                        global Cases_srf, H_srf
                                        # initialise les surfaces dans un dictionnaire
                                        Cases_srf = { colorname: pygame.Surface((Case_size - 1, Case_size - 1)) for colorname in Cases_colors }
                                        for colorname in Cases_srf:
                                            Cases_srf[colorname].fill(pygame.Color(colorname))
                                        # prepare une surface spéciale pour le highlighting
                                        H_srf = pygame.Surface((Case_size - 1, Case_size - 1))
                                        H_srf.fill(pygame.Color('white'))
                                        pygame.draw.rect(H_srf, pygame.Color('black'), pygame.Rect(2,2,Case_size-5,Case_size-5) )
                                        H_srf.set_colorkey((0,0,0))
                                    
                                    # affichage
                                    def display(screen, mat, paint_region = None):
                                        screen.fill(pygame.Color('black'))
                                        # blitte les surfaces sur l'ecran. commence depuis le bas
                                        for x,pile in enumerate(mat):
                                            for y,color in enumerate(pile):
                                                pos = x * Case_size + 1, (Tab_height - (y + 1)) * Case_size + 1
                                                screen.blit(Cases_srf[color], pos)
                                        # met la region en surbrillance
                                        if paint_region != None:
                                            for x,y in paint_region:
                                                pos = x * Case_size + 1, (Tab_height - (y + 1)) * Case_size + 1
                                                screen.blit(H_srf, pos)
                                        pygame.display.flip()
                                    
                                    # suppression d'une region
                                    def suppr_region(mat, region):
                                        for x,pile in enumerate(mat):
                                            mat[x] = [color for y,color in enumerate(pile) if (x,y) not in region]
                                        # ensuite, suppression des colonnes vides
                                        mat[:] = [pile for pile in mat if pile != []]
                                        return len(region)
                                    
                                    # comptage et enregistrement des régions
                                    def count_regions(mat):
                                        registered_cases = {}
                                        for X,pile in enumerate(mat):
                                            for Y,color in enumerate(pile):
                                                if (X,Y) not in registered_cases:
                                                    region = {(X,Y)}
                                                    fifo = deque([(X,Y)])
                                                    while len(fifo) != 0:
                                                        x,y = fifo.popleft()
                                                        region.add((x,y))
                                                        for i,j in ((-1,0),(1,0),(0,-1),(0,1)):
                                                            _x,_y = x + i, y + j
                                                            if (_x >= 0 and _x < len(mat) and _y >= 0 and _y < len(mat[_x])
                                                            and (_x,_y) not in registered_cases and mat[_x][_y] == color):
                                                                fifo.append((_x,_y))
                                                                registered_cases[_x,_y] = region
                                        return registered_cases
                                    
                                    # main
                                    if __name__ == '__main__':
                                        # initialise aléatoirement un tableau 2D
                                        mat = [[random.choice(Cases_colors) for i in range(Tab_height)] for j in range(Tab_width)]
                                        regions = count_regions(mat)
                                    
                                        pygame.init()
                                        screen = pygame.display.set_mode((Screen_width, Screen_height))
                                    
                                        init_surfaces()
                                        score = 0
                                        
                                        display(screen, mat)
                                        while len(regions) != 0:
                                            event = pygame.event.wait()
                                            if event.type == QUIT:
                                                exit()
                                            elif event.type == MOUSEBUTTONDOWN and event.button == 1:
                                                x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                                if (x,y) in regions:
                                                    n = suppr_region(mat, regions[x,y])
                                                    score += (n-1) ** 2
                                                    print(n, ' elements supprimes, score : ', score)
                                                    regions = count_regions(mat)
                                                    display(screen, mat)
                                            elif event.type == MOUSEMOTION:
                                                x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                                display(screen, mat, regions[x,y] if (x,y) in regions else None)
                                        print('Fin de la partie,\n votre score est de ', score, ' points')
                                    
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      16 août 2011 à 0:46:08

                                      j'peux pas laisser passer ça ...
                                      c'est illisible, ça pourrait être plus court mais serait plus lent à l'affichage; c'est un compromis ...
                                      je me suis même permis une petite fantaisie ...

                                      from pygame import*;import random as r;R,E,d,z,s,m=range,enumerate,display,[],0,mouse;S=d.set_mode((600,500)).fill
                                      A=[[r.choice((2631,420,4095,4025,1064))**2 for y in R(25)]for x in R(30)] # creation du tableau
                                      while event.wait().type!=QUIT: # temps qu'on ne quitte pas
                                       X,Y=m.get_pos();X,Y=X/20,24-Y/20 # position dans le tableau
                                       if not(X,Y)in z: # si on pointe un groupe different de cases
                                        z=[(X,Y)]if A[X][Y]else[] # initialise la recherche en profondeur
                                        [z.append((a,b))for x,y in z for a,b in(x-1,y),(x,y-1),(x+1,y),(x,y+1)if(0<=a<30)&(0<=b<25)and(A[a][b]==A[X][Y])&((a,b)not in z)] # la recherche elle-meme
                                        [S((len(z)>1)&((x,y)in z)and-1 or c,(x*20,480-y*20,18,18))for x,l in E(A)for y,c in E(l)];d.flip() # (re)dessine le tableau
                                       if m.get_pressed()[0]&(len(z)>1): # si clic sur une zone
                                        #uncomment for anim#[d.update([S(0,Rect(x*20,480-y*20,18,18).inflate(-e,-e))for x,y in z])for e in R(18,-4,-2)if time.wait(50)]
                                        for x,y in sorted(z,reverse=1):A[x].pop(y);A[x]+=[0] # supression des cases cliquees
                                        A.sort(None,any,1);s+=(len(z)-1)**2;z=[]# supression des colonnes vides;calcule du score;force le redrawing du tableau
                                        d.set_caption((not any([j==i[e]for i in A+zip(*A)for e,j in E(i[1:])if j])and"c'est fini, "or"")+"score = "+str(s)) # affichage du score/score final
                                      
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Python c'est bon, mangez-en. 

                                        18 août 2011 à 1:09:11

                                        yoch,
                                        un bug pas bien grave ...
                                        le hightligthing n'est actualisé que si il y a mouvement du pointeur.
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Python c'est bon, mangez-en. 

                                          18 août 2011 à 3:34:29

                                          Oui, je sais. (it's not a bug, it's a feature :p )

                                          [edit tardif :]
                                          Puisque tu y liens, voici :

                                          .
                                                  elif event.type == MOUSEBUTTONDOWN and event.button == 1:
                                                      x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                                      if (x,y) in regions:
                                                          n = suppr_region(mat, regions[x,y])
                                                          score += (n-1) ** 2
                                                          print(n, ' elements supprimes, score : ', score)
                                                          regions = count_regions(mat)
                                                          display(screen, mat, regions.get((x,y), None))
                                                  elif event.type == MOUSEMOTION:
                                                      x,y = (event.pos[0] - 1) // Case_size, Tab_height - 1 - (event.pos[1] - 1) // Case_size
                                                      display(screen, mat, regions.get((x,y), None))
                                          
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            6 septembre 2011 à 13:50:37

                                            Bonjour tout le monde.
                                            Voici mon code source (qui fonctionne) pour la première partie de cet exercice.
                                            Je pense que tout est bien expliqué, et que n'importe quelle personne pourrait le comprendre. Une code source d'un débutant pour des débutants ^^ .


                                            #Nom du fichier:           |main.py
                                            #Crée le:                  |06 Septembre 2011
                                            #Dernière modification le: |06 Septembre 2011
                                            #Par:                      |Realmagma
                                            
                                            #Rôle du fichier:          |Gère le bon fonctionnement d'une partie.
                                            #--------------------------|
                                            #--------------------------|
                                            
                                            
                                            from random import choice
                                            from sys import exit
                                            import pygame
                                            from pygame.locals import *
                                            
                                            
                                            FRAME = 30
                                            TAILLE_BLOC = 30
                                            NB_BLOC_MAX_COLONNE = 20
                                            NB_BLOC_MAX_LIGNE   = 20
                                            HAUTEUR_ECRAN = TAILLE_BLOC * NB_BLOC_MAX_COLONNE
                                            LARGEUR_ECRAN = TAILLE_BLOC * NB_BLOC_MAX_LIGNE
                                            
                                            
                                            #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                            #-*-*- <Les Classes> || Début de <Principale> -*-*-#
                                            #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                            
                                            class Principale():
                                                """Classe gérant la fenêtre principale du jeu."""
                                                def __init__(self, parent = None):
                                                    #Initialisation de la variable /parent/ de cette classe
                                                    #Invocation de la méthode *_initialisation_pygame*
                                                    #On instancie un objet /i_jeu/ de la classe <Jeu>
                                                    #
                                                    self.parent = parent
                                                    self._initialisation_pygame()
                                                    self.i_jeu  = Jeu(self)
                                                    
                                            
                                                def _initialisation_pygame(self):
                                                    """'''''''''''''''''''''''''''''''''''''''''''
                                                    - Initialise pygame.
                                                    - Créer une fenêtre en suivant les constantes.
                                                    - Initialise le titre de la fenêtre.
                                                    '''''''''''''''''''''''''''''''''''''''''''"""
                                                    #(1)(2)(3)
                                                    pygame.init()
                                                    self.screen = pygame.display.set_mode((LARGEUR_ECRAN, HAUTEUR_ECRAN))
                                                    pygame.display.set_caption("'Jeu surprise' par Josmiley.")
                                                    
                                                def nouvelle_partie(self):
                                                    """''''''''''''''''''''''''
                                                    - Exécute la méthode *nouvelle_partie* de l'objet /i_jeu/.
                                                    ''''''''''''''''''''''''"""
                                                    self.i_jeu.nouvelle_partie()
                                            
                                            
                                            
                                            #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                            #-*-*- <Les Classes> || Début de <Jeu>        -*-*-#
                                            #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                            
                                            class Jeu(pygame.sprite.Sprite):
                                                """Classe <Jeu> héritant de <pygame.sprite.Sprite>."""
                                                def __init__(self, parent):
                                                    pygame.sprite.Sprite.__init__(self)
                                                    self.parent    = parent
                                                    self._horloge  = pygame.time.Clock()
                                                    self.l_matrice = []
                                                    self.couleur   = [(255,0,0),  (0,255,0),   (0,0,255),\
                                                                      (255,255,0),(0,255,255), (255,0,255)]
                                                    #Correspond a une espacement de x pixels entre chaque bloc
                                                    self._espacement = 2
                                            
                                                def nouvelle_partie(self):
                                                    """''''''''''''''''''''''''''''''''''''''''''''''''
                                                    - Remet toutes les variables à leur état d'origine.
                                                    - On appelle la méthode *_mainloop*.
                                                    ''''''''''''''''''''''''''''''''''''''''''''''''"""
                                                    #Ici on initialise les variables
                                                    #Là on appelle la méthode *_mainloop*
                                                    self._mainloop()
                                            
                                                def creer_remplire_matrice(self):
                                                    """''''''''''''''''''''''''''''''''''''''''''''
                                                    - Transforme /l_matrice/ en une matrice 2D.
                                                    - Instancie <Case(couleur)> pour chaque membre.
                                                    - L'instantation d'une couleur est aléatoire.
                                                    ''''''''''''''''''''''''''''''''''''''''''''"""
                                                    for colonne in range(NB_BLOC_MAX_COLONNE):
                                                        self.l_matrice.append([Case(choice(self.couleur)) for colonne in range(NB_BLOC_MAX_LIGNE)])
                                                        
                                                    
                                                def _afficher(self):
                                                    """''''''''''''''''''''''''''''''''''
                                                    - Affiche le contenu de la matrice 2D.
                                                    '''''''''''''''''''''''''''''''''''"""
                                                    #Efface l'écran
                                                    self.parent.screen.fill(0)
                                                    for col in range(NB_BLOC_MAX_COLONNE):
                                                        for ligne in range(NB_BLOC_MAX_LIGNE):
                                                            self.parent.screen.fill(self.l_matrice[col][ligne].couleur, \
                                                                                    (col*TAILLE_BLOC, ligne*TAILLE_BLOC, TAILLE_BLOC-self._espacement, TAILLE_BLOC-self._espacement))
                                                    #On rafraîchit le tout
                                                    pygame.display.flip()
                                            
                                                def _mainloop(self):
                                                    """'''''''''''''''''''''''''''''''''''''
                                                    - Boucle principale du jeu en lui même.
                                                    - Gère les évènements clavier et souris.
                                                    '''''''''''''''''''''''''''''''''''''"""
                                                    continuer = True
                                                    ##ESSAI
                                                    self.creer_remplire_matrice()
                                                    self._afficher()
                                                    ##FIN ESSAI
                                                    while continuer:
                                                        self._horloge.tick(FRAME)
                                                        for event in pygame.event.get():
                                                            #Si on clique sur la croix, on quitte.
                                                            if event.type == pygame.QUIT:
                                                                pygame.quit()
                                                                return
                                                            #Gestion de la souris
                                                            elif event.type == pygame.MOUSEBUTTONDOWN:
                                                                mouse_x, mouse_y = pygame.mouse.get_pos()
                                                                #Si c'est un clique-GAUCHE
                                                                if pygame.mouse.get_pressed() == (1, 0, 0):
                                                                    print("Clique gauche: {0};{1} soit {2};{3}".format(\
                                                                        mouse_x, mouse_y, \
                                                                        mouse_x//TAILLE_BLOC, mouse_y//TAILLE_BLOC))
                                            
                                                                #Si c'est un clique-DROIT
                                                                elif pygame.mouse.get_pressed() == (0, 0, 1):
                                                                    print("Clique droit:{0};{1} soit {2};{3}".format(\
                                                                        mouse_x, mouse_y, \
                                                                        mouse_x//TAILLE_BLOC, mouse_y//TAILLE_BLOC))
                                            
                                            
                                            
                                            #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                            #-*-*- <Les Classes> || Début de <Case>       -*-*-#
                                            #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                            
                                            class Case():
                                                """Classe <Case> représentant une cellule dans un tableau"""
                                                def __init__(self, couleur):
                                                    """''''''''''''''''''''''''''
                                                    - /couleur/ est de type "rgb"
                                                    ''''''''''''''''''''''''''"""
                                                    self.couleur = couleur
                                                    
                                                    
                                                    
                                                    
                                            
                                            if __name__ == "__main__":
                                                p = Principale()
                                                p.nouvelle_partie()
                                                exit(0)
                                            
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              6 septembre 2011 à 18:45:35

                                              le code est long mais ça fonctionne ;)

                                              enfin, je dis long parce que j'aime bien les codes courts, c'est très perso comme avis ... click me
                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Python c'est bon, mangez-en. 

                                                8 septembre 2011 à 0:02:24

                                                Voici mon code pour la partie n°2. Le hightlight fonctionne correctement.
                                                J'ai commencé à coder la partie n°3 de cet exercice depuis des heures et voici ce que j'ai obtenu: Des bugs...
                                                Ils sont assez bizard, voyez par vous-même.

                                                Comment y remédier ?

                                                Des suggestions seront les bienvenues. En attendant je vous redonne mon code-source (ayant bien évidemment changé :-° )
                                                Merci d'avance.

                                                #Nom du fichier:           |main.py
                                                #Crée le:                  |06 Septembre 2011
                                                #Dernière modification le: |07 Septembre 2011
                                                #Par:                      |Realmagma
                                                
                                                #Rôle du fichier:          |Gère le bon fonctionnement d'une partie.
                                                #--------------------------|
                                                #--------------------------|
                                                
                                                
                                                from random import choice
                                                from sys import exit
                                                import pygame
                                                from pygame.locals import *
                                                
                                                
                                                FRAME = 30
                                                TAILLE_BLOC = 30
                                                NB_BLOC_MAX_COLONNE = 20
                                                NB_BLOC_MAX_LIGNE   = 20
                                                HAUTEUR_ECRAN = TAILLE_BLOC * NB_BLOC_MAX_COLONNE
                                                LARGEUR_ECRAN = TAILLE_BLOC * NB_BLOC_MAX_LIGNE
                                                
                                                
                                                #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                                #-*-*- <Les Classes> || Début de <Principale> -*-*-#
                                                #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                                
                                                class Principale():
                                                    """Classe gérant la fenêtre principale du jeu."""
                                                    def __init__(self, parent = None):
                                                        #Initialisation de la variable /parent/ de cette classe
                                                        #Invocation de la méthode *_initialisation_pygame*
                                                        #On instancie un objet /i_jeu/ de la classe <Jeu>
                                                        #
                                                        self.parent = parent
                                                        self._initialisation_pygame()
                                                        self.i_jeu  = Jeu(self)
                                                        
                                                
                                                    def _initialisation_pygame(self):
                                                        """'''''''''''''''''''''''''''''''''''''''''''
                                                        - Initialise pygame.
                                                        - Créer une fenêtre en suivant les constantes.
                                                        - Initialise le titre de la fenêtre.
                                                        '''''''''''''''''''''''''''''''''''''''''''"""
                                                        pygame.init()
                                                        self.screen = pygame.display.set_mode((LARGEUR_ECRAN, HAUTEUR_ECRAN))
                                                        pygame.display.set_caption("'Jeu surprise' par Josmiley.")
                                                        
                                                    def nouvelle_partie(self):
                                                        """''''''''''''''''''''''''
                                                        - Exécute la méthode *nouvelle_partie* de l'objet /i_jeu/.
                                                        ''''''''''''''''''''''''"""
                                                        self.i_jeu.nouvelle_partie()
                                                
                                                
                                                
                                                #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                                #-*-*- <Les Classes> || Début de <Jeu>        -*-*-#
                                                #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                                
                                                class Jeu(pygame.sprite.Sprite):
                                                    """Classe <Jeu> héritant de <pygame.sprite.Sprite>."""
                                                    def __init__(self, parent):
                                                        pygame.sprite.Sprite.__init__(self)
                                                        self.parent    = parent
                                                        self._horloge  = pygame.time.Clock()
                                                        self.l_matrice = []
                                                        self.couleur   = [(255,0,0),(0,255,0), (0,0,255), (255,255,0),\
                                                                          (0,255,255)]
                                                        #Correspond a une espacement de x pixels entre chaque bloc
                                                        self._espacement = 2
                                                        #Couleur de référence de la case pointée.
                                                        self.couleurAct  = None
                                                        self.l_zone      = []
                                                
                                                    def nouvelle_partie(self):
                                                        """''''''''''''''''''''''''''''''''''''''''''''''''
                                                        - Remet toutes les variables à leur état d'origine.
                                                        - On appelle la méthode *_mainloop*.
                                                        ''''''''''''''''''''''''''''''''''''''''''''''''"""
                                                        #Ici on initialise les variables
                                                        #Là on appelle la méthode *_mainloop*
                                                        self._mainloop()
                                                
                                                    def creer_remplire_matrice(self):
                                                        """''''''''''''''''''''''''''''''''''''''''''''
                                                        - Transforme /l_matrice/ en une matrice 2D.
                                                        - Instancie <Case(couleur)> pour chaque membre.
                                                        - L'instantation d'une couleur est aléatoire.
                                                        ''''''''''''''''''''''''''''''''''''''''''''"""
                                                        for colonne in range(NB_BLOC_MAX_COLONNE):
                                                            self.l_matrice.append([Case(choice(self.couleur)) for colonne in range(NB_BLOC_MAX_LIGNE)])
                                                            
                                                    def _afficher(self):
                                                        """''''''''''''''''''''''''''''''''''
                                                        - Affiche le contenu de la matrice 2D.
                                                        '''''''''''''''''''''''''''''''''''"""
                                                        #Efface l'écran
                                                        self.parent.screen.fill(0)
                                                        for col in range(NB_BLOC_MAX_COLONNE):
                                                            for ligne in range(NB_BLOC_MAX_LIGNE):
                                                                self.parent.screen.fill(self.l_matrice[col][ligne].couleur, \
                                                                                       (col*TAILLE_BLOC, ligne*TAILLE_BLOC, TAILLE_BLOC-self._espacement, TAILLE_BLOC-self._espacement))
                                                        for i in self.l_zone:   
                                                            pygame.draw.rect(self.parent.screen, (255,255,255), ((i[0]*TAILLE_BLOC, i[1]*TAILLE_BLOC),(TAILLE_BLOC-self._espacement,TAILLE_BLOC-self._espacement)),self._espacement)
                                                        #On rafraîchit le tout
                                                        pygame.display.flip()
                                                
                                                    def _mainloop(self):
                                                        """'''''''''''''''''''''''''''''''''''''
                                                        - Boucle principale du jeu en lui même.
                                                        - Gère les évènements clavier et souris.
                                                        '''''''''''''''''''''''''''''''''''''"""
                                                        continuer = True
                                                        self.creer_remplire_matrice()
                                                        pygame.mouse.set_pos(300,300)
                                                        
                                                        while continuer:
                                                            self._horloge.tick(FRAME)
                                                            event = pygame.event.wait()
                                                            #On récupère la position de la souris
                                                            #La couleurAct devient la celle de la case pointée
                                                            mouse_x, mouse_y = pygame.mouse.get_pos()
                                                            self.couleurAct  = self.l_matrice[mouse_x//TAILLE_BLOC][mouse_y//TAILLE_BLOC].couleur
                                                            if self.couleurAct == (0,0,0): self.couleurAct = None
                                                            #Si on clique sur la croix, on quitte.
                                                            if event.type == pygame.QUIT:
                                                                pygame.quit()
                                                                return
                                                            #Déplacement de la souris
                                                            elif event.type == pygame.MOUSEMOTION:
                                                                #On remet à zéro /l_zone/
                                                                #On trouve le hightlight à chaque déplacement de la souris
                                                                self.l_zone = []
                                                                self._hightlight(mouse_x//TAILLE_BLOC, mouse_y//TAILLE_BLOC)
                                                            #Clique gauche
                                                            elif event.type == pygame.MOUSEBUTTONDOWN:
                                                                if pygame.mouse.get_pressed() == (1, 0, 0):
                                                                    #self._fillBlack()
                                                                    self._descendreBloc()
                                                            #On affiche quoi qu'il arrive
                                                            self._afficher()
                                                
                                                    def _hightlight(self, col, ligne):
                                                        """''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                                                        - (1) Dans les 8 cases qui entourent la case actuelle.
                                                        - (2) Si certaines sont de la même couleur, elle sont hightlightés.
                                                        - (3) Récursion sur cette case si les indices n'ontpas été ajouté a
                                                          /l_zone/.
                                                        - (4) Et que ce n'est pas une case en diagonale.
                                                        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''"""
                                                        for ii in range(max(0, col-1), min(col+2, NB_BLOC_MAX_COLONNE)):
                                                            for jj in range(max(0, ligne-1), min(ligne+2, NB_BLOC_MAX_LIGNE)):
                                                                if self.l_matrice[ii][jj].couleur == self.couleurAct and (ii, jj) not in self.l_zone:
                                                                    if not (ii,jj) in ((col-1,ligne-1), (col-1,ligne+1), (col+1,ligne-1), (col+1,ligne+1)):
                                                                        self.l_zone.append((ii, jj))
                                                                        self._hightlight(ii, jj)
                                                
                                                    def _fillBlack(self):
                                                        """'''''''''''''''''''''''''''''''''''''''''''''
                                                        - Remplit la zone hightlitée en noir pour essai.
                                                        - Méthode à supprimer si problème résolu.
                                                        '''''''''''''''''''''''''''''''''''''''''''''"""
                                                        for i in self.l_zone:
                                                            self.l_matrice[i[0]][i[1]].couleur = (0,0,0)
                                                
                                                    def _descendreBloc(self):
                                                        """'''''''''''''''''''''''''''''''''''''''''''''''''
                                                        - L'idée est de supprimer les indexs de la matrice
                                                          qui permettent de faire descendre la colonne.
                                                        - On rajoute alors une case noire en haut de la pile
                                                          pour créer l'effet que la colonne descend.
                                                        '''''''''''''''''''''''''''''''''''''''''''''''''"""
                                                        for i in self.l_zone:
                                                            del(self.l_matrice[i[1]][i[0]])
                                                            self.l_matrice[i[1]].insert(0, Case((0,0,0)))
                                                
                                                                
                                                
                                                #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                                #-*-*- <Les Classes> || Début de <Case>       -*-*-#
                                                #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*#
                                                
                                                class Case():
                                                    """Classe <Case> représentant une cellule dans un tableau"""
                                                    def __init__(self, couleur):
                                                        """''''''''''''''''''''''''''
                                                        - /couleur/ est de type "rgb"
                                                        ''''''''''''''''''''''''''"""
                                                        self.couleur = couleur
                                                                
                                                        
                                                        
                                                
                                                if __name__ == "__main__":
                                                    p = Principale()
                                                    p.nouvelle_partie()
                                                    exit(0)
                                                
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  8 septembre 2011 à 7:59:52

                                                  remplaces les lignes 179-181 par
                                                  for i in self.l_zone:
                                                              del(self.l_matrice[i[0]][i[1]])
                                                              self.l_matrice[i[0]].insert(0, Case((0,0,0)))
                                                  


                                                  et vires la ligne 124: self._horloge.tick(FRAME)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  Python c'est bon, mangez-en. 

                                                    16 avril 2014 à 22:32:40

                                                    bonjour comment scripter le samegame sans le programme pygame et avec tkinter ? 

                                                    Cordialement 

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

                                                    [Pygame][Mini-projet] jeu surprise

                                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                    • Editeur
                                                    • Markdown