Trouble with accessing friend

Hello,
I'm trying to make a simple tic-tac-toe game and am having trouble with using 'friend'. During the computer's move I want the computer's class to access and modify the board array in the 'Gameboard' class.

I have declared the 'Computer' class a 'friend' in the 'Gameboard' header. However on compile a number of errors occur:

In computer cpp:
1
2
3
4
5
line 27 'board' was not declared in this scope
line 28 invalid use of member (did you forget the '&'?)
line 35 'board' has not been declared
line 35 Prototype for 'bool Computer::validateMove(int, char, char, int)' does not match any class in computer
line 41'board' was not declared in this scope


I've spent ages renaming and rearranging code but I'm guessing that there's a fundamental concept I'm missing. Any help would be great thanks.

Computer header.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef COMPUTER_H
#define COMPUTER_H

#include "Gameboard.h"

class Computer
{
public:
	Computer(char);
	void print();
	char compMove(char, char);
private: 
	char piece;
	char move;
	int sqr;
	bool validateMove(int, char, char, Gameboard board);
};

#endif 


Computer cpp

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
#include <iostream>
#include <string>
#include <time.h>

using namespace std;

#include "Computer.h"

Computer::Computer(char compPiece)
{
	piece = compPiece;
	srand(time(0));

}

void Computer::print()
{
	cout << "\nOk CPU... so this works" << endl;
}

char Computer::compMove(char x, char o)
{
	do
	{
		sqr = (rand()%9)+1;
		move = '0'+sqr;
		validateMove(move,x,o,board);
	}while(validateMove == false);
	
	cout << "computer to move to: " << move << endl;
	return move;

}

bool Computer::validateMove(int move, char xCk, char oCk, board)
{
	for(int i = 0; i < 3; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			if((board[i][j] == xCk) || (board[i][j] == oCk))
			{
				return false;
			}
			else 
			{
				return true;
			}
		}
	}

}


Gameboard header.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#ifndef GAMEBOARD_H
#define GAMEBOARD_H

class Gameboard
{
	friend class Computer;
public:
	Gameboard();
	void printBoard();
	void makeMove(char, char);
private:
	char board[3][3];
	
};

#endif 


Gameboard cpp.

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
#include <iostream>
#include <string>

using namespace std;

#include "Gameboard.h"

Gameboard::Gameboard()
{
	int k = 1;
	for(int i = 0; i < 3; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			char setNum = '0' + (j+k);
			board[i][j] = setNum;
		}
		k+=3;	
	}
}
		
void Gameboard::printBoard()
{
	cout << "\t-------------\n";
	cout << "\t| "<<board[0][0]<<" | "<<board[0][1]<<" | "<<board[0][2]<<" |\n";
	cout << "\t|---|---|---|\n";
	cout << "\t| "<<board[1][0]<<" | "<<board[1][1]<<" | "<<board[1][2]<<" |\n";
	cout << "\t|---|---|---|\n";
	cout << "\t| "<<board[2][0]<<" | "<<board[2][1]<<" | "<<board[2][2]<<" |\n";
	cout << "\t-------------\n"<< endl;
}

void Gameboard::makeMove(char move, char piece)
{
	
	for(int i = 0; i < 3; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			if(board[i][j] == move)
			{
				board[i][j] = piece;
			}
		}
	}
	
}


Main.

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
#include <iostream>
#include <string>
#include <cctype>

#include "Player.h"
#include "Computer.h"
#include "Gameboard.h"

using namespace std;

const char x = 'X';
const char o = 'O';
const char noOne = 'N';
const char tie = 'T';
void const instructions();
void pieceAsk();
char onePiece;
char compPiece;
char turn;
char winner;
char thisMove;
char test;


