0
votes

I'm doing this snakes and ladders program with classes(MyGame, Board, Player, Dice). when I build it there is no compiler error, although I do get this in the console

"/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: /cygdrive/c/Users/joshu/AppData/Local/Temp/cczkm3rv.o: in function MyGame::play(Player*, Dice, Board)':c:\Users\joshu\Documents\VSC\OOP\src\MyGame.cpp:33: undefined reference toMyGame::getNumPlayers()' c:\Users\joshu\Documents\VSC\OOP\src/MyGame.cpp:33:(.text+0x370): relocation truncated to fit: R_X86_64_PC32 against undefined symbol MyGame::getNumPlayers()' /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: c:\Users\joshu\Documents\VSC\OOP\src/MyGame.cpp:40: undefined reference toBoard::getReward()' c:\Users\joshu\Documents\VSC\OOP\src/MyGame.cpp:40:(.text+0x483): relocation truncated to fit: R_X86_64_PC32 against undefined symbol Board::getReward()' /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: c:\Users\joshu\Documents\VSC\OOP\src/MyGame.cpp:42: undefined reference toBoard::getReward()' c:\Users\joshu\Documents\VSC\OOP\src/MyGame.cpp:42:(.text+0x4ec): relocation truncated to fit: R_X86_64_PC32 against undefined symbol Board::getReward()' /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../lib/libcygwin.a(libcmain.o): in functionmain':
/usr/src/debug/cygwin-3.1.4-1/winsup/cygwin/lib/libcmain.c:37: undefined reference to WinMain' /usr/src/debug/cygwin-3.1.4-1/winsup/cygwin/lib/libcmain.c:37:(.text.startup+0x7f): relocation truncated to fit: R_X86_64_PC32 against undefined symbolWinMain' collect2: error: ld returned 1 exit status <-----------------------searched line The terminal process terminated with exit code: 1

Terminal will be reused by tasks, press any key to close it."

When I try to debug I get a pop up saying that it couldnt find the skanes.exe (skanes.cpp is my main). I searched around in google and I got that was a liner error where the linker was not able to find such code in the .o files I don't even know where the .o files are although I do know that the task.json mentions .o files since I had to edit that file (with specific instructions of my professor) to make the debugger work.task.json and launcher.json are located in a folder called .vscode the .cpp and .h files for this program are in the same folder as .vscode as well. srry if don't add the needed files to get a solution is just that I have no idea wtf is the linker or the.o files so I don't know how they work.

Im using VS Code in case this is helful.

task.json

"version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "build",
            "command": "C:\\cygwin\\bin\\g++.exe",
            "args": [
                "-g",
                "${file}",
                "${fileDirname}\\MyGame.cpp",
                "${fileDirname}\\Board.cpp",
                "${fileDirname}\\Player.cpp",
                "${fileDirname}\\Dice.cpp",
                "-I",
                "${fileDirname}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "C:\\cygwin\\bin"
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}

launch.json

"version": "0.2.0",
    "configurations": [
        {
            "name": "g++.exe - Build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\cygwin\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build"
        }
    ]
}

MyGame.h

#ifndef MYGAME_H
#define MYGAME_H
#include "Board.h"
#include "Player.h"
#include "Dice.h"

#include "Player.h"
class MyGame
{

    protected:
        static const int numPlayers = 2;

    public:
        MyGame();
        ~MyGame();
        void start();
        void play(Player[], Dice, Board);  <-------Line 18
        void win(Player[]);                <-------Line 19
        int getNumPLayers();
};

#endif

MyGame.cpp

#include <iostream>
#include <vector>
#include "MyGame.h"
#include "Board.h"
#include "Player.h"
#include "Dice.h"

MyGame::MyGame()
{

}

MyGame::~MyGame()
{

}

void MyGame::start()
{
    Board brd;
    Player plyr[numPlayers];
    Dice dc;
    while (plyr[0].getPosition() != brd.getBoardSize() && plyr[1].getPosition() != brd.getBoardSize() && plyr[numPlayers - 1].getTurn() <= plyr[numPlayers - 1].getMaxTurn())
        play(plyr, dc, brd);

    win(plyr);

}

