Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 13/04/2008, à 17:17

Seeme00

[SHELL]Variable non liée

Salut les gens smile

Je bloque dans le développement d'un petit jeu de snake en shell. L'idée est de charger le labyrinthe depuis un fichier, mais je me heurte à la lecture du tableau qui contient les coordonnées des murs:

#!/bin/bash

set -o nounset
sauvegarde=$(stty -g)


function serpent ()
{
	murs
	boucle_jeu
	fin_jeu
}


function initialisation_jeu () 
{	
	nb_oeufs=0
	nb_mouvements=0


	if ! tput init ; then
		echo "Impossible d'initialiser le terminal"
		exit 1
	fi
		
	if [ $(tput cols) -lt 60 -o $(tput lines) -lt 28 ] ; then
		echo "Ce terminal est trop petit :-)"
		exit 1
	fi
		
	nb_colonnes=60
 	nb_lignes=28

	tput clear # effacement de l'écran
	tput civis # curseur invisible

	# lecture des caractères sans retour chariot
	stty -icanon -echo time 1 min 0
	HAUT=$(echo -e "\033[A\n")
	BAS=$(echo -e "\033[B\n")
	GAUCHE=$(echo -e "\033[D\n")
	DROITE=$(echo -e "\033[C\n")

	# on crée un serpent avec déjà 3 points :-)
	x=$(($nb_colonnes / 2))
	y=$(($nb_lignes / 2))
	x_serpent[0]=$x;	y_serpent[0]=$y
	x_serpent[1]=$(($x + 1)); y_serpent[1]=$y
	x_serpent[2]=$(($x + 2)); y_serpent[2]=$y

	
	# déplacement horizontal vers la gauche
	dx=-1 ; dy=0
	ajoute_oeuf 
}



function boucle_jeu ()
{
	while true ; do
		# dessiner la tete
		tput cup ${y_serpent[0]} ${x_serpent[0]}
		echo -n "@"
		
	# lequel des deux ?
	#	read REPLY
		read
		case $REPLY in

			$HAUT | u) if [ ! $dx -eq 0 -a ! $dy -eq 1 ]; then
					dx=0 ;dy=-1
				   fi
			;;
			$BAS | n) if [ ! $dx -eq 0 -a ! $dy -eq -1 ]; then
					dx=0 ;dy=1
				  fi
			;;
			$GAUCHE | h) if [ ! $dx -eq 1 -a ! $dy -eq 0 ]; then
					dx=-1 ;dy=0
				     fi
			;;
			$DROITE | j) if [ ! $dx -eq -1 -a ! $dy -eq 0 ]; then
					dx=1 ;dy=0
				     fi

			#u) dx=0	; dy=-1
			;;
			#n) dx=0	; dy=1
			#;;
			#h) dx=-1	; dy=0
			#;;
			#j) dx=1 	; dy=0
			#;;
			q) stty $sauvegarde ; clear;  reset ; exit 3
			;;
			*)
			;;
		esac
		#remplacer l'ancienne tete par un élément du corps
		tput cup ${y_serpent[0]} ${x_serpent[0]}
		echo -n "#"

		nb_points=${#x_serpent[*]}
		i=$(($nb_points - 1 ))
		x_queue=${x_serpent[$i]}
		y_queue=${y_serpent[$i]}

		# faire glisser le corps
		while [ $i -gt 0 ] ; do
			x_serpent[$i]=${x_serpent[$(($i - 1))]}
			y_serpent[$i]=${y_serpent[$(($i - 1 ))]}
			i=$(($i - 1))
		done
	
		# le serpent se mange-t-il ?
		x_tete=$((${x_serpent[0]} + $dx))
		y_tete=$((${y_serpent[0]} + $dy))
		if dans_serpent $x_tete $y_tete ; then
			return
		fi

		# heurte-t-on un mur ?
		
	#	if [ $x_tete -eq $x_mur[$i] ] && [ $y_tete -eq $y_mur[$i] ] ; then
	#	     return	
	#	fi


		# sort-on du terminal?

		if [ $x_tete -eq $nb_colonnes ]; then
			x_tete=1
		fi
		if [ $x_tete -le 0 ] ; then
              		x_tete=$((nb_colonnes-1))
                     fi
                     if [ $y_tete -ge $nb_lignes ]; then
			y_tete=1
		fi
		if [ $y_tete -lt 0 ] ; then
			y_tete=$((nb_lignes - 1))
		fi
                     

		# la nouvelle position de la tete est correcte
		x_serpent[0]=$x_tete
		y_serpent[0]=$y_tete
		
		nb_mouvements=$(($nb_mouvements + 1))


		# le serpent mange-t-il l'oeuf ?
		if [ $x_tete -eq $xoeuf ] && [ $y_tete -eq $yoeuf ] ; then
			nb_oeufs=$(($nb_oeufs + 1))
			ajoute_oeuf 


			# on allonge le serpent
			x_serpent[$nb_points]=$x_queue
			y_serpent[$nb_points]=$y_queue
		else
			# sinon on efface l'ancienne queue
			tput cup $y_queue $x_queue
			echo -n " "
		fi
		tput cup $nb_lignes 1
		echo -n "Mouvements: " $nb_mouvements ", Oeufs : " $nb_oeufs
	done
	
}


