Projekt Wieloplikowy, Obiekty Globalne, Błędy Konsolidacji

0

Witam,

Tworze gre wieloplikową, to jest dopiero początek platformy, dlateog zależy mi żeby napisać ją w kilku plikach ( będzie dużo edycji )
Podczas konsolidacji pojawia się problem ( załączony niżej log ), jak widzę jest to problem zmiennych, a raczej obiektów globalnych, poniżej zamieszczam kod wszystkich plików.

Z góry dziękuję za pomoc,
Pozdrawiam,
Krystian

[log]g++ -c fun/main.cpp -o appo/main.o
g++ -c fun/fun1.cpp -o appo/fun1.o
g++ -c fun/maszt.cpp -o appo/maszt.o
g++ -c fun/plansza.cpp -o appo/plansza.o
g++ -c fun/statek.cpp -o appo/statek.o
g++ appo/main.o appo/fun1.o appo/maszt.o appo/plansza.o appo/statek.o -o gra
appo/fun1.o:(.bss+0x0): multiple definition of Orzel' appo/main.o:(.bss+0x0): first defined here appo/fun1.o:(.bss+0x20): multiple definition of Jastrzab'
appo/main.o:(.bss+0x20): first defined here
appo/fun1.o:(.bss+0x40): multiple definition of Hawk' appo/main.o:(.bss+0x40): first defined here appo/fun1.o:(.bss+0x5c): multiple definition of Eagle'
appo/main.o:(.bss+0x5c): first defined here
appo/maszt.o:(.bss+0x0): multiple definition of Orzel' appo/main.o:(.bss+0x0): first defined here appo/maszt.o:(.bss+0x20): multiple definition of Jastrzab'
appo/main.o:(.bss+0x20): first defined here
appo/maszt.o:(.bss+0x40): multiple definition of Hawk' appo/main.o:(.bss+0x40): first defined here appo/maszt.o:(.bss+0x5c): multiple definition of Eagle'
appo/main.o:(.bss+0x5c): first defined here
appo/plansza.o:(.bss+0x0): multiple definition of Orzel' appo/main.o:(.bss+0x0): first defined here appo/plansza.o:(.bss+0x20): multiple definition of Jastrzab'
appo/main.o:(.bss+0x20): first defined here
appo/plansza.o:(.bss+0x40): multiple definition of Hawk' appo/main.o:(.bss+0x40): first defined here appo/plansza.o:(.bss+0x5c): multiple definition of Eagle'
appo/main.o:(.bss+0x5c): first defined here
appo/statek.o:(.bss+0x0): multiple definition of Orzel' appo/main.o:(.bss+0x0): first defined here appo/statek.o:(.bss+0x20): multiple definition of Jastrzab'
appo/main.o:(.bss+0x20): first defined here
appo/statek.o:(.bss+0x40): multiple definition of Hawk' appo/main.o:(.bss+0x40): first defined here appo/statek.o:(.bss+0x5c): multiple definition of Eagle'
appo/main.o:(.bss+0x5c): first defined here
collect2: ld returned 1 exit status
make: *** [gra] Błąd 1
[/log]

funkcje.h

[cpp]

#ifndef _FUNKCJE_H
#define _FUNKCJE_H

#include <iostream> 
#include <iomanip> // setw()
#include <cstdlib> // srand()
#include <ctime> // time()

using namespace std;



class plansza;
class maszt;
class statek;
class pancernik;
class torpedowiec;

//*********************************************************************************************************************************************************

// ./fun/plansza.cpp

class plansza 
{
public:
  maszt  ***wsk;  // wskaznik do wskaznika na wskaznik :P
  plansza();
  ~plansza();
  void wyswietl();
};

//*********************************************************************************************************************************************************

// ./fun/maszt.cpp

class maszt  // elementarna klasa
{
public:
  char stan;
  int typ; // 0 - nieostrzelany, 1 - ostrzelany, 2 - zatopiony, 3 - puste, 4 - pudlo
  maszt() : stan('.'), typ(3) {} // konstruktor, na poczatku nie ma zadnych stakow czyli maszty sa puste
  void wyswietl(); 
};

//*********************************************************************************************************************************************************

// ./fun/statek.cpp

class statek  // do polimorfizmu, klasa bazowa klasy pancernik (4-masztowiec) i torpedowiec (3-masztowiec)
{
public:
	virtual bool CzyPlywam() {return true;};
	virtual void buduj(int x, int y,  plansza &NazwaPlanszy, bool pion) {};
};

