Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

undefined reference to

Ostatnio zmodyfikowano 2013-07-08 12:40
Autor Wiadomość
Bimbol
Temat założony przez niniejszego użytkownika
undefined reference to
» 2013-07-08 01:09:18
Witam,
z pomocą pewnego kursu napisałem kółko i krzyżyk.

Jednakże nie kompiluje się.
Błędy:
http://imageshack.us/a/img580​/1979/ejb.png

obj\Debug\main.o||In function `main':|
C:\Users\Patryk Bieniek\Desktop\C++\PDF\OX\main.cpp|5|undefined reference to `StartGry()'|
C:\Users\Patryk Bieniek\Desktop\C++\PDF\OX\main.cpp|8|undefined reference to `RysujPlansze()'|
C:\Users\Patryk Bieniek\Desktop\C++\PDF\OX\main.cpp|9|undefined reference to `g_StanGry'|
C:\Users\Patryk Bieniek\Desktop\C++\PDF\OX\main.cpp|13|undefined reference to `Ruch(unsigned int)'|
C:\Users\Patryk Bieniek\Desktop\C++\PDF\OX\main.cpp|16|undefined reference to `g_StanGry'|
C:\Users\Patryk Bieniek\Desktop\C++\PDF\OX\main.cpp|16|undefined reference to `g_StanGry'|
||=== Build finished: 6 errors, 0 warnings (0 minutes, 0 seconds) ===|

Kod game.h:
C/C++
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <ctime>

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

// rozpoczęcie gry
bool StartGry();
// wykonanie ruchu
bool Ruch( unsigned );
// rysowanie planszy
bool RysujPlansze();

extern GAMESTATE g_StanGry;

#endif // GAME_H_INCLUDED

Kod main.cpp:
C/C++
#include "game.h"

int main()
{
    StartGry();
    while( true )
    {
        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();
    return 0;
}

Kod game.cpp:
C/C++
#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 } };

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

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

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 )
         g_aPlansza[ uY ][ uX ] = static_cast < FIELD >( g_AktualnyGracz );
    else return false;
   
    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
                 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;
}

Nie rozumiem dlaczego się czepia.
W przypadku usunięcia z game.h, extern GAMESTATE g_StanGry; czepia się tylko tego, że g_StanGry nie istnieje.
P-87227
MordiJC
» 2013-07-08 09:14:39
1. LINE nie ma typu.
2. Brak średnika na końcu linii if( g_StanGry == GS_NOTSTARTED )  return false (;)

Po poprawieniu tych błędów działa. Sprawdź, czy odpowiednio zapisałeś pliki i includy do nich.
P-87229
DejaVu
» 2013-07-08 09:30:01
Dodaj plik *.cpp do projektu.
P-87230
Bimbol
Temat założony przez niniejszego użytkownika
» 2013-07-08 12:40:33
Hmm.. nie przez te błędy nie działa. Coś mam z linkerem.
W projekcie są oba pliki .cpp

http://imageshack.us/a/img832​/5272/ep6p.png

Dobra poradziłem sobie.

Rozwiązanie: pliki game.h oraz game.cpp nie zostały dodane do linkera.
P-87242
« 1 »
  Strona 1 z 1