• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Pliki nagłówkowe

Object Storage Arubacloud
0 głosów
155 wizyt
pytanie zadane 14 marca 2017 w C i C++ przez Niebieski_Zerg Użytkownik (610 p.)

Witam, robię pewien przykład zadań z kursu ,, Od zera do gier kodera", i mam pewien dylemat, otóż od kilku ładnych godzin zmagałem się z problemami takimi jak: nie widzi zmiennej extern, potem że nie działa jakiś plik, potem że nic nie widzi a teraz wyrzuca taki błąd : http://screenshot.sh/oux1GolufwkcV
Już nie wiem co mam z tym zrobić. Szukałem odpowiedzi na różnych forach i tych zagranicznych też ale nigdzie nie mogę znaleźć odpowiedniego rozwiązania problemu :p (Robię wszystko na dev-cpp)
Tu podaje cały kod
plik main.cpp

#include <iostream>
#include <ctime>
#include <conio.h>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include "game.h"

 using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

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;
	}
	return 0;
}

------------------

plik game.cpp

#include <iostream>
#include <ctime>
#include <conio.h>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include "game.h"

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

	SIGN g_AktualnyGracz;
       
bool StartGry()
{
	if (g_StanGry != GS_NOTSTARTED) return false;
	
	// losujemy gracza, który będzie zaczynał
	srand( 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(unsigned uNumerPola)
{
    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
    {
    	g_aPlansza[uY][uX] = static_cast<FIELD>(g_AktualnyGracz);
	}
    else
    return false;
    
    const int 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[i][j][0]][LINIE[i][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;
					}
			}
			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;
			}
			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[i][j] == FLD_EMPTY)
			// numer pola
			std::cout << i * 3 + j + 1;
		else
			// tutaj wyświetlamy kółko lub krzyżyk... ale jak? :)
			std::cout << static_cast<char>(g_aPlansza[i][j]);
		}
		// 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;
}

	
	

----------------------

plik game.h

// zmienne odpowiedzialne za prawidłowe działanie funkcji

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

enum FIELD 
     { FLD_EMPTY,
   	 FLD_CIRCLE = SGN_CIRCLE,
	 FLD_CROSS = SGN_CROSS };
	 
    enum GAMESTATE { GS_NOTSTARTED, GS_MOVE, GS_WON, GS_DRAW };
    
    extern GAMESTATE g_StanGry;
	GAMESTATE g_StanGry = GS_NOTSTARTED;	    
// prototypy funkcji
//------------------
// rozpoczęcie gry
bool StartGry();
// wykonanie ruchu
bool Ruch(unsigned);
// rysowanie planszy
bool RysujPlansze();

 

1 odpowiedź

0 głosów
odpowiedź 14 marca 2017 przez adrian17 Ekspert (344,860 p.)
    extern GAMESTATE g_StanGry;
    GAMESTATE g_StanGry = GS_NOTSTARTED;  

Definicja idzie do jednego .cpp.

Brakuje #pragma once lub include guardów w nagłówku.

> undefined reference to StartGry()

Na pewno kompilujesz game.cpp? Pokaż pełny screenshot.

komentarz 14 marca 2017 przez Niebieski_Zerg Użytkownik (610 p.)
http://screenshot.sh/m7zEijit04A0t taki Komunikat z game.cpp

http://screenshot.sh/oB4JsYR104UZb Komunikat  z main.cpp

http://screenshot.sh/m7uq9wiI6kznz Komunikat z game.h

http://screenshot.sh/m1Ns5soDdLgFX Komunikat po próbie uruchomienia programu
komentarz 14 marca 2017 przez adrian17 Ekspert (344,860 p.)
to... ma coraz mniej sensu. Z jakiegoś powodu kompilujesz main.cpp i game.cpp jako dwa niezależne programy...?

Polecam przerzucić się z dev-cpp na Code::Blocks lub VS.
komentarz 14 marca 2017 przez Niebieski_Zerg Użytkownik (610 p.)
Code::bloks mi nie działa. a co do kompilowania to dałem każdą możliwą opcję żeby nie było. :p A u ciebie owy program działa?
komentarz 14 marca 2017 przez adrian17 Ekspert (344,860 p.)

Nieważne czy działa czy nie, kompilujesz to w jakiś zupełnie dziwaczny sposób. Najlepiej stwórz projekt od nowa i przekopiuj tam kod.

Code::bloks mi nie działa

To Windows 98? Bo inaczej nie widzę powodu by cokolwiek tam miało "nie działać".

komentarz 14 marca 2017 przez Evelek Nałogowiec (28,960 p.)
Wtrącę: Przypuszczam, że to jest raczej popularny problem z dołączeniem kompilatora, bo Code::Blocks zainstalować to najmniejszy problem w tym wszystkim.
komentarz 15 marca 2017 przez Niebieski_Zerg Użytkownik (610 p.)
edycja 15 marca 2017 przez Niebieski_Zerg
Robiłem w code::blocku kilka miesięcy więc kompilator działa, często w szkole dodawałem, ale potem się coś podziało i tyle. A co do programu wiecie jak to naprawić bo na VS też wyskakuje błąd http://screenshot.sh/m2aJhKgER0fSN. http://www.elektroda.pl/rtvforum/topic1398794.html w komentarzu znajduje się plik z ową grą, która po skompilowaniu ma ten sam problem. inni mówią że im działa a niektórzy mówią że nie.
komentarz 15 marca 2017 przez adrian17 Ekspert (344,860 p.)

A co do programu wiecie jak to naprawić bo na VS też wyskakuje błąd http://screenshot.sh/m2aJhKgER0fSN

Wystarczyło stworzyć pusty projekt lub wyłączyć prekompilowane nagłówki lub, jak proponował, dodać `#include "stdafx.h"`...

komentarz 15 marca 2017 przez Niebieski_Zerg Użytkownik (610 p.)
Dodałem nagłówek (zapomniałem zedytować ) też nie działało. A czy możesz sam włączyć ten program i sprawdzić czy tobie działa? i podesłać możliwe rozwiązanie?
komentarz 15 marca 2017 przez adrian17 Ekspert (344,860 p.)
Wrzuciłem pliki, poprawiłem dwa wspomniane na górze błędy i normalnie je skompilowałem - bez problemu. Coś cały czas źle robisz w IDE.

Podobne pytania

0 głosów
1 odpowiedź 67 wizyt
pytanie zadane 29 marca 2020 w C i C++ przez zosia15 Nowicjusz (120 p.)
0 głosów
1 odpowiedź 250 wizyt
0 głosów
0 odpowiedzi 137 wizyt
pytanie zadane 1 lipca 2019 w C i C++ przez Tomasz Kolk Użytkownik (750 p.)

92,550 zapytań

141,394 odpowiedzi

319,522 komentarzy

61,935 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...