Sign in to follow this  
sheep19

How can I make a function to return two values?

Recommended Posts

Hello, I have this code:
bool checkWin ()
{

}

int main()
{
	bool winsP1, winsPC;

	/*
	I want to return the first as true and the second as false :-
        I don't want to have: winsP1 = checkWin(); winsPC = !checkWin();
	*/
	
	system ("PAUSE");
	return 0;
}

Thanks in advance!!

Share this post


Link to post
Share on other sites
C and C++ can't return two values. You can put them together as an std tuple, or pass them in by reference and then change the values in the function. Or make a structure / class that holds both the values.

Share this post


Link to post
Share on other sites
There are a few options:


  1. Make a pair

    std::pair<bool, bool>checkwin( )
    {
    // this syntax may not be exactly right
    return std::pair<bool, bool> value(true, false);
    }

  2. Make a custom struct

    struct Result
    {
    bool p1win;
    bool p2win;
    };

    Result checkwin( )
    {
    Result res;
    res.p1win = true; res.p2win = false;
    return res;
    }

  3. Pass result as reference parameters and change them

    void checkwin(bool& p1win, bool& p2win)
    {
    p1win = true;
    p2win = false;
    }

  4. Use a data type that encompasses the two you need to return. Obvioulsy not a general strategy like the others, but can be used in this example.

    enum Result
    {
    P1_WIN,
    P2_WIN,
    NOBODY_WINS
    };

    Result checkwin()
    {
    return P1_WIN;
    }

  5. Use a better language :)



Of these, the only one I really don't like is #3.

Share this post


Link to post
Share on other sites
For completeness:


6. Use individual bits to represent player state
   enum Won
{
NONE = 0,
P1 = 1,
P2 = 2
};

unsigned int checkwin()
{
// both win
return P1 | P2;

// player 1 wins
return P1;

// player 2 wins
return P2;

// nobody wins
return NONE;
}

Share this post


Link to post
Share on other sites
you can make like this:


void checkWin(int *ret1,int *ret2) {
(*ret1) = 1234;
(*ret2) = 5678;
};

void main() {
int value1,value2;
checkWin(&value1,&value2);
printf("%d %d values now!",value1,value2);
};

Share this post


Link to post
Share on other sites
Quote:
Original post by sheep19
I don't want to have: winsP1 = checkWin(); winsPC = !checkWin();


Why not? If you write a function that checks if a player (given as an argument) has won, and call it as above, your intentions are much clearer (so if you come back to your code later, it'll take less time to understand) and if you ever want to add more players, you don't have to rewrite that function.

However, if 'winsP1 == !winsPC', then there is no need to call that function twice (or to return two values), as you can simple do the following: 'winsP1 = playerWin(); winsPC = !winsP1;'

Share this post


Link to post
Share on other sites
Provided winsP1 == !winsPC always holds true then I'm completely with Captain P on this.
Don't have the function return both values, have it return just one, then call it once and invert the value for the other variable.

Not only is this clearer to read and understand, it's also easier to code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
Quote:
Original post by sheep19
I don't want to have: winsP1 = checkWin(); winsPC = !checkWin();


Why not? If you write a function that checks if a player (given as an argument) has won, and call it as above, your intentions are much clearer (so if you come back to your code later, it'll take less time to understand) and if you ever want to add more players, you don't have to rewrite that function.

However, if 'winsP1 == !winsPC', then there is no need to call that function twice (or to return two values), as you can simple do the following: 'winsP1 = playerWin(); winsPC = !winsP1;'


This was an example. I'm doing AI for my TicTacToe game. It doesn't mean that when
the player doesn't win that the computer wins (I check for it between every turn).

I will use the one that wanMaster suggested, as it's what I want. (this is going to be used to test if a node is a winning one. That's why I don't want to pass the values by reference.

Thanks everyone for your replies!

Share this post


Link to post
Share on other sites
I'd create an object pass it to the function by reference then the function can modify the two values that can be accessed by another function.


class ob{
bool winsP1;
bool winsPC;
public:
get_winsP1() return winsP1;
get_winsPC() return winsPC;
set_winsP1(bool x) winsP1 = x;
set_winsPC(bool y) winsPC = y;
}

int function1(ob &ob1){
//set or get winsP1 and winsPC as needed
return 0;
}

int main{
ob ob1;
function1(ob1);
return 0;
}

Share this post


Link to post
Share on other sites
That's it:


#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

const char PLAYER_SYMBOL = 'X';
const char PC_SYMBOL = 'O';
const char DEFAULT_SYMBOL = '-';

class TicTacToe
{
private:
vector <int> freeNodes; // the free nodes
vector <int> usedNodes; // the used nodes
char board [3] [3]; // set the board

public:
void setBoard () // set the board to empty
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board [i] [j] = '-';
}
}
}

