#!/bin/bash
# twodim.sh : Simuler un tableau à deux dimensions.

# Un tableau à une dimension consiste en une seule ligne.
# Un tableau à deux dimensions stocke les lignes séquentiellement.

Lignes=5
Colonnes=5
# Tableau de 5 sur 5.

declare -a alpha     # char alpha [Lignes] [Colonnes];
                     # Déclaration inutile. Pourquoi ?

charge_alpha ()
{
local rc=0
local index


for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y
do  # Utilisez des symbôles différents si vous le souhaitez.
  local ligne=`expr $rc / $Colonnes`
  local colonne=`expr $rc % $Lignes`
  let "index = $ligne * $Lignes + $colonne"
  alpha[$index]=$i
  # alpha[$ligne][$colonne]
  let "rc += 1"
done  

#  Un peu plus simple
#+   declare -a alpha=( A B C D E F G H I J K L M N O P Q R S T U V W X Y )
#+ mais il manque néanmoins le "bon goût" d'un tableau à deux dimensions.
}

affiche_alpha ()
{
local ligne=0
local index

echo

while [ "$ligne" -lt "$Lignes" ]  # Affiche dans l'ordre des lignes -
do                                # les colonnes varient
                                  # tant que ligne (la boucle externe) reste
				  # identique
  local colonne=0
  
  echo -n "       "
  
  while [ "$colonne" -lt "$Colonnes" ]
  do
    let "index = $ligne * $Lignes + $colonne"
    echo -n "${alpha[index]} "  # alpha[$ligne][$colonne]
    let "colonne += 1"
  done

  let "ligne += 1"
  echo

done  

# Un équivalent plus simple serait
#   echo ${alpha[*]} | xargs -n $Colonnes

echo
}

filtrer ()     # Filtrer les index négatifs du tableau.
{

echo -n "  "  # Apporte le tilt.
              # Expliquez comment.

if [[ "$1" -ge 0 &amp;&amp;  "$1" -lt "$Lignes" &amp;&amp; "$2" -ge 0 &amp;&amp; "$2" -lt "$Colonnes" ]]
then
    let "index = $1 * $Lignes + $2"
    # Maintenant, l'affiche après rotation.
    echo -n " ${alpha[index]}"
    #           alpha[$ligne][$colonne]
fi    

}
  



rotate ()  #  Bascule le tableau de 45 degrés
{          #+ (le "balance" sur le côté gauche en bas).
local ligne
local colonne

for (( ligne = Lignes; ligne &gt; -Lignes; ligne-- ))
do  # Traverse le tableau en sens inverse. Pourquoi ?

  for (( colonne = 0; colonne &lt; Colonnes; colonne++ ))
  do

    if [ "$ligne" -ge 0 ]
    then
      let "t1 = $colonne - $ligne"
      let "t2 = $colonne"
    else
      let "t1 = $colonne"
      let "t2 = $colonne + $ligne"
    fi  

    filtrer $t1 $t2   # Filtre les index négatifs du tableau.
                      # Que se passe-t'il si vous ne le faites pas ?
  done

  echo; echo

done 

#  Rotation du tableau inspirée par les exemples (pp. 143-146) de
#+ "Advanced C Programming on the IBM PC", par Herbert Mayer
#+ (voir bibliographie).
#  Ceci ne fait que montrer que ce qui est fait en C peut aussi être fait avec
#+ des scripts shell.

}


#----- Maintenant, que le spectacle commence. --------#
charge_alpha     # Charge le tableau.
affiche_alpha    # L'affiche.
rotate           # Le fait basculer sur 45 degrés dans le sens contraire des
                 # aiguilles d'une montre.
#-----------------------------------------------------#

exit 0

# C'est une simulation assez peu satisfaisante.
#
# Exercices :
# ----------
# 1)  Réécrire le chargement du tableau et les fonctions d'affichage
#     d'une façon plus intuitive et élégante.
#
# 2)  Comprendre comment les fonctions de rotation fonctionnent.
#     Astuce : pensez aux implications de l'indexage arrière du tableau.
#
# 3)  Réécrire ce script pour gérer un tableau non carré, tel qu'un 6 sur 4.
#     Essayez de minimiser la distorsion lorsque le tableau subit une rotation.
