Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[Problem] Enum Field w pliku nagłówkowym


Rekomendowane odpowiedzi

Opublikowano

Witajcie. Korzystam z poradnika "Od zera do gier kodera". Nauczyłem sie podstaw i wgl. Ale ni o tym mowa..... Dochodząc do rozdziału w którym piszemy pierwszą grę. Kółko Krzyżyk. No i wlasnie tu mam problem. Ogarniając temat i po wgłębieniu napisałem oto taki plik nagłówkowy

 

 

#ifndef ASDASD_H_INCLUDED
#define ASDASD_H_INCLUDED


enum SIGN {SGN_CIRCLE, SGN_CROSS};
enum FIELD{FLD_EMPTY, FLD_CIRCLE, FLD_CROSS};
enum GAMESTATE {GS_NOTSTARTED, GS_MOVE, GS_WON, GS_DRAW};

// prototypy funkcji
bool StartGry();
bool Ruch(unsigned);
bool RysujPlansze();

enum FIELD
{ FLD_EMPTY, FLD_CIRCLE = SGN_CIRCLE, FLD_CROSS = SGN_CROSS };


#endif

Tak to wygląda. A błędy z konsoli wystakują jak te niżej:

 

C:\Users\NEONET\Desktop\game.h|16|error: multiple definition of 'enum FIELD'|
C:\Users\NEONET\Desktop\game.h|4|error: previous definition here|
C:\Users\NEONET\Desktop\game.h|17|error: conflicting declaration 'FLD_EMPTY'|
C:\Users\NEONET\Desktop\game.h|4|error: 'FLD_EMPTY' has a previous declaration as 'FIELD FLD_EMPTY'|
C:\Users\NEONET\Desktop\game.h|17|error: conflicting declaration 'FLD_CIRCLE'|
C:\Users\NEONET\Desktop\game.h|4|error: 'FLD_CIRCLE' has a previous declaration as 'FIELD FLD_CIRCLE'|
C:\Users\NEONET\Desktop\game.h|17|error: conflicting declaration 'FLD_CROSS'|
C:\Users\NEONET\Desktop\game.h|4|error: 'FLD_CROSS' has a previous declaration as 'FIELD FLD_CROSS'|
||=== Build finished: 8 errors, 0 warnings ===|

 

 

I teraz nasuwa się pytanie gdzie popełniłem błąd ??

 

 

@Edit

 

Dodam że próbowałem pisać np:

enum FIELD { FIELD FLD_CROSS, FIELD FLD_CIRCLE //.... i takie tam inne [code]

Ale błedy również były

hcq0.png


Opublikowano

Pozwolę sobie zaprezentować fragment twojego kodu:

 

enum FIELD{FLD_EMPTY, FLD_CIRCLE, FLD_CROSS};

/* 
( ... ) 
*/ 

enum FIELD
{ FLD_EMPTY, FLD_CIRCLE = SGN_CIRCLE, FLD_CROSS = SGN_CROSS };

 

I zapytać:

AYFKM? <_<

Ta sygnatura jest pusta.

Opublikowano

Dalej te same logi :)

C:\Users\NEONET\Desktop\game.h|18|error: multiple definition of 'enum FIELD'|
C:\Users\NEONET\Desktop\game.h|6|error: previous definition here|
C:\Users\NEONET\Desktop\game.h|19|error: conflicting declaration 'FLD_EMPTY'|
C:\Users\NEONET\Desktop\game.h|6|error: 'FLD_EMPTY' has a previous declaration as 'FIELD FLD_EMPTY'|
C:\Users\NEONET\Desktop\game.h|19|error: conflicting declaration 'FLD_CIRCLE'|
C:\Users\NEONET\Desktop\game.h|6|error: 'FLD_CIRCLE' has a previous declaration as 'FIELD FLD_CIRCLE'|
C:\Users\NEONET\Desktop\game.h|19|error: conflicting declaration 'FLD_CROSS'|
C:\Users\NEONET\Desktop\game.h|6|error: 'FLD_CROSS' has a previous declaration as 'FIELD FLD_CROSS'|
||=== Build finished: 8 errors, 0 warnings ===|

hcq0.png


Opublikowano

