Salut,
voilà je doit compléter un tic-tac-toe (dans le cadre d'un exercice) en langage haskell.
Si il y en a qui connaissent et qui accepterait de passer qques minutes à réfléchir dessus, ça serait sympa.
Je sais que la paresse est la mère de tous les maux mais j'ai vraiment vraiment besoin de réussir cet exercice !
Ca fait un bout de temps que j'y réfléchi mais je sais pas trop par où commencer.
ss énoncé du sujet :
Nous nous proposons de definir la fonction valuation :: Etat -> Integer
qui evalue l'interet d'un etat. Nous donnons quelques primitives de base pourss
construire cette fonction; a vous de completer en COMMENTANT vos choix.
a) soit un joueur j et une case de coordonnees c; une case de coordonnees css
est une case amie pour le joueur j ssi c est deja occupee par un pion duss
joueur j.
estAmie :: Joueur -> Grille -> Coordonnees -> Bool
estAmie j g c = member (Couleur j c) g
Etant donnee une case, un Alignement est une ligne, une colonne ou une
diagonale (principale ou secondaire) complete qui contient cette case.
Ainsi, nous recherchons des alignements suivant 4 directions: ligne, colonne,ss
diagonale principale et diagonale secondaire. Nous developpons iciss
l'alignement "meme ligne";ss
a vous de completer dans les 3 autres directions: alignementColonne,ss
alignementDiagPrincipale et alignementDiagSecondaire
type Alignement = [Coordonnees]
alignementLigne :: Coordonnees -> Alignement
alignementLigne (l, c) = [(l,c' | c' <- [1..ncolonnes]]
b) Detection de la fin d'une partie
ss
si il existe un alignement gagnant pour l'etat (g, j)
ssssalors le joueur j a gagne (et son adversaire a perdu)
sssssinon
ssssss si aucun alignement n'est gagnant et la grille est pleine
ssssss alors match nul fsi
fsissssssss
ss code source à compléter :
---------------------------------------------------------------------------
-- ATTENTION
--ssss . INSERER LA DEFINITION DE VOS PROPRES FONCTIONS ICI
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-- ATTENTION
--ssss .ssNE JAMAIS MODIFIER LES DEFINITIONS QUI SUIVENT
---------------------------------------------------------------------------
---------------------------------------------------------------------------
data Joueur = Ami | Adv
ssssssssderiving (Show,Ord,Eq)
adversaire :: Joueur -> Joueur
adversaire Ami = Adv
adversaire Adv = Ami
-------------------------------------------------------------------
-- 1) determiner le coup qui permet de passer dans le meilleur etatss
--ssss(correspond a la section 1 du tp7)
-------------------------------------------------------------------
--
-- 1. developper l'arbre de recherche jusqu'a la profondeur fixee n
-- 2. appliquer la fonction d'evaluation et combiner par min-max
-- 3. retenir le (l'un des) fils les plus prometteurs
data ArbreNaire a = Node a [ArbreNaire a]
ssssssssderiving Show
type ArbreJeu = ArbreNaire Etat
developperProf :: Int -> Etat -> ArbreJeu
developperProf 0 e = Node e []
developperProf n e = Node e (map (developperProf (n-1)) (successeurs e))
meilleureVal :: Joueur -> [ArbreNaire Int] -> Int
meilleureVal Ami xs = maximum [n | (Node n _) <- xs]
meilleureVal Adv xs = minimum [n | (Node n _) <- xs]
minmax :: Joueur -> ArbreJeu -> ArbreNaire Int
minmax _ (Node e []) = Node (valuation e) []
minmax j (Node e ts) = Node (meilleureVal j ls) ls
sssssssssssssssssssswhere ls = map (minmax (adversaire j)) ts
-- si plusieurs etats ont la meme valuation, on prend le premier
-- si l'on avait possede des criteres supplementaires, alors les appliquer
--ss
meilleurEtat :: Joueur -> Etat -> Int -> Etat
meilleurEtat j e n = head [s | s <- successeurs e, valuation s == val]
sssssssssssssssssswhere (Node val _)= minmax j (developperProf n e)
-- --------------------------------------------------------------------------
-- 2) representation d'un etat, fonction successeurs
--ssss(correspond aux sections 2.1, 2.2 et 2.3 du tp7)
-------------------------------------------------------------------
--ss
-- un Etat c'est la grille courante et le joueur dont c'est le tour
type Etat = (Grille, Joueur)
-- une grille c'est la liste ordonnee de toutes les cases occupees
-- (les cases vides sont celles ne figurant pas dans la liste)
-- l'ordre retenu est l'ordre lexicographique
type Grille = [CaseOccupee]
-- une CaseOccupee est composee de la couleur et des coordonnees
data CaseOccupee = Couleur Joueur Coordonnees
deriving (Ord,Eq,Show)
type Coordonnees = (Int, Int)
-- accesseurs
coordonnees :: CaseOccupee -> Coordonnees
coordonnees (Couleur j (l,c)) = (l,c)
-- on parametre la taille de la Grille
nlignes=3
ncolonnes=3
-- la nouvelle grille est l'ancienne avec le joueur j occupant la case c
jouerCoup :: Grille -> Joueur -> Coordonnees -> Grille
jouerCoup g j c = insertCase g (Couleur j c)
-- il faut respecter l'ordre sur la liste representant la grille
insertCase :: Grille -> CaseOccupee -> Grille
insertCase [] cssssss= [c]
insertCase (c1:gs) css
|(coordonnees c) <= (coordonnees c1) = cc1:gs)
|otherwisessssssssssssssssssssssssss = c1insertCase gs c)
member x []ssss = False
member x (y:ys) = (x==y) || (member x ys)
-- casesVides retourne la liste des cases non occupees de la Grille
casesVides :: Grille -> [Coordonnees]
casesVides g = [(l,c) | l <- [1..nlignes], c <- [1..ncolonnes],ss
ssssssssssssssssnot(member (Couleur Ami (l,c)) g),ss
ssssssssssssssssnot(member (Couleur Adv (l,c)) g)]
-- le joueur j peut occuper n'importe quelle case vide
coupsPossibles :: Joueur -> Grille -> [Grille]
coupsPossibles j g = map (jouerCoup g j) (casesVides g)
-- enfin, on obtient la liste des successeurs d'un etat i.e (grille,joueur)
successeursss:: Etat -> [Etat]
successeurs (g,j) = [(g', adversaire j) | g' <- (coupsPossibles j g)]
---------------------------------------------------------------------------
-- 3) Fonctions d'affichage
--ssss(correspond a la section 2.4 du tp7)
---------------------------------------------------------------------------
--
showGrille :: Grille -> String
showGrille g = [symbole g l c | l <- [1..nlignes], c <- [1..ncolonnes]]
symbole :: Grille -> Int -> Int -> Char
symbole _ _ 4 = '
'
symbole g l css
|occupation == [Ami] = 'O'
|occupation == [Adv] = 'X'
|otherwisessssssssss = '.'
sswhere occupation = couleurCase (l,c) g
joueur (Couleur j _) = j
couleurCase :: Coordonnees -> Grille -> [Joueur]
couleurCase _ [] = []
couleurCase c (c':gs)ss
|c <= (coordonnees c' = []
|c == (coordonnees c' = [joueur c']
|otherwisessssss = couleurCase c gs
printGrille :: Grille -> IO()
printGrille g = putStr (showGrille g)
printEtat :: Etat -> IO()
printEtat e = putStr(showEtat e)
showEtat :: Etat -> String
showEtat (g,j) = showGrille g ++ showJoueur j
showJoueur :: Joueur -> String
showJoueur Ami = "a 'O' de jouer"
showJoueur Adv = "a 'X' de jouer"
showTree :: Show a => ArbreNaire a -> String
showTree t = showIndentTree 0 tss
showIndentTree :: Show a => Int -> ArbreNaire a -> String
showIndentTree k (Node n ts) = [' ' | i <- [1..k]] ++ show n ++ "
"
ssss++ concat (map (showIndentTree (k+1)) ts)
printTree :: Show a => ArbreNaire a -> IO()
printTree t = putStr (showTree t)
-------------------------------------------------------------------
-- 4) fonction d'evaluation
-------------------------------------------------------------------
--ss
estAmie :: Joueur -> Grille -> Coordonnees -> Bool
estAmie j g c = member (Couleur j c) g
type Alignement = [Coordonnees]
alignementLigne :: Coordonnees -> Alignement
alignementLigne (l, c) = [(l,c' | c' <- [1..ncolonnes]]