int main() 
{

	Gameboard boardObj;
    instructions();
	boardObj.printBoard();
	pieceAsk();
	Player playerOne(onePiece);
	Computer comp(compPiece);
	winner = noOne;
	turn = x;
	
	while(winner == noOne)
	{
	
		if(turn == onePiece)
		{
			playerOne.print();
			//thisMove = playerOne.playerMove();
			boardObj.makeMove(playerOne.playerMove(), onePiece);
			boardObj.printBoard();
			turn = compPiece;

			
		}
		else if(turn == compPiece)
		{
			boardObj.makeMove(comp.compMove(x,o), compPiece);
			boardObj.printBoard();
			turn = onePiece;
		}
		else
		{
			printf("Something's gone wrong");
		}
	}
	
    return 0;
}

void const instructions()
{
	cout << "\nXOXOXOX Noughts and Crosses Extreme XOXOXOX" << endl;
	cout << "\nRules: Match three in a row vertically, horizontally or diagonally\n"<<endl;
}

void pieceAsk()
{
	char choice;
	cout << "Would you like to be Os or Xs (Enter O or X): ";
	cin >> choice;
	
	while((choice != o) && (choice != x))
	{
		cout << "Please enter a valid answer (X or O): ";
		cin >> choice;
	}
		
	if(choice == x)
	{
		cout << "\nYou will play as X's\n";
		onePiece = x;
		compPiece = o;
	}
	else if(choice == o)
	{
		cout << "\nYou will play as O's\n";
		onePiece = o;
		compPiece = x;
	}
	else
	{
		cout << "\nERROR. DEFAULT SETTING: You will play as X's\n";
		onePiece = x;
		compPiece = o;
	}
}



line 27: when you make class A a friend of class B, A can access private members of B object. You do need to have a B class object. board is a member of GameBoard class. You cannot access it without a GameBoard object. The right way would be my_board.board. You could either make boardObj a global variable (not suggested) or add a GameBoard& to Computer class.

line 28: validateMove is a function, not a variable. The right way would be }while(validateMove(/*some arguments*/) == false);

line 35: when you put something in argument list you must specify its class (GameBoard in this case)
line 35: since compiler couldn't understand your arguments it cannot find appropriate function declared in Computer class and complains about it.

line 41: this is caused by errors on line 35. I can't say what is the compiler thinking though..
Last edited on
Thanks for the reply... your suggestion fixed the 'validateMove' problem...

I'm still unsure on the 'friend' problem...

I've changed a few functions and tried to use the boardObj as an argument in the compMove function.

In 'main' I changed
boardObj.makeMove(comp.compMove(x,o), compPiece);
to
boardObj.makeMove(comp.compMove(x,o,boardObj), compPiece);

I now only get the following error on lines 7 and 8 in the Computer cpp code that follows:
No matching function for call to 'Computer::validateMove(char&,char&, char&, char[3][3])'

What needs to be done to fix this? Thanks.


Computer header

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef COMPUTER_H
#define COMPUTER_H

#include "Gameboard.h"

class Computer
{
public:
	Computer(char);
	void print();
	char compMove(char, char, Gameboard &boardSet);
private: 
	char piece;
	char move;
	int sqr;
	bool validateMove(int, char, char, Gameboard &board);
};

#endif 


Computer cpp

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
char Computer::compMove(char x, char o, Gameboard &boardSet)
{
	do
	{
		sqr = (rand()%9)+1;
		move = '0'+sqr;
		validateMove(move,x,o,boardSet.board);
	}while(validateMove(move,x,o,boardSet.board) == false);
	
	cout << "computer to move to: " << move << endl;
	return move;

}

bool Computer::validateMove(int move, char xCk, char oCk,Gameboard& boardSet)
{
	for(int i = 0; i < 3; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			if((boardSet.board[i][j] == xCk) || (boardSet.board[i][j] == oCk))
			{
				return false;
			}
			else 
			{
				return true;
			}
		}
	}
}

Last edited on
This is because function expects Gameboard object, you give it Gameboard::board which is char[3][3]. Just change 'boardSet.board' to 'boardSet' since you want to pass the whole object and not only its member.

Nore: line 7 is useless. You're just calling the same function twice..
Cool... that works...

Thanks a lot hamsterman...
Topic archived. No new replies allowed.