"""
Logique pure du jeu MasterMind - sans GUI
"""
import random
from typing import List, Tuple
from config import CODE_LENGTH, NUM_COLORS, MAX_ATTEMPTS, COLORS
class MasterMindGame:
"""Moteur du jeu MasterMind"""
def __init__(self):
"""Initialise une nouvelle partie"""
self.secret_code = self._generate_secret()
self.attempts = [] # Liste de tuples (guess, feedback)
self.game_over = False
self.won = False
def _generate_secret(self) -> List[int]:
"""Génère un code secret aléatoire (indices de couleurs)"""
return [random.randint(0, NUM_COLORS - 1) for _ in range(CODE_LENGTH)]
def _calculate_feedback(self, guess: List[int]) -> Tuple[int, int]:
"""
Calcule le feedback pour une tentative.
Retourne (noirs, blancs) où:
- noirs = positions correctes (bonne couleur + bonne position)
- blancs = bonnes couleurs mais mauvaises positions
"""
secret = self.secret_code.copy()
guess_copy = guess.copy()
# D'abord compter les noirs (positions exactes)
black = 0
for i in range(CODE_LENGTH):
if guess_copy[i] == secret[i]:
black += 1
guess_copy[i] = None # Marquer comme compté
secret[i] = None
# Ensuite compter les blancs (bonnes couleurs mal placées)
white = 0
for i in range(CODE_LENGTH):
if guess_copy[i] is not None:
for j in range(CODE_LENGTH):
if secret[j] is not None and guess_copy[i] == secret[j]:
white += 1
secret[j] = None
break
return black, white
def make_guess(self, guess: List[int]) -> Tuple[bool, Tuple[int, int]]:
"""
Effectue une tentative.
Args:
guess: Liste d'indices de couleurs (0 à NUM_COLORS-1)
Returns:
(is_correct, feedback) où feedback = (noirs, blancs)
"""
if self.game_over:
raise ValueError("La partie est terminée")
if len(guess) != CODE_LENGTH:
raise ValueError(f"Le guess doit contenir {CODE_LENGTH} couleurs")
feedback = self._calculate_feedback(guess)
self.attempts.append((guess.copy(), feedback))
# Vérifier si gagné
if feedback[0] == CODE_LENGTH:
self.won = True
self.game_over = True
elif len(self.attempts) >= MAX_ATTEMPTS:
self.game_over = True
return self.won, feedback
def get_remaining_attempts(self) -> int:
"""Retourne le nombre de tentatives restantes"""
return MAX_ATTEMPTS - len(self.attempts)
def reveal_secret(self) -> List[int]:
"""Retourne le code secret (pour affichage en fin de partie)"""
return self.secret_code.copy()
def reset(self):
"""Réinitialise la partie"""
self.__init__()
def guess_to_colors(guess: List[int]) -> List[str]:
"""Convertit une liste d'indices en noms de couleurs"""
return [COLORS[i][0] for i in guess]
def feedback_to_string(feedback: Tuple[int, int]) -> str:
"""Formatte le feedback pour affichage"""
black, white = feedback
return f"⬛{black} ⬜{white}"
if __name__ == "__main__":
# Test simple de la logique
game = MasterMindGame()
print(f"Code secret (indices): {game.secret_code}")
print(f"Code secret (couleurs): {guess_to_colors(game.secret_code)}")
# Test d'une tentative
test_guess = game.secret_code.copy() # Devine le secret (should win)
won, feedback = game.make_guess(test_guess)
print(f"Guess: {guess_to_colors(test_guess)} -> Feedback: {feedback} - Gagné: {won}")