Jump to content
  • Advertisement
Sign in to follow this  

Another Tic Tac Toe problem

This topic is 4756 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im currently trying to make a simple tic tac toe game in C++, and right now Im not sure how to make it so that if an X is there already, you cannot place an O on it. Heres my board: cout << " _________________ \n" << " | | | |\n" << " | " << board[7] << " | " << board[8] << " | " << board[9] << " |\n" << " |_____|_____|_____|\n" << " | | | |\n" << " | " << board[4] << " | " << board[5] << " | " << board[6] << " |\n" << " |_____|_____|_____|\n" << " | | | |\n" << " | " << board[1] << " | " << board[2] << " | " << board[3] << " |\n" << " |_____|_____|_____|\n" << endl; Also, is this a good approach: Make the turns go by odds and evens. If so, how would you do this the short way? Im doing it the long way (with lots of ifs) (Im prretty new at this, so...) Other tips are greatly appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
If so, how would you do this the short way? Im doing it the long way (with lots of ifs)


I think I found out how to already....still not totally sure though.

*edit : Nope, I retried it and it didnt work, does anyone know how?

Share this post


Link to post
Share on other sites
Quote:
Original post by dragoon38900
Im currently trying to make a simple tic tac toe game in C++, and right now Im not sure how to make it so that if an X is there already, you cannot place an O on it.


Well here's a few ideas for you - first, how do you assign the X or O in the first place? Since you know where they choose to put it, as in you know what board[X] is going to be used, you can do a quick check of that location first and see if it's "empty", not "X" or "O" on a per term basics. What I mean is like this (pseudo code)

char board[9] = {0}; // all are 0 to being with, 0 == empty
P1 Turn:
- Get location to place piece( board[1] )
- Check location if( board[1] == 0 ) canMove = 1; else canMove = 0;
-- See how we check to see if it's empty and not if its 'X' or 'O'? Much simpler this way!
- Now add the piece if canMove:: if ( canMove ) board[1] = 'X'; change turn() else warn() return to Get Location()


That's all there is to it really. I hope that's clearn, if not feel free to ask for clarifications [wink].

Share this post


Link to post
Share on other sites
Just another quick tip.

Why don't you build your board into a string and then output that. It doesn't matter much with TTT as you will be stopping the game for input (probably) after outputing the board. But if you are continually drawing and input is via something like kbhit() and getch() then you will get quite a lot of flicker by drawing each line individually.

Just a thought..:)

Share this post


Link to post
Share on other sites
If you are using a char array (or is it "array of chars") for the board, you can do:

char board[ 9 ] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };

bool checkMove( int m ) // pass the move into the function
{
if ( board[ m ] > 47 ) // if the character is not a number it has already
// been changed to an 'X' or 'O'
// '9' has an ASCII value of 47, so if the value is
// larger, then it is, for sure, not a number
return false; // checkMove returns false, the move is already taken
else
return true;

}


Also, you could of course just use the "if" without putting it in a function, but I like it that way.

Share this post


Link to post
Share on other sites
Quote:
Also, is this a good approach: Make the turns go by odds and evens. If so, how would you do this the short way? Im doing it the long way (with lots of ifs)

if ( turn % 2 == 1 ) // turn is odd, else it is even
board[ m ] = 'X';
else
board[ m ] = 'O';

board[ m ] = turn % 2 == 1 ? 'X' : 'O'; // This is a shorthand way of doing it. Of
// course, if this is less clear to you,
// it would be poor practice to use it. If
// not, either one is fine.

Share this post


Link to post
Share on other sites
#include<iostream>

using std::cout;
using std::cin;
using std::endl;

void draw_board( char [] );// function to draw the board

void get_pos( char [], int );

int main()
{

char board_array[10] = { 0 };// an array to keep track of the board


int turn = 1;// an integer to keep track of the turn

while ( turn <= 9 /*&& gameOver() != true */ ) {

draw_board( board_array );// draw the board

get_pos( board_array, turn );// get the input from the player and change the board

turn++;// go to the next turn
}

cout << endl;

return 0;
}

void draw_board( char board[] )
{
system( "cls" );

cout << " _________________ _________________ \n"
<< " | | | | | | | |\n"
<< " | " << board[7] << " | " << board[8] << " | " << board[9] << " | | 7 | 8 | 9 |\n"
<< " |_____|_____|_____| |_____|_____|_____|\n"
<< " | | | | | | | |\n"
<< " | " << board[4] << " | " << board[5] << " | " << board[6] << " | | 4 | 5 | 6 |\n"
<< " |_____|_____|_____| |_____|_____|_____|\n"
<< " | | | | | | | |\n"
<< " | " << board[1] << " | " << board[2] << " | " << board[3] << " | | 1 | 2 | 3 |\n"
<< " |_____|_____|_____| |_____|_____|_____|\n" << endl;
}

void get_pos( char board[], int turn )
{
static int pos;

cout << "Please make your move: ";
cin >> pos;
if ( pos > 0 && pos < 10) {
if ( board[pos] == 0 ) {
if ( turn % 2 == 1 ) {
board[pos] = 'X';
}
else {
board[pos] = 'O';
}
}
else {
cout << "Something's there already!";
}
}
else {
cout << "Please choose a number between 1-9";
}
}


