﻿#!/bin/bash

nom_joueurs()
{
	clear
	echo -n "Saisissez le nom du joueur 1 : "
	read joueur1
	clear
	echo -n "Saisissez le nom du joueur 2 : "
	read joueur2
}
aff_joueur() #définition et affichage du joueur dont c'est le tour
{
	if [ $joueur = 1 ]
	then
		echo "Au tour de "$joueur1"."
		joueur=2
		symbole=X
	else
		echo "Au tour de "$joueur2"."
		joueur=1
		symbole=O
	fi
}

aff_plate() #affichage du plateau
{
	clear
	echo -e "           1     2     3     4     5     6     7"
	echo " "
	for (( i=0; i<6; i++ )) do
		for (( j=0; j<8; j++ ))do
			echo -n "     "${plateau[$i,$j]}
		done
		echo ""
		echo ""
	done
}

Verif_Diag-basgauche() # Vérifie s'il y a puissance 4 sur la diag bas-gauche
{
	total=0
	if [ $i -lt 3 ] && [ $j -gt 3 ]
	then
		while [ $total != 3 ] && [ $total != 666 ]
		do
			((i++))
			((j--))
			if [ ${plateau[$i,$j]} = $symbole ]
			then
				((total++))
			else
				total=666
			fi
		done
		
		if [ $total = 3 ]
		then
			partie_finie=1
		fi
	fi
}
	
Verif_Diag-basdroite() # Vérifie s'il y a puissance 4 sur la diag bas-droite
{
	total=0
	if [ $i -lt 3 ] && [ $j -lt 5 ]
	then
		while [ $total != 3 ] && [ $total != 666 ]
		do
			((i++))
			((j++))
			if [ ${plateau[$i,$j]} = $symbole ]
			then
				((total++))
			else
				total=666
			fi
		done
		
		if [ $total = 3 ]
		then
			partie_finie=1
		fi
	fi
}
	
Verif_ligne() # Vérifie s'il y a puissance 4 sur la ligne
{
	total=0
	if [ $j -lt 5 ]
	then
		while [ $total != 3 ] && [ $total != 666 ]
		do
			((j++))
			if [ ${plateau[$i,$j]} = $symbole ]
			then
				((total++))
			else
				total=666
			fi
		done
		
		if [ $total = 3 ]
		then
			partie_finie=1
		fi
	fi
}
	
Verif_colonne() # Vérifie s'il y a puissance 4 sur la colonne
{
	total=0
	if [ $i -lt 3 ]
	then
		while [ $total != 3 ] && [ $total != 666 ]
		do
			((i++))
			if [ ${plateau[$i,$j]} = $symbole ]
			then
				((total++))
			else
				total=666
			fi
		done
				
		if [ $total = 3 ]
		then
			partie_finie=1
		fi
	fi
}

Verif_win() #Vérifie si le joueur a gagné
{
	for (( k=0; k<6; k++ )); do
		for (( l=1; l<8; l++ )); do
			symbole=${plateau[$k,$l]}
			if [ $symbole != "." ]
			then
				i=$k # Ne pas oublier de remettre i et j à chaque fois, car ils sont modifiés dans chaque vérif
				j=$l
				Verif_Diag-basdroite
				i=$k
				j=$l
				Verif_Diag-basgauche
				i=$k
				j=$l
				Verif_colonne
				i=$k
				j=$l
				Verif_ligne
				i=$k
				j=$l
			fi
		done
	done
	return 0
}

Verif_plateauplein() # Vérifie si le plateau est plein
{
	if [ ${plateau[0,1]} = "." ] || [ ${plateau[0,2]} = "." ] || [ ${plateau[0,3]} = "." ] || [ ${plateau[0,4]} = "." ] || [ ${plateau[0,5]} = "." ] || [ ${plateau[0,6]} = "." ] || [ ${plateau[0,7]} = "." ]
	then
		plateau_plein=0
	else
		plateau_plein=1
	fi
}