class pancernik : public statek // klasa czteromasztowcow
{
public:
	int iks,igrek;   // wspolrzedne poczatku statku
	bool pionowy;    // zmienna okreslajaca czy statek jest polozony pionowo czy poziomo
    maszt* tablica[4];   // tablica 4 wskaznikow do obiektow typu maszt - czesci skladowych czteromasztowca
	void buduj(int x, int y, plansza &NazwaPlanszy, bool pion);
	bool CzyPlywam();
};

class torpedowiec : public statek    // klasa trojmasztowcow
{
public:
	int iks,igrek;  // wspolrzedne poczatku statku
	bool pionowy;   // zmienna okreslajaca czy statek jest polozony pionowo czy poziomo
	maszt* tablica[3]; // tablica 3 wskaznikow do obiektow typu maszt - czesci skladowych trojmasztowca
	void buduj(int x, int y, plansza &NazwaPlanszy, bool pion);
	bool CzyPlywam();
};

void Ruch(plansza &NazwaPlanszy, pancernik &okret, torpedowiec &torpeda);
int IlePlywa(int wyswietl);
#endif

[/cpp]

zmienne.h

[cpp]

#ifndef _ZMIENNE_H
#define _ZMIENNE_H
#include "funkcje.h"

	pancernik Orzel, Jastrzab;   // dwa cztermosztowce
	torpedowiec Hawk,Eagle;      // dwa trojmasztowce
	const bool Linux=true;
	const bool Testowanie=false; // zmien na false, jak nie chcesz widziec, gdzie sa statki
#endif

[/cpp]

main.cpp:

[cpp]

#include "../lib/funkcje.h"
#include "../lib/zmienne.h"


int main()
{
	extern pancernik Orzel, Jastrzab;   // dwa cztermosztowce
	extern torpedowiec Hawk,Eagle;      // dwa trojmasztowce
	
	srand(time(NULL));
	plansza statki;
	bool pion=rand()%2;
	// losowe ustawienie dwoch 4-masztowcow:
	statek *wsk=&Orzel;
	(*wsk).buduj((pion)? (rand()%15)+1 : (rand()%12)+1,(pion) ? (rand()%12)+1 : (rand()%15)+1,statki,pion);  // polimorfizm
	pion=rand()%2; // losowanie pion/poziom, powtorne bo by byly oba pion/poziom zawsze
	int iks_, igrek_;                                           //
	do                                                          //
	{                                                           // eliminowanie kolizji (zeby statki sie nie krzyzowaly)
		iks_=(pion)? (rand()%15)+1 : (rand()%12)+1;             // losujemy wspolrzedne dopoty dopoki nie beda odpowiednie
		igrek_=(pion) ? (rand()%12)+1 : (rand()%15)+1;          //
	}	while((abs(iks_ - Orzel.iks)<4) || (abs(igrek_ - Orzel.igrek)<4));  //
	wsk=&Jastrzab;
	(*wsk).buduj(iks_, igrek_,statki,pion);
	pion=rand()%2;
	do                                                          //
	{                                                           // eliminowanie kolizji (zeby statki sie nie krzyzowaly)
		iks_=(pion)? (rand()%15)+1 : (rand()%12)+1;             // losujemy wspolrzedne dopoty dopoki nie beda odpowiednie
		igrek_=(pion) ? (rand()%12)+1 : (rand()%15)+1;          //
	}	while((abs(iks_ - Orzel.iks)<3 || abs(iks_ - Jastrzab.iks)<3) || (abs(igrek_ - Orzel.igrek)<3 || abs(igrek_ - Jastrzab.igrek)<3));
	wsk=&Hawk;
	(*wsk).buduj(iks_,igrek_,statki,pion);
	pion=rand()%2;
	do                                                          //
	{                                                           // eliminowanie kolizji (zeby statki sie nie krzyzowaly)
		iks_=(pion)? (rand()%15)+1 : (rand()%12)+1;             //
		igrek_=(pion) ? (rand()%12)+1 : (rand()%15)+1;          //
	}	while((abs(iks_ - Orzel.iks)<3 && (abs(igrek_ - Orzel.igrek)<3) || (abs(iks_ - Jastrzab.iks)<3 && abs(igrek_ - Jastrzab.igrek)<3) || (abs(iks_ - Hawk.iks)<2) && abs(igrek_ - Hawk.igrek)<3));
	wsk=&Eagle;
	(*wsk).buduj(iks_,igrek_,statki,pion);
	statki.wyswietl	();
	int ile=4;   // na poczatku plywaja 4 statki
	int IloscRuchow=0;  // zmienna do liczenia ruchow
	while(IlePlywa(0)) 
	{
		IlePlywa(1);
		Ruch(statki, Orzel, Hawk);
		++IloscRuchow;
		IlePlywa(1);  // wyswietlenie ilosci plywajacych (niezatopionych statkow)
		if(IlePlywa(0))  // jezeli plywa jeszcze jakis statek 
		{
			Ruch(statki, Jastrzab, Eagle);
			++IloscRuchow;
		}
	}
	statki.wyswietl();
	cout << "Brawo! Wszystkie zatopione!\n"
		<< "Ilosc ruchow: "<< IloscRuchow << "\n";
	return 0;
}

