Dec 24, 2015 at 7:10am UTC
(If other header or cpp files are necessary, I will provide them accordingly)
here is the compiler error I'm receiving:
Undefined symbols for architecture x86_64:
"TicTacToe::rungame()", referenced from:
_main in main-672692.o
"TicTacToe::TicTacToe()", referenced from:
_main in main-672692.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
here is my code:
header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#ifndef ____tictactoe__
#define ____tictactoe__
#include <iostream>
#include "player.h"
#include "cell.h"
#include "date.h"
using namespace std;
class TicTacToe
{
public :
TicTacToe();
TicTacToe(Player [],Player []);
void setplayer();
void Displayboard();
void makeMove();
bool checkWin();
bool validmove();
void chooseplayer();
bool validatebounds(int , int );
bool validatechoice(int , int );
void rungame();
void displayBlank();
void clearBoard();
void stats();
private :
static const int ROW = 3;
static const int COL = 3;
int currentplayer;
static const int DEFAULT_NUM_PLAYERS = 2;
Player p[DEFAULT_NUM_PLAYERS];
Cell board[ROW][COL];
Date d;
int numGamesPlayed, turn;
};
#endif /* defined(____tictactoe__) */
cpp file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
#include "tictactoe.h"
#include "cell.h"
#include "date.h"
#include <iostream>
using namespace std;
int ROW = 3;
int COL = 3;
//Tic Tac Toe default constructor
TicTacToe::TicTacToe()
{
cout << "Welcome to my TicTacToe Program!" << endl;
turn=0;
currentplayer=0;
numGamesPlayed = 0;
d.input();
}
//Function to input player information and assign a marker to each player
void TicTacToe::setplayer()
{
cout << "Player 1 please input your information:\n" ;
p[0].input();
cout << endl;
cout << "Player 2 please input your information:\n" ;
p[1].input();
cout << p[currentplayer].gethandle() <<", what marker would you like to use? " << endl;
cout << "\t1. X" << endl << "\t2. O\n" ;
int choice;
cin >> choice;
switch (choice) {
case 1:
p[0].setmarker('X' );
p[1].setmarker('O' );
break ;
case 2:
p[0].setmarker('O' );
p[1].setmarker('X' );
break ;
default :
p[0].setmarker('X' );
p[1].setmarker('O' );
break ;
}
}
//Function that chooses which player's turn it is
void TicTacToe::chooseplayer()
{
if (turn%2==0)
{
currentplayer = 0;
}
else
currentplayer = 1;
}
//Display board function
void TicTacToe::Displayboard(){
int i = 0;
int r = 0;
for ( i = 0; i < COL; i++)
{
for (r = 0; r < ROW; r++)
{
if (r < ROW-1)
{
cout << board[i][r].getmarker() << " | " ;
}
else
{
cout << board [i][r].getmarker() << endl;
if (i !=COL-1){
cout << "---------------" ;
cout << endl;
}
else
cout << endl;
}
}
}
}
//Function to allow player to make move
//Function validates if the choice is within the bounds and if it has chosen already
void TicTacToe::makeMove(){
int x,y;
do {
cout << p[currentplayer].gethandle() << ", please enter the space of the coordinates (ROW,COL)" << endl;
cin >> x >> y;
}while (!(validatebounds(x, y)&&validatechoice(x, y)));
board[x-1][y-1].setmarkers(p[currentplayer].getmarker());
}
//Validation functions
bool TicTacToe::validatebounds(int x, int y)
{
bool validate = true ;
if (x<0||x>COL)
{
validate = false ;
cout << "Your entry was invalid" << endl;
}
if (y<0||y>ROW)
{
validate = false ;
cout << "Your entry was invalid" << endl;
}
return validate;
}
bool TicTacToe::validatechoice(int x, int y)
{
bool validate = true ;
if (board[x-1][y-1].getmarker() == 'O' || board[x-1][y-1].getmarker()== 'X' )
{
validate = false ;
cout << "Please choose another space, this one has been taken" << endl;
}
return validate;
}
//Function to check for wins
bool TicTacToe::checkWin()
{
bool winner(false );
int x;
//Checks for wins on diagonals
if (board[0][0].getmarker() != ' ' && board[0][0].getmarker() == board[1][1].getmarker() && board[0][0].getmarker() == board[2][2].getmarker())
return winner = true ;
else if (board[ROW][0].getmarker() != ' ' && board[ROW][0].getmarker() == board[1][1].getmarker() && board[ROW][0].getmarker() == board[0][ROW].getmarker())
return winner = true ;
//Checks for wins in rows
for (x = 0; x < ROW; x++){
if (board[x][0].getmarker() != ' ' && board[x][0].getmarker() == board[x][1].getmarker() && board[x][0].getmarker() == board[x][2].getmarker())
return winner = true ;
}
//Checks for wins in columns
for (x = 0; x < COL; x++)
{
if (board[0][x].getmarker() != ' ' && board[0][x].getmarker() == board[1][x].getmarker() &&board[1][x].getmarker() && board [0][x].getmarker() == board[2][x].getmarker())
return winner = true ;
}
return (winner);
}
//Run game function
void TicTacToe::rungame()
{
char ans;
bool validate = false ;
bool endgame = false ;
setplayer();
do {
displayBlank();
do {
makeMove();
Displayboard();
turn++;
if (turn==9)
{
validate = true ;
if (!checkWin())
{
cout << "TIE" << endl;
}
}
if (turn>4)
{
if (checkWin())
{
validate=true ;
cout << p[currentplayer].gethandle() << " wins!" << endl;
p[currentplayer].increasewins();
}
}
chooseplayer();
}while (!validate);
numGamesPlayed++;
clearBoard();
stats();
turn=0;
cout << "Would you like to play again?(Y/N)" ;
cin >> ans;
if (ans=='n' || ans=='N' )
{
endgame=true ;
clearBoard();
}
}while (!endgame);
}
//Initializes board to blank
void TicTacToe::displayBlank()
{
for (int x=0; x<COL;x++){
for (int y = 0; y<ROW; y++) {
if (y==ROW-1)
{
cout << " " ;
}
else
cout << " " << "|" ;
}
if (x==COL-1) {
cout << endl;
}
else
{
cout << endl << "-----------------" << endl;
}
}
}
//Function to clear board after game has ended
void TicTacToe::clearBoard()
{
for (int x = 0; x < COL; x++)
for (int y = 0; y < ROW; y++)
board[x][y].setmarkers(' ' );
}
//Function to display end stats for game
void TicTacToe::stats()
{
cout << "Games Played: " << numGamesPlayed << endl;
}
main driver:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <iostream>
#include "player.h"
#include "cell.h"
#include "tictactoe.h"
using namespace std;
int main()
{
TicTacToe t;
t.rungame();
}
Last edited on Dec 24, 2015 at 7:29am UTC
Dec 24, 2015 at 9:05am UTC
This isn't a compiler error. It's a link error.
It means that at the point when your linker is trying to stick all your compiled files together, some things are missing. In this case, the linker can't find all those functions in your larger cpp file, in any of the compiled object files it has been told to stick together.
The problem is one of these:
1) Your build command line is missing a file (if you're doing the build yourself).
2) If you're using an IDE, you haven't put everything in the "project" or whatever your IDE calls collections of source code files.
3) You've installed bad/conflicting versions of compilers/linkers and they're not working well together
While I'm here, I see you've put using namespace std;
in a header file. This is a very very very bad idea indeed and you shouldn't do it.
Last edited on Dec 24, 2015 at 9:06am UTC
Dec 24, 2015 at 3:01pm UTC
To be more specific, it does not appear that you compiled tictactoe.cpp.
main() makes two references to your class.
Line 10: it calls TicTacToe's constructor. TicTacToe::TicTacToe()
Line 11: it calls TicTacToe::rungame().
These are exactly the two functions that the linker can not find.
Both exist in your .cpp file, so the only conclusion is that the linker did not find tictactoe.o (the object file from the compile of the .cpp file). This could be for one of several reasons:
1) the .cpp file has errors and did not produce an object file
2) the object file in the wrong place
3) the .o file did not get included in the list of files needed to produce an executable.