====== Le Nim ====== ===== Description ===== [[https://fr.wikipedia.org/wiki/Jeux_de_Nim|Fiche wikipedia]] * Un tas contient par exemple 20 allumettes, * chaque joueur doit enlever, chacun son tour, 1, 2 ou 3 allumettes, * le joueur qui enlève la dernière allumette a gagné. ===== Variantes ===== * **Plusieurs tas :** chaque joueur peut prélever les jetons dans plusieurs tas qui peuvent avoir des tailles différentes, mais pas dans plusieurs tas à la fois. * **Misère :** celui qui prend la dernière allumette perd. * [[https://fr.wikipedia.org/wiki/Jeu_de_Marienbad|Jeu de Marienbad]] ===== Implémentation Pythton possible ===== **Attention :** L'implémentation proposée définit les règles de fonctionnement d'une partie. Elle ne définit pas l'interface d'une partie. C'est à dire que pour jouer une partie, il faudrait intégrer le module dans une programme qui se chargerait d'initialiser la partie, de commander son affichage à chaque coup, de demander aux joueurs ce qu'ils veulent faire pour leur prochain coup... ==== Avec classes ==== ''' module nim ''' class Nim: TAS = (7, 11, 13, 17) # quantités dans les différents tas SYMBOLE = '|' END_IF_ONLY_ONE_CLEARED = False # Si True, game over quand une ligne est vide MAX_PER_TURN = 3 # nombre max d'item pouvant être enlevé par tour, 0 pour pas de limite def __init__(self): self.__tas = list(self.TAS) # joueur en cours est P1 self.__current_player_is_1 = True def clone(self): ''' création d'un clone de la partie en cours ''' n = Nim() for indice, value in enumerate(self.__tas): n.__tas[indice] = value n.__current_player_is_1 = self.__current_player_is_1 return n def change_player(self): ''' change le joueur en cours ''' self.__current_player_is_1 = not self.__current_player_is_1 def current_player_is_1(self): ''' renvoie True si le joueur courant est P1 ''' return self.__current_player_is_1 def current_player_choose(self, indice_line, number): ''' le joueur en cours sélectionne une ligne et enlève number items ''' assert 0 <= indice_line < len(self.__tas) assert self.MAX_PER_TURN == 0 or number <= self.MAX_PER_TURN assert 0 < number <= self.__tas[indice_line] self.__tas[indice_line] -= number def game_over(self): ''' renvoie True si la partie est terminée. ''' if self.END_IF_ONLY_ONE_CLEARED: # si une ligne vide, fin return 0 in self.__tas # fin si toutes les lignes sont vides return max(self.__tas) == 0 def __str__(self): ''' renvoie une version texte de l'état actuel de la partie ''' return "\n".join(["{}: {}".format(indice, self.SYMBOLE*value) for indice, value in enumerate(self.__tas)])