Hola!
Cada vez que hago una clase en CodeBlocks y trato de incluirla en el archivo header de otra clase, el compilador me da un error de declaración múltiple en todos los métodos y no se a que se puede deber ya que estos solo son definidos una vez y todos los headers tienen al principio el #ifndef
Mi programa:
TicTacToeEngine.h
#ifndef TICTACTOEENGINE_H
#define TICTACTOEENGINE_H
#include <vector>
using namespace std;
class TicTacToeEngine
{
protected:
vector <unsigned short> board;
unsigned short state;
bool first__player_turn;
void Check();
public:
TicTacToeEngine(void);
TicTacToeEngine( const vector<unsigned short>);
TicTacToeEngine( const TicTacToeEngine&);
~TicTacToeEngine(void);
TicTacToeEngine operator=( const TicTacToeEngine&);
bool Movement(unsigned short);
vector<unsigned short> Board(void) const;
void Restart(void);
unsigned short State(void) const;
bool FirstPlayer(void) const;
};
#endif // TICTACTOEENGINE_H
TicTacToeEngine.cpp
#include "TicTacToeEngine.h"
//////////////////////////////////////////////////////////////////////////////////////////
// win checker
//checks if there is a line
void TicTacToeEngine::Check(void)
{
/////////////
//CHECK TIE//
/////////////
unsigned short i = 0;
while(i < 9 && board[i] != 0) {
if(i == 8) {
state = 3;
return;
}
i++;
}
//////////////////////
//CHECK FIRST PLAYER//
//////////////////////
//CHECK HORIZONTAL
//first line
if(board[0] == 1 && board[1] == 1 && board[2] == 1)
state = 1;
return;
//second line
if(board[3] == 1 && board[4] == 1 && board[5] == 1)
state = 1;
return;
//third line
if(board[6] == 1 && board[7] == 1 && board[8] == 1)
state = 1;
return;
//CHECK VERTICAL
//first line
if(board[0] == 1 && board[3] == 1 && board[6] == 1)
state = 1;
return;
//second line
if(board[1] == 1 && board[4] == 1 && board[7] == 1)
state = 1;
return;
//third line
if(board[2] == 1 && board[5] == 1 && board[8] == 1)
state = 1;
return;
//DIAGONAL LINES
//top right to bottom left
if(board[2] == 1 && board[4] == 1 && board[6] == 1 )
state = 1;
return;
//top left to bottom right
if(board[0] == 1 && board[4] == 1 && board[8] == 1 )
state = 1;
return;
///////////////////////
//CHECK second PLAYER//
///////////////////////
//CHECK HORIZONTAL
//first line
if(board[0] == 2 && board[1] == 2 && board[2] == 2 )
state = 2;
return;
//second line
if(board[3] == 2 && board[4] == 2 && board[5] == 2 )
state = 2;
return;
//third line
if(board[6] == 2 && board[7] == 2 && board[8] == 2 )
state = 2;
return;
//CHECK VERTICAL
//first line
if(board[0] == 2 && board[3] == 2 && board[6] == 2 )
state = 2;
return;
//second line
if(board[1] == 2 && board[4] == 2 && board[7] == 2 )
state = 2;
return;
//third line
if(board[2] == 2 && board[5] == 2 && board[8] == 2 )
state = 2;
return;
//DIAGONAL LINES
//top right to bottom left
if(board[2] == 2 && board[4] == 2 && board[6] == 2 )
state = 2;
return;
//top left to bottom right
if(board[0] == 2 && board[4] == 2 && board[8] == 2 )
state = 2;
return;
return;
}
//////////////////////////////////////////////////////////////////////////////////////////
// constructors & destructor
//normal constructor
TicTacToeEngine::TicTacToeEngine(void) :
state(0), first__player_turn(false)
{
//creates an array filled with 0 (empty board)
for(int i = 0; i < 9; i++) {
board.push_back(0);
}
}
//constructor with vector as argument
TicTacToeEngine::TicTacToeEngine( const vector<unsigned short> original_board) :
board(original_board), first__player_turn(false)
{
Check();
}
//copy constructor
TicTacToeEngine::TicTacToeEngine( const TicTacToeEngine& original) :
board( original.board), state(original.state),
first__player_turn(original.first__player_turn) {}
TicTacToeEngine::~TicTacToeEngine(void) {}
//////////////////////////////////////////////////////////////////////////////////////////
// operator =
TicTacToeEngine TicTacToeEngine::operator=( const TicTacToeEngine& original)
{
board = original.board;
state = original.state;
first__player_turn = original.first__player_turn;
return *this;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Movement method
bool TicTacToeEngine::Movement(unsigned short place)
{
//if the place is not between 0 and 8 or occupied or if the game has finished returns false
if( place < 0 || place > 8 || board[place] != 0 || state != 0)
return false;
//else the place in the board is filled
if(first__player_turn) {
board[place] = 1;
}
else {
board[place] = 2;
}
//check if the game has ended
Check();
first__player_turn = !first__player_turn;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Return board method
vector<unsigned short> TicTacToeEngine::Board(void) const
{
return board;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Restart method
void TicTacToeEngine::Restart(void)
{
//restarts the board array with all elements at 0
board.clear();
for(int i = 0; i < 9; i++) {
board.push_back(0);
}
//restarts game data
state = 0;
first__player_turn = true;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Returns true if the game has finished
unsigned short TicTacToeEngine::State(void) const
{
return state;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Returns true if it is the turn of the first player
bool TicTacToeEngine::FirstPlayer(void) const
{
return first__player_turn;
}
//////////////////////////////////////////////////////////////////////////////////////////
TicTacToe.h
#ifndef TICTACTOE_H
#define TICTACTOE_H
#include <iostream>
#include <windows.h>
#include "TicTacToeEngine.h"
using namespace std;
class TicTacToe : public TicTacToeEngine
{
void Graphic(unsigned short);
public:
TicTacToe(void);
bool GraphicMovement(void);
void Play(void);
};
/*
base class methods:
TicTacToeEngine(void);
TicTacToeEngine( const vector<unsigned short>);
TicTacToeEngine( const TicTacToeEngine&);
~TicTacToeEngine(void);
TicTacToeEngine operator=( const TicTacToeEngine&);
bool Movement(unsigned short);
vector<unsigned short> Board(void) const;
void Restart(void);
unsigned short State(void) const;
bool FirstPlayer(void) const;
*/
#endif // TICTACTOE_H
TicTacToe.cpp
#include "TicTacToe.h"
//////////////////////////////////////////////////////////////////////////////////////////
// constructors & destructor
//normal constructor
TicTacToeEngine::TicTacToeEngine(void) :
state(0), first__player_turn(false)
{
//creates an array filled with 0 (empty board)
for(int i = 0; i < 9; i++) {
board.push_back(0);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// Graphic Movement
void TicTacToe::Graphic(unsigned short i)
{
if(board[i] == 0) {
cout << " ";
}
if(board[i] == 1) {
cout << "x";
}
if(board[i] == 2) {
cout << "O";
}
}
bool TicTacToe::GraphicMovement(void)
{
system("CLS");
cout << endl << endl;
cout << " "; Graphic(0); cout << " | "; Graphic(1); cout << " | "; Graphic(2); cout << endl;
cout << " ------------" << endl;
cout << " "; Graphic(3); cout << " | "; Graphic(4); cout << " | "; Graphic(5); cout << endl;
cout << " ------------" << endl;
cout << " "; Graphic(6); cout << " | "; Graphic(7); cout << " | "; Graphic(8); cout << endl;
cout << endl << endl;
cout << "Movimiento del jugador";
if(first__player_turn)
cout << " 1: ";
if(!first__player_turn)
cout << " 2: ";
unsigned short movement;
bool moved;
cin >> movement;
moved = Movement(movement);
return moved;
}
//////////////////////////////////////////////////////////////////////////////////////////
//Just play
void TicTacToe::Play(void)
{
while(state == 0) {
GraphicMovement();
}
cout << endl << endl << "End of the game." << endl << endl << "Result: ";
if(state == 1) {
cout << "First player has won." << endl << endl;
}
if(state == 2) {
cout << "Second player has won." << endl << endl;
}
if(state == 3) {
cout << "Tie" << endl << endl;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
Estoy tiempo sin tocar c, pero si no recuerdo mal, el problema está cuando extiendes la clase TicTacToeEngine. Hay varias soluciones, una rápida es que definas las funciones de la clase TicTacToeEngine, en la cabecera empleando métodos inline.