function fin_jeu ()
{
	tput reset 	# Réinitialisation écran
	stty sane 	# Réinitialisaton clavier
	clear		# Effacement écran
	echo -e "Mouvements : " $nb_mouvements " , Oeufs : " $nb_oeufs". \n\n "
	echo "voulez-vous recommencer? (tapez \"o\" pour recommencer)"
	read reponse
	if [ $reponse != "o" ] ; then
		
		stty $sauvegarde
		clear
		reset
		exit 3

	else
		nb_oeufs=0
		nb_mouvements=0


		tput clear # effacement de l'écran
		tput civis # curseur invisible
		stty -icanon -echo time 1 min 0
		
		#on efface le serpent existant avant
		unset x_serpent
		unset y_serpent 
				
		# on crée un serpent avec déjà 3 points :-)
		x=$(($nb_colonnes / 2))
		y=$(($nb_lignes / 2))
		x_serpent[0]=$x;	y_serpent[0]=$y
		x_serpent[1]=$(($x + 1)); y_serpent[1]=$y
		x_serpent[2]=$(($x + 2)); y_serpent[2]=$y

		# déplacement horizontal vers la gauche
		dx=-1 ; dy=0
		
		ajoute_oeuf

	fi	
}


function murs ()
{ #cette fonction permet de créer des murs
  #et d'en stocker les valeurs dans un tableau

  local i
  local j
  local x
  local y

  #on récupère les coordonnées de début et de fin de mur
  i=0
  coord=$(cat fichier1.txt)>/dev/null
  for ligne in $coord;do
  	x=$(echo $ligne|sed 's/|.*//g')
    y=$(echo $ligne|sed 's/.*|//g')

    x_mur[$i]=$x
    y_mur[$i]=$y

    ((i=$i+1))
  done

 	#on affiche le mur entre les deux coordonnées
  i=0
	while [ $i -lt ${#x_mur[*]} ];do

  	if [ ${x_mur[$i]} -eq ${x_mur[$(($i+1))]} ];then

    	for ((j=${y_mur[$i]};j<=${y_mur[$(($i+1))]};j++));do
      	tput cup $j ${x_mur[$i]}
        echo -n "+"
	    done

    else

    	for ((j=${x_mur[$i]};j<=${x_mur[$(($i+1))]};j++));do
      	tput cup ${y_mur[$i]} $j
        echo -n "+"
      done
        	
		fi

    i=$(($i+2))

	done

}



function ajoute_oeuf ()
{
	# Cette routine ajoute un oeuf à une position aléatoire
	# en vérifiant qu'il ne soit pas sur le corps du serpent

	xoeuf=$(($RANDOM / (32767 / $nb_colonnes)))
	yoeuf=$(($RANDOM / (32767 / $nb_lignes)))
	while dans_mur $xoeuf $yoeuf || dans_serpent $xoeuf $yoeuf ; do
		xoeuf=$(($RANDOM / (32767 / nb_colonnes)))
		yoeuf=$(($RANDOM / (32767 / nb_lignes)))
	done
	tput cup $yoeuf $xoeuf
	echo -n "o"
}


function dans_serpent ()
{
	# cette fonction vérifie si les coordonnées X / Y
	# transmises en argument sont sur le corps du serpent.

	local i
	i=$((${#x_serpent[*]} - 1))
	while [ $i -ge 0 ] ; do
		if [ $1 -eq ${x_serpent[$i]} ] && [ $2 -eq ${y_serpent[$i]} ] ;
		then
			return 0
		fi
		i=$(($i - 1))
	done
	return 1
}


function dans_mur ()
{
 #cette fonction permet de vérifier que ce qui est transmis en argument n'est pas dans le mur
 
	local i
	i=0
  while [ $i -lt ${#x_mur[*]}} ] ; do
  	
		if [ $1 -ge ${x_mur[$i]} ] && [ $1 -le ${x_mur[$(($i+1))]} ];then
			
			if [ $2 -ge ${y_mur[$i]} ] && [ $2 -ge ${y_mur[$(($i+1))]} ];then
      	return 0
			fi
	
   	fi
    i=$(($i +2))
       
	done
  return
}

initialisation_jeu
while serpent ; do : ; done

Le problème vient de cette ligne, dans la fonction "dans_mur":
while [ $i -lt ${#x_mur[*]}} ] ; do
Il me met que la variable x_mur ets non liée..

Merci de votre aide
@+
Seeme

#2 Le 14/04/2008, à 23:31

snapshot

Re : [SHELL]Variable non liée

et bien...

set -o nounset

demande à bash de générer une erreur en cas d'utilisation d'une variable non précédemment initialisée (ça correspond à "use strict;" en perl si ça ye dit quelque chose).
et le message "variable non liée [comprendre : à une valeur]" signifie que cette variable est utilisée mais on ne lui a jamais donné de valeur avant (autrement dit, "x_mur" n'est pas initialisé... du point de vue du shell).

Le set -o nounset (ou set -u en abrégé) est très utile pour signaler les nom de variables mal écrites, qui sans cette option prendrait une valeur vide, ce qui causerait sans nul doute un bug.


Pensez à mettre [Résolu] dans le titre une fois votre problème réglé !

Hors ligne

#3 Le 14/04/2008, à 23:42

snapshot

Re : [SHELL]Variable non liée

pour ton problème, je pense que si le fichier1.txt est vide, alors coord est vide, et donc la boucle for n'est pas exécutée. Et comme tu affectes une valeur à x_mur dans cette boucle, il se trouve qu'elle n'est pas connu du shell... d'où l'erreur plus loin dans le while.

Pour résoudre ton problème, je verrais bien :

typeset -a x_mur 
typeset -a y_mur

à la suite des déclarations des local de la fonction, ou mieux en en-tête de ton script, avec toutes les autres. L'option set -o nounset implique que toute les variables soient déclarées comme en C... Donc il faut le faire.


Pensez à mettre [Résolu] dans le titre une fois votre problème réglé !

Hors ligne

#4 Le 15/04/2008, à 14:24

Seeme00

Re : [SHELL]Variable non liée

ça marche!!!
génial merci pour tout ça fesait longtemps que je bloquais dessus smile