Ok, here is my code so far. Its not correct though, I still have a problem. When it executes the 'else', it continues with the process, thus still adding one to Turn, and clears the screen, leaving no time for the player to read that it was an invalid move. How would I go about fixing this?

Furthermore, my brother is doing this same exact game in Python. Is there a difference on how the code is going to be besides the format of the functions?(like I know its cout for C++ and print in python, but is there a difference in the order of things, or possibly other differences I should know) This is due next monday, and I need to complete the C++ code by tomorrow, so all the help is highly appreciated. Thanks

Share this post


Link to post
Share on other sites
Another question, based on my code I posted, whats the best way to check who wins? I tried doing this :

void checkwin( char board[])
{
if ( board[1] == 'X' && board[2] == 'X' && board[3] == 'X' ) || ( board[4] == 'X'
&& board[5] == 'X' && board[6] == 'X' ) || ( board[7] == 'X' && board[8] == 'X'
&& board[9] == 'X' ) || ( board[1] == 'X' && board[4] == 'X' && board[7] == 'X' )
|| ( board[2] == 'X' && board[5] == 'X' && board[8] == 'X' ) || ( board[3] == 'X' &&
board[6] == 'X' && board[9] == 'X' && ) || ( board[1] == 'X' && board[5] == 'X'
&& board[9] == 'X' ) || ( board[3] == 'X' && board[5] == 'X' && board[7] == 'X' )


and etc, but it doesnt work.

Please help! I would learn this myself, but lets just say Ive had the most bad luck ever over the past 2 weeks.

Share this post


Link to post
Share on other sites
Hi ,
I went through your code and fixed your problem. What you need to do is increment turn only if the player makes a valid move.

There are more ways than one to do this but I chose to increment turn in get_pos() rather than in the main().

Now we know that if a varaible is passed to a function, it is actually a copy of the variable that is being passed. So, if we modify that copy in the function, we will not be modifying the original variable.

So if we want to increment turn from inside the function, we have two options:

1. We could pass the variable 'turn' by reference.(pass the address of
turn to the function...so function will be able to modify 'turn'.

or

2. We could make turn a global variable.
- This means that 'turn' does not have to passed to the function at all.

I modified your code for option 1.

#include<iostream>
#include<conio.h> // for the getch() function.

using std::cout;
using std::cin;
using std::endl;

void draw_board( char [] );// function to draw the board

void get_pos( char [], int* );

int main()
{

char board_array[10] = { 0 };// an array to keep track of the board


int turn=1;// 1;// an integer to keep track of the turn


while ( turn <= 9 /*&& gameOver() != true */ ) {

draw_board( board_array );// draw the board

get_pos( board_array, &turn );// get the input from the player and change the board

//turn++;// go to the next turn // Turn is incremented in get_pos function
}

cout << endl;

return 0;
}

void draw_board( char board[] )
{
system( "cls" );

cout << " _________________ _________________ \n"
<< " | | | | | | | |\n"
<< " | " << board[7] << " | " << board[8] << " | " << board[9] << " | | 7 | 8 | 9 |\n"
<< " |_____|_____|_____| |_____|_____|_____|\n"
<< " | | | | | | | |\n"
<< " | " << board[4] << " | " << board[5] << " | " << board[6] << " | | 4 | 5 | 6 |\n"
<< " |_____|_____|_____| |_____|_____|_____|\n"
<< " | | | | | | | |\n"
<< " | " << board[1] << " | " << board[2] << " | " << board[3] << " | | 1 | 2 | 3 |\n"
<< " |_____|_____|_____| |_____|_____|_____|\n" << endl;
}

void get_pos( char board[], int *turn )
{
static int pos;

cout << "Please make your move: ";
cin >> pos;


if ( pos > 0 && pos < 10) {
if ( board[pos] == 0 ) {
if ( *turn % 2 == 1 ) {
board[pos] = 'X';
}
else {
board[pos] = 'O';
}
(*turn)++;
}
else {
cout << "Something's there already.. Press Any Key To Continue";
getch();
}
}
else {
cout << "Please choose a number between 1-9";
}
}


/* Changes I made to your code:
- I am incrementing turn only in get_pos()
- Changed the prototype of get_pos() so it now accepts a pointer to turn
( turn is passed by reference to get_pos()

Note:
If you are not familiar with pointers yet, don't worry, you could make turn
a global variable. So you won't need to pass "turn" variable to get_pos() at all.
- Just declare turn as a global variable
- get_pos() will only need one argument, so change its
prototype
[/souce]



Hope this helps...

v-EktOr -->

Share this post


Link to post
Share on other sites
There is a third option:

getPos() could return the turn as an int:



int getPos(char board[], int turn);

int main(whatever)
{
.
.
some stuff;
.
.

turn = getPos(board, turn);
.
.
some more stuff;
.
.
}

int getPos(char board[], int turn)
{
.
.
more stuff;
.
.
++turn;
.
even more stuff;
.
.

return turn;
}




Just a thought..:) Although return values like this are usually used to return success or failure indicators, but of course they don't have to be.

Happy trucking...:)

Oh..and there is a fourth option. Passing the turn value as a reference (V-ektor was actually passing a pointer to turn not a reference)

prototype/declaration would be:

void get_pos(char [], int&); instead of
void get_pos(char [], int*);

and use would be:

get_pos(board_array, turn);

and it'd be used in the normal way:

turn++;

Just another thought..:)

Hope you get it nailed..:)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!