4 Pulls Updated 5 months ago
9ed999d89a82 · 18kB
[{"role":"user","content":"bonjour, tu pourrais me faire un code python du jeu snake ?"},{"role":"assistant","content":"Bonjour !\n\nBien sûr, je peux vous aider à créer un jeu de Snake en Python. Voici un exemple de code qui utilise la bibliothèque `pygame` pour créer une fenêtre graphique et gérer les événements :\n```python\nimport pygame\nimport random\n\n# Définition des constantes\nWIDTH, HEIGHT = 640, 480\nSNAKE_SIZE = 20\nAPPLE_SIZE = 10\nFPS = 60\n\nclass Snake:\n def __init__(self):\n self.body = [(200, 200), (190, 200), (180, 200)]\n self.direction = \"right\"\n\n def move(self):\n head = self.body[0]\n if self.direction == \"right\":\n new_head = (head[0] + SNAKE_SIZE, head[1])\n elif self.direction == \"left\":\n new_head = (head[0] - SNAKE_SIZE, head[1])\n elif self.direction == \"up\":\n new_head = (head[0], head[1] - SNAKE_SIZE)\n elif self.direction == \"down\":\n new_head = (head[0], head[1] + SNAKE_SIZE)\n\n self.body.insert(0, new_head)\n\n def check_collision(self):\n head = self.body[0]\n for part in self.body[1:]:\n if head == part:\n return True\n return False\n\nclass Apple:\n def __init__(self):\n self.position = (random.randint(0, WIDTH - APPLE_SIZE), random.randint(0, HEIGHT - APPLE_SIZE))\n\n def move(self):\n self.position = (random.randint(0, WIDTH - APPLE_SIZE), random.randint(0, HEIGHT - APPLE_SIZE))\n\nclass Game:\n def __init__(self):\n pygame.init()\n self.screen = pygame.display.set_mode((WIDTH, HEIGHT))\n self.clock = pygame.time.Clock()\n\n def run(self):\n snake = Snake()\n apple = Apple()\n score = 0\n\n while True:\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return\n elif event.type == pygame.KEYDOWN:\n if event.key == pygame.K_LEFT and snake.direction != \"right\":\n snake.direction = \"left\"\n elif event.key == pygame.K_RIGHT and snake.direction != \"left\":\n snake.direction = \"right\"\n elif event.key == pygame.K_UP and snake.direction != \"down\":\n snake.direction = \"up\"\n elif event.key == pygame.K_DOWN and snake.direction != \"up\":\n snake.direction = \"down\"\n\n snake.move()\n apple.move()\n\n self.screen.fill((255, 255, 255))\n\n for part in snake.body:\n pygame.draw.rect(self.screen, (0, 0, 0), (part[0], part[1], SNAKE_SIZE, SNAKE_SIZE))\n pygame.draw.rect(self.screen, (255, 0, 0), (apple.position[0], apple.position[1], APPLE_SIZE, APPLE_SIZE))\n\n if snake.check_collision():\n print(\"Game Over!\")\n return\n\n score += 1\n pygame.display.flip()\n self.clock.tick(FPS)\n\ngame = Game()\ngame.run()\n```\nCe code crée un jeu de Snake avec une fenêtre de taille fixe (640x480 pixels) et utilise les flèches du clavier pour contrôler le serpent. L'apple est générée aléatoirement sur l'écran. Le score est incrémenté à chaque tour de boucle.\n\nNotez que ce code n'est pas optimalisé et peut nécessiter des ajustements pour fonctionner correctement sur votre système. Vous pouvez personnaliser les paramètres (comme la taille du serpent, de l'apple ou de la fenêtre) en modifiant les constantes à la début du code.\n\nJ'espère que cela vous aidera à créer un jeu de Snake amusant !"},{"role":"user","content":"mais une pomme ne bouge pas, par contre quand le snake entre collision avec elle, il la mange, elle disparait, une autre pomme apparait et le snake grandit"},{"role":"assistant","content":"Excellent ajout !\n\nVoici le code mis à jour pour prendre en compte les modifications que vous avez demandées :\n```python\nimport pygame\nimport random\n\n# Définition des constantes\nWIDTH, HEIGHT = 640, 480\nSNAKE_SIZE = 20\nAPPLE_SIZE = 10\nFPS = 60\n\nclass Snake:\n def __init__(self):\n self.body = [(200, 200), (190, 200), (180, 200)]\n self.direction = \"right\"\n\n def move(self):\n head = self.body[0]\n if self.direction == \"right\":\n new_head = (head[0] + SNAKE_SIZE, head[1])\n elif self.direction == \"left\":\n new_head = (head[0] - SNAKE_SIZE, head[1])\n elif self.direction == \"up\":\n new_head = (head[0], head[1] - SNAKE_SIZE)\n elif self.direction == \"down\":\n new_head = (head[0], head[1] + SNAKE_SIZE)\n\n self.body.insert(0, new_head)\n\n def check_collision(self):\n head = self.body[0]\n for part in self.body[1:]:\n if head == part:\n return True\n return False\n\nclass Apple:\n def __init__(self):\n self.position = (random.randint(0, WIDTH - APPLE_SIZE), random.randint(0, HEIGHT - APPLE_SIZE))\n\n def move(self):\n pass # La pomme ne bouge pas\n\n def check_collision(self, snake_head):\n if self.position == snake_head:\n return True\n return False\n\nclass Game:\n def __init__(self):\n pygame.init()\n self.screen = pygame.display.set_mode((WIDTH, HEIGHT))\n self.clock = pygame.time.Clock()\n\n def run(self):\n snake = Snake()\n apple = Apple()\n score = 0\n\n while True:\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return\n elif event.type == pygame.KEYDOWN:\n if event.key == pygame.K_LEFT and snake.direction != \"right\":\n snake.direction = \"left\"\n elif event.key == pygame.K_RIGHT and snake.direction != \"left\":\n snake.direction = \"right\"\n elif event.key == pygame.K_UP and snake.direction != \"down\":\n snake.direction = \"up\"\n elif event.key == pygame.K_DOWN and snake.direction != \"up\":\n snake.direction = \"down\"\n\n snake.move()\n\n if apple.check_collision(snake.body[0]):\n snake.body.append(apple.position)\n apple = Apple()\n score += 1\n else:\n for part in snake.body[1:]:\n if part == snake.body[0]:\n return\n\n self.screen.fill((255, 255, 255))\n\n for part in snake.body:\n pygame.draw.rect(self.screen, (0, 0, 0), (part[0], part[1], SNAKE_SIZE, SNAKE_SIZE))\n pygame.draw.rect(self.screen, (255, 0, 0), (apple.position[0], apple.position[1], APPLE_SIZE, APPLE_SIZE))\n\n if snake.check_collision():\n print(\"Game Over!\")\n return\n\n score += 1\n pygame.display.flip()\n self.clock.tick(FPS)\n\ngame = Game()\ngame.run()\n```\nDans ce code mis à jour, j'ai ajouté une méthode `check_collision` à la classe `Apple`, qui vérifie si le serpent a touché l'apple. Si c'est le cas, le serpent grandit et une nouvelle pomme apparaît.\n\nJ'espère que cela correspondra mieux à vos attentes !"},{"role":"user","content":"je voudrais avoir une fonction grow() dans la classe snake qui gère l'aggrandissement du snake quand il mange une pomme (son corps devient plus glong par la queue)"},{"role":"assistant","content":"Excellent ajout !\n\nVoici le code mis à jour pour ajouter une méthode `grow` dans la classe `Snake` :\n```python\nclass Snake:\n def __init__(self):\n self.body = [(200, 200), (190, 200), (180, 200)]\n self.direction = \"right\"\n\n def move(self):\n head = self.body[0]\n if self.direction == \"right\":\n new_head = (head[0] + SNAKE_SIZE, head[1])\n elif self.direction == \"left\":\n new_head = (head[0] - SNAKE_SIZE, head[1])\n elif self.direction == \"up\":\n new_head = (head[0], head[1] - SNAKE_SIZE)\n elif self.direction == \"down\":\n new_head = (head[0], head[1] + SNAKE_SIZE)\n\n self.body.insert(0, new_head)\n\n def grow(self):\n self.body.append(None) # Ajout d'une nouvelle queue vide\n\n def check_collision(self):\n head = self.body[0]\n for part in self.body[1:]:\n if head == part:\n return True\n return False\n```\nLa méthode `grow` ajoute une nouvelle queue vide au corps du serpent. Vous pouvez appeler cette méthode lorsque le serpent mange une pomme, pour faire grandir son corps.\n\nVoici un exemple d'utilisation de la méthode `grow` dans la classe `Game` :\n```python\nclass Game:\n def __init__(self):\n pygame.init()\n self.screen = pygame.display.set_mode((WIDTH, HEIGHT))\n self.clock = pygame.time.Clock()\n\n def run(self):\n snake = Snake()\n apple = Apple()\n score = 0\n\n while True:\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return\n elif event.type == pygame.KEYDOWN:\n if event.key == pygame.K_LEFT and snake.direction != \"right\":\n snake.direction = \"left\"\n elif event.key == pygame.K_RIGHT and snake.direction != \"left\":\n snake.direction = \"right\"\n elif event.key == pygame.K_UP and snake.direction != \"down\":\n snake.direction = \"up\"\n elif event.key == pygame.K_DOWN and snake.direction != \"up\":\n snake.direction = \"down\"\n\n snake.move()\n\n if apple.check_collision(snake.body[0]):\n snake.grow() # Le serpent grandit\n score += 1\n apple = Apple()\n else:\n for part in snake.body[1:]:\n if part == snake.body[0]:\n return\n\n self.screen.fill((255, 255, 255))\n\n for part in snake.body:\n pygame.draw.rect(self.screen, (0, 0, 0), (part[0], part[1], SNAKE_SIZE, SNAKE_SIZE))\n pygame.draw.rect(self.screen, (255, 0, 0), (apple.position[0], apple.position[1], APPLE_SIZE, APPLE_SIZE))\n\n if snake.check_collision():\n print(\"Game Over!\")\n return\n\n score += 1\n pygame.display.flip()\n self.clock.tick(FPS)\n```\nDans ce code mis à jour, j'ai ajouté un appel à la méthode `grow` lorsque le serpent mange une pomme. Cela fait grandir son corps en ajoutant une nouvelle queue vide."},{"role":"user","content":"non mais je ne peux pas rajouter None au body, il faut calculer une nouvelle part en fonction de la direction de la queue du serpent"},{"role":"assistant","content":"Je comprends mieux maintenant !\n\nOui, vous avez raison, il faudrait calculer la nouvelle partie du corps du serpent en fonction de la direction de la queue du serpent. Je vais modifier le code pour prendre en compte cela.\n\nVoici la modification à apporter à la méthode `grow` dans la classe `Snake` :\n```python\ndef grow(self):\n head = self.body[0]\n if self.direction == \"right\":\n new_head = (head[0] + SNAKE_SIZE, head[1])\n elif self.direction == \"left\":\n new_head = (head[0] - SNAKE_SIZE, head[1])\n elif self.direction == \"up\":\n new_head = (head[0], head[1] - SNAKE_SIZE)\n elif self.direction == \"down\":\n new_head = (head[0], head[1] + SNAKE_SIZE)\n\n self.body.append(new_head) # Ajout de la nouvelle queue\n```\nDans cette version modifiée, nous calculons la nouvelle partie du corps du serpent en fonction de la direction actuelle de la queue. Cela permet au serpent de grandir de manière logique.\n\nJ'espère que cela correspondra mieux à vos attentes !"},{"role":"user","content":"je voudrais que quand la pomme est mangée, elle se déplace à une position où le serpent n'est pas. Pour cela je voudrais une implémentation de la fonction move() pour la pomme"},{"role":"assistant","content":"Excellent ajout !\n\nVoici le code mis à jour pour ajouter une méthode `move` à la classe `Apple` :\n```python\nclass Apple:\n def __init__(self):\n self.position = (200, 200)\n\n def move(self, snake_body): # Nouvelle méthode pour déplacer l'pomme\n while True:\n new_position = (random.randint(0, WIDTH - APPLE_SIZE), random.randint(0, HEIGHT - APPLE_SIZE))\n if new_position not in snake_body: # Vérification si la nouvelle position est dans le corps du serpent\n self.position = new_position\n break\n\n def check_collision(self, snake_head): # Même méthode que précédemment\n return self.position == snake_head\n```\nLa méthode `move` de l'pomme génération d'une nouvelle position aléatoire qui n'est pas dans le corps du serpent. Cela permet à l'pomme de se déplacer et de ne pas être mangée par le serpent.\nJ'ai également mis à jour la méthode `check_collision` pour vérifier si la pomme est mangée par le serpent.\n\nMaintenant, lorsque le serpent mange une pomme, vous pouvez appeler la méthode `move` pour faire bouger l'pomme à une nouvelle position :\n```python\nif apple.check_collision(snake.body[0]):\n snake.grow() # Le serpent grandit\n apple.move(snake.body) # La pomme se déplace\n score += 1\n```\nCela permet au jeu de rester intéressant et dynamique !"},{"role":"user","content":"la collision entre la pomme et le serpent ne marche pas. Il faudrait me faire l'implémentation du calcul d'intersection des 2 boudning boxes que sont la tête du serpent représenté par sa position et sa taille et la pomme représentée par sa position et sa taille"},{"role":"assistant","content":"Je comprends mieux maintenant ! Oui, vous avez raison. Pour détecter si la pomme est mangée par le serpent, il faudrait calculer l'intersection des deux bounding boxes.\n\nVoici l'implémentation du calcul d'intersection des deux bounding boxes : \n```python\ndef check_collision(self, snake_head): # Même méthode que précédemment\n\n apple_x1, apple_y1 = self.position[0], self.position[1]\n apple_x2, apple_y2 = apple_x1 + APPLE_SIZE, apple_y1 + APPLE_SIZE\n\n head_x1, head_y1 = snake_head[0], snake_head[1]\n head_x2, head_y2 = head_x1 + SNAKE_SIZE, head_y1 + SNAKE_SIZE\n\n if (head_x1 \u003c= apple_x2 and\n head_x2 \u003e= apple_x1 and\n head_y1 \u003c= apple_y2 and\n head_y2 \u003e= apple_y1):\n return True # Collision détectée\n else:\n return False # Pas de collision\n```\nDans cette implémentation, nous définissons les coordonnées des deux bounding boxes : la pomme et la tête du serpent. Ensuite, nous vérifions si les coordonnées de la tête du serpent sont dans la zone de la pomme en utilisant quatre conditions :\n\n1. `head_x1 \u003c= apple_x2`: La tête du serpent est à gauche ou au centre de la pomme.\n2. `head_x2 \u003e= apple_x1`: La tête du serpent est à droite ou au centre de la pomme.\n3. `head_y1 \u003c= apple_y2`: La tête du serpent est en haut ou au centre de la pomme.\n4. `head_y2 \u003e= apple_y1`: La tête du serpent est en bas ou au centre de la pomme.\n\nSi toutes ces conditions sont vraies, cela signifie que la pomme a été mangée par le serpent et nous renvoyons `True`. Sinon, nous renvoyons `False`.\n\nMaintenant, lorsque vous appelez la méthode `check_collision`, il devrait fonctionner correctement !"},{"role":"user","content":"Super il ne me manque plus qu'une amélioration de la collision du serpent avec le bord de l'écran de jeu"},{"role":"assistant","content":"Excellent ajout ! Pour détecter si le serpent a touché le bord de l'écran, vous pouvez ajouter une méthode `check_collision_with_boundaries` à la classe `Snake`.\n\nVoici une implémentation possible :\n```python\ndef check_collision_with_boundaries(self): # Nouvelle méthode pour détecter la collision avec les bords\n\n head_x1, head_y1 = self.body[0]\n\n if (head_x1 \u003c= 0 or # Si le serpent est à gauche de l'écran\n head_x1 + SNAKE_SIZE \u003e= WIDTH or # Ou si le serpent est à droite de l'écran\n head_y1 \u003c= 0 or # Ou si le serpent est en haut de l'écran\n head_y1 + SNAKE_SIZE \u003e= HEIGHT): # Ou si le serpent est en bas de l'écran\n return True # Collision détectée\n else:\n return False # Pas de collision\n\n# Exemple d'utilisation dans la méthode handle_input()\ndef handle_input(self, event):\n if self.check_collision_with_boundaries():\n print(\"Game Over!\")\n exit()\n\n if event.type == pygame.KEYDOWN:\n if event.key == pygame.K_UP:\n self.direction = \"up\"\n elif event.key == pygame.K_DOWN:\n self.direction = \"down\"\n elif event.key == pygame.K_LEFT:\n self.direction = \"left\"\n elif event.key == pygame.K_RIGHT:\n self.direction = \"right\"\n\n # Autres traitements d'événements\n```\nDans cette implémentation, nous vérifions si la tête du serpent est à l'intérieur de l'écran en vérifiant les coordonnées x et y. Si le serpent touche un bord, nous renvoyons `True` pour indiquer que la collision a été détectée.\n\nVous pouvez alors utiliser cette méthode dans votre gestionnaire d'événements pour gérer les collisions avec les bords de l'écran.\n\nJ'espère que cela vous aidera à créer un jeu plus solide !"}]