home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 17
/
Freelog017.iso
/
BeOS
/
ababelone
/
Sources
/
DeplacementHumain.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-11-20
|
13KB
|
271 lines
/*
Copyright (C) 2000 by Hervé PHILIPPE <rv@bemail.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "DeplacementHumain.h"
/////////////////////////////////////////
// CONSTRUCTEUR de "DeplacementHumain" //
/////////////////////////////////////////---
// Construit l'objet "Deplacement" hérité --
//------------------------------------------
DeplacementHumain::DeplacementHumain(PlateauDeJeuInterne* plateau_de_jeu_interne, PlateauDeJeuGraphique* plateau_de_jeu_graphique, int8 couleur)
// 3 PARAMETRES : ENTREE/SORTIE (modification par la suite) ENTREE/SORTIE (modification par la suite) ENTREE
: Deplacement(plateau_de_jeu_interne, plateau_de_jeu_graphique, couleur, false)
{
}
///////////////////////////////////
// FONCTION "JoueurAppuieSouris" //
///////////////////////////////////------------------
// L'utilisateur appuie sur un bouton de la souris --
//---------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
DeplacementHumain::JoueurAppuieSouris(BPoint where)
// 1 PARAMETRE : ENTREE
{
// Création et initialisation éventuelle des variables locales
int8 i, min, max;
int8 boule_choisie = 0; // Pour sortir de la boucle
bool bonne_boule_selectionnee = false;
bool deplacement_possible = false;
// Initialisation des variables "min" et "max" définissant les bornes de la boucle
// Numéro de la première boule de la couleur du joueur (minimum inclu)
min = 1 + m_CouleurCourante * m_PlateauInterne->NombreBoulesCouleur();
// Numéro de la dernière boule de la couleur du joueur (maximum NON inclu)
max = min + m_PlateauInterne->NombreBoulesCouleur();
// Boucle pour tester si une boule de la bonne couleur a été appuyée
for (i = min; i < max && boule_choisie == 0; i++)
// Si la position de la souris est incluse dans la vue de la boule n┬░i;
// bien sûr, la boule n°i doit être visible (pas sortie du plateau)
if ((m_PlateauGraphique->Boule(i)).Contains(where) &&
m_PlateauGraphique->BouleVisible(i) == true) {
boule_choisie = i; // Pour sortir de la boucle
// Positionner la vue "Select" n°1 à la boule sélectionnée (boule appuyée)
if (m_NombreBoulesSelectionnees == 1)
// Si cette boule a déjà été sélectionnée, la sélectionner "normalement"
if (m_PremiereBouleSelectionnee == boule_choisie) {
m_PlateauGraphique->EffacerSelect(2); // Effacer la vue "Select" n┬░2
bonne_boule_selectionnee = true;
}
// Si une autre boule a déjà été sélectionnée, il s'agit peut-être d'un déplacement latéral ?
else {
// Si les 2 boules sélectionnées sont sur une ligne latérale possible
// c'est-à-dire si 2 ou 3 boules sont consécutives sur un même axe
// REMARQUE : la fonction "LigneLateralePossible" déplace et affiche la vue "Select" n°2
LigneLateralePossible(boule_choisie);
if (m_NombreBoulesSelectionnees != 1)
bonne_boule_selectionnee = true;
}
else {
bonne_boule_selectionnee = true;
// Mise à jour des informations relatives à la première boule sélectionnée
m_PremiereBouleSelectionnee = boule_choisie;
m_NombreBoulesSelectionnees = 1;
}
if (bonne_boule_selectionnee == true) { // Si une nouvelle boule vient d'être appuyée
// Calculer tous les déplacements possibles et afficher les flèches correspondantes
for (i = 0; i < 6; i++) {
// Si la direction n°i correspond à un déplacement possible pour la boule sélectionnée
if ((m_NombreBoulesSelectionnees == 1 && DirectionPousseePossible(i) == true)
// ou à un déplacement latéral possible pour les 2 ou 3 boules sélectionnées
|| (m_NombreBoulesSelectionnees > 1
&& i%3 != m_DirectionLaterale%3
&& DirectionLateralePossible(i) )) {
deplacement_possible = true;
// Déplacer et afficher la flèche n°i
m_PlateauGraphique->AfficherFleche(i,boule_choisie);
}
}
if (deplacement_possible == true) { // S'il y a au moins 1 déplacement possible
m_PlateauGraphique->AfficherSelect(1,boule_choisie);
// Si 3 boules sont sélectionnées, il faut positionner la vue "Select" du milieu (n°3)
if (m_NombreBoulesSelectionnees == 3) {
boule_choisie = m_PlateauInterne->ValeurCaseSuivante(m_PremiereBouleSelectionnee,m_DirectionLaterale);
m_PlateauGraphique->AfficherSelect(3,boule_choisie);
}
}
else // Si aucun déplacement n'est possible,
// on fait comme si on n'avait pas appuyé sur une boule valide
if (m_NombreBoulesSelectionnees == 1)
m_NombreBoulesSelectionnees = 0;
else
m_NombreBoulesSelectionnees = 1;
}
}
}
////////////////////////////////////
// FONCTION "JoueurRelacheSouris" //
////////////////////////////////////--------------
// L'utilisateur relâche un bouton de la souris --
//------------------------------------------------
int8 // VALEUR DE RETOUR
DeplacementHumain::JoueurRelacheSouris(BPoint where, bool faire_glisser_les_boules)
// 2 PARAMETRES : ENTREE ENTREE
{
// Création et initialisation éventuelle des variables locales
int8 i;
int8 deplacement_ejection = -1; // Valeur de retour
m_Direction = -1;
if (m_NombreBoulesSelectionnees > 0) { // Si aucune boule n'est appuyée (c'est-à-dire sélectionnée avec le bouton
// de la souris enfoncé) on ne fait rien !
// Boucle pour effacer toutes les flèches qui ont été affichées
// et pour déterminer sur quelle flèche l'utilisateur relâche la souris
// et donc savoir quel déplacement il faut faire
for (i = 0; i < 6; i++)
if (m_PlateauGraphique->Fleche(i) != BOULE_CACHEE) { // Si la vue "Fleche" est visible
// Déterminer la direction sélectionnée (en fonction de la vue sur laquelle pointe la souris)
// REMARQUE : petite optimisation à cause de l'évaluation paresseuse...
if (m_Direction == -1 && (m_PlateauGraphique->Fleche(i)).Contains(where))
m_Direction = i;
m_PlateauGraphique->EffacerFleche(i); // la cacher
}
// Effacer les sélections effectuées
m_PlateauGraphique->EffacerSelect(1); // Cacher la vue "Select" n┬░1
// REMARQUE : cette sélection est la sélection "active" et doit être
// effacée. C'est-à-dire :
// .s'il n'y a qu'une seule boule sélectionnée, cette sélection
// est remplacée par la vue "Select" n°2 (voir plus haut)
// .s'il y a 2 boules sélectionnées, la 2ième boule est désélectionnée
// .s'il y a 3 boules sélectionnées, la 3ième boule est désélectionnée
if (m_NombreBoulesSelectionnees == 3) // S'il y a 3 boules sélectionnées, il faut cacher
m_PlateauGraphique->EffacerSelect(3); // la vue "Select" n°3 (pour la sélection du milieu)
// Si une direction est sélectionnée
if (m_Direction > -1) {
deplacement_ejection = 0; // Valeur de retour : il y a eu un deplacement;
if (m_NombreBoulesSelectionnees > 1) { // S'il y a plusieurs boules sélectionnées
m_PlateauGraphique->EffacerSelect(2); // Cacher la vue "Select" n┬░2
DeplacerBoulesLaterales(faire_glisser_les_boules); // Deplacement latéral des boules
}
else // S'il n'y a qu'une seule boule sélectionnée
if (DeplacerBoulesPoussee(faire_glisser_les_boules) == true) // Déplacement des boules
deplacement_ejection = 1; // Valeur de retour : il y a eu une éjection
m_NombreBoulesSelectionnees = 0;
}
// Si aucune direction n'est sélectionnée
else {
if (m_NombreBoulesSelectionnees > 0) { // S'il n'y a qu'une seule boule sélectionnée
m_NombreBoulesSelectionnees = 1;
// Replacer la vue "Select" n°2 (à la place de la vue "Select" n°1)
m_PlateauGraphique->AfficherSelect(2,m_PremiereBouleSelectionnee);
}
}
}
if (m_NombreBoulesSelectionnees > 0)
m_NombreBoulesSelectionnees = 1;
return deplacement_ejection;
}
//////////////////////////////////////
// FONCTION "LigneLateralePossible" //
//////////////////////////////////////----------------------------------------------------------
// Calcule si une ligne latérale est possible à partir d'une boule, c'est-à-dire si plusieurs --
// boules contigues du joueur courant peuvent se déplacer pour un déplacement latéral. --
// "m_NombreBoulesSelectionnees" vaut 1 si ce n'est pas possible et 2 ou 3 si c'est possible --
//----------------------------------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
DeplacementHumain::LigneLateralePossible(int8 numero_boule_appuyee)
// 1 PARAMETRE : ENTREE
{
// Création et initialisation éventuelle des variables locales
int delta_x, delta_y;
int8 boule = m_PremiereBouleSelectionnee;
// Calculer "delta_x" et "delta_y", en fonction de la boule 'appuyée' et de la boule 'sélectionnée'
// REMARQUE : ces deltas permettent de savoir :
// .si les 2 boules sont sur le même axe
// .si ces 2 boules ne sont distantes que d'une boule (de la même couleur) au maximum
delta_x = m_PlateauInterne->CoordonneesBoule(numero_boule_appuyee).x - m_PlateauInterne->CoordonneesBoule(m_PremiereBouleSelectionnee).x;
delta_y = m_PlateauInterne->CoordonneesBoule(numero_boule_appuyee).y - m_PlateauInterne->CoordonneesBoule(m_PremiereBouleSelectionnee).y;
// Traitement pour les directions : | REMARQUE :
// 1 | .si delta_x == 0,
// | / | .|delta_y| représente le nombre de boules à déplacer
// 0 -- -- 3 | (attention : pas plus de 3 boules !)
// / | | .le signe de delta_y représente une des 2 directions (0 ou 3)
// 4 | .et vice-versa pour delta_y == 0
if ((delta_x * delta_y) == 0 && abs(delta_x + delta_y) < 3 && (delta_x + delta_y) != 0) {
if (delta_x == 0)
if (delta_y < 0) { // delta_x == 0 et delta_y < 0 et |delta_y| < 3
m_DirectionLaterale = 1;
m_NombreBoulesSelectionnees = 1 - delta_y;
}
else { // delta_x == 0 et delta_y > 0 et |delta_y| < 3
m_DirectionLaterale = 4;
m_NombreBoulesSelectionnees = 1 + delta_y;
}
else // delta_x < 0 et delta_y == 0 et |delta_x| < 3
if (delta_x < 0) {
m_DirectionLaterale = 0;
m_NombreBoulesSelectionnees = 1 - delta_x;
}
else { // delta_x > 0 et delta_y == 0 et |delta_x| < 3
m_DirectionLaterale = 3;
m_NombreBoulesSelectionnees = 1 + delta_x;
}
}
else
// Traitement pour les directions : | REMARQUE :
// 2 | dans les 2 cas, on a :
// | / | .delta_x == -delta_y ET |delta_x| == |delta_y|
// -- -- | .en plus, delta_x (ou delta_y) peut valoir 1 ou 2
// / | | (car, en déplacement latéral, on ne déplace que 2 ou 3 boules)
// 5 |
if ((delta_x * delta_y) == -1 || ((delta_x * delta_y) == -4 && abs(delta_x - delta_y) == 4))
if (delta_x > 0) {
m_DirectionLaterale = 2;
m_NombreBoulesSelectionnees = 1 + delta_x; // (delta_x == -delta_y)
}
else {
m_DirectionLaterale = 5;
m_NombreBoulesSelectionnees = 1 + delta_y; // (delta_x == -delta_y)
}
else
m_NombreBoulesSelectionnees = 1; // A priori non-nécessaire... mais bon, on ne sait jamais !
// S'il y a 3 boules à déplacer, on veut vérifier que la boule du milieu est bien de la même couleur
// que les 2 autres boules (on sait déjà que les 2 autres boules sont de la même couleur)
if (m_NombreBoulesSelectionnees == 3) {
boule = m_PlateauInterne->ValeurCaseSuivante(boule,m_DirectionLaterale);
// Si on tombe sur une case avec une boule et que cette boule est de la couleur courante
if (m_PlateauInterne->CouleurBoule(boule) != m_CouleurCourante)
m_NombreBoulesSelectionnees = 1; // la ligne latérale n'est pas possible
}
}
///////////////////////////////
// FONCTION "Deselectionner" //
///////////////////////////////-----------
// Désélectionne une boule sélectionnée --
//----------------------------------------
void // AUCUNE VALEUR DE RETOUR
DeplacementHumain::Deselectionner()
// AUCUN PARAMETRE
{
// Si une boule a déjà été sélectionnée, la délectionner
if (m_NombreBoulesSelectionnees == 1) {
m_PlateauGraphique->EffacerSelect(2); // Effacer la vue "Select" n┬░2
m_NombreBoulesSelectionnees = 0;
}
}