Przeczytaj jeszcze raz, na spokojnie, co napisałem powyżej.

 

Oraz skorzystaj z google translate aby przetłumaczyć komunikat zwracany Ci przez kompilator:

"multiple definition of 'enum FIELD'|"

Ta sygnatura jest pusta.

Opublikowano

4GGR skapłem sie jak wziełem pierwszą definicje "Enuma" w komentarz i teraz wyświetla mi logi takie

C:\Users\NEONET\Desktop\main.o:main.cpp|| undefined reference to `StartGry()'|
C:\Users\NEONET\Desktop\main.o:main.cpp|| undefined reference to `RysujPlansze()'|
C:\Users\NEONET\Desktop\main.o:main.cpp|| undefined reference to `g_StanGry'|
C:\Users\NEONET\Desktop\main.o:main.cpp|| undefined reference to `Ruch(unsigned int)'|
C:\Users\NEONET\Desktop\main.o:main.cpp|| undefined reference to `g_StanGry'|
||=== Build finished: 5 errors, 0 warnings ===|

 

@Edit

Czyżby niema dostępu do funkcji ??

hcq0.png


Opublikowano
Opublikowano

Z jakiego IDE korzystasz?

Czy kompilator prawidłowo tworzy plik game.o w folderze projektu ?

 

@Sopel

Ćśśś, bo się nie znasz ;P Plików .cpp się nie includuj'e, od tego jest linker.

Ta sygnatura jest pusta.

Opublikowano

@4ggr

 

Korzystam z Code::Blocks 10.05. Wiem że na początku sprawiłem wrażenie typowego nobka :) ale aż takim nie jestem. Nie dorównuje wam poziomem dlatego sie do was zwracam :) . Spróbuje przeanalizować na jutro jeszce raz mój kod i Dam wam znac co i jak.

Zwracam sie do Was (czyt. Ogarniętych koderów) żebyście zaglądali w temat jutro tak koło 16-17 już ogarne jescze raz. Spakuje wam moje pliki i sami zbaczycie :)

Narazie Lajki i 5* za pomoc macie.

Zapraszam jutro serdecznie w celu dalszej pomocy :)

hcq0.png


Opublikowano

C::B, bardzo dobrze.

 

Więc tak:

1. Żeby tworzyć projekt podzielony na kilka plików źródłowych, musisz - po pierwsze - stworzyć projekt. Nie możesz operować na pojedynczym pliku .cpp. Nagłówki poprawnie się do niego dołączą, bo to żadna filozofia, ale jeśli masz podział na kilka źródeł ( .cpp ) to się poprawnie nie zlinkuje.

2. File > New > Project > Console Application ( lub cokolwiek innego, jeśli wiesz, co robisz ).

3. Ctrl+Shift+N. Wyskoczy dialog "Czy chcesz dodać plik do projektu?". Oczywiście, że tak.

4. Jak wyżej, bo potrzebujesz dwa pliki - nagłówek i źródło (game.h i game.cpp).

5. Nazewnictwo jest bardzo ważne, mianowicie musi być identyczne. Wielkość liter jest MMAMNMZTTSNPNB**.

6. Shift+[F2] taką liczbę razy, aby pokazał się Management (domyślnie z lewej). Projects > /nazwa/ > sourcers (oraz headers). Jeśli w obu gałęziach drzewa plików znajduje się odpowiedni plik, jesteśmy w domu. Każdy uzupełniasz swoim stuff'em (upewnij się, że w każdym nagłówku masz #ifndef H_SYMBOL_NAGLOWKA #define...).

7. Powinno działać.

 

 

 

*mniej więcej

**Może Mieć A Może Nie Mieć Znaczenia. Teraz Tego Sprawdzać Na Pewno Nie Będę

Ta sygnatura jest pusta.

Opublikowano

@4grr

 

Słuchaj mam tak. Main.cpp jest to moja głowna lokacja ona tylko wywołuje funkcje ktore są w game.cpp. posiadam również game.h w ktorym mam prototypy funkcji itp. Wiesz pewnie o czym mówię. i jezeli chce uruchomic aplikacje to wyskakuje mi ze nie posiadam dostępu do Wszystkich moich funkcji.

Dodam Ci pliki w spoilerach abyś mogła zobaczyc co może być nie tak :)

 

Main.cpp

 

#include <iostream>

#include <conio.h>

#include "game.h"

 

extern GAMESTATE g_StanGry;

int main()

{

StartGry();

for (; ;)

{

RysujPlansze();

if (g_StanGry == GS_MOVE)

{

unsigned uNumerPola;

std::cin >> uNumerPola;

Ruch (uNumerPola);

}

else if (g_StanGry == GS_WON || g_StanGry == GS_DRAW);

break;

}

getch();

}

 

 

Game.h

 

#ifndef ASDASD_H_INCLUDED

#define ASDASD_H_INCLUDED

 

 

enum SIGN {SGN_CIRCLE, SGN_CROSS};

enum FIELD

{ FLD_EMPTY, FLD_CIRCLE = SGN_CIRCLE, FLD_CROSS = SGN_CROSS };

enum GAMESTATE {GS_NOTSTARTED, GS_MOVE, GS_WON, GS_DRAW};

 

// prototypy funkcji

//------------------

// rozpoczęcie gry

bool StartGry();

// wykonanie ruchu

bool Ruch(unsigned);

// rysowanie planszy

bool RysujPlansze();

extern GAMESTATE g_StanGry;

#endif

 

 

 

 

Game.cpp

 

#include <iostream>

#include <ctime>

#include "game.h"

 

g_aPlansza, g_StanGry, g_AktualnyGracz:

FIELD g_aPlansza[3][3] = { { FLD_EMPTY, FLD_EMPTY, FLD_EMPTY },

{ FLD_EMPTY, FLD_EMPTY, FLD_EMPTY },

{ FLD_EMPTY, FLD_EMPTY, FLD_EMPTY } };

GAMESTATE g_StanGry = GS_NOTSTARTED;

SIGN g_AktualnyGracz;

 

bool StartGry()

{

if (g_StanGry != GS_NOTSTARTED) return false;

// losujemy gracza, który będzie zaczynał

srand (static_cast<unsigned>(time(NULL)));

g_AktualnyGracz = (rand() % 2 == 0 ? SGN_CIRCLE : SGN_CROSS);

// ustawiamy stan gry na ruch graczy

g_StanGry = GS_MOVE;

return true;

}

 

bool Ruch()

{

if (g_StanGry != GS_MOVE) return false;

if (!(uNumerPola >= 1 && uNumerPola <= 9)) return false;

unsigned uY = (uNumerPola - 1) / 3;

unsigned uX = (uNumerPola - 1) % 3;

if (g_aPlansza[uY][uX] == FLD_EMPTY)

// wstaw znak aktualnego gracza w podanym polu

else

return false;

g_aPlansza[uY][uX] = static_cast<FIELD>(g_AktualnyGracz);

const LINIE[][3][2] = { { { 0,0 }, { 0,1 }, { 0,2 } }, // górna pozioma

{ { 1,0 }, { 1,1 }, { 1,2 } },// środ. pozioma

{ { 2,0 }, { 2,1 }, { 2,2 } },// dolna pozioma

{ { 0,0 }, { 1,0 }, { 2,0 } }, // lewa pionowa

{ { 0,1 }, { 1,1 }, { 2,1 } }, // środ. pionowa

{ { 0,2 }, { 1,2 }, { 2,2 } }, // prawa pionowa

{ { 0,0 }, { 1,1 }, { 2,2 } }, // p. backslashowa

{ { 2,0 }, { 1,1 }, { 0,2 } } }; // p. slashowa

 

FIELD Pole, ZgodnePole;

unsigned uLiczbaZgodnychPol;

for (int i = 0; i < 8; ++i)

{

// i przebiega po kolejnych możliwych liniach (jest ich osiem)

// zerujemy zmienne pomocnicze

Pole = ZgodnePole = FLD_EMPTY; // obie zmienne == FLD_EMPTY

uLiczbaZgodnychPol = 0;

for (int j = 0; j < 3; ++j)

{

// j przebiega po trzech polach w każdej linii

// pobieramy rzeczone pole

// to zdecydowanie najbardziej pogmatwane wyrażenie :)

Pole = g_aPlansza[LINIE[j][0]][LINIE[j][1]];

// jeśli sprawdzane pole różne od tego, które ma się zgadzać...

if (Pole != ZgodnePole)

{

// to zmieniamy zgadzane pole na to aktualne

ZgodnePole = Pole;

uLiczbaZgodnychPol = 1;

}

else

// jeśli natomiast oba pola się zgadzają, no to

// inkrementujemy licznik takich zgodnych pól

++uLiczbaZgodnychPol;

}

// teraz sprawdzamy, czy udało nam się zgodzić linię

if (uLiczbaZgodnychPol == 3 && ZgodnePole != FLD_EMPTY)

{

// jeżeli tak, no to ustawiamy stan gry na wygraną

g_StanGry = GS_WON;

// przerywamy pętlę i funkcję

return true;

}

}

for (int j = 0; j < 3; ++j)

{

Pole = g_aPlansza[LINIE[j][0]][LINIE[j][1]];

if (Pole != ZgodnePole)

{

ZgodnePole = Pole;

uLiczbaZgodnychPol = 1;

}

else

++uLiczbaZgodnychPol;

}

if (uLiczbaZgodnychPol == 3 && ZgodnePole != FLD_EMPTY)

g_StanGry = GS_WON;

return true;

 

unsigned uLiczbaZapelnionychPol = 0;

for (int i = 0; i < 3; ++i)

for (int j = 0; j < 3; ++j)

if (g_aPlansza[j] != FLD_EMPTY)

++uLiczbaZapelnionychPol;

 

if (uLiczbaZapelnionychPol == 3*3)

{

g_StanGry = GS_DRAW;

return true;

}

g_AktualnyGracz = (g_AktualnyGracz == SGN_CIRCLE ?

SGN_CROSS : SGN_CIRCLE);

return true;

}

 

bool RysujPlansze()

{

if (g_StanGry == GS_NOTSTARTED) return false;

system ("cls");

std::cout << " KOLKO I KRZYZYK " << std::endl;

std::cout << "---------------------" << std::endl;

std::cout << std::endl;

std::cout << " -----" << std::endl;

for (int i = 0; i < 3; ++i)

{

// lewa część ramki

std::cout << " |";

// wiersz

for (int j = 0; j < 3; ++j)

{

if (g_aPlansza[j] == FLD_EMPTY)

// numer pola

std::cout << i * 3 + j + 1;

else

enum SIGN { SGN_CIRCLE = 'O', SGN_CROSS = 'X' };

std::cout << static_cast<char>(g_aPlansza[j]);

// tutaj wyświetlamy kółko lub krzyżyk... ale jak? :)

}

// prawa część ramki

std::cout << "|" << std::endl;

}

std::cout << " -----" << std::endl;

std::cout << std::endl;

 

switch (g_StanGry)

{

case GS_MOVE:

// prośba o następny ruch

std::cout << "Podaj numer pola, w ktorym" << std::endl;

std::cout << "chcesz postawic ";

std::cout << (g_AktualnyGracz == SGN_CIRCLE ?

"kolko" : "krzyzyk") << ": ";

break;

case GS_WON:

// informacja o wygranej

std::cout << "Wygral gracz stawiajacy ";

std::cout << (g_AktualnyGracz == SGN_CIRCLE ?

"kolka" : "krzyzyki") << "!";

break;

case GS_DRAW:

// informacja o remisie

std::cout << "Remis!";

break;

}

return true;

}

 

 

 

 

Na marginesie cały ten kod kopiowałem z poradnika żeby zobaczyc czy ja coś nie zrobiłem źle i dalej to sam :)

hcq0.png


Opublikowano

#include <stdlib.h>

 

Jest jeszcze kilka błędów.

Z tych na temat:

- zewnętrzne ( nienależące do twojego projektu ) nagłówki przerzuć z game.cpp do game.h

- korzystaj z tabulatora. Zacznij od Plugins > Source Code Formatter i postaraj się, żeby to dalej jakoś wyglądało

Ta sygnatura jest pusta.

Opublikowano

Dobra jest teraz Git tylko błąd wywala mi przy stałej która ma za zadanie sprawdzac gdzie czy gdzies są 3 "O" lub "X" :)

 const LINIE[][3][2] = { { { 0,0 }, { 0,1 }, { 0,2 } }, // górna pozioma
					{ { 1,0 }, { 1,1 }, { 1,2 } },// œrod. pozioma
					{ { 2,0 }, { 2,1 }, { 2,2 } },// dolna pozioma
					{ { 0,0 }, { 1,0 }, { 2,0 } }, // lewa pionowa
					{ { 0,1 }, { 1,1 }, { 2,1 } }, // œrod. pionowa
					{ { 0,2 }, { 1,2 }, { 2,2 } }, // prawa pionowa
					{ { 0,0 }, { 1,1 }, { 2,2 } }, // p. backslashowa
					{ { 2,0 }, { 1,1 }, { 0,2 } } }; // p. slashowa

 

a bład jest taki

C:\Users\NEONET\Desktop\dupadupa\dupadupa\game.cpp|37|error: ISO C++ forbids declaration of 'LINIE' with no type|

 

Oraz błąd jest tutaj

 

for (int j = 0; j < 3; ++j)
{
Pole = g_aPlansza[LINIE[i][j][0]][LINIE[i][j][1]];  <<<----- na tą linie wpada bład
if (Pole != ZgodnePole)

A błąd mam taki

C:\Users\NEONET\Desktop\dupadupa\dupadupa\game.cpp|83|error: name lookup of 'i' changed for ISO 'for' scoping|

hcq0.png


Opublikowano

Macie to jest do 2 błędu

for (int j = 0; j < 3; ++j)
{
Pole = g_aPlansza[LINIE[i][j][0]][LINIE[i][j][1]];
if (Pole != ZgodnePole)
{
ZgodnePole = Pole;
uLiczbaZgodnychPol = 1;
}
else
++uLiczbaZgodnychPol;
}
g_StanGry = GS_WON;
return true;
unsigned uLiczbaZapelnionychPol = 0;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
if (g_aPlansza[i][j] != FLD_EMPTY)
++uLiczbaZapelnionychPol;
if (uLiczbaZapelnionychPol == 3*3)
{
g_StanGry = GS_DRAW;
return true;
}

hcq0.png


Opublikowano

for (int j = 0; j < 3; ++j)
{
Pole = g_aPlansza[LINIE[i][j][0]][LINIE[i][j][1]];
if (Pole != ZgodnePole)
{
ZgodnePole = Pole;
uLiczbaZgodnychPol = 1;
}
else
++uLiczbaZgodnychPol;
}

nie ma zadeklarowanej zmiennej i

Opublikowano

Teeraz to zgłupialem :) jak czytałem cały kurs c++ (chodzi mi o te kółko krzyżyk) totam nic nie było o zmiennej 'i'. Więc teraz to juz niewiem co mam zrobic

hcq0.png


Opublikowano

Pole = g_aPlansza[LINIE[i][j][0]][LINIE[i][j][1]];
		//^ta tu, nie zadeklarowałeś jej.

masz pętle for w której deklarujesz zmienną "j", którą zwiększasz z każdą iteracją, więc zrób podobną ze zmienną "i" (zawrzyj w nią tą pętle co masz, lub na odwrót).

Opublikowano

On tam ma pętlę, w której deklaruje int i

Boże, jakbym wiedział, że takie problemy z tego będą, to bym od razu ci poprawił te dwa błędy... Myślałem, że twórca tematu sam to ogarnie...

 

W każdym razie:

Używasz zmiennej i poza zasięgiem pętli for, w której została zadeklarowana.

 

for ( int i; ; ) {

 

 

}

std::cout << i ; // error: 'i' not declared in this scope

 

I to jest zgodne z aktualnym standardem (kiedyś zmieniło się w przeszłości, i było zupełnie inaczej w C, więc czasami takie kursy mogą mieć błędy).

 

No więc wystarczy machnąć:

 

int i = 0;

for ( ; ; )

{

}

std::cout << i;

 

Z tym, że musisz się jeszcze upewnić, że żadnych zmniennych zadeklarowanych w zasięgu pętli for nie będziesz używał gdzieś indziej ( gdyż ich żywotność jest ograniczona do pętli for ).

Ta sygnatura jest pusta.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...