[/cpp]

fun1.cpp

[cpp]

#include "../lib/funkcje.h"
#include "../lib/zmienne.h"

	extern pancernik Orzel, Jastrzab;   // dwa cztermosztowce
	extern torpedowiec Hawk,Eagle;      // dwa trojmasztowce
	

int IlePlywa(int wyswietl)  // zwraca ilosc plywajacych statkow, wyswietl=0 - nie wyswietla, 1 - wyswietla
{
	int ile=0;  // zerujemy licznik bo zaraz sprawdzimy ile w danej chwili aktualnie plywa
	//(Orzel.CzyPlywam()) ? ile++ :ile;      //
	//(Jastrzab.CzyPlywam()) ? ile++ :ile;   // sprawdzenie (nie polimorfizm)
	//(Hawk.CzyPlywam()) ? ile++ :ile;	     //
	//(Eagle.CzyPlywam()) ? ile++ :ile;      //

	//statek *wsk;                                     //
	//(*(wsk=&Orzel)).CzyPlywam() ? ile++ : ile;       //
	//(*(wsk=&Jastrzab)).CzyPlywam() ? ile++ : ile;    // sprawdzenie (polimorfizm)
	//(*(wsk=&Hawk)).CzyPlywam() ? ile++ : ile;        //        dluzsza wersja
	//(*(wsk=&Eagle)).CzyPlywam() ? ile++ : ile;       //

	statek *wsk[4]={&Orzel,&Jastrzab,&Hawk,&Eagle};     //
	for(int i=0; i<4; ++i)                              // j.w.- krotsza wersja
		if((*(wsk[i])).CzyPlywam()) ile++;              //
	if(wyswietl) cout << "Plywa jeszcze statkow: " << ile << endl;
	return ile;
}

void Ruch(plansza &NazwaPlanszy, pancernik &okret, torpedowiec &torpeda)
{
	bool CzyZatopiony=false;
	int x,y;
	do    // wczytywanie danych + zabezpieczenie przed podaniem zlych wspolrzednych
	{
		cout << "Podaj x: ";
		cin >> x;
		cout << "Podaj y: ";
		cin >> y;
		if(x>16 || y>16 || x<0 || y<0) 
		{
			if(!x || !y) exit(0);   // zero -> konczymy program
			NazwaPlanszy.wyswietl();
			IlePlywa(1);
			cout << "Zle wspolrzedne, podaj jeszcze raz!\n";
			if(x==1337) // cheat, jak wpiszemy pod x 1337, program pokazuje wszystkie statki ;)
			{
				Testowanie==true;
				NazwaPlanszy.wyswietl();
			}
		}
	} while(x>16 || y>16 || x<0 || y<0); 
	if(x==0 || y==0) exit(0);  // na wcisniecie zera program sie konczy
	char temp=NazwaPlanszy.wsk[y-1][x-1]->stan;
	switch (temp)
	{
	case '.': 
		NazwaPlanszy.wsk[y-1][x-1]->stan=char(219);  // symbol ASCII zapelnionego prostokatu - pod Linuxem moze nie wyswietlac prawidlowo
		NazwaPlanszy.wsk[y-1][x-1]->typ=4;
		break;
	case 'X':
	case 'o':
		NazwaPlanszy.wsk[y-1][x-1]->stan='o';
		NazwaPlanszy.wsk[y-1][x-1]->typ=1;
		break;
	}
	statek *wsk;
	wsk=&okret;
	if(okret.CzyPlywam()==false)  // jak czteromasztowiec nie plywa, to znaczy ze tonie, zmieniamy jego znaki na "/" i typ masztow na zatopione
	{
		for(int i=1; i<=4; i++)
		{
			(okret.pionowy) ? NazwaPlanszy.wsk[okret.igrek+4-i][okret.iks]->stan='\\' : NazwaPlanszy.wsk[okret.igrek][okret.iks+4-i]->stan='\\';
			(okret.pionowy) ? NazwaPlanszy.wsk[okret.igrek+4-i][okret.iks]->typ=2: NazwaPlanszy.wsk[okret.igrek][okret.iks+4-i]->typ=2;
		}
	}
	if(torpeda.CzyPlywam()==false) // j.w. tyle ze trojmasztowiec
	{
		for(int i=1; i<=3; i++)
		{
			(torpeda.pionowy) ? NazwaPlanszy.wsk[torpeda.igrek+3-i][torpeda.iks]->stan='\\' : NazwaPlanszy.wsk[torpeda.igrek][torpeda.iks+3-i]->stan='\\';
			(torpeda.pionowy) ? NazwaPlanszy.wsk[torpeda.igrek+3-i][torpeda.iks]->typ=2 : NazwaPlanszy.wsk[torpeda.igrek][torpeda.iks+3-i]->typ=2;
		}
	}
	NazwaPlanszy.wyswietl(); // odswiezamy plansze po kazdym ruchu
}
[/cpp]