Sauvegarde() #Ecriture des données necessaires dans sauvegarde.txt
{
	echo $joueur > Sauvegarde.txt # La variable joueur occupe la première ligne
	echo $symbole >> Sauvegarde.txt # La variable symbole occupe la deuxième ligne
	for (( i=0; i<6; i++ )) do # Ecriture des valeurs de chaque case du plateau sur les lignes suivantes
		for (( j=1; j<8; j++ ))do
			echo ${plateau[$i,$j]} >> Sauvegarde.txt
		done
	done
	echo $joueur1 >> Sauvegarde.txt
	echo $joueur2 >> Sauvegarde.txt
	echo $cpt_tour >> Sauvegarde.txt
	echo "Votre partie a ete sauvegardee, vous pouvez la reprendre depuis le menu principal."
	echo "Retour au menu principal..."
	sleep 3
}

Chargement() #Recupération des données dans sauvegarde.txt, et reprise de la partie
{
	{	# Initialisation du plateau
	declare -A plateau
	for (( i=0; i<6; i++ )) do
		for (( j=0; j<8; j++ ))do
			plateau[$i,$j]="."
		done
	done

	plateau[0,0]="1"
	plateau[1,0]="2"
	plateau[2,0]="3"
	plateau[3,0]="4"
	plateau[4,0]="5"
	plateau[5,0]="6"
	}
	
	{ # Récupération des données
	declare -A temp 
	cpt=0
	
	while read line  # Stockage des données contenues dans sauvegarde.txt dans un tableau temporaire
	do   
		temp[$cpt]=$line
		((cpt++))
	done < Sauvegarde.txt
		
	cpt=2
	joueur=${temp[0]} # joueur prend la valeur de la première ligne de sauvegarde.txt
	symbole=${temp[1]}  # symbole la valeur de la deuxième ligne
	joueur1=${temp[44]}
	joueur2=${temp[45]}
	cpt_tour=${temp[46]}
	for (( i=0; i<6; i++ )) do # Remplissage du plateau comme il était avant la sauvegarde
		for (( j=1; j<8; j++ ))do
			plateau[$i,$j]=${temp[$cpt]}
			((cpt++))
		done
	done
	}
	
	{  #Reprise de la partie normalement
		partie_finie=0
		plateau_plein=0
		if [ $joueur = 1 ] #necessaire pluisque la fonction "aff_joueur", appelée plus loin
		then
			joueur=2
		else
			joueur=1
		fi
		while [ $plateau_plein = 0 ] && [ $partie_finie != 1 ] #tant qu'aucun des joueurs n'a gagné ou que le plateau n'est pas rempli
		do
			aff_plate
			aff_joueur
			{ # Saisie de la colonne par l'utilisateur
			echo -e -n "\nDans quelle colonne voulez vous placer votre jeton ?\nPour sauvegarder la partie et la reprendre plus tard, saisissez S\nPour quitter la partien saisissez Q\n\nVotre choix : "
			colonne=0
			while [ $colonne = 0 ] # Saisie sécurisée
			do
				read colonne
				case $colonne in
					1) ;;
					2) ;;
					3) ;;
					4) ;;
					5) ;;
					6) ;;
					7) ;;
					S)	Sauvegarde  # l'utilisateur sauvegarde sa partie en cours
						partie_finie=2
						plateau_plein=1 ;;#Moyen de sortir sans afficher de résultat à la partie
					Q)	confirmation=0 # L'utilisateur quitte la partie
						while [ $confirmation != 1 ] # Demande de confirmation, car la partie n'est pas sauvegardée
						do
							echo -e "\nEtes vous sur de vouloir quitter ? La partie ne sera pas sauvegardee."
							echo "1. Oui"
							echo "2. Non"
							echo -e -n "\nVotre choix : "
							read confirmation
							case $confirmation in
								1) return 1 ;;# Sortie de la fonction pour retourner au menu
								2) confirmation=1
								   clear
								   aff_plate
								   if [ $joueur=2 ]
								   then
										echo "Au tour de "$joueur1 # Les joueurs sont inversés par aff_joueur
								   else
										echo "Au tour de "$joueur2
								   fi
								   echo -e -n "\nDans quelle colonne voulez vous placer votre jeton ?\nPour sauvegarder la partie et la reprendre plus tard, saisissez S\nPour quitter la partie, saisissez Q\n\nVotre choix : "
								   colonne=0;;
							esac
						done
						;;
					*) echo "Invalide. Saisisez un chiffre entre 1 et 7." # Choix d'une colonne inexistante
					   colonne=0 ;;
				esac
				if [ ${plateau[0,$colonne]} != "." ] && [ $colonne != 0 ] && [ $colonne != "S" ] #Choix d'une colonne pleine
				then
					echo "La colonne est pleine, choisisez en une autre."
					colonne=0
				fi	
			done
			}
			
			if [ $colonne != "S" ] # si le joueur n'a pas décidé de sauvegarder sa partie pour la reprendre plus tard
			then
				{ # Animation de descente du pion
					plateau[0,$colonne]=$symbole
					aff_plate
					sleep 0.1
					a=1
					while [ ${plateau[$a,$colonne]} = "." ]
					do
						plateau[$a,$colonne]=$symbole
						plateau[$((a-1)),$colonne]="."
						aff_plate
						sleep 0.1
						((a++))
					done
				}
				
				Verif_win # Vérification d'un potentiel puissance 4 suite au dernier coup
				Verif_plateauplein	# Vérification de plateau plein
			fi
			((cpt_tour++))
		done
		
		if [ $joueur = 1 ]
		then
			joueur=2
			symbole="O"
		else
			joueur=1
			symbole="X"
		fi
		
		if [ $partie_finie = 0 ] # Cas du plateau rempli
		then
			echo "Plateau plein ! Egalite !"
			echo "Retour au menu principal..."
			sleep 3
		fi
		if [ $partie_finie = 1 ] # Un joueur a gagné
		then
			echo -n "Puissance 4 ! "
			if [ joueur = 1 ]
			then
				echo -n $joueur2
			else	
				echo -n $joueur1
			fi	
		echo " gagne !"
		echo "Partie terminee en "$cpt_tour" tours."
			echo -e "\nRetour au menu principal..."
			sleep 4.5
		fi
	}
}