void setFreeNodes ()
{
for (int i = 1; i <= 9; i++)
{
freeNodes.push_back (i);
}
}

void printBoard () // print the board on the screen
{
cout << "\n";
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << board [i] [j] << " ";
}
cout << "\n";
}
}
int getNode ()
{
int node;
cout << "\n" << "Enter a number from 1-9: ";
cin >> node;
return node;
}
bool checkInput (int node)
{
vector <int>::iterator it;

for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
if (node == *it)
{
return true;
}
}
cout << "\n" << "Invalid input.";
return false;
}
void applyInputToBoard (int node, bool playsP1, bool playsPC)
{
int i, j;
if (node % 3 != 0)
{
i = node / 3;
j = node % 3 - 1;
}
else
{
i = node / 3 - 1;
j = 2;
}

if (playsP1 == true)
board [i] [j] = PLAYER_SYMBOL; // ('X')
else
board [i] [j] = PC_SYMBOL; // ('O')
}
void undoInputToBoard (int node) // undo the pc's move (see pcNode)
{
int i, j;
if (node % 3 != 0)
{
i = node / 3;
j = node % 3 - 1;
}
else
{
i = node / 3 - 1;
j = 2;
}

// undo the move
board [i] [j] = DEFAULT_SYMBOL; // ('-')
}
void addRemoveNodes (int node)
{
usedNodes.push_back (node); // add the node in usedNodes
sort (usedNodes.begin(), usedNodes.end() );

//remove the node from freeNodes
int position = 0;
vector <int>::const_iterator it;
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
if (*it == node)
{
break;
}

position ++; // position is the position of the number (node) in the vector
}

/*when (*it = node), position isn't increased, because it breaks the loop. But that doesn't matter because when erase, I have to delete -1
because it starts from the the first element. position is already -1 so I don't have to subtract anything.
eg it should have been "freeNodes.erase (freeNodes.begin() + position - 1);", but position is -1 from the
node's position, so, it's ok.*/


freeNodes.erase (freeNodes.begin() + position);
sort (freeNodes.begin(), freeNodes.end() );
}
int checkWin ()
{
enum Won
{
none = 0,
winsP1 = 1,
winsPC = 2
};

//horizontal
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i] [j] != DEFAULT_SYMBOL && board [i] [j+1] != DEFAULT_SYMBOL && board [i] [j+2])
{
if (board [i] [j] == board [i] [j+1])
{
if (board [i] [j] == board [i] [j+2])
{
if (board [i] [j] == PLAYER_SYMBOL)
return winsP1;
else
return winsPC;
}
}
}
}
}

//vertical
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i] [j] != DEFAULT_SYMBOL && board [i+1] [j] != DEFAULT_SYMBOL && board [i+2] [j])
{
if (board [i] [j] == board [i+1] [j])
{
if (board [i] [j] == board [i+2] [j])
{
if (board [i] [j] == PLAYER_SYMBOL)
return winsP1;
else
return winsPC;
}
}
}
}
}

