home *** CD-ROM | disk | FTP | other *** search
/ Freelog 17 / Freelog017.iso / BeOS / ababelone / Sources / DeplacementOrdinateur.cpp < prev    next >
C/C++ Source or Header  |  2000-11-05  |  14KB  |  295 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 "DeplacementOrdinateur.h"
  20.  
  21.   /////////////////////////////////////
  22.  // VARIABLE "m_TableauPonderation" //
  23. /////////////////////////////////////------------------------------------------
  24. // Variable membre en "static" qui d├⌐finit la pond├⌐ration du tableau interne --
  25. //-----------------------------------------------------------------------------
  26. int16    DeplacementOrdinateur::m_TableauPonderation[11][11] = {
  27.         {   0,   0,   0,   0,   0,   1,   1,   1,   1,   1,   1},
  28.         {   0,   0,   0,   0,   1, 900, 900, 900, 900, 900,   1},
  29.         {   0,   0,   0,   1, 900,1000,1000,1000,1000, 900,   1},
  30.         {   0,   0,   1, 900,1000,1001,1001,1001,1000, 900,   1},
  31.         {   0,   1, 900,1000,1001,1004,1004,1001,1000, 900,   1},
  32.         {   1, 900,1000,1001,1004,1014,1004,1001,1000, 900,   1},
  33.         {   1, 900,1000,1001,1004,1004,1001,1000, 900,   1,   0},
  34.         {   1, 900,1000,1001,1001,1001,1000, 900,   1,   0,   0},
  35.         {   1, 900,1000,1000,1000,1000, 900,   1,   0,   0,   0},
  36.         {   1, 900, 900, 900, 900, 900,   1,   0,   0,   0,   0},
  37.         {   1,   1,   1,   1,   1,   1,   0,   0,   0,   0,   0}};
  38.  
  39.   /////////////////////////////////////////////
  40.  // CONSTRUCTEUR de "DeplacementOrdinateur" //
  41. /////////////////////////////////////////////-----------------------------------
  42. // Construit l'objet "Deplacement" h├⌐rit├⌐ et initialise les variables membres --
  43. //------------------------------------------------------------------------------
  44. DeplacementOrdinateur::DeplacementOrdinateur(PlateauDeJeuInterne* plateau_de_jeu_interne, PlateauDeJeuGraphique* plateau_de_jeu_graphique, int8 couleur, uint8 profondeur_max)
  45. // 4 PARAMETRES :                                ENTREE/SORTIE (modification par la suite)    ENTREE/SORTIE (modification par la suite)            ENTREE            ENTREE
  46.     : Deplacement(plateau_de_jeu_interne, plateau_de_jeu_graphique, couleur, true)
  47. {
  48.     m_ProfondeurMax = profondeur_max;
  49. }
  50.  
  51.   //////////////////////
  52.  // FONCTION "Jouer" //
  53. //////////////////////---------------------------------------------------------
  54. // Joue un coup automatiquement (de la part du joueur de type "ordinateur"). --
  55. // Le d├⌐placement peut ├¬tre r├⌐aliste ou non                                  --
  56. //-----------------------------------------------------------------------------
  57. void        // AUCUNE VALEUR DE RETOUR
  58. DeplacementOrdinateur::Jouer(bool faire_glisser_les_boules)
  59. // AUCUN PARAMETRE
  60. {
  61.     if (CalculerMeilleurCoupPossible() != COUP_IMPOSSIBLE) {
  62.         RestaurerMeilleurCoup();
  63.         if (m_NombreBoulesSelectionnees == 1)
  64.             DeplacerBoulesPoussee(faire_glisser_les_boules);
  65.         else
  66.             DeplacerBoulesLaterales(faire_glisser_les_boules);
  67.     }
  68.     // Sinon, l'ordinateur passe son tour !!!!
  69. }
  70.  
  71.   /////////////////////////////////////////////
  72.  // FONCTION "CalculerMeilleurCoupPossible" //
  73. /////////////////////////////////////////////--------------------------------------------
  74. // Renvoie le meilleur coup possible pour une profondeur donn├⌐e                        --
  75. // REMARQUE : cette fonction et la fonction "CalculerCoup" sont r├⌐cursives entre elles --
  76. //---------------------------------------------------------------------------------------
  77. int16        // VALEUR DE RETOUR
  78. DeplacementOrdinateur::CalculerMeilleurCoupPossible(uint8 profondeur)
  79. // 1 PARAMETRE :                                        ENTREE
  80. {
  81.     // Cr├⌐ation et initialisation ├⌐ventuelle des variables locales
  82.     int8 i, j, k, min, max;
  83.     int8 nombre_boules_joueur;
  84.     int8 nombre_boules_adversaire;
  85.     bool deplacement_avec_2_boules;
  86.     bool direction_possible;
  87.     int16 meilleur_coup = COUP_IMPOSSIBLE;
  88.     PlateauDeJeuInterne* ancien_plateau_interne = new PlateauDeJeuInterne();
  89.     PlateauDeJeuInterne* nouveau_plateau_interne = new PlateauDeJeuInterne();
  90.  
  91.     // Initialisation des variables "min" et "max" d├⌐finissant les bornes de la boucle    
  92.     // Num├⌐ro de la premi├¿re boule de la couleur du joueur (minimum inclu)
  93.     min = 1 + m_CouleurCourante * m_PlateauInterne->NombreBoulesCouleur();
  94.     // Num├⌐ro de la derni├¿re boule de la couleur du joueur (maximum NON inclu)
  95.     max = min + m_PlateauInterne->NombreBoulesCouleur();
  96.  
  97.     m_Direction = -1;
  98.     // Boucle pour tester si le d├⌐placement d'une boule de la bonne couleur est possible
  99.     for (i = min; i < max; i++) {
  100.         m_PremiereBouleSelectionnee = i;
  101.         // Calculer tous les d├⌐placements possibles
  102.         for (j = 0; j < 6; j++) {
  103.             m_NombreBoulesSelectionnees = 1;
  104.             // Si la direction n┬░i correspond ├á un d├⌐placement possible pour la boule s├⌐lectionn├⌐e
  105.             direction_possible = DirectionPousseePossible(j, &nombre_boules_joueur, &nombre_boules_adversaire);
  106.             if (direction_possible == true) {
  107.                 m_Direction = j;
  108. // Une pouss├⌐e possible
  109.                 CalculerCoup(meilleur_coup, ancien_plateau_interne, nouveau_plateau_interne, profondeur, nombre_boules_joueur, nombre_boules_adversaire);
  110.             }
  111.             if (j < 3 && nombre_boules_joueur > 1) {
  112.                 m_DirectionLaterale = j;
  113.                 if (nombre_boules_joueur > 2)
  114.                     m_NombreBoulesSelectionnees = 3;
  115.                 else
  116.                     m_NombreBoulesSelectionnees = 2;
  117.                 for (k = 0; k < 6; k++) {
  118.                     if (k%3 != j) {
  119.                         direction_possible = DirectionLateralePossible(k, &deplacement_avec_2_boules);
  120.                         m_Direction = k;
  121.                         if (direction_possible == true || deplacement_avec_2_boules == true) {
  122.                             if (m_NombreBoulesSelectionnees == 3)
  123.                                 m_NombreBoulesSelectionnees = 2;
  124. // Un d├⌐placement lat├⌐ral possible avec 2 boules
  125.                             CalculerCoup(meilleur_coup, ancien_plateau_interne, nouveau_plateau_interne, profondeur);
  126.                             if (nombre_boules_joueur > 2)
  127.                                 m_NombreBoulesSelectionnees = 3;
  128.                             if (direction_possible == true && m_NombreBoulesSelectionnees == 3) {
  129. // Un d├⌐placement lat├⌐ral possible avec 3 boules
  130.                                 CalculerCoup(meilleur_coup, ancien_plateau_interne, nouveau_plateau_interne, profondeur);
  131.                             }
  132.                         }
  133.                     }
  134.                 }
  135.             }
  136.         }
  137.     }            
  138.     delete ancien_plateau_interne;
  139.     delete nouveau_plateau_interne;
  140.     return meilleur_coup;
  141. }
  142.  
  143.   /////////////////////////////
  144.  // FONCTION "CalculerCoup" //
  145. /////////////////////////////-----------------------------------------------------
  146. // Calcule un coup possible                                                     --
  147. // REMARQUE : cette fonction et la fonction "CalculerMeilleurCoupPossible" sont --
  148. // r├⌐cursives entre elles                                                       --
  149. //--------------------------------------------------------------------------------
  150. void        // AUCUNE VALEUR DE RETOUR
  151. DeplacementOrdinateur::CalculerCoup(int16& meilleur_coup, PlateauDeJeuInterne* ancien_plateau_interne, PlateauDeJeuInterne* nouveau_plateau_interne, uint8 profondeur, int8 nombre_boules_joueur, int8 nombre_boules_adversaire)
  152. // 6 PARAMETRES :                    ENTREE/SORTIE (@)                    ENTREE/SORTIE                            ENTREE/SORTIE                                ENTREE                ENTREE                        ENTREE
  153. {
  154.     int8 premiere_boule_selectionnee;
  155.     int8 direction;
  156.     int8 nombre_boules_selectionnees;
  157.     int8 direction_laterale;
  158.     int16 coup;
  159.     int16 coup_temp;
  160.     int8 couleur_courante;
  161.  
  162.     if (profondeur == m_ProfondeurMax)
  163.         if (m_NombreBoulesSelectionnees > 1)
  164.             coup = CalculerValeurCoupLateral();
  165.         else
  166.             coup = CalculerValeurCoupPoussee(nombre_boules_joueur, nombre_boules_adversaire);
  167.     else {
  168.         *nouveau_plateau_interne = *m_PlateauInterne;
  169.         *ancien_plateau_interne = *m_PlateauInterne;
  170.         *m_PlateauInterne = *nouveau_plateau_interne;
  171.         premiere_boule_selectionnee = m_PremiereBouleSelectionnee;
  172.         nombre_boules_selectionnees = m_NombreBoulesSelectionnees;
  173.         direction = m_Direction;
  174.         direction_laterale = m_DirectionLaterale;
  175.         if (m_NombreBoulesSelectionnees > 1)
  176.             coup = CalculerValeurCoupLateral(true);
  177.         else
  178.             coup = CalculerValeurCoupPoussee(nombre_boules_joueur, nombre_boules_adversaire, true);        
  179.  
  180.         couleur_courante = m_CouleurCourante;
  181.         m_CouleurCourante = m_PlateauInterne->JoueurSuivant(m_CouleurCourante);
  182.         coup_temp = CalculerMeilleurCoupPossible(profondeur+1);
  183. ///////////ATTENTION////////
  184.         coup -= coup_temp; ////ATTENTION : - par -, ├ºa fait +, donc c'est valable
  185. ///////////ATTENTION//////// pour 2 joueurs. Pour 3 joueurs, il faut utiliser la fonction
  186. // "NombreJoueurs" de la classe "PlateauDeJeu", pour savoir si on doit additionner ou
  187. // soustraire
  188.         m_CouleurCourante = couleur_courante;
  189.  
  190.         *m_PlateauInterne = *ancien_plateau_interne;
  191.         m_PremiereBouleSelectionnee = premiere_boule_selectionnee;
  192.         m_NombreBoulesSelectionnees = nombre_boules_selectionnees;
  193.         m_Direction = direction;
  194.         m_DirectionLaterale = direction_laterale;
  195.     }
  196.     if (coup > meilleur_coup) {
  197.         if (profondeur == 1)
  198.             SauvegarderMeilleurCoup();
  199.         meilleur_coup = coup;
  200.     }
  201. }
  202.  
  203.   //////////////////////////////////////////
  204.  // FONCTION "CalculerValeurCoupPoussee" //
  205. //////////////////////////////////////////-------------------------------------------
  206. // Renvoie la valeur d'un coup pour un d├⌐placement en pouss├⌐e (pour un d├⌐placement --
  207. // virtuel ou non)                                                                 --
  208. //-----------------------------------------------------------------------------------
  209. int16        // VALEUR DE RETOUR
  210. DeplacementOrdinateur::CalculerValeurCoupPoussee(int8 nombre_boules_joueur, int8 nombre_boules_adversaire, bool deplacement_virtuel)
  211. // 3 PARAMETRES :                                            ENTREE                        ENTREE                        ENTREE
  212. {
  213.     // Cr├⌐ation et initialisation ├⌐ventuelle des variables locales
  214.     int8 i;
  215.     int16 valeur_coup = 0;
  216.     Coordonnees coord_boule = m_PlateauInterne->CoordonneesBoule(m_PremiereBouleSelectionnee);
  217.  
  218.     valeur_coup -= m_TableauPonderation[coord_boule.x][coord_boule.y];
  219.     for (i = 0; i < nombre_boules_joueur; i++)
  220.         if (deplacement_virtuel == true)
  221.             coord_boule = m_PlateauInterne->DeplacerBoule(coord_boule, m_Direction);    // Se positionner sur la case suivante
  222.         else
  223.             coord_boule = m_PlateauInterne->CoordonneesSuivantes(coord_boule, m_Direction);    // Se positionner sur la case suivante
  224.     valeur_coup += m_TableauPonderation[coord_boule.x][coord_boule.y];
  225.  
  226.     if (nombre_boules_adversaire != 0) {
  227.         valeur_coup += m_TableauPonderation[coord_boule.x][coord_boule.y];
  228.         for (i = 0; i < nombre_boules_adversaire; i++)
  229.             if (deplacement_virtuel == true)
  230.                 coord_boule = m_PlateauInterne->DeplacerBoule(coord_boule, m_Direction);    // Se positionner sur la case suivante
  231.             else
  232.                 coord_boule = m_PlateauInterne->CoordonneesSuivantes(coord_boule, m_Direction);    // Se positionner sur la case suivante
  233.         valeur_coup -= m_TableauPonderation[coord_boule.x][coord_boule.y];
  234.     }
  235.     return valeur_coup;
  236. }
  237.  
  238.   //////////////////////////////////////////
  239.  // FONCTION "CalculerValeurCoupLateral" //
  240. //////////////////////////////////////////----------------------------------------
  241. // Renvoie la valeur d'un coup pour un d├⌐placement lat├⌐ral (pour un d├⌐placement --
  242. // virtuel ou non)                                                              --
  243. //--------------------------------------------------------------------------------
  244. int16        // VALEUR DE RETOUR
  245. DeplacementOrdinateur::CalculerValeurCoupLateral(bool deplacement_virtuel)
  246. // 1 PARAMETRE :                                        ENTREE
  247. {
  248.     // Cr├⌐ation et initialisation ├⌐ventuelle des variables locales
  249.     int8 i;
  250.     int16 valeur_coup = 0;
  251.     Coordonnees coord_boule = m_PlateauInterne->CoordonneesBoule(m_PremiereBouleSelectionnee);
  252.     Coordonnees coord_boule_deplacee;
  253.  
  254.     for (i = 0; i < m_NombreBoulesSelectionnees; i++) {
  255.         if (deplacement_virtuel == true)
  256.             coord_boule_deplacee = m_PlateauInterne->DeplacerBoule(coord_boule, m_Direction);    // Se positionner sur la case suivante
  257.         else
  258.             coord_boule_deplacee = m_PlateauInterne->CoordonneesSuivantes(coord_boule, m_Direction);    // Se positionner sur la case suivante
  259.         valeur_coup += m_TableauPonderation[coord_boule_deplacee.x][coord_boule_deplacee.y];
  260.         valeur_coup -= m_TableauPonderation[coord_boule.x][coord_boule.y];
  261.         coord_boule = m_PlateauInterne->CoordonneesSuivantes(coord_boule, m_DirectionLaterale);    // Se positionner sur la case suivante
  262.     }
  263.     return valeur_coup;
  264. }
  265.  
  266.   ////////////////////////////////////////
  267.  // FONCTION "SauvegarderMeilleurCoup" //
  268. ////////////////////////////////////////----------------------
  269. // Sauvegarde le meilleur coup dans des variables r├⌐serv├⌐es --
  270. //------------------------------------------------------------
  271. void        // AUCUNE VALEUR DE RETOUR
  272. DeplacementOrdinateur::SauvegarderMeilleurCoup()
  273. // AUCUN PARAMETRE
  274. {
  275.     m_PremiereBouleSelectionnee_MeilleurCoup = m_PremiereBouleSelectionnee;
  276.     m_Direction_MeilleurCoup = m_Direction;
  277.     m_NombreBoulesSelectionnees_MeilleurCoup = m_NombreBoulesSelectionnees;
  278.     m_DirectionLaterale_MeilleurCoup = m_DirectionLaterale;
  279. }
  280.  
  281.   //////////////////////////////////////
  282.  // FONCTION "RestaurerMeilleurCoup" //
  283. //////////////////////////////////////--------------------------
  284. // Restaure le meilleur coup ├á partir des variables r├⌐serv├⌐es --
  285. //--------------------------------------------------------------
  286. void        // AUCUNE VALEUR DE RETOUR
  287. DeplacementOrdinateur::RestaurerMeilleurCoup()
  288. // AUCUN PARAMETRE
  289. {
  290.     m_PremiereBouleSelectionnee = m_PremiereBouleSelectionnee_MeilleurCoup;
  291.     m_Direction = m_Direction_MeilleurCoup;
  292.     m_NombreBoulesSelectionnees = m_NombreBoulesSelectionnees_MeilleurCoup;
  293.     m_DirectionLaterale = m_DirectionLaterale_MeilleurCoup;
  294. }
  295.