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]