void MyGame::play(Player p[], Dice d, Board b)
{

        for (int i = 0; i < b.getBoardSize(); i++)
        {
            p[i].setPosition(d.roll());
            if(p[i].getPosition() > b.getBoardSize())
            {
                p[i].setPosition( (b.getBoardSize() - p[i].getPosition()) * 2 );
            }

            if (b.getType(p[i].getPosition()) == 'S')
                p[i].setPosition(-b.getSnakeLadderMove());
            else if (!b.getType(p[i].getPosition()) == 'L')
                p[i].setPosition(b.getSnakeLadderMove());

            p[i].setTurn();
        }

}

void MyGame::win(Player p[])
{
    for (int i = 0; i > numPlayers; i++) 
    {
        if (p[i].getPosition() == 30)
            std::cout << "Payer " << i << "wins!!" << std::endl;
    }
}

Board.h

#ifndef BOARD_H
#define BOARD_H
#include "MyGame.h"

class Board
{
    public:
        Board();
        ~Board();
        bool getType(int);
        int getNumeber(int);
        int getSnakeLadderMove();
        int getBoardSize();

    private:
        struct tile
        {
            char type;
            int number;
        };

        static const int boardSize = 30;
        static const int snakeLadderMove  = 3;
        tile place[boardSize];
};

#endif

Board.cpp

#include <stdlib.h>
#include <time.h>
#include "Board.h"

Board::Board()
{
    int count = 0;
    //initialize random seed to randomize snakes and ladders.
    srand(time(NULL));

    for (int k = 0; k < boardSize; k++)
    {
        place[k].type = 'N';
        place[k].number = k + 1;
    }

    while(count <= 3)
    {
        int index = rand() % boardSize + 1;

        while (index < 4)
        {
            index = rand() % boardSize + 1;
            // Makes sure it only replaces tiles with type = 'N'
            while(getType(index) != 'N')
                index = rand() % boardSize + 1;
        }

        place[index].type = 'S';

        while (index > boardSize - 3)
        {
            index = rand() % boardSize + 1;
            // Makes sure it only replaces tiles with type = 'N' 
            while(getType(index) != 'N')
                index = rand() % boardSize + 1;
        }   

        place[index].type = 'L';
        count++;

    }
}

Board::~Board()
{

}

int Board::getNumeber(int index)
{
    return place[index].number;
}

bool Board::getType(int index)
{
    return place[index].type;
}

int Board::getBoardSize()
{
    return boardSize;
}

Player.h

#ifndef PLAYER_H
#define PLAYER_H
#include "MyGame.h"
#include "Board.h"

class Player
{
    public:
        Player();
        ~Player();
        void setPosition(int);
        void setTurn();
        int getPosition();
        int getTurn();
        int getMaxTurn();
        int getNumPlayers();

    private:
        static const int maxTurn = 20;
        int position;
        int turn;
};

#endif

Player.cpp

#include <iostream>
#include "Player.h"
#include "Board.h"

Player::Player()
{

    /* 
        In order for the setters to work position and turn
        have to be equal to 1;
    */
    position = 1;
    turn = 1;
}

Player::~Player()
{

}

void Player::setPosition(int move)
{
    //Assumes constructor setted the value to 0
    position += move;
    ;
}

void Player::setTurn()
{
    //Assumes constructor sette4d the value to 0
    turn++;
}


int Player::getPosition()
{
    return position;
}

int Player::getTurn()
{
    return turn;
}

int Player::getMaxTurn()
{
    return maxTurn;
}

Dice.h

#ifndef CDADO_H_INCLUDED
#define CDADO_H_INCLUDED

#include <ctime>
#include <cstdlib>

class Dice{

    public:

        Dice();
        int roll();

};


#endif

Dice.cpp

#include <iostream>
#include "Dice.h"

using namespace std;


Dice::Dice()
{
    srand(time(0));
}


int Dice::roll()
{
    return  (rand() % 6) + 1;
}  

skanes.cpp //It was supposed to be snakes.

#include <iostream>
#include "MyGame.h"

using namespace std;

int main()
{
    MyGame snakes;

    snakes.start();
}
1

1 Answers

0
votes
int getNumPLayers();

The problem lies here . Linker tries to find its definition but couldn't find it . You have define it but not implemented it . A minimalistic definition will solve your problem.

By minimalistic i mean something like this in .cpp file.

int className::getNumPLayers(){}