maszt.cpp

[cpp]

#include "../lib/funkcje.h"
#include "../lib/zmienne.h"

	extern pancernik Orzel, Jastrzab;   // dwa cztermosztowce
	extern torpedowiec Hawk,Eagle;      // dwa trojmasztowce
	

void maszt::wyswietl()
{
    if(Testowanie)  // jak testujemy to pokazujemy statki od razu
		cout << stan << "  ";
	else  // jak gramy to statki sa ukryte
		(stan=='X') ? cout << ".  " : cout << stan << "  ";
}

[/cpp]

plansza.cpp

[cpp]

#include "../lib/funkcje.h"
#include "../lib/zmienne.h"


	extern pancernik Orzel, Jastrzab;   // dwa cztermosztowce
	extern torpedowiec Hawk,Eagle;      // dwa trojmasztowce


plansza::plansza()  // konstruktor planszy
{
  wsk=new maszt**[18];   // plansza jest 2-wymiarowa tablica wskaznikow do masztow
  for(int i=0; i<18; i++)  // rozmiar 18 a plansza 16x16, zeby nie bylo przekroczenia zakresu przy losowym ustawianiu statkow 
  {							// (pionowy statek moglby sie zaczac np w y=15 i mamy przekroczenie zakresu)
      wsk[i]=new maszt*[18]; 
      for(int j=0; j<18; j++)
	  {
		  wsk[i][j]=new maszt();  // pojedynczy maszt
	  }
  }
}

plansza::~plansza()  // destruktor planszy, wykonuje sie kiedy plansza jest niszczona czyli po zakonczeniu gry
{
  cout << "Plansza kaput!\n";  // do testowania zadzialania destruktora
  for(int i=0; i<18; i++)   // zwolnienie zaalokowanej pamieci
  {
	  for(int j=0; j<18; j++)
	  {
		  delete wsk[i][j];  // niszczymy pojedyncze maszty
	  }
	  delete wsk[i];  // ... tablice masztow
  }
  delete wsk;   // ... i tablice tablic
  if(!Linux) system("pause");
}

void plansza::wyswietl() // wyswietlanie planszy
{
  if(Linux)system("clear");   // linux
  else system("cls"); // windows
  for(int i=1; i<=16; i++)  // wyswietlenie 16 wierszy
    {
	cout << setw(2) << i << " ";  // ladny rowny odstep
    for(int j=1; j<=16; j++)
		 wsk[i-1][j-1]->wyswietl(); // wyswietlanie 16 kolumn masztow
	switch(i)
	{
		case 1:
			  cout << "Legenda: " ;
			  break;
		case 2:
			cout << " .  Pole puste nieostrzelane";
			break;
		case 3:
			cout << " /  Maszt zatopiony";
			break;
		case 4:
			cout << " o  Maszt ostrzelany";
			break;
		case 5:
			cout << " " << char(219) << "  Pudlo";
			break;
		case 6: 
			cout << "    x=1337 - cheat ;-)";
			break;
		case 8:
			cout << " 0 - wyjscie z programu";
			break;
    }
	cout << endl;
  }
  cout << "   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16\n\n";
}

