home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 17
/
Freelog017.iso
/
BeOS
/
ababelone
/
Sources
/
FenetreAbabelone.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-11-22
|
38KB
|
1,056 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 "FenetreAbabelone.h"
////////////////////////////////////////
// CONSTRUCTEUR de "FenetreAbabelone" //
////////////////////////////////////////---------------------------------------------------------------------------
// Construit les objects et met à jour toutes les variables membres. Affiche aussi toutes les vues de la fenêtre --
//-----------------------------------------------------------------------------------------------------------------
FenetreAbabelone::FenetreAbabelone()
// AUCUN PARAMETRE
: BWindow(BRect(0,24,0,24), VERSION_ABABELONE,B_TITLED_WINDOW,B_NORMAL_WINDOW_FEEL | B_NOT_V_RESIZABLE | B_OUTLINE_RESIZE /*| B_NOT_ZOOMABLE*/)
{
BDirectory repertoire;
BPath chemin;
BEntry entree;
BRect rect;
int i;
uint8 langue = 1;
uint8 plateau_de_jeu = 1;
m_AffichageAPropos = true;
m_NombreJoueurs = 2;
m_DeplacementRealiste = true;
m_TableauJoueurs = new uint8[NOMBRE_JOUEURS_MAXI];
m_TableauDeplacementJoueurs = new (Deplacement*)[NOMBRE_JOUEURS_MAXI];
m_JoueurCourant = 0;
for (i=0; i < NOMBRE_JOUEURS_MAXI; i++) {
m_TableauJoueurs[i] = 0;
m_TableauDeplacementJoueurs[i] = NULL;
}
m_FichierPreferences = NULL;
find_directory(B_USER_SETTINGS_DIRECTORY, &chemin, true);
chemin.Append(REPERTOIRE_FICHIER_PREFERENCES);
repertoire.CreateDirectory(chemin.Path(), &repertoire);
repertoire.SetTo(chemin.Path());
if (repertoire.FindEntry(FICHIER_PREFERENCES, &entree) == B_NO_ERROR) {
m_FichierPreferences = new BFile(&entree, O_RDWR);
if (m_FichierPreferences->InitCheck() == B_NO_ERROR) {
m_FichierPreferences->Seek(0, 0);
m_FichierPreferences->Read(&m_NombreJoueurs, sizeof(uint8));
for (i=0; i < NOMBRE_JOUEURS_MAXI; i++)
m_FichierPreferences->Read(&(m_TableauJoueurs[i]), sizeof(uint8));
m_FichierPreferences->Read(&m_DeplacementRealiste, sizeof(bool));
m_FichierPreferences->Read(&langue, sizeof(uint8));
m_FichierPreferences->Read(&plateau_de_jeu, sizeof(uint8));
m_FichierPreferences->ReadAttr("AfficherFenêtreAuDébut", B_BOOL_TYPE, 0, &m_AffichageAPropos, sizeof(bool));
}
}
else {
m_FichierPreferences = new BFile();
if (repertoire.CreateFile(FICHIER_PREFERENCES, m_FichierPreferences) != B_NO_ERROR) {
delete m_FichierPreferences;
m_FichierPreferences = NULL;
}
}
chemin.Append(REPERTOIRE_PARTIES);
repertoire.CreateDirectory(chemin.Path(), &repertoire);
// Initialisation des variables membre
m_Debut = true;
m_Textes = new TextesDuLogiciel;
m_PartieTerminee = false;
m_PartieInterrompue = true;
m_PartieInterrompueTemporairement = false;
m_NombreBoules = 0;
m_SemaphoreThread = create_sem(1, "SemaphoreThread");
m_MessagePourFenetre = new BMessage;
m_ListeCoupsJoues = new BList;
m_ListeCoupsJoues->MakeEmpty();
m_NumeroCoupJoueCourant = 0;
m_ChargerFichier = new BFilePanel(B_OPEN_PANEL);
m_ChargerFichier->SetPanelDirectory(chemin.Path());
m_ChargerFichier->SetTarget(this);
m_SauvegarderFichier = new BFilePanel(B_SAVE_PANEL);
m_SauvegarderFichier->SetPanelDirectory(chemin.Path());
m_SauvegarderFichier->SetTarget(this);
CreerMenu(langue, plateau_de_jeu); // Créer le menu déroulant
SetSizeLimits(275,LARGEUR_PLATEAU-1,200,HAUTEUR_PLATEAU-1+20);
Zoom();
rect = Bounds();
// Créer l'objet "PlateauDeJeu" et lier la vue "Plateau" à la fenêtre
m_PlateauInterne = new PlateauDeJeuInterne(m_NombreBoules, m_NombreJoueurs);
m_PlateauGraphique = new PlateauDeJeuGraphique(BRect(0,20,LARGEUR_PLATEAU-1,HAUTEUR_PLATEAU-1+20), "PlateauDeJeuGraphique", m_Textes, m_MenuPlateauDeJeu, m_NombreBoules, m_NombreJoueurs);
AddChild(m_PlateauGraphique);
// m_PlateauGraphique->MiseAJourBufferEntier(); // Inutile car fait dans le FrameResized (appelé par Zoom)
// Afficher la fenêtre
Show();
if (m_AffichageAPropos == true)
APropos();
}
///////////////////////////////////////
// DESTRUCTEUR de "FenetreAbabelone" //
///////////////////////////////////////-------------
// Détruit les objects créés dans le constructeur --
//--------------------------------------------------
FenetreAbabelone::~FenetreAbabelone()
// AUCUN PARAMETRE
{
// Délier de la fenêtre la vue "Plateau"
RemoveChild(m_PlateauGraphique);
// Détruire l'objet "PlateauDeJeu"
delete m_PlateauInterne;
delete m_PlateauGraphique;
if (m_FichierPreferences != NULL)
delete m_FichierPreferences;
}
//////////////////////////////
// FONCTION "QuitRequested" //
//////////////////////////////------
// L'utilisateur ferme la fenêtre --
//----------------------------------
bool // VALEUR DE RETOUR
FenetreAbabelone::QuitRequested()
// AUCUN PARAMETRE
{
int i;
uint8 langue = m_MenuLangue->NumeroFichier();
uint8 plateau_de_jeu = m_MenuPlateauDeJeu->NumeroFichier();
// if (m_PartieInterrompue == false)
// InterromprePartie();
if (m_FichierPreferences != NULL) {
m_FichierPreferences->Seek(0, 0);
m_FichierPreferences->Write(&m_NombreJoueurs, sizeof(uint8));
for (i=0; i < NOMBRE_JOUEURS_MAXI; i++)
m_FichierPreferences->Write(&(m_TableauJoueurs[i]), sizeof(uint8));
m_FichierPreferences->Write(&m_DeplacementRealiste, sizeof(bool));
m_FichierPreferences->Write(&langue, sizeof(uint8));
m_FichierPreferences->Write(&plateau_de_jeu, sizeof(uint8));
m_FichierPreferences->WriteAttr("AfficherFenêtreAuDébut", B_BOOL_TYPE, 0, &m_AffichageAPropos, sizeof(bool));
}
be_app->PostMessage(B_QUIT_REQUESTED);
return true;//BWindow::QuitRequested(); // ou "return true;"
}
/////////////////////////////
// FONCTION "FrameResized" //
/////////////////////////////--------------------------------------------
// Change la taille de la fenêtre et la réactualise à la bonne échelle --
//-----------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::FrameResized(float width, float height)
// 2 PARAMETRES : ENTREE ENTREE
{
float echelle = (width+1.0)/LARGEUR_PLATEAU;
// float nouvelle_largeur = (echelle*LARGEUR_PLATEAU-1.0);
float nouvelle_hauteur = int(echelle*HAUTEUR_PLATEAU+19.0);
if ((nouvelle_hauteur) == (height)) {
m_PlateauGraphique->ChangerEchelle(echelle);
m_PlateauGraphique->MiseAJourBufferEntier();
}
else {
ResizeTo(width, nouvelle_hauteur);
}
}
////////////////////////////////
// FONCTION "MessageReceived" //
////////////////////////////////--------------------------------------
// Reçoit et traite tous les messages pour la gestion de la fenêtre --
//--------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::MessageReceived(BMessage* message)
// 1 PARAMETRE : ENTREE
{
bool partie_a_reprendre = false;
int32 compteur;
void* adresse_donnee = NULL;
if (message->what == MSG_QUITTER)
QuitRequested();
else {
get_sem_count(m_SemaphoreThread, &compteur);
if(compteur == 0) {
switch(message->what)
{
case B_WINDOW_RESIZED:
case MSG_PARTIE_PAUSE:
case MSG_CHARGER:
case B_REFS_RECEIVED:
case B_SAVE_REQUESTED:
case MSG_SAUVEGARDER:
case MSG_NOUVELLE_PARTIE:
case MSG_CHANGER_PARTIE:
case MSG_COMMENCER_NOUVELLE_PARTIE:
case MSG_COMMENCER_PARTIE:
case MSG_COUP_PRECEDENT:
case MSG_COUP_SUIVANT:
case MSG_COUP_SUIVANT_REALISTE:
case MSG_DEPLACEMENT_REALISTE:
case MSG_A_PROPOS_DE:
compteur = 1;
break;
}
if (compteur == 1 || m_MenuLangue->Active(message->what)
|| m_MenuPlateauDeJeu->Active(message->what))
if (!has_data(m_ThreadJouer)) {
*m_MessagePourFenetre = *message;
send_data(m_ThreadJouer, message->what, adresse_donnee, 0);
}
}
else {
acquire_sem(m_SemaphoreThread);
switch(message->what)
{
case B_WINDOW_RESIZED:
m_ChargerFichier->Show();
break;
/* case MSG_QUITTER:
QuitRequested();
break;
*/ case MSG_PARTIE_PAUSE:
if (m_PartieInterrompue == false)
InterromprePartie();
else
ContinuerPartie();
break;
case MSG_CHARGER:
m_ChargerFichier->Show();
break;
case B_REFS_RECEIVED:
ChargerFichier(message);
break;
case B_SAVE_REQUESTED:
SauvegarderFichier(message);
break;
case MSG_SAUVEGARDER:
m_SauvegarderFichier->Show();
break;
case MSG_NOUVELLE_PARTIE:
m_FenetreChangementDePartie = new FenetreChangementDePartie(this, m_TableauJoueurs, &m_NombreJoueurs, m_Textes, true);
break;
case MSG_CHANGER_PARTIE:
m_FenetreChangementDePartie = new FenetreChangementDePartie(this, m_TableauJoueurs, &m_NombreJoueurs, m_Textes, false);
break;
case MSG_COMMENCER_NOUVELLE_PARTIE:
m_FenetreChangementDePartie->PostMessage(B_QUIT_REQUESTED);
if (m_PartieInterrompue == false)
InterromprePartie();
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue);
m_PartieInterrompue = false;
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue);
CommencerPartie(true);
ContinuerPartie();
m_Debut = false;
break;
case MSG_COMMENCER_PARTIE:
m_FenetreChangementDePartie->PostMessage(B_QUIT_REQUESTED);
if (m_PartieInterrompue == false) {
InterromprePartie();
partie_a_reprendre = true;
}
CommencerPartie(false);
if (partie_a_reprendre == true)
ContinuerPartie();
else {
AfficherTitre(false);
}
break;
case MSG_COUP_PRECEDENT:
CoupPrecedent();
break;
case MSG_COUP_SUIVANT:
CoupSuivant();
break;
case MSG_COUP_SUIVANT_REALISTE:
CoupSuivant(true);
break;
case MSG_DEPLACEMENT_REALISTE:
m_DeplacementRealiste = ! m_DeplacementRealiste;
m_ItemDeplacementRealiste->SetMarked(m_DeplacementRealiste);
break;
case MSG_A_PROPOS_DE:
APropos();
break;
default:
if (m_MenuLangue->Active(message->what))
ChangerTextes(message->what - MSG_LANGUE);
else
if (m_MenuPlateauDeJeu->Active(message->what))
m_PlateauGraphique->ChangerPlateauDeJeu(message->what - MSG_PLATEAU_DE_JEU);
break;
}
release_sem(m_SemaphoreThread);
}
}
}
/////////////////////////////////////////
// FONCTION "SourisBoutonGaucheAppuye" //
/////////////////////////////////////////-------------------
// L'utilisateur appuie sur le bouton gauche de la souris --
//----------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::SourisBoutonGaucheAppuye(BPoint where)
// 1 PARAMETRE : ENTREE
{
if (Lock()) {
if (m_PartieInterrompue == false && m_HumainADejaJoue == false && m_TableauDeplacementJoueurs[m_JoueurCourant]->Ordinateur() == false)
((DeplacementHumain*)m_TableauDeplacementJoueurs[m_JoueurCourant])->JoueurAppuieSouris(where);
Unlock();
}
}
////////////////////////////////////////
// FONCTION "SourisBoutonDroitAppuye" //
////////////////////////////////////////-------------------
// L'utilisateur appuie sur le bouton droit de la souris --
//---------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::SourisBoutonDroitAppuye()
// AUCUN PARAMETRE
{
if (Lock()) {
if (m_PartieInterrompue == false && m_HumainADejaJoue == false && m_TableauDeplacementJoueurs[m_JoueurCourant]->Ordinateur() == false)
((DeplacementHumain*)m_TableauDeplacementJoueurs[m_JoueurCourant])->Deselectionner();
Unlock();
}
}
////////////////////////////////////
// FONCTION "SourisBoutonRelache" //
////////////////////////////////////--------------
// L'utilisateur relâche un bouton de la souris --
//------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::SourisBoutonRelache(BPoint where)
// 1 PARAMETRE : ENTREE
{
// Création et initialisation éventuelle des variables locales
int8 deplacement_ejection;
if (Lock()) {
if (m_PartieInterrompue == false && m_HumainADejaJoue == false && m_TableauDeplacementJoueurs[m_JoueurCourant]->Ordinateur() == false) {
deplacement_ejection = ((DeplacementHumain*)m_TableauDeplacementJoueurs[m_JoueurCourant])->JoueurRelacheSouris(where, m_DeplacementRealiste);
if (deplacement_ejection != -1) { // Si déplacement
m_HumainADejaJoue = true;
resume_thread(m_ThreadJouer);
}
}
Unlock();
}
}
//////////////////////////
// FONCTION "CreerMenu" //
//////////////////////////----------------
// Crée le menu déroulant de la fenêtre --
//----------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::CreerMenu(uint8 numero_langue, uint8 numero_plateau_de_jeu)
// 2 PARAMETRES : ENTREE ENTREE
{
// Création des variables locales
BRect rect_menu;
BMenu* sous_menu;
BMenuItem* item;
rect_menu = Bounds();
rect_menu.bottom = rect_menu.top+15;
m_MenuBar = new BMenuBar(rect_menu,"MenuBar");
sous_menu = new BMenu("");
sous_menu->AddItem(item=new BMenuItem("",new BMessage(MSG_NOUVELLE_PARTIE),'N',B_COMMAND_KEY));
sous_menu->AddItem(m_ItemChangerJoueurs=new BMenuItem("",new BMessage(MSG_CHANGER_PARTIE),'C',B_COMMAND_KEY));
m_ItemChangerJoueurs->SetEnabled(false);
sous_menu->AddSeparatorItem();
sous_menu->AddItem(m_ItemCharger=new BMenuItem("",new BMessage(MSG_CHARGER),'O',B_COMMAND_KEY));
sous_menu->AddItem(m_ItemSauvegarder=new BMenuItem("",new BMessage(MSG_SAUVEGARDER),'S',B_COMMAND_KEY));
m_ItemSauvegarder->SetEnabled(false);
sous_menu->AddSeparatorItem();
sous_menu->AddItem(new BMenuItem("",new BMessage(MSG_QUITTER),'Q',B_COMMAND_KEY));
m_MenuBar->AddItem(sous_menu);
sous_menu = new BMenu("");
sous_menu->AddItem(m_ItemCoupPrecedent = new BMenuItem("",new BMessage(MSG_COUP_PRECEDENT), B_LEFT_ARROW,B_COMMAND_KEY));
m_ItemCoupPrecedent->SetEnabled(false);
sous_menu->AddItem(m_ItemCoupSuivant = new BMenuItem("",new BMessage(MSG_COUP_SUIVANT), B_RIGHT_ARROW,B_COMMAND_KEY));
m_ItemCoupSuivant->SetEnabled(false);
sous_menu->AddItem(m_ItemCoupSuivantRealiste = new BMenuItem("",new BMessage(MSG_COUP_SUIVANT_REALISTE), B_UP_ARROW,B_COMMAND_KEY));
m_ItemCoupSuivantRealiste->SetEnabled(false);
sous_menu->AddSeparatorItem();
sous_menu->AddItem(m_ItemDeplacementRealiste = new BMenuItem("",new BMessage(MSG_DEPLACEMENT_REALISTE), 'R',B_COMMAND_KEY));
m_ItemDeplacementRealiste->SetMarked(m_DeplacementRealiste);
sous_menu->AddSeparatorItem();
sous_menu->AddItem(m_ItemTerminer=new BMenuItem("",new BMessage(MSG_PARTIE_PAUSE),'P',B_COMMAND_KEY));
m_ItemTerminer->SetEnabled(false);
m_ItemTerminer->SetMarked(false);
m_MenuBar->AddItem(sous_menu);
m_MenuBar->AddItem(sous_menu = new BMenu(""));
m_MenuLangue = new MenuDynamique(sous_menu, "Langues", MSG_LANGUE);
m_MenuBar->AddItem(sous_menu = new BMenu(""));
m_MenuPlateauDeJeu = new MenuDynamique(sous_menu, "Images/Plateaux de jeu", MSG_PLATEAU_DE_JEU);
m_MenuBar->AddItem(new BMenuItem("",new BMessage(MSG_A_PROPOS_DE)));
ChangerTextes(numero_langue);
m_MenuPlateauDeJeu->SelectionnerFichier(numero_plateau_de_jeu);
m_MenuBar->ResizeToPreferred();
AddChild(m_MenuBar);
}
//////////////////////////////
// FONCTION "ChangerTextes" //
//////////////////////////////------------------------------------------------
//----------------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::ChangerTextes(uint8 numero_langue)
// 1 PARAMETRE : ENTREE
{
BMenu* sous_menu;
BMenuItem* item;
BEntry entree_fichier;
int i = 0, j;
uint8 numero_texte;
char* chaine_fichier;
char* chaine;
entree_fichier = m_MenuLangue->SelectionnerFichier(numero_langue);
m_Textes->ChargerFichier(&entree_fichier);
while ((sous_menu = m_MenuBar->SubmenuAt(i)) != NULL) {
sous_menu = m_MenuBar->SubmenuAt(i);
(m_MenuBar->ItemAt(i))->SetLabel(m_Textes->Texte(0));
j = 0;
while ((item = sous_menu->ItemAt(j)) != NULL) {
numero_texte = 0;
switch (i) {
case 0:
switch (j) {
case 0: (m_MenuBar->ItemAt(i))->SetLabel(m_Textes->Texte(0));
numero_texte = 1;break;
case 1: numero_texte = 2;break;
case 3: numero_texte = 3;break;
case 4: numero_texte = 4;break;
case 6: numero_texte = 5;break;
}
break;
case 1:
switch (j) {
case 0: (m_MenuBar->ItemAt(i))->SetLabel(m_Textes->Texte(6));
numero_texte = 7;break;
case 1: numero_texte = 8;break;
case 2: numero_texte = 9;break;
case 4: numero_texte = 10;break;
case 6: numero_texte = 11;break;
}
break;
case 2:
(m_MenuBar->ItemAt(i))->SetLabel(m_Textes->Texte(34));
break;
case 3:
(m_MenuBar->ItemAt(i))->SetLabel(m_Textes->Texte(35));
break;
}
if (numero_texte != 0)
item->SetLabel(m_Textes->Texte(numero_texte));
j++;
}
i++;
}
(m_MenuBar->ItemAt(4))->SetLabel(m_Textes->Texte(12));
m_ChargerFichier->SetButtonLabel(B_DEFAULT_BUTTON, m_Textes->Texte(22));
m_ChargerFichier->SetButtonLabel(B_CANCEL_BUTTON, m_Textes->Texte(28));
m_ChargerFichier->Window()->SetTitle(m_Textes->Texte(14));
m_SauvegarderFichier->SetButtonLabel(B_DEFAULT_BUTTON, m_Textes->Texte(23));
m_SauvegarderFichier->SetButtonLabel(B_CANCEL_BUTTON, m_Textes->Texte(28));
m_SauvegarderFichier->Window()->SetTitle(m_Textes->Texte(15));
chaine = m_Textes->Texte(13);
chaine_fichier = new char[strlen(chaine) + strlen(EXTENTION_FICHIER) + 1];
strcpy(chaine_fichier, chaine);
strcat(chaine_fichier, EXTENTION_FICHIER);
m_SauvegarderFichier->SetSaveText(chaine_fichier);
delete chaine_fichier;
if (m_Debut == false) {
m_PlateauGraphique->ChangerTypeJoueurs(m_NombreJoueurs, m_TableauJoueurs, m_PlateauInterne->TableauBoulesEjectees());
AfficherTitre(m_PartieTerminee);
}
}
////////////////////////////////////////////////////////
// FONCTION "RemplirTableauHexagonalPositionDeDepart" //
////////////////////////////////////////////////////////------------------------------------------------
// Remplit le tableau interne et le tableau graphique. --
// Les valeurs correspondent à la position de départ du tableau hexagonal standard (5 boules de côté) --
//------------------------------------------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::RemplirTableauHexagonalPositionDeDepart()
// AUCUN PARAMETRE
{
int i, j, x, y, numero_boule;
for (i = 0; i < 11; i++)
for (j = 0; j < 11; j++) {
numero_boule = 0; // Cases vides dans l'hexagone (valeur : 0)
if (i == 0 || j == 0 || i == 10 || j == 10 || (i+j) < 6 || (i+j) > 14)
numero_boule = -1; // Cases hors de l'hexagone (valeur : -1)
else
switch(j) {
case 1 : // Ligne horizontale n┬░1
numero_boule = i - 4; // avec 5 boules noires
break;
case 2 : // Ligne horizontale n┬░2
numero_boule = i + 2; // avec 6 boules noires
break;
case 3 : // Ligne horizontale n┬░3
if (m_NombreJoueurs == 2)
if (i > 4 && i < 8) // avec 3 boules noires
numero_boule = i + 7;
break;
case 4 : // Ligne horizontale n┬░4
if (m_NombreJoueurs == 3) {
if (i == 2) // avec x boules x
numero_boule = i + 10;
if (i == 9)
numero_boule = i + 14;
}
break;
case 5 : // Ligne horizontale n┬░5
if (m_NombreJoueurs == 3) {
if (i == 1 || i == 2) // avec x boules x
numero_boule = i + 12;
if (i == 8 || i == 9)
numero_boule = i + 16;
}
break;
case 6 : // Ligne horizontale n┬░6
if (m_NombreJoueurs == 3) {
if (i == 1 || i == 2) // avec x boules x
numero_boule = i + 14;
if (i == 7 || i == 8)
numero_boule = i + 19;
}
break;
case 7 : // Ligne horizontale n┬░7
if (m_NombreJoueurs == 2) {
if (i > 2 && i < 6) // avec 3 boules blanches
numero_boule = i + 12;
}
else {
if (i == 1 || i == 2) // avec x boules x
numero_boule = i + 16;
if (i == 6 || i == 7)
numero_boule = i + 22;
}
break;
case 8 : // Ligne horizontale n┬░8
if (m_NombreJoueurs == 2)
numero_boule = i + 17; // avec 6 boules blanches
else {
if (i == 1 || i == 2) // avec x boules x
numero_boule = i + 18;
if (i == 5 || i == 6)
numero_boule = i + 25;
}
break;
case 9 : // Ligne horizontale n┬░9
if (m_NombreJoueurs == 2)
numero_boule = i + 23; // avec 5 boules blanches
else {
if (i == 1 || i == 2) // avec x boules x
numero_boule = i + 20;
if (i == 4 || i == 5)
numero_boule = i + 28;
}
break;
}
if (numero_boule > 0) {
x = ORIGINE_X + (2*i - 7 + j)*(LARGEUR_CASE_BOULE/2);
y = ORIGINE_Y + (j-1)*HAUTEUR_CASE_BOULE;
m_PlateauGraphique->SetBoule(numero_boule, BRect(x,y,x+LARGEUR_BOULE,y+HAUTEUR_BOULE));
}
m_PlateauInterne->SetCase(Coordonnees(i,j), numero_boule); // Cases (valeur : numero_boule)
}
m_PlateauGraphique->InitialiserSelectEtFleche();
m_PlateauInterne->InitialiserBoulesEjectees();
}
//////////////////////
// FONCTION "Jouer" //
//////////////////////-----------------------------------------------------------------------------------------
// Thread qui permet de jouer. C'est la boucle qui fait jouer l'ordinateur et qui permet aux joueurs humains --
// de jouer --
//-------------------------------------------------------------------------------------------------------------
int32 // VALEUR DE RETOUR
FenetreAbabelone::Jouer(void* ptr_objet)
// 1 PARAMETRE : ENTREE/SORTIE (en fait, correspond à "this")
{
FenetreAbabelone* w = (FenetreAbabelone*) ptr_objet;
type_deplacement* coup_joue;
thread_id numero_thread;
void * adresse_donnee = NULL;
int32 code;
while (w->m_PartieTerminee == false) {
acquire_sem(w->m_SemaphoreThread);
if (w->m_TableauDeplacementJoueurs[w->m_JoueurCourant]->Ordinateur() == true)
((DeplacementOrdinateur*)w->m_TableauDeplacementJoueurs[w->m_JoueurCourant])->Jouer(w->m_DeplacementRealiste);
else {
w->m_HumainADejaJoue = false;
release_sem(w->m_SemaphoreThread);
if (has_data(w->m_ThreadJouer))
receive_data(&numero_thread, adresse_donnee, 0);
suspend_thread(w->m_ThreadJouer);
acquire_sem(w->m_SemaphoreThread);
}
w->PreparerListeAvantDeJouer();
coup_joue = new type_deplacement(w->m_TableauDeplacementJoueurs[w->m_JoueurCourant]->CoupJoue());
w->m_ListeCoupsJoues->AddItem(coup_joue);
w->m_NumeroCoupJoueCourant++;
if (w->m_NumeroCoupJoueCourant > 0)
w->m_ItemCoupPrecedent->SetEnabled(true);
w->m_ItemCoupSuivant->SetEnabled(false);
w->m_ItemCoupSuivantRealiste->SetEnabled(false);
if (w->m_ListeCoupsJoues->CountItems() == 0)
w->m_ItemSauvegarder->SetEnabled(false);
else
w->m_ItemSauvegarder->SetEnabled(true);
if (w->m_PlateauInterne->BoulesEjectees(w->m_JoueurCourant) == 6)
w->m_PartieTerminee = true;
w->m_JoueurCourant = w->m_PlateauInterne->JoueurSuivant(w->m_JoueurCourant);
// if (w->m_PartieTerminee == false)
// w->m_PlateauGraphique->AfficherBouleCouleurAJouer(w->m_JoueurCourant, w->m_PartieInterrompue);
// else
// w->m_PlateauGraphique->EffacerBouleCouleurAJouer();
w->m_PlateauGraphique->AfficherBouleCouleurAJouer(w->m_JoueurCourant, w->m_PartieInterrompue, w->m_PartieTerminee);
release_sem(w->m_SemaphoreThread);
if (has_data(w->m_ThreadJouer)) {
code = receive_data(&numero_thread, adresse_donnee, 0);
w->PostMessage(w->m_MessagePourFenetre);
}
snooze(1000);
}
w->InterromprePartie(false);
}
//////////////////////////////////
// FONCTION "InterromprePartie" //
//////////////////////////////////-------------------------------------------------------------------------
// Met en pause une partie. Si la pause est temporaire, les joueurs humains éventuels peuvent jouer sans --
// avoir besoin d'enlever la pause --
//---------------------------------------------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::InterromprePartie(bool tuer_thread, bool interrompre_temporairement)
// 2 PARAMETRES : ENTREE ENTREE
{
if (m_PartieInterrompue == false) {
if (interrompre_temporairement == true && m_PartieInterrompueTemporairement == false)
m_PartieInterrompueTemporairement = true;
m_PartieInterrompue = true;
if (tuer_thread == true)
kill_thread(m_ThreadJouer);
// m_PlateauGraphique->AfficherPause();
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue, m_PartieTerminee);
if (m_PartieTerminee == true)
m_ItemTerminer->SetEnabled(false);
AfficherTitre(m_PartieTerminee);
m_ItemTerminer->SetMarked(m_PartieInterrompue);
}
}
////////////////////////////////
// FONCTION "ContinuerPartie" //
////////////////////////////////-----
// Continue une partie interrompue --
//-----------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::ContinuerPartie()
// AUCUN PARAMETRE
{
if (m_PartieTerminee == true)
m_PartieTerminee = false;
if (m_PartieInterrompueTemporairement == true)
m_PartieInterrompueTemporairement = false;
if (m_PartieInterrompue == true) {
m_PartieInterrompue = false;
m_ItemTerminer->SetMarked(m_PartieInterrompue);
}
AfficherTitre(false);
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue);
m_ThreadJouer = spawn_thread((FenetreAbabelone::Jouer), "JoueurSuivant", B_NORMAL_PRIORITY, (void*)this);
resume_thread(m_ThreadJouer);
}
////////////////////////////////
// FONCTION "CommencerPartie" //
////////////////////////////////--------------------------------
// Commence une nouvelle partie ou change le type des joueurs --
//--------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::CommencerPartie(bool commencer_du_debut, bool mise_a_jour_buffer_ecran)
// 2 PARAMETRES : ENTREE ENTREE
{
int32 i, max;
void* coup_joue;
if (commencer_du_debut == true) {
max = m_ListeCoupsJoues->CountItems();
for (i = 0; i < max; i++) {
coup_joue = m_ListeCoupsJoues->ItemAt(i);
delete ((type_deplacement*)coup_joue);
}
m_ListeCoupsJoues->MakeEmpty();
m_NumeroCoupJoueCourant = 0;
}
for (i=0; i < NOMBRE_JOUEURS_MAXI; i++) {
if (m_TableauDeplacementJoueurs[i] != NULL) {
delete m_TableauDeplacementJoueurs[i];
m_TableauDeplacementJoueurs[i] = NULL;
}
}
AfficherTitre(false);
if (m_NombreJoueurs == 2)
m_NombreBoules = 28;
else
m_NombreBoules = 33;
m_PlateauInterne->ChangerNombreBoules(m_NombreBoules);
m_PlateauInterne->ChangerNombreJoueurs(m_NombreJoueurs);
m_PlateauGraphique->ChangerNombreBoules(m_NombreBoules);
m_PlateauGraphique->ChangerTypeJoueurs(m_NombreJoueurs, m_TableauJoueurs, m_PlateauInterne->TableauBoulesEjectees());
if (commencer_du_debut == true) {
RemplirTableauHexagonalPositionDeDepart();
if (mise_a_jour_buffer_ecran == true)
m_PlateauGraphique->MiseAJourBufferEntier();
m_JoueurCourant = 0;
m_ItemTerminer->SetEnabled(true);
m_ItemSauvegarder->SetEnabled(true);
m_ItemChangerJoueurs->SetEnabled(true);
m_ItemCoupPrecedent->SetEnabled(false);
m_ItemCoupSuivant->SetEnabled(false);
m_ItemCoupSuivantRealiste->SetEnabled(false);
}
}
//////////////////////////////
// FONCTION "CoupPrecedent" //
//////////////////////////////-----------------
// Joue le coup précédent, si c'est possible --
//---------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::CoupPrecedent()
// AUCUN PARAMETRE
{
void* coup_joue;
if (m_NumeroCoupJoueCourant > 0) {
coup_joue = m_ListeCoupsJoues->ItemAt(m_NumeroCoupJoueCourant-1);
m_JoueurCourant = m_PlateauInterne->JoueurPrecedent(m_JoueurCourant);
if (m_TableauDeplacementJoueurs[m_JoueurCourant]->Ordinateur() == true)
InterromprePartie(true, true);
else
if (m_PartieInterrompueTemporairement == true && m_PartieInterrompue == true)
ContinuerPartie();
m_TableauDeplacementJoueurs[m_JoueurCourant]->JouerCoupPrecedent(*((type_deplacement*)coup_joue));
m_NumeroCoupJoueCourant--;
m_ItemCoupSuivant->SetEnabled(true);
m_ItemCoupSuivantRealiste->SetEnabled(true);
m_ItemTerminer->SetEnabled(true);
AfficherTitre(false);
if (m_NumeroCoupJoueCourant == 0)
m_ItemCoupPrecedent->SetEnabled(false);
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue);
}
}
////////////////////////////
// FONCTION "CoupSuivant" //
////////////////////////////-----------------
// Joue le coup suivant, si c'est possible --
//-------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::CoupSuivant(bool faire_glisser_les_boules, bool mise_a_jour_buffer_ecran)
// 2 PARAMETRES : ENTREE ENTREE
{
void* coup_joue;
if (m_NumeroCoupJoueCourant < m_ListeCoupsJoues->CountItems()) {
coup_joue = m_ListeCoupsJoues->ItemAt(m_NumeroCoupJoueCourant);
m_TableauDeplacementJoueurs[m_JoueurCourant]->JouerCoup(*((type_deplacement*)coup_joue), faire_glisser_les_boules, mise_a_jour_buffer_ecran);
m_JoueurCourant = m_PlateauInterne->JoueurSuivant(m_JoueurCourant);
if (m_TableauDeplacementJoueurs[m_JoueurCourant]->Ordinateur() == true)
InterromprePartie(true, true);
else
if (m_PartieInterrompueTemporairement == true && m_PartieInterrompue == true)
ContinuerPartie();
m_NumeroCoupJoueCourant++;
m_ItemCoupPrecedent->SetEnabled(true);
if (m_NumeroCoupJoueCourant == m_ListeCoupsJoues->CountItems()) {
if (mise_a_jour_buffer_ecran == true)
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue, m_PartieTerminee);
m_ItemCoupSuivant->SetEnabled(false);
m_ItemCoupSuivantRealiste->SetEnabled(false);
if (m_PartieTerminee == true) {
m_ItemTerminer->SetEnabled(false);
if (mise_a_jour_buffer_ecran == true)
AfficherTitre(true);
}
}
else
if (mise_a_jour_buffer_ecran == true)
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue);
}
}
///////////////////////////////
// FONCTION "ChargerFichier" //
///////////////////////////////-----------------------------
// Charge une partie sauvée préalablement dans un fichier --
//----------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::ChargerFichier(BMessage* message)
// 1 PARAMETRE : ENTREE
{
BEntry entree;
BPath chemin;
BFile fichier;
entry_ref ref;
status_t statut;
int32 max;
int32 i;
bool partie_terminee;
void* coup_joue;
char chaine[500];
message->FindRef("refs", 0, &ref);
entree.SetTo(&ref);
chemin.SetTo(&entree);
statut = fichier.SetTo(chemin.Path(), B_READ_ONLY);
if (statut != B_OK) {
sprintf(chaine, "%s \"%s\" %s", m_Textes->Texte(16), chemin.Path(), m_Textes->Texte(17));
(new BAlert("", chaine, m_Textes->Texte(21), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
}
else {
if (fichier.Read(chaine, (strlen(ENTETE_FICHIER)+1)*sizeof(char)) != (signed)(strlen(ENTETE_FICHIER)+1) || strcmp(chaine, ENTETE_FICHIER) != 0) {
sprintf(chaine, "%s \"%s\" %s", m_Textes->Texte(16), chemin.Path(), m_Textes->Texte(18));
(new BAlert("", chaine, m_Textes->Texte(21), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
}
else {
m_PartieInterrompueTemporairement = false;
// m_PartieInterrompue = false;
if (m_PartieInterrompue == false)
InterromprePartie();
else
m_ItemTerminer->SetMarked(m_PartieInterrompue);
sprintf(chaine,"%s - %s", VERSION_ABABELONE, m_Textes->Texte(20));
SetTitle(chaine);
fichier.Read(&m_NombreBoules, sizeof(uint8));
fichier.Read(&m_NombreJoueurs, sizeof(uint8));
for (i=0; i < m_NombreJoueurs; i++)
fichier.Read(&(m_TableauJoueurs[i]), sizeof(uint8));
fichier.Read(&partie_terminee, sizeof(bool));
fichier.Read(&max, sizeof(int32));
CommencerPartie(true, false);
for (i=0; i < max; i++) {
coup_joue = new type_deplacement;
m_ListeCoupsJoues->AddItem(coup_joue);
fichier.Read(coup_joue, sizeof(type_deplacement));
CoupSuivant(false, false);
}
fichier.Unset();
m_PartieTerminee = partie_terminee;
AfficherTitre(m_PartieTerminee);
if (m_PartieTerminee == false)
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue);
else {
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_PlateauInterne->JoueurPrecedent(m_JoueurCourant), m_PartieInterrompue);
m_PlateauGraphique->AfficherBouleCouleurAJouer(m_JoueurCourant, m_PartieInterrompue, true);
// m_PlateauGraphique->EffacerBouleCouleurAJouer();
}
if (m_TableauDeplacementJoueurs[m_JoueurCourant]->Ordinateur() == false)
ContinuerPartie();
m_PlateauGraphique->MiseAJourBufferEntier();
m_Debut = false;
}
}
}
///////////////////////////////////
// FONCTION "SauvegarderFichier" //
///////////////////////////////////---
// Sauve une partie dans un fichier --
//------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::SauvegarderFichier(BMessage* message)
// 1 PARAMETRE : ENTREE
{
BEntry entree;
BPath chemin;
BFile fichier;
entry_ref repertoire;
const char* nom_du_fichier;
status_t statut;
int32 max;
int32 i;
void* coup_joue;
char chaine[500];
message->FindRef("directory", 0, &repertoire);
message->FindString("name", &nom_du_fichier);
entree.SetTo(&repertoire);
chemin.SetTo(&entree);
strcpy(chaine, nom_du_fichier);
if (strlen(chaine) < strlen(EXTENTION_FICHIER) || strcmp(&(chaine[strlen(chaine)-strlen(EXTENTION_FICHIER)]), EXTENTION_FICHIER))
strcat(chaine, EXTENTION_FICHIER);
chemin.Append(chaine);
max = m_ListeCoupsJoues->CountItems();
statut = fichier.SetTo(chemin.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (statut != B_OK) {
sprintf(chaine, "%s \"%s\" %s", m_Textes->Texte(16), chemin.Path(), m_Textes->Texte(19));
(new BAlert("", chaine, m_Textes->Texte(21), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
}
else {
strcpy(chaine, ENTETE_FICHIER);
fichier.Write(chaine, (strlen(ENTETE_FICHIER)+1)*sizeof(char));
fichier.Write(&m_NombreBoules, sizeof(uint8));
fichier.Write(&m_NombreJoueurs, sizeof(uint8));
for (i=0; i < m_NombreJoueurs; i++)
fichier.Write(&(m_TableauJoueurs[i]), sizeof(uint8));
fichier.Write(&m_PartieTerminee, sizeof(bool));
fichier.Write(&max, sizeof(int32));
for (i=0; i < max; i++) {
coup_joue = m_ListeCoupsJoues->ItemAt(i);
fichier.Write(coup_joue, sizeof(type_deplacement));
}
fichier.Unset();
}
}
//////////////////////////////////////////
// FONCTION "PreparerListeAvantDeJouer" //
//////////////////////////////////////////----------------------------------------------------------------------
// Prépare la liste des coups joués juste avant de recommencer la partie. C'est-à-dire efface les coups joués --
// après la position courante, puisque la partie recommence juste après la position courante --
//--------------------------------------------------------------------------------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::PreparerListeAvantDeJouer()
// AUCUN PARAMETRE
{
int32 i, max;
m_ItemCoupSuivant->SetEnabled(false);
m_ItemCoupSuivantRealiste->SetEnabled(false);
max = m_ListeCoupsJoues->CountItems();
for (i = m_NumeroCoupJoueCourant; i < max; i++) {
m_NumeroCoupJoueCourant = m_ListeCoupsJoues->CountItems();
m_ListeCoupsJoues->RemoveItem(m_NumeroCoupJoueCourant-1);
}
m_NumeroCoupJoueCourant = m_ListeCoupsJoues->CountItems();
}
//////////////////////////////
// FONCTION "AfficherTitre" //
//////////////////////////////------
// Affiche le titre de la fenêtre --
//----------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::AfficherTitre(bool partie_finie)
// 1 PARAMETRE : ENTREE
{
int i;
char chaine_titre[500];
sprintf(chaine_titre,"%s - ", VERSION_ABABELONE);
for (i=0; i < m_NombreJoueurs; i++) {
if (i != 0)
sprintf(chaine_titre,"%s / ", chaine_titre);
if (m_TableauJoueurs[i] == 0) {
m_TableauDeplacementJoueurs[i] = (DeplacementHumain*)new DeplacementHumain(m_PlateauInterne, m_PlateauGraphique, i);
sprintf(chaine_titre,"%s%s", chaine_titre, m_Textes->Texte(24));
}
else {
m_TableauDeplacementJoueurs[i] = (DeplacementOrdinateur*)new DeplacementOrdinateur(m_PlateauInterne, m_PlateauGraphique, i, m_TableauJoueurs[i]);
sprintf(chaine_titre,"%s%s", chaine_titre, m_Textes->Texte(25));
}
}
if (partie_finie == true) {
strcat(chaine_titre, " ----> ");
strcat(chaine_titre, m_Textes->Texte(27));
}
else
if (m_PartieInterrompue == true) {
strcat(chaine_titre, " ---- ");
strcat(chaine_titre, m_Textes->Texte(26));
}
SetTitle(chaine_titre);
}
////////////////////////
// FONCTION "APropos" //
////////////////////////--------------
// Affiche la fenêtre "A propos..." --
//------------------------------------
void // AUCUNE VALEUR DE RETOUR
FenetreAbabelone::APropos()
// AUCUN PARAMETRE
{
char* chaine;
chaine = new char[strlen(VERSION_ABABELONE)+strlen(m_Textes->Texte(36))+5];
sprintf(chaine,"\t\t%s\n\n%s", VERSION_ABABELONE, m_Textes->Texte(36));
(new BAlert("", chaine, m_Textes->Texte(37)))->Go();
delete chaine;
}