Commit d5455caa authored by Pauline LEYRIT's avatar Pauline LEYRIT
Browse files

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	joueur.py
parents ce41c524 3aa29580
import numpy as np
from numpy.random import randint
from numpy.random import choice
import sys
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,22 +119,32 @@ 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 : '))
......@@ -142,14 +156,17 @@ class Joueur(metaclass = ABCMeta):
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')
......
This diff is collapsed.
import numpy as np
from numpy.random import randint
import sys
from abc import ABC, abstractmethod
from pieces import Piece, Montagne, Animal, Elephant, Rhinoceros
from joueur import Joueur, Theo, Pauline,IA
class Plateau(list):
num_partie=0 #variable de classe permettant de compter le nombre de plateaux générés et donc le nombre de parties jouées
"""
Ce module contient la définition de la classe principale servant à gérer le jeu
"""
"""classe décrivant de tableau de jeu et de joueur, on commencera par l'initer
avec de grandes dimensions, puis il faudra le réduire à 25 cases """
class Plateau(list):
"""
Classe gérant le déroulement du jeu.
Classe décrivant le tableau de jeu, qui est une liste contentant les différentes pièces
"""
def __init__(self, xmax=5, ymax=5, nb_montagne=3, joueur1=Theo, joueur2=Pauline):
"""
On crée un tableau de jeu aux dimensions désirées, avec un nombre de montagne choisie sur le plateau
On crée un tableau de jeu aux dimensions désirées, avec un nombre de montagne choisi.
Les règles de Siam imposent que xmax et ymax soient égaux à 5
Paramètres
Paramètres
----------
xmax, ymax: int
Lorgeur et longueur du plateau, normalement tout les deux égaux à 5
xmax=ymax car le plateau est carré
xmax, ymax: int
Largeur et longueur du plateau, normalement tout les deux égaux à 5
xmax=ymax car le plateau est carré
nb_montagne: int
nomalement initié à 3 montagnes sur le plateau en début de jeu
nb_mmontagne: int
nomalement initié à 3 montagnes sur le plateau en début de jeu
joueur1, joueur2: joueurs importés de 'joueur'
Joueurs disponibles: 'Theo' qui doit jouer les Elephants,'Pauline' qui doit jouer les Rhinoceros,
'IA' qui doit jouer les Rhinoceros
table_jeu: np.array
taille [xmax,ymax]
Par ailleurs,
self.ele, self.mont et self.rhino sont des listes qui stockeront l'état des pièces avant de les afficher
sur le plateau de jeu avec la méthode unTour
elephants et rhinocéros : Joueurs
"""
......@@ -39,25 +45,19 @@ class Plateau(list):
self.rhino = []
self.joueur1=joueur1
self.joueur2=joueur2
self.partie_finie=False # devient true si une montagne sort
self.partie_finie=False # permet de savoir si la partie est finie ou non. Il devient True si une montagne sort
f = open("historique des parties.txt", mode="w") #on l'ouvre en write pour écraser la partie d'avant
f.write('NOUVELLE PARTIE \n')
f = open("historique des parties.txt", mode="w") #on ouvre le fichier de sauvegarde en mode write pour écraser la partie d'avant
f.write('NOUVELLE PARTIE \n \n')
f.close()
Plateau.num_partie+=1
def __str__(self):
"""
Affiche le plateau de jeu en mode texte suivant les caractères définis
dans les sous classes de ''Animal''.
dans les sous classes de ''Piece''.
Paramètres
----------
......@@ -66,20 +66,20 @@ class Plateau(list):
Renvoie
-------
s: string
La chaîne de caractères qui sera affichée via ''print''
La chaîne de caractères qui sera affichée via ''print'', représentant le plateau de jeu
"""
pos = {}
for piece in self:
pos[piece.coords[0],piece.coords[1]] = (piece.nom+piece.orientation)
pos[piece.coords[0],piece.coords[1]] = (piece.nom+piece.orientation) #une piece est représentée par son nom et son orientation
s = ""
for j in range(self.ymax):
for i in range(-2,7):
if (i, j) in pos:
s += pos[(i, j)]+' '
else:
s += "0 "
s += ". " #les cases vides sont représentées par des points
s += "\n"
return s
......@@ -89,39 +89,41 @@ class Plateau(list):
def initialiserPlateau(self):
"""
initialisation du plateau : toutes les cases sont vides sauf 3 au centre, où se trouvent les montagnes.
On crée également les 5 Elephants et les 5 Rhinoceros que l'on disposera à l'extérieur du plateau, dans leurs
positions et orientations initiales
Paramètres
----------
Aucun
Renvoie
-------
s: string
La chaîne de caractères qui sera affichée via ''print''
Comme dit précédemment, on crée ces Pieces dans les listes self.ele, self.rhino et self.mont, puis on les
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 rochers un à un, en rangée, au milieu du plateau
self.mont.append( Montagne ( midx,midy+k-self.nb_montagne//2,'0 ',self))
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
for k in range(5):
self.ele.append(Elephant(6, k, 'g', self)) #on crée les 5 elephants que l'on oriente vers la gauche et que l'on
#place à droite du plateau
self.rhino.append(Rhinoceros(-2, k, 'd', self))#on crée les 5 rhinoceros que l'on oriente vers la droite et que l'on
# place à gauche du plateau
self.ele.append(Elephant(6, k, 'g', self))
self.rhino.append(Rhinoceros(-2, k, 'd', self))
def unTour(self):
"""
Permet de mettre à jour les pieces sur le plateau
On commence par supprimer toutes les pièces du plateau, avant de remettre les pièces à jour, qui se trouvent
dans les listes self.ele, sekf.rhino et self. mont"""
def unTour(self): #permet de mettre à jour les pieces sur le plateau
for i in (self): # on efface tout le plateau ( sinon redondance) pour mettre à jour
for i in (self): # on efface tout le plateau pour mettre à jour
del(i)
for i in (self.mont): # remet les pions a leur place en fonction de leur coords
for i in (self.mont):
self.append(i)
for i in (self.ele):
self.append(i)
......@@ -129,45 +131,58 @@ class Plateau(list):
self.append(i)
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
while bool==False: #tant qu'on n'a pas trouvé le vainqueur
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
......@@ -177,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