[/cpp]

statek.cpp

[cpp]

#include "../lib/funkcje.h"
#include "../lib/zmienne.h"

	extern pancernik Orzel, Jastrzab;   // dwa cztermosztowce
	extern torpedowiec Hawk,Eagle;      // dwa trojmasztowce
	

void pancernik::buduj(int x, int y,  plansza &NazwaPlanszy, bool pion)  // pion=1 statek pionowo, pion=0 statek poziomo
{
	iks=x;  // do dostepu z zewnatrz - musimy potem znac wspolrzedne statku
	igrek=y; // j.w.
	pionowy=pion;  // j.w.
	for(int i=0; i<4; i++)
	{
		(pion) ? tablica[i]=NazwaPlanszy.wsk[y+i][x] : tablica[i]=NazwaPlanszy.wsk[y][x+i];  // przypisanie masztow do statku
		(pion) ? NazwaPlanszy.wsk[y+i][x]->stan='X' : NazwaPlanszy.wsk[y][x+i]->stan='X';    // i ich znakow - z poczatku wszystkie dobre
		(pion) ? NazwaPlanszy.wsk[y+i][x]->typ=0 : NazwaPlanszy.wsk[y][x+i]->typ=0;          // typ - tez dobre
	}
}

bool pancernik::CzyPlywam()
{
	int Good=4;
	for(int i=0; i<4; i++)
	{
		if(tablica[i]->typ==1 || tablica[i]->typ==2)   // jezeli maszt ostrzelany lub zatopiony
			Good--;   // to zmniejszamy ilosc dobrych masztow w statku
	}
	if(Good>0) return true;  // jezeli ilosc masztow dobrych >0 to statek jeszcze plywa
	return false;            // w przeciwnym wypadku jest zatopiony
}

void torpedowiec::buduj(int x, int y,  plansza &NazwaPlanszy, bool pion)  // pion=1 statek pionowo, pion=0 statek poziomo
{
	iks=x;  // do dostepu z zewnatrz
	igrek=y; // j.w.
	pionowy=pion; // j.w.
	for(int i=0; i<3; i++)
	{
		(pion) ? tablica[i]=NazwaPlanszy.wsk[y+i][x] : tablica[i]=NazwaPlanszy.wsk[y][x+i];  // przypisanie statkowi odpowiednich masztow
		(pion) ? NazwaPlanszy.wsk[y+i][x]->typ=0 : NazwaPlanszy.wsk[y][x+i]->typ=0;   // i nadanie im wartosci (nieostrzelane)
		(pion) ? NazwaPlanszy.wsk[y+i][x]->stan='X' : NazwaPlanszy.wsk[y][x+i]->stan='X';
	}
}

bool torpedowiec::CzyPlywam()
{
	int Good=3;
	for(int i=0; i<3; i++)
	{
		if(tablica[i]->typ==1 || tablica[i]->typ==2)   // jezeli maszt ostrzelany lub zatopiony
			Good--;   // to zmniejszamy ilosc dobrych masztow w statku
	}
	if(Good>0) return true;
	return false;
}

[/cpp]

1

Zmienne.h przemianuj w Zmenne.cpp (ewentualnie usuń ifdef'a) i normalnie dołącz do projektu.
Natomiast wiersze:

        extern pancernik Orzel, Jastrzab;   // dwa cztermosztowce
        extern torpedowiec Hawk,Eagle;      // dwa trojmasztowce
        extern const bool Linux=true,Testowanie=false; // zmien na false, jak nie chcesz widziec, gdzie sa statki

Dołącz do funkcje.h

0

Dlaczego mam przemianować w zmienne.cpp ? nie mogę mieć zmiennych globalnych w pliku.h ? Czytałem ostatnimi czasy trochę na ten temat, ale ciężko gdziekolwiek znaleźć informacjie.

2

Zmiennych globalnych W OGÓLE nie powinieneś tam mieć i zaręczam ci że będziesz później płakał i pluł sobie w brodę że tak to zrobiłeś...

1
KrystianR napisał(a):

nie mogę mieć zmiennych globalnych w pliku.h ?

Deklaracja samej zmiennej ma być jeden raz na projekt, zaś .h jest dołączany wielokrotnie.
Dokładnie tak samo jak z definicją funkcji może być tylko raz dla tego jest w plikach .cpp

0

błąd rozwiązany - do zamknięcia :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1