//diagonal
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i] [j] != DEFAULT_SYMBOL && board [i+1] [j+1] != DEFAULT_SYMBOL && board [i+2] [j+2] != DEFAULT_SYMBOL)
{
if (board [0] [0] == board [i+1] [j+1])
{
if (board [0] [0] == board [i+2] [j+2])
{
if (board [i] [j] == PLAYER_SYMBOL)
return winsP1;
else
return winsPC;
}
}
}
}
}

return none;
}
int pcNode ()
{
vector <int>::iterator it = freeNodes.begin();

// for every free node, check if can win
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
bool winsP1, winsPC;

applyInputToBoard (*it, false, true);

int win = checkWin();
if (win == 1)
winsP1 = true;
else if (win == 2)
winsPC = true;

if (winsPC == true) // if this is a winning move, done
return *it;
else // if not, undo the move :)
{
undoInputToBoard (*it);
}
}
/////

srand (static_cast<unsigned int>(time(NULL)));

int node;
int randomNode = 1 + rand() % 9;

it = freeNodes.begin();

while (it < freeNodes.end() )
{
if (randomNode == *it) // if node is free
{
int i = randomNode;
return randomNode;
}

it++;

if (it == freeNodes.end() ) // if the node is not in freeNodes (if it's not free), repeat again
{
it = freeNodes.begin();
randomNode = 1 + rand () % 9;
}
}

node = randomNode;
return node;
}
void print()
{
cout << "\n" << "Used nodes: ";
vector <int>::const_iterator it;
for (it = usedNodes.begin(); it < usedNodes.end(); it++)
{
cout << *it << " ";
}

cout << "\n" << "Free nodes: ";
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
cout << *it << " ";
}

cout << "\n";
}
};

int main()
{
cout << "Tic Tac Toe" << "\t" << "by Minas Mina"
<< "\n" << "You: X" << "\t" << "PC: O";

TicTacToe game; // create an object for the class

game.setBoard(); // set the board
game.setFreeNodes();

bool playsP1 = true, playsPC = false;
bool winsP1 = false, winsPC = false;

while ( (winsP1 == false) && (winsPC == false) )
{
if (playsP1 == true)
{
int node;
bool acceptInput = false;

while (acceptInput == false)
{
node = game.getNode();
acceptInput = game.checkInput (node); // check if the node is free
}
game.addRemoveNodes (node);
game.applyInputToBoard (node, playsP1, playsPC); //update the board

int win = game.checkWin();
if (win == 1)
winsP1 = true;
else if (win == 2)
winsPC = true;

game.printBoard();
playsP1 = false;
playsPC = true;
game.print();
}

if (winsP1 == true || winsPC == true)
break;

if (playsPC == true)
{
int node = game.pcNode ();
cout << "\n" << "The pc plays " << node;
game.addRemoveNodes (node);
game.applyInputToBoard (node, playsP1, playsPC); //update the board

int win = game.checkWin();

if (win == 1)
winsP1 = true;
else if (win == 2)
winsPC = true;

game.printBoard();
playsP1 = true;
playsPC = false;
game.print();
}
}

if (winsP1 == true)
cout << "\n" << "You win!!";
else
cout << "\n" << "You lose..";

cout << "\n";
system ("PAUSE");
return 0;
}


I only need to make the AI better (pcNode function). It currently wins when it can, else it places in random nodes. :)

Share this post


Link to post
Share on other sites
I would change your logic up a bit:




bool PlayerHasWon(const Player& player)
{
// return whether player has won
}

bool IsGameDraw()
{
for(std::vector<Player>::iterator player = Players.begin(); player != Players.end(); ++player) {
if(PlayerHasWon(*player)) {
return false;
}
}
if(FreeCellCount == 0) {
return true;
} else {
return false;
}
}

