home *** CD-ROM | disk | FTP | other *** search
/ Freelog 17 / Freelog017.iso / BeOS / ababelone / Sources / DeplacementHumain.cpp < prev    next >
C/C++ Source or Header  |  2000-11-20  |  13KB  |  271 lines

  1. /*
  2.     Copyright (C) 2000 by Herv├⌐ PHILIPPE <rv@bemail.org>
  3.  
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.  
  9.     This library is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.     Library General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Library General Public
  15.     License along with this library; if not, write to the Free
  16.     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #include "DeplacementHumain.h"
  20.  
  21.   /////////////////////////////////////////
  22.  // CONSTRUCTEUR de "DeplacementHumain" //
  23. /////////////////////////////////////////---
  24. // Construit l'objet "Deplacement" h├⌐rit├⌐ --
  25. //------------------------------------------
  26. DeplacementHumain::DeplacementHumain(PlateauDeJeuInterne* plateau_de_jeu_interne, PlateauDeJeuGraphique* plateau_de_jeu_graphique, int8 couleur)
  27. // 3 PARAMETRES :                        ENTREE/SORTIE (modification par la suite)    ENTREE/SORTIE (modification par la suite)            ENTREE
  28.     : Deplacement(plateau_de_jeu_interne, plateau_de_jeu_graphique, couleur, false)
  29. {
  30. }
  31.  
  32.   ///////////////////////////////////
  33.  // FONCTION "JoueurAppuieSouris" //
  34. ///////////////////////////////////------------------
  35. // L'utilisateur appuie sur un bouton de la souris --
  36. //---------------------------------------------------
  37. void        // AUCUNE VALEUR DE RETOUR
  38. DeplacementHumain::JoueurAppuieSouris(BPoint where)
  39. // 1 PARAMETRE :                        ENTREE
  40. {
  41.     // Cr├⌐ation et initialisation ├⌐ventuelle des variables locales
  42.     int8 i, min, max;
  43.     int8 boule_choisie = 0;            // Pour sortir de la boucle
  44.     bool bonne_boule_selectionnee = false;
  45.     bool deplacement_possible = false;
  46.  
  47.     // Initialisation des variables "min" et "max" d├⌐finissant les bornes de la boucle    
  48.     // Num├⌐ro de la premi├¿re boule de la couleur du joueur (minimum inclu)
  49.     min = 1 + m_CouleurCourante * m_PlateauInterne->NombreBoulesCouleur();
  50.     // Num├⌐ro de la derni├¿re boule de la couleur du joueur (maximum NON inclu)
  51.     max = min + m_PlateauInterne->NombreBoulesCouleur();
  52.  
  53.     // Boucle pour tester si une boule de la bonne couleur a ├⌐t├⌐ appuy├⌐e
  54.     for (i = min; i < max && boule_choisie == 0; i++)
  55.         // Si la position de la souris est incluse dans la vue de la boule n┬░i;
  56.         //  bien s├╗r, la boule n┬░i doit ├¬tre visible (pas sortie du plateau)
  57.         if ((m_PlateauGraphique->Boule(i)).Contains(where) &&
  58.                         m_PlateauGraphique->BouleVisible(i) == true) {
  59.             boule_choisie = i;        // Pour sortir de la boucle
  60.             // Positionner la vue "Select" n┬░1 ├á la boule s├⌐lectionn├⌐e (boule appuy├⌐e)
  61.             if (m_NombreBoulesSelectionnees == 1)
  62.                 // Si cette boule a d├⌐j├á ├⌐t├⌐ s├⌐lectionn├⌐e, la s├⌐lectionner "normalement"
  63.                 if (m_PremiereBouleSelectionnee == boule_choisie) {
  64.                     m_PlateauGraphique->EffacerSelect(2);        // Effacer la vue "Select" n┬░2
  65.                     bonne_boule_selectionnee = true;
  66.                 }
  67.                 // Si une autre boule a d├⌐j├á ├⌐t├⌐ s├⌐lectionn├⌐e, il s'agit peut-├¬tre d'un d├⌐placement lat├⌐ral ?
  68.                 else {
  69.                     // Si les 2 boules s├⌐lectionn├⌐es sont sur une ligne lat├⌐rale possible
  70.                     //  c'est-├á-dire si 2 ou 3 boules sont cons├⌐cutives sur un m├¬me axe
  71.                     // REMARQUE : la fonction "LigneLateralePossible" d├⌐place et affiche la vue "Select" n┬░2
  72.                     LigneLateralePossible(boule_choisie);
  73.                     if (m_NombreBoulesSelectionnees != 1)
  74.                         bonne_boule_selectionnee = true;
  75.                 }
  76.             else {
  77.                 bonne_boule_selectionnee = true;
  78.                 // Mise ├á jour des informations relatives ├á la premi├¿re boule s├⌐lectionn├⌐e
  79.                 m_PremiereBouleSelectionnee = boule_choisie;
  80.                 m_NombreBoulesSelectionnees = 1;
  81.             }
  82.             if (bonne_boule_selectionnee == true) {    // Si une nouvelle boule vient d'├¬tre appuy├⌐e
  83.                 // Calculer tous les d├⌐placements possibles et afficher les fl├¿ches correspondantes
  84.                 for (i = 0; i < 6; i++) {
  85.                     // Si la direction n┬░i correspond ├á un d├⌐placement possible pour la boule s├⌐lectionn├⌐e
  86.                     if ((m_NombreBoulesSelectionnees == 1 && DirectionPousseePossible(i) == true)
  87.                     //   ou ├á un d├⌐placement lat├⌐ral possible pour les 2 ou 3 boules s├⌐lectionn├⌐es
  88.                             || (m_NombreBoulesSelectionnees > 1
  89.                             && i%3 != m_DirectionLaterale%3
  90.                             && DirectionLateralePossible(i) )) {
  91.                         deplacement_possible = true;
  92.                         // D├⌐placer et afficher la fl├¿che n┬░i
  93.                         m_PlateauGraphique->AfficherFleche(i,boule_choisie);
  94.                     }
  95.                 }
  96.                 if (deplacement_possible == true) {    // S'il y a au moins 1 d├⌐placement possible
  97.                     m_PlateauGraphique->AfficherSelect(1,boule_choisie);
  98.                     // Si 3 boules sont s├⌐lectionn├⌐es, il faut positionner la vue "Select" du milieu (n┬░3)
  99.                     if (m_NombreBoulesSelectionnees == 3) {
  100.                         boule_choisie = m_PlateauInterne->ValeurCaseSuivante(m_PremiereBouleSelectionnee,m_DirectionLaterale);
  101.                         m_PlateauGraphique->AfficherSelect(3,boule_choisie);
  102.                     }
  103.                 }
  104.                 else    // Si aucun d├⌐placement n'est possible,
  105.                         // on fait comme si on n'avait pas appuy├⌐ sur une boule valide
  106.                     if (m_NombreBoulesSelectionnees == 1)
  107.                         m_NombreBoulesSelectionnees = 0;
  108.                     else
  109.                         m_NombreBoulesSelectionnees = 1;
  110.             }
  111.         }            
  112. }
  113.  
  114.   ////////////////////////////////////
  115.  // FONCTION "JoueurRelacheSouris" //
  116. ////////////////////////////////////--------------
  117. // L'utilisateur rel├óche un bouton de la souris --
  118. //------------------------------------------------
  119. int8        // VALEUR DE RETOUR
  120. DeplacementHumain::JoueurRelacheSouris(BPoint where, bool faire_glisser_les_boules)
  121. // 2 PARAMETRES :                        ENTREE                    ENTREE
  122. {
  123.     // Cr├⌐ation et initialisation ├⌐ventuelle des variables locales
  124.     int8 i;
  125.     int8 deplacement_ejection = -1;        // Valeur de retour
  126.     
  127.     m_Direction = -1;
  128.     if (m_NombreBoulesSelectionnees > 0) {    // Si aucune boule n'est appuy├⌐e (c'est-├á-dire s├⌐lectionn├⌐e avec le bouton
  129.                                     //  de la souris enfonc├⌐) on ne fait rien !
  130.         // Boucle pour effacer toutes les fl├¿ches qui ont ├⌐t├⌐ affich├⌐es
  131.         //  et pour d├⌐terminer sur quelle fl├¿che l'utilisateur rel├óche la souris
  132.         //  et donc savoir quel d├⌐placement il faut faire
  133.         for (i = 0; i < 6; i++)
  134.             if (m_PlateauGraphique->Fleche(i) != BOULE_CACHEE) {    // Si la vue "Fleche" est visible
  135.                 // D├⌐terminer la direction s├⌐lectionn├⌐e (en fonction de la vue sur laquelle pointe la souris)
  136.                 // REMARQUE : petite optimisation ├á cause de l'├⌐valuation paresseuse...
  137.                 if (m_Direction == -1 && (m_PlateauGraphique->Fleche(i)).Contains(where))
  138.                     m_Direction = i;
  139.                 m_PlateauGraphique->EffacerFleche(i);            //  la cacher
  140.             }
  141.         // Effacer les s├⌐lections effectu├⌐es
  142.         m_PlateauGraphique->EffacerSelect(1);    // Cacher la vue "Select" n┬░1
  143.                                         // REMARQUE : cette s├⌐lection est la s├⌐lection "active" et doit ├¬tre
  144.                                         // effac├⌐e. C'est-├á-dire :
  145.                                         //  .s'il n'y a qu'une seule boule s├⌐lectionn├⌐e, cette s├⌐lection
  146.                                         //    est remplac├⌐e par la vue "Select" n┬░2 (voir plus haut)
  147.                                         //  .s'il y a 2 boules s├⌐lectionn├⌐es, la 2i├¿me boule est d├⌐s├⌐lectionn├⌐e
  148.                                         //  .s'il y a 3 boules s├⌐lectionn├⌐es, la 3i├¿me boule est d├⌐s├⌐lectionn├⌐e
  149.         if (m_NombreBoulesSelectionnees == 3)    // S'il y a 3 boules s├⌐lectionn├⌐es, il faut cacher
  150.             m_PlateauGraphique->EffacerSelect(3);        //  la vue "Select" n┬░3 (pour la s├⌐lection du milieu)
  151.     
  152.         // Si une direction est s├⌐lectionn├⌐e
  153.         if (m_Direction > -1) {
  154.             deplacement_ejection = 0;    // Valeur de retour : il y a eu un deplacement;
  155.             if (m_NombreBoulesSelectionnees > 1) {    // S'il y a plusieurs boules s├⌐lectionn├⌐es
  156.                 m_PlateauGraphique->EffacerSelect(2);        // Cacher la vue "Select" n┬░2
  157.                 DeplacerBoulesLaterales(faire_glisser_les_boules);    // Deplacement lat├⌐ral des boules
  158.             }
  159.             else    // S'il n'y a qu'une seule boule s├⌐lectionn├⌐e
  160.                 if (DeplacerBoulesPoussee(faire_glisser_les_boules) == true)        // D├⌐placement des boules
  161.                     deplacement_ejection = 1;    // Valeur de retour : il y a eu une ├⌐jection
  162.                 m_NombreBoulesSelectionnees = 0;
  163.         }
  164.         // Si aucune direction n'est s├⌐lectionn├⌐e
  165.         else {
  166.             if (m_NombreBoulesSelectionnees > 0) {    // S'il n'y a qu'une seule boule s├⌐lectionn├⌐e
  167.                 m_NombreBoulesSelectionnees = 1;
  168.                 // Replacer la vue "Select" n┬░2 (├á la place de la vue "Select" n┬░1)
  169.                 m_PlateauGraphique->AfficherSelect(2,m_PremiereBouleSelectionnee);
  170.             }
  171.         }
  172.     }
  173.  
  174.     if (m_NombreBoulesSelectionnees > 0)
  175.         m_NombreBoulesSelectionnees = 1;
  176.     return deplacement_ejection;
  177. }
  178.  
  179.   //////////////////////////////////////
  180.  // FONCTION "LigneLateralePossible" //
  181. //////////////////////////////////////----------------------------------------------------------
  182. // Calcule si une ligne lat├⌐rale est possible ├á partir d'une boule, c'est-├á-dire si plusieurs --
  183. // boules contigues du joueur courant peuvent se d├⌐placer pour un d├⌐placement lat├⌐ral.        --
  184. // "m_NombreBoulesSelectionnees" vaut 1 si ce n'est pas possible et 2 ou 3 si c'est possible  --
  185. //----------------------------------------------------------------------------------------------
  186. void        // AUCUNE VALEUR DE RETOUR
  187. DeplacementHumain::LigneLateralePossible(int8 numero_boule_appuyee)
  188. // 1 PARAMETRE :                                ENTREE
  189. {
  190.     // Cr├⌐ation et initialisation ├⌐ventuelle des variables locales
  191.     int delta_x, delta_y;
  192.     int8 boule = m_PremiereBouleSelectionnee;
  193.  
  194.     // Calculer "delta_x" et "delta_y", en fonction de la boule 'appuy├⌐e' et de la boule 's├⌐lectionn├⌐e'
  195.     // REMARQUE : ces deltas permettent de savoir :
  196.     //  .si les 2 boules sont sur le m├¬me axe
  197.     //  .si ces 2 boules ne sont distantes que d'une boule (de la m├¬me couleur) au maximum
  198.     delta_x = m_PlateauInterne->CoordonneesBoule(numero_boule_appuyee).x - m_PlateauInterne->CoordonneesBoule(m_PremiereBouleSelectionnee).x;
  199.     delta_y = m_PlateauInterne->CoordonneesBoule(numero_boule_appuyee).y - m_PlateauInterne->CoordonneesBoule(m_PremiereBouleSelectionnee).y;
  200.  
  201. // Traitement pour les directions : | REMARQUE :
  202. //                       1                |    .si delta_x == 0, 
  203. //                     | /            |        .|delta_y| repr├⌐sente le nombre de boules ├á d├⌐placer
  204. //                0 --   -- 3            |          (attention : pas plus de 3 boules !)
  205. //                   / |                |        .le signe de delta_y repr├⌐sente une des 2 directions (0 ou 3)
  206. //                     4                |    .et vice-versa pour delta_y == 0
  207.     if ((delta_x * delta_y) == 0 && abs(delta_x + delta_y) < 3 && (delta_x + delta_y) != 0) {
  208.         if (delta_x == 0)
  209.             if (delta_y < 0) {    // delta_x == 0 et delta_y < 0 et |delta_y| < 3
  210.                 m_DirectionLaterale = 1;
  211.                 m_NombreBoulesSelectionnees = 1 - delta_y;
  212.             }
  213.             else {                // delta_x == 0 et delta_y > 0 et |delta_y| < 3
  214.                 m_DirectionLaterale = 4;
  215.                 m_NombreBoulesSelectionnees =  1 + delta_y;
  216.             }
  217.         else                    // delta_x < 0 et delta_y == 0 et |delta_x| < 3
  218.             if (delta_x < 0) {
  219.                 m_DirectionLaterale = 0;
  220.                 m_NombreBoulesSelectionnees = 1 - delta_x;
  221.             }
  222.             else {                // delta_x > 0 et delta_y == 0 et |delta_x| < 3
  223.                 m_DirectionLaterale = 3;
  224.                 m_NombreBoulesSelectionnees = 1 + delta_x;
  225.             }
  226.     }
  227.     else
  228. // Traitement pour les directions : | REMARQUE :
  229. //                          2            |  dans les 2 cas, on a :
  230. //                     | /            |    .delta_x == -delta_y ET |delta_x| == |delta_y|
  231. //                  --   --            |    .en plus, delta_x (ou delta_y) peut valoir 1 ou 2
  232. //                   / |                |      (car, en d├⌐placement lat├⌐ral, on ne d├⌐place que 2 ou 3 boules)
  233. //                  5                    |
  234.         if ((delta_x * delta_y) == -1 || ((delta_x * delta_y) == -4 && abs(delta_x - delta_y) == 4))
  235.             if (delta_x > 0) {
  236.                 m_DirectionLaterale = 2;
  237.                 m_NombreBoulesSelectionnees = 1 + delta_x;    // (delta_x == -delta_y)
  238.             }
  239.             else {
  240.                 m_DirectionLaterale = 5;
  241.                 m_NombreBoulesSelectionnees = 1 + delta_y;    // (delta_x == -delta_y)
  242.             }
  243.         else
  244.             m_NombreBoulesSelectionnees = 1;    // A priori non-n├⌐cessaire... mais bon, on ne sait jamais !
  245.  
  246. // S'il y a 3 boules ├á d├⌐placer, on veut v├⌐rifier que la boule du milieu est bien de la m├¬me couleur
  247. //  que les 2 autres boules (on sait d├⌐j├á que les 2 autres boules sont de la m├¬me couleur)
  248.     if (m_NombreBoulesSelectionnees == 3) {
  249.         boule = m_PlateauInterne->ValeurCaseSuivante(boule,m_DirectionLaterale);
  250.         // Si on tombe sur une case avec une boule et que cette boule est de la couleur courante
  251.         if (m_PlateauInterne->CouleurBoule(boule) != m_CouleurCourante)
  252.             m_NombreBoulesSelectionnees = 1;    // la ligne lat├⌐rale n'est pas possible
  253.     }
  254. }
  255.  
  256.   ///////////////////////////////
  257.  // FONCTION "Deselectionner" //
  258. ///////////////////////////////-----------
  259. // D├⌐s├⌐lectionne une boule s├⌐lectionn├⌐e --
  260. //----------------------------------------
  261. void        // AUCUNE VALEUR DE RETOUR
  262. DeplacementHumain::Deselectionner()
  263. // AUCUN PARAMETRE
  264. {
  265.     // Si une boule a d├⌐j├á ├⌐t├⌐ s├⌐lectionn├⌐e, la d├⌐lectionner
  266.     if (m_NombreBoulesSelectionnees == 1) {
  267.         m_PlateauGraphique->EffacerSelect(2);        // Effacer la vue "Select" n┬░2
  268.         m_NombreBoulesSelectionnees = 0;
  269.     }
  270. }
  271.