New_game() # Déroulement d'une nouvelle partie
{
	{	# Initialisation du plateau
	declare -A plateau
	for (( i=0; i<6; i++ )) do
		for (( j=0; j<8; j++ ))do
			plateau[$i,$j]="."
		done
	done

	plateau[0,0]="1"
	plateau[1,0]="2"
	plateau[2,0]="3"
	plateau[3,0]="4"
	plateau[4,0]="5"
	plateau[5,0]="6"
	}
	
	partie_finie=0
	plateau_plein=0
	nom_joueurs
	cpt_tour=0 # compteur de tours
	while [ $plateau_plein = 0 ] && [ $partie_finie != 1 ] #tant qu'aucun des joueurs n'a gagné ou que le plateau n'est pas rempli
	do
		aff_plate
		aff_joueur
		
		{ # Saisie de la colonne par l'utilisateur
		echo -e -n "\nDans quelle colonne voulez vous placer votre jeton ?\nPour sauvegarder la partie et la reprendre plus tard, saisissez S\nPour quitter la partie, saisissez Q\n\nVotre choix : "
		colonne=0
		while [ $colonne = 0 ] # Saisie sécurisée
		do
			read colonne
			case $colonne in
				1) ;;
				2) ;;
				3) ;;
				4) ;;
				5) ;;
				6) ;;
				7) ;;
				S)	Sauvegarde  # l'utilisateur sauvegarde sa partie en cours
					partie_finie=2
					plateau_plein=1 ;; # Moyen de sortir sans afficher de résultat à la partie
				Q)	confirmation=0 # L'utilisateur quitte la partie
						while [ $confirmation != 1 ] # Demande de confirmation, car la partie n'est pas sauvegardée
						do
							echo -e "\nEtes vous sur de vouloir quitter ? La partie ne sera pas sauvegardee."
							echo "1. Oui"
							echo "2. Non"
							echo -e -n "\nVotre choix : "
							read confirmation
							case $confirmation in
								1) return 1 ;;# Sortie de la fonction pour retourner au menu
								2) confirmation=1
								   clear
								   aff_plate
								   if [ $joueur=2 ]
								   then
										echo "Au tour de "$joueur1 # Les joueurs sont inversés par aff_joueur
								   else
										echo "Au tour de "$joueur2
								   fi
								   echo -e -n "\nDans quelle colonne voulez vous placer votre jeton ?\nPour sauvegarder la partie et la reprendre plus tard, saisissez S\nPour quitter la partie, saisissez Q\n\nVotre choix : "
								   colonne=0;;
							esac
						done
						;;
				*) echo "Invalide. Saisisez un chiffre entre 1 et 7." #Choix d'une colonne inexistante
				   colonne=0 ;;
			esac
			if [ ${plateau[0,$colonne]} != "." ] && [ $colonne != 0 ] && [ $colonne != "S" ] # Choix dune colonne pleine
			then
				echo "La colonne est pleine, choisisez en une autre."
				colonne=0
			fi	
		done
		}
		
		if [ $colonne != "S" ] # si le joueur n'a pas décidé de sauvegarder sa partie pour la reprendre plus tard
		then
			{ # Animation de descente du pion
				plateau[0,$colonne]=$symbole
				aff_plate
				sleep 0.1
				a=1
				while [ ${plateau[$a,$colonne]} = "." ]
				do
					plateau[$a,$colonne]=$symbole
					plateau[$((a-1)),$colonne]="."
					aff_plate
					sleep 0.1
					((a++))
				done
			}
			
			Verif_win # Vérification d'un potentiel puissance 4 suite au dernier coup
			Verif_plateauplein	# Vérification de plateau plein
		fi
		((cpt_tour++))
	done
	
	if [ $joueur = 1 ]
	then
		joueur=2
		symbole="O"
	else
		joueur=1
		symbole="X"
	fi
	
	if [ $partie_finie = 0 ] # Cas du plateau rempli
	then
		echo "Plateau plein ! Egalite !"
		echo "Retour au menu principal..."
		sleep 3
	fi
	if [ $partie_finie = 1 ] # Un joueur a gagné
	then
		echo -n "Puissance 4 ! "
			if [ joueur = 1 ]
			then
				echo -n $joueur2
			else	
				echo -n $joueur1
			fi	
		echo " gagne !"
		echo "Partie terminee en "$cpt_tour" tours."
		echo -e "\nRetour au menu principal..."
		sleep 4.5
	fi
}
	
	while [ 1=1 ] # Affichage du menu
	do	
		joueur=1 #initialisation du joueur
		symbole=0 #initialisation du symbole

		choix_menu=0
		clear
		echo "Ceci est un splendide jeu de Puissance 4"
		echo ""
		echo "1. Nouvelle Partie"
		echo "2. Reprendre la partie"
		echo "3. Quitter"
		echo ""
		echo "Que souhaitez-vous faire ?"
		echo -n "Votre choix : "

		while [ $choix_menu = 0 ] # Saisie sécurisée
		do
			read choix_menu
			case $choix_menu in
				1) New_game ;; #Début de partie
				2) Chargement ;; # Chargement d'une partie sauvegardée
				3) clear # Quitter
				   echo "Merci d'avoir joue !"
				   echo ""
				   exit
				   ;;
				*) echo -n "Saisie incorrecte. Votre choix : "
				   choix_menu=0;;
			esac
		done	
	done