bool IsGameOver()
{
for(std::vector<Player>::iterator player = Players.begin(); player != Players.end(); ++player) {
if(PlayerHasWon(*player)) {
return true;
}
}
if(IsGameDraw()) {
return true;
}
return false;
}



[Edited by - smr on November 20, 2007 11:24:13 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by sheep19
That's it:

*** Source Snippet Removed ***

I only need to make the AI better (pcNode function). It currently wins when it can, else it places in random nodes. :)


edit: there's an error somewhere, it says pc wins when it doesn't.

edit: i found it:
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

const char PLAYER_SYMBOL = 'X';
const char PC_SYMBOL = 'O';
const char DEFAULT_SYMBOL = '-';

class TicTacToe
{
private:
vector <int> freeNodes; // the free nodes
vector <int> usedNodes; // the used nodes
char board [3] [3]; // set the board

public:
void setBoard () // set the board to empty
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board [i] [j] = '-';
}
}
}

void setFreeNodes ()
{
for (int i = 1; i <= 9; i++)
{
freeNodes.push_back (i);
}
}

void printBoard () // print the board on the screen
{
cout << "\n";
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << board [i] [j] << " ";
}
cout << "\n";
}
}
int getNode ()
{
int node;
cout << "\n" << "Enter a number from 1-9: ";
cin >> node;
return node;
}
bool checkInput (int node)
{
vector <int>::iterator it;

for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
if (node == *it)
{
return true;
}
}
cout << "\n" << "Invalid input.";
return false;
}
void applyInputToBoard (int node, bool playsP1, bool playsPC)
{
int i, j;
if (node % 3 != 0)
{
i = node / 3;
j = node % 3 - 1;
}
else
{
i = node / 3 - 1;
j = 2;
}

if (playsP1 == true)
board [i] [j] = PLAYER_SYMBOL; // ('X')
else
board [i] [j] = PC_SYMBOL; // ('O')
}
void undoInputToBoard (int node) // undo the pc's move (see pcNode)
{
int i, j;
if (node % 3 != 0)
{
i = node / 3;
j = node % 3 - 1;
}
else
{
i = node / 3 - 1;
j = 2;
}

// undo the move
board [i] [j] = DEFAULT_SYMBOL; // ('-')
}
void addRemoveNodes (int node)
{
usedNodes.push_back (node); // add the node in usedNodes
sort (usedNodes.begin(), usedNodes.end() );

//remove the node from freeNodes
int position = 0;
vector <int>::const_iterator it;
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
if (*it == node)
{
break;
}

position ++; // position is the position of the number (node) in the vector
}

/*when (*it = node), position isn't increased, because it breaks the loop. But that doesn't matter because when erase, I have to delete -1
because it starts from the the first element. position is already -1 so I don't have to subtract anything.
eg it should have been "freeNodes.erase (freeNodes.begin() + position - 1);", but position is -1 from the
node's position, so, it's ok.*/


freeNodes.erase (freeNodes.begin() + position);
sort (freeNodes.begin(), freeNodes.end() );
}
int checkWin ()
{
enum Won
{
none = 0,
winsP1 = 1,
winsPC = 2
};

//horizontal
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i] [j] != DEFAULT_SYMBOL && board [i] [j+1] != DEFAULT_SYMBOL && board [i] [j+2] != DEFAULT_SYMBOL)
{
if (board [i] [j] == board [i] [j+1])
{
if (board [i] [j] == board [i] [j+2])
{
if (board [i] [j] == PLAYER_SYMBOL)
return winsP1;
else
return winsPC;
}
}
}
}
}

//vertical
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i] [j] != DEFAULT_SYMBOL && board [i+1] [j] != DEFAULT_SYMBOL && board [i+2] [j] != DEFAULT_SYMBOL)
{
if (board [i] [j] == board [i+1] [j])
{
if (board [i] [j] == board [i+2] [j])
{
if (board [i] [j] == PLAYER_SYMBOL)
return winsP1;
else
return winsPC;
}
}
}
}
}

