Commit 3aa29580 authored by Théo BOUTEMY's avatar Théo BOUTEMY
Browse files

tout fini!!!!!

parent 99053011
import numpy as np
from numpy.random import randint
from numpy import choice
import sys
from numpy.random import choice
from abc import ABCMeta, abstractmethod
from pieces import Piece, Montagne, Animal, Elephant, Rhinoceros
......@@ -16,19 +14,19 @@ class Joueur(metaclass = ABCMeta):
def __init__(self, plateau):
"""
On crée donc les joueurs,
on a besoin d'un plateau (chaque pièce des joueurs sera définit notemment
par sa position sur le plateau
On crée donc les joueurs,
on a besoin d'un plateau (chaque pièce des joueurs sera définit notemment
par sa position sur le plateau
Paramètres
----------
plateau : le plateau de jeux regroupant les informations des pions des joueurs
Paramètres
----------
plateau : le plateau de jeux regroupant les informations des pions des joueurs
"""
self.plateau=plateau
self.coup=["entrer","sortir", "pousser","pousser", "entrer en poussant","orientation"] #coup possible pour l'ia
#on met deux fois 'pousser' pour augmenter les chance que le cup se rpoduise (puisque il nécessite plus de conditions pour qu'il se produise)
self.coup=["entrer","sortir", "pousser","pousser", "entrer en poussant","orientation"] #coups possibles pour l'ia
#on met deux fois 'pousser' pour augmenter les chances que le cup se repoduise (puisqu'il nécessite plus de conditions pour qu'il se produise)
self.numero_pieces=['0','1','2','3','4'] #numéro de pieces possibles pour l'IA (numérotés de 0 à 4)
self.ori_possible=['droite','gauche','demi-tour','rien'] #orientation possible pour l'IA
......@@ -44,16 +42,20 @@ class Joueur(metaclass = ABCMeta):
def a_son_tour(self):
""" méthode permettant de jouer: on différencie le joueur humain et l'IA (pour ne pas afficher les messages
""" méthode permettant de jouer: on différencie le joueur humain et l'IA (on prend garde à ne pas afficher les messages
d'erreurs de l'ia qui seraient trop nombreux avant qu'elle ne fasse un tour valide)
On définit ici à qui est ce le tour, et en fonction du joueur (humain ou ia) on attribut les fonctions
On définit ici le joueur qui doit jouer, et en fonction du joueur (humain ou ia) on attribut les fonctions
corrspondantes au coup qu'il a choisit d'effectuer, c'est également ici que les paramètres des fonctions
sont entrés
C'est également cette méthode qui définiera certaines exception/conditions de jeux, le but étant de différencier
sont entrées
C'est également cette méthode qui définiera certaines exceptions/conditions de jeux, le but étant de différencier
le cas où le joueur est l'ia de celui ou le joueur est humain, puisque les messages à afficher sont différents
Ainsi, si les deux types joueurs doivent vérifier les mêmes conditions, l'ia ne fait pas s'afficher les
messages d'erreur.
la fonction continue de laisser le joueur jouer jusqu'à ce que son tour ne soit valide
La fonction continue de laisser le joueur jouer jusqu'à ce que son tour ne soit valide. Pour être sûr que le joueur
a bien effectué son tour avant de passer à un autre joueur, on utilise le tour_effectué du fichier pieces
Paramètres
----------
......@@ -73,7 +75,7 @@ class Joueur(metaclass = ABCMeta):
coup=self.coup[randint(0,5)]
else: # se le joueur est humain, on le laisse choisir
n = input('quelle piece voulez-vous bouger: 0? 1? 2? 3? 4?')
coup = input('quel coup souhaitez-vous faire: entrer? sortir? orientation? position? pousser?')
coup = str(input('quel coup souhaitez-vous faire: entrer? sortir? orientation? position? pousser?'))
if coup not in ['entrer', 'sortir','orientation', 'position' ,'pousser', 'entrer en poussant']:
print('coup non reconnu') # si jamais le joueur a mal orthographié son coup
......@@ -82,8 +84,10 @@ class Joueur(metaclass = ABCMeta):
a, b = self.pieces_du_joueur()[n].coords[0], self.pieces_du_joueur()[n].coords[1]
#on va maintenant associer l'action au coup choisit : on se servira des fonctions définies dans la classe pièce, mais
# elles ne sont pas complètes, c'est ici que la totalité des fonctions s'écrit
#on va maintenant associer l'action au coup choisit : on se servira des fonctions définies dans la classe pièce,
#et on s'assure que le coup est reglementaire
if coup== 'entrer':
self.pieces_du_joueur()[n].tour_effectué=False #permet de laisser le joueur jouer, lorsque la variable
......@@ -97,12 +101,12 @@ class Joueur(metaclass = ABCMeta):
j = int(input('entrer la nouvelle ordonnée : '))
ori = input('droite? gauche? ou demi-tour? ou rien ? ')
if a in [0, 1, 2, 3, 4] and b in [0, 1, 2, 3, 4] : #on test si la pièce n'étais pas déjà entré
if a in [0, 1, 2, 3, 4] and b in [0, 1, 2, 3, 4] : #on test si la pièce n'était pas déjà entré
if self.nom!='IA': #on affiche les messages d'erreurs uniquement si ce n'est pas l'ia (pour éviter
# d'en avoir trop à la fois
print('la piece est déjà rentrée sur le plateau')
else:
if (i == 0 or i == 4 and j in [0,1,2,3,4]) or ( j == 4 or j == 0 and i in [0,1,2,3,4]):
if ((i == 0 or i == 4) and j in [0,1,2,3,4]) or ( (j == 4 or j == 0) and i in [0,1,2,3,4]):
self.pieces_du_joueur()[n].entrer(i,j,ori) #l'action n'a lieux que si les conditions sont respectées
# (il faut entrer sur une case situé sur un bord du plateau)
# ces condition s'applique à tous les joueurs
......@@ -115,41 +119,54 @@ class Joueur(metaclass = ABCMeta):
#pour tous les coups
elif coup == 'sortir':
self.pieces_du_joueur()[n].tour_effectué = False
if (a in [ 0, 4] or b in [0, 4]): #on ne peut sortir que si la pièce est sur un bord du plateau
self.pieces_du_joueur()[n].sortir()
if a not in [0, 1, 2, 3, 4] or b not in [0, 1, 2, 3, 4]: # on test si la pièce est bien sur le plateau
if self.nom != 'IA':
print('la piece n est pas sur le plateau')
else:
if self.nom!='IA':
print("pour sortir une pièce, celle-ci doit être sur l'extérieur du plateau")
if (a in [ 0, 4] or b in [0, 4]): #on ne peut sortir que si la pièce est sur un bord du plateau
self.pieces_du_joueur()[n].sortir()
else:
if self.nom!='IA':
print("pour sortir une pièce, celle-ci doit être sur l'extérieur du plateau")
bool = self.pieces_du_joueur()[n].tour_effectué
elif coup=='entrer en poussant':
self.pieces_du_joueur()[n].tour_effectué = False
#comme pour entrer, on laisse le joueur choisir les paramètres
if self.nom=='IA':
i,j=choice(-1,5),choice(-1,5)
i,j=choice([-1,5]),randint(0,5)
ori=self.ori_possible[randint(0,4)]
else:
i = int(input('entrer la nouvelle abscisse : '))
j = int(input('entrer la nouvelle ordonnée : '))
ori = input('droite? gauche? ou demi-tour? ou rien ? ')
if a in [0, 1, 2, 3, 4] and b in [0, 1, 2, 3, 4] : #la pièce ne doit pas encore être entré
if a in [0, 1, 2, 3, 4] and b in [0, 1, 2, 3, 4] : #la pièce ne doit pas encore être entrée
if self.nom!='IA':
print('la piece est déjà rentrée sur le plateau')
else:
if i == -1 or i == 5 or j == -1 or j == 5: #la pièce doit être sur une case à l'extérieure du plateau, devant
# case qui doit être poussée
# la case qui doit être poussée
self.pieces_du_joueur()[n].entrer_en_poussant(i,j,ori)
else:
if self.nom!='IA':
print('pour rentrer en poussant, vous devez mettre la piece sur une case extérieure au plateau, la mettre dans la bonne orientation et pousser')
print('pour rentrer en poussant, vous devez mettre la piece sur une case extérieure au plateau, en face de la case qui doit être poussée')
bool = self.pieces_du_joueur()[n].tour_effectué
if coup == 'pousser':
elif coup == 'pousser':
self.pieces_du_joueur()[n].tour_effectué = False
if (a in [0, 1, 2, 3, 4] and b in [ 0, 1, 2, 3, 4]): #il faut que le pion soit déjà entré pour utiliser la fonction pousser
self.pieces_du_joueur()[n].pousser()
......@@ -160,10 +177,11 @@ class Joueur(metaclass = ABCMeta):
elif coup== 'orientation':
self.pieces_du_joueur()[n].tour_effectué=False
if (a in [-1, 0, 1, 2, 3, 4, 5] and b in [-1, 0, 1, 2, 3, 4, 5]): #on doit pouvoir s'orienter avec les fonctions
# qui n'existent que si je pion est sur le plateau, mais aussi pour entrer_en_poussant, lorsque le pion est situé à l'extérieur
if (a in [0, 1, 2, 3, 4] and b in [ 0, 1, 2, 3, 4]): #on doit pouvoir s'orienter avec les fonctions
# qui n'existent que si le pion est sur le plateau, mais aussi pour entrer_en_poussant, lorsque le pion est situé à l'extérieur
#on défini les paramètres
if self.nom=='IA':
......@@ -177,18 +195,29 @@ class Joueur(metaclass = ABCMeta):
bool=self.pieces_du_joueur()[n].tour_effectué
elif coup== 'position':
self.pieces_du_joueur()[n].tour_effectué=False
if (a in [0, 1, 2, 3, 4] and b in [0, 1, 2, 3, 4]): #le pion doit être déjà entré sur le plateau
#on définit les paramètres
if self.nom=='IA':
i,j=randint(0,5),randint(0,5)
ori=self.ori_possible[randint(0,4)]
if self.nom=='IA':
i,j=randint(0,5),randint(0,5)
ori=self.ori_possible[randint(0,4)]
else:
i = int(input('entrer la nouvelle abscisse : '))
j = int(input('entrer la nouvelle ordonnée : '))
ori = input('droite? gauche? ou demi-tour? ou rien ? ')
if (a in [0, 1, 2, 3, 4] and b in [0, 1, 2, 3, 4]): # le pion doit être déjà entré sur le plateau
if ((i == a + 1 or i == a - 1) and j == b) or ((j == b + 1 or j == b - 1) and i == a): # si on demande un déplacement sur une case adjacente
self.pieces_du_joueur()[n].changement_position(i, j, ori) #on effectue le déplacement
else:
i = int(input('entrer la nouvelle abscisse : '))
j = int(input('entrer la nouvelle ordonnée : '))
ori = input('droite? gauche? ou demi-tour? ou rien ? ')
self.pieces_du_joueur()[n].changement_position(i,j,ori)
if self.nom == 'IA':
print("le déplacement n'est pas réglementaire, choisir d'autres coordonnées")
else:
if self.nom != 'IA':
print('vous ne pouvez pas déplacer une piece qui n est pas sur le plateau')
......
......@@ -110,6 +110,56 @@ class Animal(Piece, metaclass=ABCMeta):
"""
pass
def entrer(self,i,j,ori):
"""
Cette méthode permet d'entrer un des animaux sur le plateau, en vérifiant que cette case
ne soit pas déjà occupée
On vérifiera que le coup est réglementaire (entrée par une case extérieure) dans la
méthode 'à son tour' du fichier joueur
Paramètres:
i, j : int ==> Les coordonnées auxquelles on souhaite entrer la pièce
ori: str ==> le changement d'orientation que l'on veut affecter à la piece
"""
bool2=True # booléen qui permet de savoir si la case est déjà occupée ou non
for k in (self.plateau): # on vérifie que la case n'est pas déjà occupée
if k.coords == [i, j]:
print("la case choisie est déjà prise, choisir d'autres coordonnées")
bool2 = False
break
if bool2:
self.coords = [i, j] # on met à jour les coordonnées de notre pièce, qui rentre sur le plateau
self.changement_orientation(ori)
self.tour_effectué = True
def sortir(self):
"""
Cette méthode permet de sortir un des animaux du plateau.
L'animal retourne alors à sa position initiale, avec son orientation initiale
On vérifiera que le coup est réglementaire (sortie autorisée que si la pièce est en bordure de plateau) dans la
méthode 'à son tour' du fichier joueur.
"""
if self.car() == 'R':
self.coords = [-2, self.numero] #coordonnées et orientations initiales des rhinoceros
self.orientation='d'
else:
self.coords =[ 6, self.numero]
self.orientation = 'g'
self.tour_effectué = True # le tour est effectivement joué
def pousser(self):
"""
Méthode permettant de réaliser le coup : pousser
......@@ -264,33 +314,6 @@ class Animal(Piece, metaclass=ABCMeta):
def entrer(self,i,j,ori):
"""
Cette méthode permet d'entrer un des animaux sur le plateau, en vérifiant que cette case
ne soit pas déjà occupée
On vérifiera que le coup est réglementaire (entrée par une case extérieure) dans la
méthode 'à son tour' du fichier joueur
Paramètres:
i, j : int ==> Les coordonnées auxquelles on souhaite entrer la pièce
ori: str ==> le changement d'orientation que l'on veut affecter à la piece
"""
bool2=True # booléen qui permet de savoir si la case est déjà occupée ou non
for k in (self.plateau): # on vérifie que la case n'est pas déjà occupée
if k.coords == [i, j]:
print("la case choisie est déjà prise, choisir d'autres coordonnées")
bool2 = False
break
if bool2:
self.coords = [i, j] # on met à jour les coordonnées de notre pièce, qui rentre sur le plateau
self.changement_orientation(ori)
self.tour_effectué = True
def entrer_en_poussant(self,i,j,ori):
......@@ -317,33 +340,15 @@ class Animal(Piece, metaclass=ABCMeta):
#le coup n'étant pas fini, on le remet à False
self.pousser() #si cela est possible, alors tour_effectué devient True
if self.coords[0] in [-1,5] or self.coords[1] in [-1,-2,5,6]: #ca veut dire que la pièce n'est pas entrée sur le plateau
if self.coords[0] in [-1,-2,5,6] or self.coords[1] in [-1,-2,5,6]: #ca veut dire que la pièce n'est pas entrée sur le plateau
self.sortir() #on remet la piece à sa position initiale
self.tour_effectué=False # au final le tour n'est pas joué
def sortir(self):
"""
Cette méthode permet de sortir un des animaux du plateau.
L'animal retourne alors à sa position initiale, avec son orientation initiale
On vérifiera que le coup est réglementaire (sortie autorisée que si la pièce est en bordure de plateau) dans la
méthode 'à son tour' du fichier joueur.
"""
if self.car() == 'R':
self.coords = [-2, self.numero] #coordonnées et orientations initiales des rhinoceros
self.orientation='d'
else:
self.coords =[ 6, self.numero]
self.orientation = 'g'
self.tour_effectué = True # le tour est effectivement joué
def changement_orientation(self,ori):
"""
Cette méthode permet de changer l'orientation d'une piece
......@@ -394,24 +399,23 @@ class Animal(Piece, metaclass=ABCMeta):
ori: str ==> le changement d'orientation que l'on veut affecter à la piece
On vérifiera que le coup est réglementaire (déplacement sur une case adjacente) dans la
méthode 'à son tour' du fichier joueur.
Comme stipulé dans les règles du jeu, on peut changer la position et l'orientation dans un même coup
"""
bool2 = True # on vérifie que la case n'est pas déjà occupée
bool3 = False # on vérifie que le déplacement est bien réglementaire, c'est à dire sur une case adjacente, et pas en diagonale
for k in (self.plateau): # on vérifie que la case n'est pas déjà occupée
if k.coords == (i, j): # si la case est déjà occupée
print("la case choisie est déjà prise, choisir d'autres coordonnées")
bool2 = False
break
if ((i == self.coords[0] + 1 or i == self.coords[0] - 1) and j == self.coords[1] )\
or ((j == self.coords[1] + 1 or j == self.coords[1] - 1) and i == self.coords[0]): #si on demande un déplacement sur une case adjacente
bool3 = True
else:
print("le déplacement n'est pas réglementaire, choisir d'autres coordonnées")
if bool2 and bool3: #si toutes les conditions sont réunies
if bool2 : #si toutes les conditions sont réunies
self.coords = [i, j] #on déplace la piece
self.changement_orientation(ori) # et on change son orientation
......
......@@ -97,9 +97,8 @@ class Plateau(list):
affichera sur le plateau avec la méthode 'unTour'
"""
#on initialise dans les listes pas dans le plateau
# self.plateau = np.zeros([self.xmax, self.ymax], dtype=Piece)
midx, midy=self.xmax//2, self.ymax//2 # indices de la case correspondant au centre du plateau
for k in range(self.nb_montagne): # place les montagnes un à un, en colonne, au milieu du plateau
self.mont.append( Montagne ( midx,midy+k-self.nb_montagne//2,'0 ',self)) #la montagne n'a pas d'orientation particulière
......@@ -134,47 +133,56 @@ class Plateau(list):
def vainqueur(self):
"""
Méthode permettant de savoir s'il y a un vainqueur ou non
on regarde d'abord si les montagnes sont sorties du plateau
si c'est la cas, alors ono distingue 4 cas: sortie vers le hait, le bas, la gauche ou la droite du plateau
Enfin, on détermine le vainqueur qui est le joueur qui est le plus proche du rocher et dans le même sens de poussée
"""
bool=False
for m in self.mont:
for m in self.mont: #on passe en revue toutes les montagnes
if m.coords[0]==-1: #la montagne est sortie du plateau, à gauche
while bool==False: # tant qu'on n'a pas trouvé le vainqueur
for i in range (1,5):
for piece in self:
if piece.coords[0]==m.coords[0]+i and piece.coords[1]==m.coords[1] and piece.orientation=='g':
winner=piece
#on commence par étudier la piece à droite de la montagne: si les conditions sont vérifiées pour
#gagner, alors on a trouvé le gagnant. Sinon on prend la piece encore à droite et on
#cherche à vérifier les conditions, etc
winner=piece #c'est la piece gagnante
bool=True
self.partie_finie=True
break
if m.coords[0]==5: #la montagne est sortie du plateau
if m.coords[0]==5: #la montagne est sortie du plateau, à droite
while bool==False: #tant qu'on n'a pas trouvé le vainqueur
for i in range (1,5):
for piece in self:
if piece.coords[0]==m.coords[0]-i and piece.coords[1]==m.coords[1] and piece.orientation=='d':
#de même, le vainqueur se trouve dans les pieces situées à gauche de la montagne
winner=piece
bool=True
self.partie_finie = True
break
if m.coords[1]==-1: #la montagne est sortie du plateau
if m.coords[1]==-1: #la montagne est sortie du plateau,en haut
while bool==False: #tant qu'on n'a pas trouvé le vainqueur
for i in range (1,5):
for piece in self:
if piece.coords[1]==m.coords[1]+i and piece.coords[0]==m.coords[0] and piece.orientation=='h':
# de même, le vainqueur se trouve dans les pieces situées en bas de la montagne
winner=piece
bool=True
self.partie_finie = True
break
if m.coords[1]==5: #la montagne est sortie du plateau
if m.coords[1]==5: #la montagne est sortie du plateau, en bas
while bool==False: #tant qu'on n'a pas trouvé le vainqueur
for i in range (1,5):
for piece in self:
if piece.coords[1]==m.coords[1]-i and piece.coords[0]==m.coords[0] and piece.orientation=='b':
# de même, le vainqueur se trouve dans les pieces situées en haut de la montagne
winner=piece
bool=True
self.partie_finie = True
......@@ -184,70 +192,63 @@ class Plateau(list):
if bool==True and winner.car()=='R':
print('la partie est finie, le vainqueur est', self.joueur2(self).nom)
f = open("historique des parties.txt", mode="a")
if bool==True and winner.car()=='R': #si la piece gagnante est un rhinoceros
print('la partie est finie, le vainqueur est', self.joueur2(self).nom) #alors elle appartient au joueur 2, qui gagne la partie
f = open("historique des parties.txt", mode="a") #on note cela dans le fichier
f.write('la partie est finie, le vainqueur est {0} \n \n \n \n'.format( self.joueur2(self).nom))
f.close()
if bool== True and winner.car()=='E' :
if bool== True and winner.car()=='E' : #de même si la pièce est un elephant
print ('partie finie, le vainqueur est', self.joueur1(self).nom)
f = open("historique des parties.txt", mode="a")
f.write('la partie est finie, le vainqueur est {0} \n \n \n \n '.format(self.joueur1(self).nom))
f.close()
def jouer(self):
"""
c'est cette fonction qui lance vraiment le jeu
On initialise d'abord le plateau
Puis tant qu'il n'y a pas de joueur, on fait jouer le joueur 1 puis le joueur2, en vérifiant à chaque fois
s'il n'y a pas un gagnant, et en affichant le plateau de jeu
# """
# on exécute les actions des joueurs, définies dans la classe animal
#
# """
#
# self.append(Elephant(0,0,'d',self).entrer()) #l'idée c'est de faire rentrer un animal au bord mais ca marche po
#
#
def jouer(self):
"""
self.initialiserPlateau()
bool=True
# while not self.joueur1.winner :#and self.joueur2.winner==False : # il faut mettre la condition d'arret du jeu*
bool=True #bool ne devient jamais False: le programme tourne à l'infini à priori. En réalité, le jeu s'arrête
# s'il y a un gagnant, grâce à un break
while bool:
self.unTour() # remet le plateau a jour
print(self) # le plateau
print(self) # on affiche le plateau
print('c est au tour du joueur',self.joueur1(self).description) # self de joueur
self.joueur1(self).a_son_tour() # quel pion, fonction..
self.unTour()
self.vainqueur() # vérifie si partie finie
print('c est au tour du joueur',self.joueur1(self).description)
self.joueur1(self).a_son_tour() # le joueur 1 indique le coup qu'il veut faire et la piece à déplacer
self.unTour()#remet à jour le plateau
self.vainqueur() # on vérifie si partie finie
if self.partie_finie: #devient true si une montagne est sortie
break # le programme s'arrete
break # le jeu s'arrete
print(self)
# if M1 not in (range(5),range(5)) or M2 not in (range(5),range(5)) or M3 not in (range(5),range(5)):
# print('fin du jeu, le joueur est ',self.joueur1(self).nom)
# break
print('c est au tour du joueur', self.joueur2(self).description)
print('c est au tour du joueur', self.joueur2(self).description) #même principe, mais cette fois c'est au tour du joueur 2
self.joueur2(self).a_son_tour()
self.unTour()
self.vainqueur()
if self.partie_finie:
break
# if M1 not in (range(5),range(5)) or M2 not in (range(5),range(5)) or M3 not in (range(5),range(5)):
# print('fin du jeu, le joueur est ',self.joueur2(self).nom)
# break
if __name__ == "__main__":
plateau = Plateau(xmax=5, ymax=5, nb_montagne=3, joueur1=Theo, joueur2=IA) # c'est ici qu'on def les joueurs
plateau = Plateau(xmax=5, ymax=5, nb_montagne=3, joueur1=Theo, joueur2=IA) # c'est ici qu'on choisit les joueurs
Plateau.jouer(plateau)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment