Can anyone lead me in the right direction to get this to work???

my << overload compiles fine...

ofstream& operator<<(ofstream& ofs, const GameBoard& b) //overloaded ofstream operator to save board & piece
{
    for (int row=0; row < b.size; row++) {
        for (int col; col < b.size; col++) {
            ofs << b.pieces[row][col].pType;
        }
    }
    return ofs;
};

I get an error trying to use it...

void GameBoard::PrintGametoFile()       

{
    ofstream outFile;
    outFile << *this;
}

error - error C2593: 'operator <<' is ambiguous

Edited 3 Years Ago by diafol: fixed formatting

This may be an issue.

for (int col; col < b.size; col++) {

Initialize col.

As far as the other error, let me try to find the rest of your code. (And functions don't end in a semicolon.)

[edit]The advice here is to have it the other way around -- to have the "operator<< call that printOn() method".

Is there a way to fix this so I don't have to create a new function? I attached my code to look at, if that helps...

Attachments
/*********************************************************
	TITLE:		GameBoard.cpp
	AUTHOR		Marcia Tritt
	PROJECT		Tic Tac Toe Game
	DUE DATE	27 June 2005
*********************************************************/
#include <string>
#include <fstream>
#include <iostream>
#include <iomanip>

#include "gameboard.h"
#include "gamepiece.h"

GameBoard::GameBoard()								// default constructor 3x3 board
:playType(1), size(3), maxMoves(9)
{
	pieces = new GamePiece*[size];					//instantiate row array pointers to col arrays 
	for (int i=0; i<size; i++) 
	{
		pieces[i]= new GamePiece[size];				// instatiate col arrays 
	}
}

GameBoard::GameBoard(int gameType, const int gSize) 
:playType(gameType), size(gSize)	
{
	maxMoves = size*size;
	pieces = new GamePiece*[size];					// instantiate row array 
	for (int i=0; i<size; i++) 
	{
		pieces[i]= new GamePiece[size];				// instantiate col arrays 
	}
}

GameBoard::~GameBoard()								// delete sequence 
{
	for (int i = 0; i < size; ++i) {
        delete[] pieces[i];
	}
	delete[] pieces;
}

GameBoard::GameBoard(const GameBoard& b)			// copy constructor
:playType(b.playType), size(b.size)
{
	if(&pieces!=NULL) {								// delete existing instances of row arrays 
		for (int i = 0; i < size; ++i) {
		    if(pieces[i]!=NULL) {
				delete[] pieces[i];
			}
		}
		delete[] pieces;							// delete existing instances of col arrays 
	}
	pieces = new GamePiece*[b.size];				// copy from b to new instance row array 
	for (int i=0; i<size; i++) 
	{
		pieces[i]= new GamePiece(*b.pieces[i]);		// copy from b to new instances of col arrays 
	}
}

GameBoard& GameBoard::operator=(const GameBoard& right)
{
	for (int i = 0; i < size; ++i) {				// destructor if existing 
        delete[] pieces[i];
	}
	delete[] pieces;

	const int size = right.size;
	playType = right.playType;
	
	maxMoves = size*size;
	pieces = new GamePiece*[size];
	for (i=0; i<size; i++) 
	{
		pieces[i]=new GamePiece[size];
	} return *this;
}

ostream& operator<<(ostream& os, const GameBoard& b) 
{
	for (int row=0; row < b.size; row++) {
		for (int col; col < b.size; col++) {
			os << setw(5) << b.pieces[row][col].pType;
		}
		cout << endl;
	}
	cout << endl << endl;
	return os;
}

ofstream& operator<<(ofstream& ofs, const GameBoard& b)	//overloaded ofstream operator to save board & piece
{
	for (int row=0; row < b.size; row++) {
		for (int col; col < b.size; col++) {
			ofs << b.pieces[row][col].pType;
		}
	}
	return ofs;
}

ifstream& operator>>(ifstream& ifs, GameBoard& b)		//overloaded ostream operator to input saved board & piece
{
	for (int row=0; row < b.size; row++) {
		for (int col; col < b.size; col++) {
			ifs >> b.pieces[row][col].pType;
		}
	}
	return ifs;
}

void GameBoard::PrintGametoFile()		

{
	ofstream outFile;
	outFile << *this;
}

void GameBoard::ReadGameFromFile()		
{
	bool fileOpen;
	ifstream inFile;
	inFile.open("tttgame.txt");
	if (!inFile) {
		cout << "Cannot open vile. \n";
		fileOpen=false;
	}
	else {
		fileOpen = true;
	}
	if (fileOpen) {
		GameBoard *board = new GameBoard();
		inFile >> board;
	}
}

void GameBoard::PlayerVsPlayer(GamePiece& p1, GamePiece& p2)
{
	int row; 
	int col;
	maxMoves = size*size;

	// Player 1 move
	for (int i; i <= maxMoves; i++) {
		cout << "Player 1 select row and column (between 0 and ";
		cout << size << ": " << endl;
		cout << "row: ";
		cin >> row;
		cout << endl << "column: ";
		cin >> col;
		cout << endl;

		// check for valid entry
		while (row > size || row < 0 || col > size || col < 0) {
			cout << "Invalid entry. Try again." << endl << "row: ";		
			cin >> row;
			cout << "column: ";
			cin >> col;
			cout << endl << endl;
		}

		AssignPlayer1(row, col, p1);
		RefreshBoard();
		CheckForWinner(p1, p2);

		// Player 2 move
		cout << "Player 2 select row and column (between 0 and ";
		cout << size << ": " << endl;
		cout << "row: ";
		cin >> row;
		cout << endl << "column: ";
		cin >> col;
		cout << endl;

		// check for valid entry
		while (row > size || row < 0 || col > size || col < 0) {
			cout << "Invalid entry. Try again." << endl << "row: ";		
			cin >> row;
			cout << "column: ";
			cin >> col;
			cout << endl << endl;
		}

		AssignPlayer2(row, col, p2);
		RefreshBoard();
		CheckForWinner(p1, p2);
	}
}	
	
void GameBoard::PlayerVsComputer(GamePiece& p1, GamePiece& p2)
{
	int row; 
	int col;
	maxMoves = size*size;

	// Player 1 move
	for (int i; i<=maxMoves; i++) {
		cout << "Player 1 select row and column (between 0 and ";
		cout << size << ": " << endl;
		cout << "row: ";
		cin >> row;
		cout << endl << "column: ";
		cin >> col;
		cout << endl;

		// check for valid entry
		while (row > size || row < 0 || col > size || col < 0) {
			cout << "Invalid entry. Try again." << endl << "row: ";
			cin >> row;
			cout << "column: ";
			cin >> col;
			cout << endl << endl;
		}

		AssignPlayer1(row, col, p1);
		RefreshBoard();
		CheckForWinner(p1, p2);
		
		// Computer move
		cout << "Computer's turn... " << endl;

		AssignComputer2(p2);
		RefreshBoard();
		CheckForWinner(p1, p2);
	}
}	
	
void GameBoard::ComputerVsComputer(GamePiece& p1, GamePiece& p2)
{
	maxMoves = size*size;

	// Computer 1 move
	AssignComputer1(p1);
	RefreshBoard();
	CheckForWinner(p1, p2);
		
	// Computer 2 move
	AssignComputer2(p2);
	RefreshBoard();
	CheckForWinner(p1, p2);
}
	
void GameBoard::PlayGame(GamePiece& p1, GamePiece& p2)
{
	switch (playType) {
	case 1:	
		// Player vs. Player
		cout << "Player 1 ('X'), enter name: ";
		cin >> p1.pName;
		cout << endl;
		p1.pType = 'X';

		cout << "Player 2 ('O'), enter name: ";
		cin >> p2.pName;
		cout << endl << endl;
		p2.pType = 'O';

		PlayerVsPlayer(p1, p2);
		break;

	case 2: 
		// Player vs. Computer
		cout << "Player 1 ('X'), enter name: ";
		cin >> p1.pName;
		cout << endl;
		p1.pType = 'X';

		cout << "Player 2 ('O') will be the computer ";
		cout << endl << endl;
		strcpy(p2.pName, "Computer");
		p2.pType = 'O';

		PlayerVsComputer(p1, p2);
		break;

	case 3: 
		// Computer vs. Computer
		cout << "Sit back and enjoy the show...";
		cout << endl << endl;
		strcpy(p1.pName, "Computer 1");
		p1.pType = 'X';

		strcpy(p2.pName, "Computer 2");
		p2.pType = 'O';
	
		ComputerVsComputer(p1, p2);
		break;

	default:
		break;
	}
}

void GameBoard::RefreshBoard()
{
	for (int row = 0; row < size; row++) {
		for (int col; col < size; col++) {
			cout << setw(5) << pieces[row][col].pType;
		} 
		cout << endl;
	}
	cout << endl << endl;
}

void GameBoard::AssignPlayer1(int row, int col, GamePiece& p1)
{
	while (&pieces[row][col].pType != NULL) {
		cout << "Space is already taken, tray again" << endl;
		cout << "row: ";
		cin >> row;
		cout << endl << "column: ";
		cin >> col;
		cout << endl << endl;
	}
	pieces[row][col].pType = p1.pType; 
}

void GameBoard::AssignPlayer2(int row, int col, GamePiece& p2)
{
	while (&pieces[row][col].pType != NULL) {
		cout << "Space is already taken, try again" << endl;
		cout << "row: ";
		cin >> row;
		cout << endl << "column: ";
		cin >> col;
		cout << endl << endl;
	}
	pieces[row][col].pType = p2.pType;
}


void GameBoard::AssignComputer1(GamePiece& p1)
{
	for (int row = 0; row < size; row++) {
		for (int col = 0; col<size; col++) {
			if (pieces[row][col].pType == 0) {
				pieces[row][col].pType = p1.pType;
			}
		}
	}
}

void GameBoard::AssignComputer2(GamePiece& p2)
{
	for (int row = 0; row < size; row++) {
		for (int col = 0; col<size; col++) {
			if (pieces[row][col].pType == 0) {
				pieces[row][col].pType = p2.pType;
			}
		}
	}
}

void GameBoard::CheckForWinner(GamePiece& p1, GamePiece& p2)
{
	maxMoves = size*size;
	bool matchX = false;
	bool matchO = false;
	
	//check X across
	for(int i = 0; i<=maxMoves; i++) {
		for (int row=0; row < size; row++) {
			for (int col=0; col < size; col++) {
				if (pieces[row][col].pType == 'X' && pieces[row][col].pType == pieces[row][col+1].pType) {
					matchX = true;
				}
			}
		}
	}

	//check O across
	for(i=0; i<=maxMoves; i++) {
		for (int row=0; row < size; row++) {
			for (int col=0; col < size; col++) {
				if (pieces[row][col].pType=='O' && pieces[row][col].pType==pieces[row][col+1].pType) {
					matchO = true;
				}
			}
		}
	}

	//check X down
	for(i=0; i<=maxMoves; i++) {
		for (int row=0; row < size; row++) {
			for (int col=0; col < size-1; col++) {
				if (pieces[row][col].pType=='X' && pieces[row][col].pType==pieces[row+1][col].pType) {
					matchX = true;
				}
			}
		}
	}

	//check O down
	for(i=0; i<=maxMoves; i++) {
		for (int row=0; row < size; row++) {
			for (int col=0; col < size-1; col++) {
				if (pieces[row][col].pType=='O' && pieces[row][col].pType==pieces[row+1][col].pType) {
					matchO = true;
				}
			}
		}
	}
	//check X diagonal left to right
	int row=0;
	int col=0;
	for(i=0; i<=maxMoves; i++) {
		if (pieces[row][col].pType=='X' && pieces[row][col].pType==pieces[row+1][col+1].pType) {
			matchX = true;
			row++;
			col++;
		}
	}

	//check X diagonal right to left
	row = size;
	col = size;
	for(i=0; i<=maxMoves; i++) {
		if (pieces[row][col].pType=='X' && pieces[row][col].pType==pieces[row-1][col-1].pType) {
			matchX = true;
			row--;
			col--;
		}
	}


	//check O diagonal left to right
	row=0;
	col=0;
	for(i=0; i<=maxMoves; i++) {
		if (pieces[row][col].pType=='O' && pieces[row][col].pType==pieces[row+1][col+1].pType) {
			matchO = true;
			row++;
			col++;
		}
	}

	//check O diagonal right to left
	row = size;
	col = size;
	for(i=0; i<=maxMoves; i++) {
		if (pieces[row][col].pType=='O' && pieces[row][col].pType==pieces[row-1][col-1].pType) {
			matchO = true;
			row--;
			col--;
		}
	}

	if (matchX==true) {
		cout << p1.pName << " wins!" << endl;
	}
	else {
		if (matchO==true) {
			cout << p2.pName << " wins!" << endl;
		}
		else {
				cout << "Nobdy wins!" << endl;
		}
		
	}
}	

void GameBoard::ResetGame() 
{
	for (int row=0; row<
/*********************************************************
	TITLE:		GameBoard.h
	AUTHOR		Marcia Tritt
	PROJECT		Tic Tac Toe Game - Summer 2005
	DUE DATE	27 June 2005
*********************************************************/

#ifndef GAMEBOARD_H
#define GAMEBOARD_H

#include <iostream>
#include <fstream>

#include "GamePiece.h"

using namespace std;
//********************************************************

class GameBoard
{
public:
		const int size;
		GamePiece **pieces;

	private:
		int playType;											// game play type (player vs player, etc.)
		int maxMoves;

	public:
		GameBoard();											// default constructor 3x3 board
		GameBoard(int playType, const int gSize);				// constructor
		~GameBoard();
		GameBoard(const GameBoard& b);							// copy constructor

		GameBoard& operator=(const GameBoard& right);			//assignment operator overload
		
		friend ostream& operator<<(ostream& os, const GameBoard& b);  //overloaded ostream operator to print board & piece
		friend ofstream& operator<<(ofstream& ofs, const GameBoard& b);  //overloaded ofstream operator to save board & piece
		friend ifstream& operator>>(ifstream& ifs, GameBoard& b);  //overloaded ostream operator to input saved board & piece	// Change - ifstream was misspelled
		
		void PrintGametoFile();		
		void ReadGameFromFile();	

		void PlayerVsPlayer(GamePiece& p1, GamePiece& p2);
		void PlayerVsComputer(GamePiece& p1, GamePiece& p2);
		void ComputerVsComputer(GamePiece& p1, GamePiece& p2);
		void PlayGame(GamePiece& p1, GamePiece& p2);

		void RefreshBoard();

		void AssignPlayer1(int row, int col, GamePiece& p1);
		void AssignPlayer2(int row, int col, GamePiece& p2);		
		void AssignComputer1(GamePiece& c1);
		void AssignComputer2(GamePiece& c2);

		void CheckForWinner(GamePiece& p1, GamePiece& p2);
		void ResetGame(); 

};

#endif

It looks to me like there are other things to fix first.

GameBoard& GameBoard::operator=(const GameBoard& right)
{
    for (int i = 0; i < size; ++i) {             // destructor if existing
        delete[] pieces[i];
    }
    delete[] pieces;

    const int size = right.size;
    playType = right.playType;

    maxMoves = size*size;
    pieces = new GamePiece*[size];
    for (i=0; i<size; i++)
    {
        pieces[i]=new GamePiece[size];
    } return *this;
}

Dead giveaway of MSVC6 -- use of broken scoping rules. Declare i above the first for loop.

for (int col; col < b.size; col++) {

You still have a lot of these errors -- using uninitialized counters.

And I get quite a few of these:

Error E2247 testpp.cpp 364: 'GamePiece::pType' is not accessible in function GameBoard::CheckForWinner(GamePiece &,GamePiece &)
Error E2228 testpp.cpp 364: Too many error or warning messages in function GameBoard::CheckForWinner(GamePiece &,GamePiece &)

void GameBoard::PrintGametoFile()       
{
    ofstream outFile;
    outFile << *this;
}

Just where do you expect this "output" to go?

Edited 3 Years Ago by diafol: fixed formatting

I'm sure there are a lot of errors ;) I haven't written anything for about 3-4 years and that was just the intro to c++ class...

I'm really struggling with the overloaded operators << and >> and how they are actually called by the other functions...

Is this sufficient for the ofstream??

{
	ofstream outFile;
	outFile.open("tttgame.txt");
	outFile << *this;
}

also, what compiler are you using?

Is this sufficient for the ofstream??

{
	ofstream outFile;
	outFile.open("tttgame.txt");
	outFile << *this;
}

Looks okay to me.

also, what compiler are you using?

BC55

what would cause this error??

error C2593: 'operator <<' is ambiguous

using the code above with the ofstream overload??

mt

Perhaps.

Sorry, I'm just not seeing it. I made a project in MSVC6 with these two files and its only complaint was this.

C:\Test\GAMEBOARD.CPP(133) : error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class GameBoard *' (or there is no acceptable conversion)

Simple fix:

inFile >> *board;

I've gotten that one, too... For some reason, that one's disappeared for me now... Not sure what's going on... :o

Thanks for all of the suggestions.. I really appreciate it!

mt

This article has been dead for over six months. Start a new discussion instead.