//diagonal
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i] [j] != DEFAULT_SYMBOL && board [i+1] [j+1] != DEFAULT_SYMBOL && board [i+2] [j+2] != DEFAULT_SYMBOL)
{
if (board [0] [0] == board [i+1] [j+1])
{
if (board [0] [0] == board [i+2] [j+2])
{
if (board [i] [j] == PLAYER_SYMBOL)
return winsP1;
else
return winsPC;
}
}
}
}
}

return none;
}
int pcNode ()
{
vector <int>::iterator it = freeNodes.begin();

// for every free node, check if can win
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
bool winsP1, winsPC;

applyInputToBoard (*it, false, true);

int win = checkWin();
if (win == 1)
winsP1 = true;
else if (win == 2)
winsPC = true;

if (winsPC == true) // if this is a winning move, done
return *it;
else // if not, undo the move :)
{
undoInputToBoard (*it);
}
}
/////

srand (static_cast<unsigned int>(time(NULL)));

int node;
int randomNode = 1 + rand() % 9;

it = freeNodes.begin();

while (it < freeNodes.end() )
{
if (randomNode == *it) // if node is free
{
int i = randomNode;
return randomNode;
}

it++;

if (it == freeNodes.end() ) // if the node is not in freeNodes (if it's not free), repeat again
{
it = freeNodes.begin();
randomNode = 1 + rand () % 9;
}
}

node = randomNode;
return node;
}
void print()
{
cout << "\n" << "Used nodes: ";
vector <int>::const_iterator it;
for (it = usedNodes.begin(); it < usedNodes.end(); it++)
{
cout << *it << " ";
}

cout << "\n" << "Free nodes: ";
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
cout << *it << " ";
}

cout << "\n";
}
};

int main()
{
cout << "Tic Tac Toe" << "\t" << "by Minas Mina"
<< "\n" << "You: X" << "\t" << "PC: O";

TicTacToe game; // create an object for the class

game.setBoard(); // set the board
game.setFreeNodes();

bool playsP1 = true, playsPC = false;
bool winsP1 = false, winsPC = false;

while ( (winsP1 == false) && (winsPC == false) )
{
if (playsP1 == true)
{
int node;
bool acceptInput = false;

while (acceptInput == false)
{
node = game.getNode();
acceptInput = game.checkInput (node); // check if the node is free
}
game.addRemoveNodes (node);
game.applyInputToBoard (node, playsP1, playsPC); //update the board

int win = game.checkWin();
if (win == 1)
winsP1 = true;
else if (win == 2)
winsPC = true;

game.printBoard();
playsP1 = false;
playsPC = true;
game.print();
}

if (winsP1 == true || winsPC == true)
break;

if (playsPC == true)
{
int node = game.pcNode ();
cout << "\n" << "The pc plays " << node;
game.addRemoveNodes (node);
game.applyInputToBoard (node, playsP1, playsPC); //update the board

int win = game.checkWin();

if (win == 1)
winsP1 = true;
else if (win == 2)
winsPC = true;

game.printBoard();
playsP1 = true;
playsPC = false;
game.print();
}
}

if (winsP1 == true)
cout << "\n" << "You win!!";
else
cout << "\n" << "You lose..";

cout << "\n";
system ("PAUSE");
return 0;
}


Now the game is almost finished. This is my first project that uses a bit of AI. And I'm new to objects as well. Like some people said, I'm not using OOP, but I'm using objects to implement procedural programming. This is why I haven't learned how to yet.

Thanks everyone for your time.

Share this post


Link to post
Share on other sites
Quote:

4. Use a data type that encompasses the two you need to return. Obvioulsy not a general strategy like the others, but can be used in this example.

enum Result
{
P1_WIN,
P2_WIN,
NOBODY_WINS
};

Quote:

6. Use individual bits to represent player state
   enum Won
{
NONE = 0,
P1 = 1,
P2 = 2
};


The same basic idea, but (4) is a more accurate description of what we want in this case, because "both win" is not a valid game state for tic-tac-toe, but "draw", for example, is.

Share this post


Link to post
Share on other sites
Quote:
Original post by sheep19
There is still an error! ouch..

Your checkWin() function doesn't work correctly. I was WIN but it didn't show that I won.

O - X
- X 0
X - -

Share this post


Link to post
Share on other sites
If I was you, I would simply use this function to check the winner. checkWin(char player) where player is refer to character of each player.


bool checkWin(char player) {
if ((board[0][0] == player && board[0][1] == player && board[0][2] == player) ||
(board[1][0] == player && board[1][1] == player && board[1][2] == player) ||
(board[2][0] == player && board[2][1] == player && board[2][2] == player) ||
(board[0][0] == player && board[1][0] == player && board[2][0] == player) ||
(board[0][1] == player && board[1][1] == player && board[2][1] == player) ||
(board[0][2] == player && board[1][2] == player && board[2][2] == player) ||
(board[2][2] == player && board[1][1] == player && board[0][0] == player) ||
(board[2][0] == player && board[1][1] == player && board[0][2] == player) {
return true;
else return false;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by invisal
If I was you, I would simply use this function to check the winner. checkWin(char player) where player is refer to character of each player.


bool checkWin(char player) {
if ((board[0][0] == player && board[0][1] == player && board[0][2] == player) ||
(board[1][0] == player && board[1][1] == player && board[1][2] == player) ||
(board[2][0] == player && board[2][1] == player && board[2][2] == player) ||
(board[0][0] == player && board[1][0] == player && board[2][0] == player) ||
(board[0][1] == player && board[1][1] == player && board[2][1] == player) ||
(board[0][2] == player && board[1][2] == player && board[2][2] == player) ||
(board[2][2] == player && board[1][1] == player && board[0][0] == player) ||
(board[2][0] == player && board[1][1] == player && board[0][2] == player)) {
return true;
}
else return false;
}


Unbroke!

Share this post


Link to post
Share on other sites
I DO understand that you use vector to store the available nobe and un-available nobe. However, I think it is pointless to use it when you could simply do it without vector. Here it is how I would change your code into.

Your code:

bool checkInput (int node)
{
vector <int>::iterator it;

for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
if (node == *it)
{
return true;
}
}
cout << "\n" << "Invalid input.";
return false;
}


After chnage:

bool checkInput (int node)
{
if (node > 0 && node <= 9 &&
board[node%3-1][(node-1)/3] == '-') return true;
else {
cout << "\n" << "Invalid input.";
return false;
}
}


Your Code

void print()
{
cout << "\n" << "Used nodes: ";
vector <int>::const_iterator it;
for (it = usedNodes.begin(); it < usedNodes.end(); it++)
{
cout << *it << " ";
}

cout << "\n" << "Free nodes: ";
for (it = freeNodes.begin(); it < freeNodes.end(); it++)
{
cout << *it << " ";
}

cout << "\n";
}


After Change

void print()
{
cout << "\n" << "Used nodes: ";
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++)
if (board[j][i] != '-') cout << (i + 1) * (j + 1);

cout << "\n" << "Free nodes: ";
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++)
if (board[j][i] == '-') cout << (i + 1) * (j + 1);

cout << "\n";
}

Share this post


Link to post
Share on other sites
Quote:
If I was you, I would simply use this function to check the winner. checkWin(char player) where player is refer to character of each player.

[Snip DailyWTF submission]


* Dies of heart attack *

At least pretend to remove repetitiveness:

int checks[][3] = {
{0,1,2}, {3,4,5}, {6,7,8}, {0,3,6},
{1,4,7}, {2,5,8}, {0,4,8}, {2,4,6} };

for (int i = 0; i < 8; ++i)
{
bool row_full = true;
for (int j = 0; j < 3; ++j)
{
row_full =
row_full && (player == board[checks[i][j] / 3][checks[i][j] % 3]);
}

if (row_full) return true;
}

return false;

Share this post


Link to post
Share on other sites
Or to make it board size independent:


const int NumCellsX = 3;
const int NumCellsY = 3;
const int NumCellsToWin = 3;

bool CheckWin(int player)
{
/* horizontal */
for (int y = 0; y < NumCellsX; y++)
{
int n = 0;

for (int x = 0; x < NumCellsX; x++)
{
if (board[y][x] == player)
n++;
}

if (n > 2)
return true;
}

/* vertical */
for (int x = 0; x < NumCellsX; x++)
{
int n = 0;

for (int y = 0; y < NumCellsX; y++)
{
if (board[y][x] == player)
n++;
}

if (n > 2)
return true;
}

/* diagonal (top left to bottom right) */
for (int x = 0; x <= NumCellsX - NumCellsToWin; x++)
{
int n = 0;

for (int y = 0; y <= NumCellsY - NumCellsToWin; y++)
{
for (int i = 0; i < NumCellsToWin; i++)
{
if (board[y + i][x + i] == player)
n++;
}
}

if (n > 2)
return true;
}

/* diagonal (top right to bottom left) */
for (int x = NumCellsX - 1; x >= NumCellsToWin; x--)
{
int n = 0;

for (int y = NumCellsY - 1; y >= NumCellsToWin; y--)
{
for (int i = 0; i < NumCellsToWin; i++)
{
if (board[y - i][x - i] == player)
n++;
}
}

if (n > 2)
return true;
}

return false;
}



I haven't tested it and it could probably be optimized a little more, but it should work.

Share this post


Link to post
Share on other sites
Quote:
Original post by invisal
Your code:

bool checkInput (int node)
{
// Uglies
}


Correct version:
bool checkInput (int node)
{
return std::find(freenodes.begin(), freenodes.end(), node) != freenodes.end();
}



Quote:
Your Code

void print()
{
// Uglies
}


Correct version:
void print()
{
cout << "\n" << "Used nodes: ";
std::copy (usedNodes.begin(), usedNodes.end(),
std::ostream_iterator<int>(std::cout, " "));

cout << "\n" << "Free nodes: ";
std::copy (freeNodes.begin(), freeNodes.end(),
std::ostream_iterator<int>(std::cout, " "));

cout << "\n";
}

Share this post


Link to post
Share on other sites
Quote:
Original post by WanMaster
Or to make it board size independent:
I haven't tested it and it could probably be optimized a little more, but it should work.

Your code is not perfectly work. It doesb't work when:

- - X
- X -
X - -

Share this post


Link to post
Share on other sites
[source lang="cpp"//horizontal
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i][j] == board [i][j+1] && board [i][j] == board [i][j+2])
{
if (board [i][j] == PLAYER_SYMBOL)
return winsP1;
else if (board [i][j] == PC_SYMBOL)
return winsPC;
}
}
}

//vertical
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i][j] == board [i+1][j] && board [i][j] == board [i+2][j])
{
if (board [i][j] == PLAYER_SYMBOL)
return winsP1;
else if (board [i][j] == PC_SYMBOL)
return winsPC;
}
}
}

//diagonal
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board [i][j] == board [i+1][j+1] && board [i][j] == board [i+2][j+2])
{
if (board [i][j] == PLAYER_SYMBOL)
return winsP1;
else if (board [i][j] == PC_SYMBOL)
return winsPC;
}
if (board [i+2][j] == board [i+1][j+1] && board [i+2][j] == board [i][j+2])
{
if (board [i+2][j] == PLAYER_SYMBOL)
return winsP1;
else if (board [i+2][j] == PC_SYMBOL)
return winsPC;
}
}
}



what about this?
{i'm making the diagonal now)

edit: finished

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this