Sign in to follow this  
burgert

my first game tic tac toe

Recommended Posts

my first game in c++ please tell me what you think of it #include <iostream> using namespace std; int main() { char a = '1'; char b = '2'; char c = '3'; char d = '4'; char e = '5'; char f = '6'; char g = '7'; char h = '8'; char i = '9'; char playermark; int player = 1; char move; int gamedone = 0; do { cout << a << " " << b << " " << c << endl; cout << d << " " << e << " " << f << endl; cout << g << " " << h << " " << i << endl; if (player == 1) { playermark = 'x'; } else { playermark = 'o'; } cout << "enter your move player " << player << endl; cin >> move; if (move == '1' ) { a = playermark; } else if (move == '2' ) { b = playermark; } else if (move == '3' ) { c = playermark; } else if (move == '4') { d = playermark; } else if (move == '5' ) { e = playermark; } else if (move == '6' ) { f = playermark; } else if (move == '7') { g = playermark; } else if (move == '8' ) { h = playermark; } else if (move == '9' ) { i = playermark; } else { cout << "invaild move stupid" << endl; } if (a == b & b == c ) { cout << "you won player " << player << endl; gamedone = 1; } else if (d == e & e == f ) { cout << "you won player " << player << endl; gamedone = 1; } else if (g == h & h == i ) { cout << "you won player " << player << endl; gamedone = 1; } else if (a == e & e == i) { cout << "you won player " << player << endl; gamedone = 1; } else if(c == e & e == g ) { cout << "you won player " << player << endl; gamedone = 1; } else if(a == d & d == g) { cout << "you won player " << player << endl; gamedone = 1; } else if(b == e & e == h) { cout << "you won player " << player << endl; gamedone = 1; } else if(c == f & f == i) { cout << "you won player " << player << endl; gamedone = 1; } if (player == 1) { player = 2; } else { player = 1; } } while (gamedone == 0); }

Share this post


Link to post
Share on other sites
There is room for improvement. Your code would become far simpler if you used an array or std::vector. In the comments I suggest an alternate way to write the code using an array instead of assigning each position a letter using an array. Outside of that I simplify a little bit of the logic. None of the code below is tested. Hope this helps.

#include <iostream>
using namespace std;
int main()
{
// using an array:
// (using 0-based indexing to simplify math)
// char board[9] = {'0', '1', '2', '3', '4', '5', '6', '7', '8'};
char a = '1';
char b = '2';
char c = '3';
char d = '4';
char e = '5';
char f = '6';
char g = '7';
char h = '8';
char i = '9';
char playermark = 'x';
// using an array:
// int move;
char move;
bool gamedone = false;

// no reason to use do-while loop
while(!gamedone)
{
// using an array:
// cout << board[0] << " " << board[1] << " " << board[2] << endl;
// cout << board[3] << " " << board[4] << " " << board[5] << endl;
// cout << board[6] << " " << board[7] << " " << board[8] << endl;

cout << a << " " << b << " " << c << endl;
cout << d << " " << e << " " << f << endl;
cout << g << " " << h << " " << i << endl;

// we don't need 'player'. Playermark is always the same for each
// player. Just call each player 'x' or 'o'.

cout << "enter your move player " << playermark << endl;
cin >> move;
// using an array:
// if(move < 0 || move > 8)
// {
// cout << "invaild move stupid" << endl;
// }
// else
// {
// board[move] = playermark;
// }
if (move == '1' )
{
a = playermark;
}
else if (move == '2' )
{
b = playermark;
}
else if (move == '3' )
{
c = playermark;
}
else if (move == '4')
{
d = playermark;
}
else if (move == '5' )
{
e = playermark;
}
else if (move == '6' )
{
f = playermark;
}
else if (move == '7')
{
g = playermark;
}
else if (move == '8' )
{
h = playermark;
}
else if (move == '9' )
{
i = playermark;
}
else
{
cout << "invaild move stupid" << endl;
}

// you used '&' but you probably meant to use '&&'. That '&' worked
// is a coincidence. Also, you print the same thing for all of the
// conditions. Just use '||' to cut down on copy-paste
// using an array:
// if ((board[0] == board[1] && board[1] == board[2]) ||
// (board[3] == board[4] && board[4] == board[5]) ||
// (board[6] == board[7] && board[7] == board[8]) ||
// (board[0] == board[4] && board[4] == board[8]) ||
// (board[2] == board[4] && board[4] == board[6]) ||
// (board[0] == board[3] && board[3] == board[6]) ||
// (board[1] == board[4] && board[4] == board[7]) ||
// (board[2] == board[5] && board[5] == board[8]))
if ((a == b && b == c) || (d == e && e == f) || (g == h && h == i) ||
(a == e && e == i) || (c == e && e == g) || (a == d && d == g) ||
(b == e && e == h) || (c == f && f == i))
{
cout << "you won player " << playermark << endl;
gamedone = true;
}

if (playermark == 'x')
{
playermark = 'o';
}
else
{
playermark = 'x';
}
}
}


Share this post


Link to post
Share on other sites
Here's the code for my first ever C++ program, which also happens to be a tic tac toe program. As you can see, it is much simpler with arrays, although my code probably has lots of room for improvement as well.

If you want to make anything more complicated then Hello World, you are going to have to learn about how to use functions.


#include <iostream>

using namespace std;

char symbol[]={' ','X','O'}; //array size automatically set by number of elements on the right side
int board[9];

int newgame(int);
int getmove(int[], int, int);
int computermove(int[], int);
int playermove();
int evalmax(int[],int,int);
int evalmin(int[],int,int);
int result(int[]);
void displayboard(int[]);

int main()
{
int mode;
char response;

cout << "The only winning move is not to play\n";
cout << "\t\t\t - War Games\n\n\n";

cout <<"Select Mode:\n1:Human vs Human\n2:Human vs Computer\n3:Computer vs Human\n";
cin >> mode;

do
{
newgame(mode);
cout<<"Want to play again? Y/N\n";
cin >> response;
if (!(response=='y' || response=='Y'))
{
break;
}
} while (1);

return 0;
}

int newgame(int mode)
{
int p1type=0;
int p2type=0;

for (int i=0;i<9;i++)
{
board[i]=0;
}

switch (mode)
{
case 1:
p1type=0;
p2type=0;
break;
case 2:
p1type=0;
p2type=1;
break;
case 3:
p1type=1;
p2type=0;
break;
case 4:
p1type=1;
p2type=1;
break;
}

for (int i=0;i<9;i++)
{
cout << "\n";
if (i%2 == 0)
{
board[getmove(board,1,p1type)]=1;
}
else
{
board[getmove(board,2,p2type)]=2;
}

if (result(board)>0)
{
i=9; //stop the game
cout<<"\n";
displayboard(board);
switch (result(board))
{
case 1:
cout<<"Player 1 Wins\n";
break;
case 2:
cout<<"Player 2 Wins\n";
break;
case 3:
cout<<"Tie Game\n";
break;
}
}

}

return result(board);
}

int result(int b[])
{

switch (b[0]*b[1]*b[2])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}
switch (b[3]*b[4]*b[5])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}
switch (b[6]*b[7]*b[8])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}

switch (b[0]*b[3]*b[6])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}
switch (b[1]*b[4]*b[7])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}
switch (b[2]*b[5]*b[8])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}

switch (b[0]*b[4]*b[8])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}
switch (b[2]*b[4]*b[6])
{
case 1:
return 1;
break;
case 8:
return 2;
break;
}

if ((b[0] * b[1] * b[2] * b[3] * b[4] * b[5] * b[6] * b[7] * b[8]) > 0)
{
return 3;
}
else
{
return 0;
}

return -1;// this should never happen anyway
}

int getmove(int b[], int player, int ptype)
{
int move;

switch (ptype)
{
case 0:
displayboard(b);
move=playermove();
break;
case 1:
move=computermove(b,player);
break;
}

return move;
}

int computermove(int b[], int player)
{
int lboard[9];
int move=-1;
int moveval;
int c;

for(int i=0;i<9;i++)
{
lboard[i]=b[i];
}

if (player==1)
{
moveval=-1000;
for(int i=0;i<9;i++)
{
if (lboard[i]==0)
{
lboard[i]=1;
c=evalmin(lboard,999,-999);
//cout << c << "\n";
lboard[i]=0;
if (c>moveval)
{
move=i;
moveval=c;
}
}
}
}
else
{
moveval=1000;
for(int i=0;i<9;i++)
{
if (lboard[i]==0)
{
lboard[i]=2;
c=evalmax(lboard,-999,999);
//cout << c << "\n";
lboard[i]=0;
if (c<moveval)
{
move=i;
moveval=c;
}
}
}
}

return move;
}

int playermove()
{
int move;
int valid;

valid=0;
cout << "Where do you want to move? (1-9)\n";

do
{

cin >> move;
valid = 1;
move--;
if (move<0 || move>8) // || means logical or
{
cout << "Please enter a number from 1 to 9\n";
valid = 0;
continue; // should jump to the end of hte do loop
}

if (board[move]>0) // || means logical or
{
cout << "You may only move in an empty space.\n";
valid = 0;
displayboard(board);
}

} while (valid==0);

return move;
}

int evalmax(int refboard[], int best, int goal)
{
int lboard[9];
int a=best;
int b=goal;
int c;

switch (result(refboard))
{
case 1:
return 999;
break;
case 2:
return -999;
break;
case 3:
return 0;
break;
}

for (int i=0;i<9;i++)
{
lboard[i]=refboard[i];
}

for (int i=0;i<9;i++)
{
if (lboard[i]==0)
{
lboard[i]=1;
c=evalmin(lboard,b,a);
lboard[i]=0;
if (c>a)
{
a=c;
}
if (a>=b)
{
i=9;
}
}
}
return a;
}

int evalmin(int refboard[], int best, int goal)
{
int lboard[9];
int a=best;
int b=goal;
int c;

switch (result(refboard))
{
case 1:
return 999;
break;
case 2:
return -999;
break;
case 3:
return 0;
break;
}

for (int i=0;i<9;i++)
{
lboard[i]=refboard[i];
}

for (int i=0;i<9;i++)
{
if (lboard[i]==0)
{
lboard[i]=2;
c=evalmax(lboard,b,a);
lboard[i]=0;
if (c<a)
{
a=c;
}
if (a<=b)
{
i=9;
}
}
}
return a;
}

void displayboard(int b[])
{
cout << "+---+\n|";
for (int i=0; i<9; i++)
{
cout << symbol[b[i]];
if ((i == 2) || (i == 5))
{
cout << "|\n|";
}
}
cout << "|\n+---+\n";
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Storyyeller
Here's the code for my first ever C++ program, which also happens to be a tic tac toe program. As you can see, it is much simpler with arrays, although my code probably has lots of room for improvement as well.


I'll say. I'm guessing you have considerable prior experience with other languages, in order to come up with the idea of implementing an alpha-beta search in your first C++ program, to say nothing of the bizarre arithmetic tricks in your win-detection function. Unfortunately you don't seem to have yet gained enough experience to figure out how to make things readable. :) Error checking for inputs might be a good idea, too.

I've made adjustments to one of your functions to suggest a few possible improvements. Comments I would actually write are in // style; comments intended to explain to you what I'm doing (and why I think it improves things) are in /* */ style.


/* There's no reason for the board to be global; thus, I create it locally
and pass it around. */


/* Why remember numeric status codes yourself when you can have the compiler
do it for you? */

enum { STILL_PLAYING, PLAYER_1, PLAYER_2, TIE } result_type;
enum { HUMAN, AI } player_type;

typedef int board_type[9];
/* Now you can write the other functions to accept board_type&, for a little
better documentation value. */


/* The return value would never be used, so there's no point in returning.
It might make sense, though, to move the "main loop" into its own function
that returns the game result... */

void play(int mode) {
// Declare and initialize the board.
board_type board;

for (int i = 0; i < 9; i++) {
board[i] = 0;
}

// Translate mode to determine player types.
/* This part didn't require nearly the effort you were putting into it.
I could do this with some bitwise arithmetic, too, but this way seems
more flexible and readable. */

player_type ptypes[2] = {
(mode == 3 || mode == 4) ? AI : HUMAN,
(mode == 2 || mode == 4) ? AI : HUMAN
};

/* The win-detection already checks the move count implicitly, so there's
no need for it as a loop condition. Rather, we want to keep looping while
we receive the "game is still going on" result. */


/* I use 0 and 1 as player identifiers so that I can use them to index into
the ptypes array, and easily flip between them. I add an offset of 1 when
calling getmove() and so on in order to preserve compatibility with the
other functions. */

int turn = 0;
result_type r; /* I save this result to avoid repeatedly calling the function.
That's a pretty meaningless optimization in general, but
sometimes you have to do this because the function is
designed to have side effects or return differently if you
call it multiple times... e.g. rand() */


// Main loop.
do {
cout << "\n";
/* Making the move should have its own function. Or rather, do the setting
work in getmove(), and rename it to makemove() or something. */

board[getmove(board, (turn + 1), ptypes[turn])] = turn + 1;
r = result(board);
turn ^= 1; // 0 if it was 1; 1 if it was 0
} while (r == STILL_PLAYING);

// When we get here, we know the result is something else.
// The calling code is responsible for displaying the result.
cout << "\n";
displayboard(board);
switch (r) {
case PLAYER_1:
cout << "Player 1 Wins\n";
break;

case PLAYER_2:
cout << "Player 2 Wins\n";
break;

case TIE:
cout << "Tie Game\n";
break;
}
}


Share this post


Link to post
Share on other sites
i tryed to rewrite it but it dosent work i cant find the problem


#include &lt;iostream&gt;
using namespace std;
int main()
{
char a[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
char playermark;
int player = 1;
char move = 0;
int gamedone = 0;
do {
cout &lt;&lt; a[0] &lt;&lt; " " &lt;&lt; a[1] &lt;&lt; " " &lt;&lt; a[2] &lt;&lt; endl;
cout &lt;&lt; a[3] &lt;&lt; " " &lt;&lt; a[4] &lt;&lt; " " &lt;&lt; a[5] &lt;&lt; endl;
cout &lt;&lt; a[6] &lt;&lt; " " &lt;&lt; a[7] &lt;&lt; " " &lt;&lt; a[8] &lt;&lt; endl;


if (player == 1)
{
playermark = 'x';
}
else if (player == 2)
{
playermark = 'o';
}
cout &lt;&lt; "enter you move player " &lt;&lt; player &lt;&lt; endl;
cin &gt;&gt; move;

a[--move] = playermark; // i think this dos not work
if (a[0] == a[1] && a[1] == a[2] || a[3] == a[4] && a[4] == a[5] || a[6] == a[7] && a[7] == a[8]
|| a[0] == a[4] && a[0] == a[8] || a[2] == a[4] && a[4] == a[6] || a[0] == a[3] && a[3] == a[6]
|| a[1] == a[4] && a[4] == a[7] || a[2] == a[5] && a[5] == a[8] )
{
cout &lt;&lt; "you won player" &lt;&lt; player;
gamedone = 1;
}
if (player == 1)
{
player = 2;
}
else
{
player = 1;
}
} while (gamedone == 0);
}











[Edited by - burgert on January 24, 2009 10:45:48 PM]

Share this post


Link to post
Share on other sites
try replacing the & lt; and & gt; with regular < and > signs

Also, are you sure that the conditionals in the victory checking line are correct? Try adding parentheses to make sure it is evaluated the way it is supposed to be. Or just rewrite that part completely.

Share this post


Link to post
Share on other sites
i made a new version with a 2d array

#include <iostream>
#include <string>
using namespace std;
int main()
{
char mark;
const int rows = 3;
const int cols = 3;
char borad[rows][cols] = {{'1','2','3'},{'4','5','6'},{'7','8','9'}};
int move = 0;
bool gameover = false;
int player = 1;


while(!gameover) // game loop
{
for (int a = 0;a < rows; a++) // display borad
{
for (int b = 0;b < cols; b++)
{
cout << " " << borad[a][b] << " ";
}
cout << endl;
}
if (player == 1)
{
mark = 'x';
}
else
{
mark = 'o';
}
cout << "enter you move" << endl;
cin >> move; //get move
if (move == 1) // set move
{
borad[0][0] = mark;
}
else if (move == 2)
{
borad[0][1] = mark;
}
else if (move == 3)
{
borad[0][2] = mark;
}
else if (move == 4)
{
borad[1][0] = mark;
}
else if (move == 5)
{
borad[1][1] = mark;
}
else if (move == 6)
{
borad[1][2] = mark;
}
else if (move == 7)
{
borad[2][0] = mark;
}
else if (move == 8)
{
borad[2][1] = mark;
}
else if (move == 9)
{
borad[2][2] = mark;
}
if (borad[0][0] == borad[0][1] && borad[0][1] == borad[0][2] || borad[1][0] == borad[1][1] && borad[1][1] == borad[1][2] // check for win
|| borad[2][0] == borad[2][1] && borad[2][1] == borad[2][2] || borad[0][0] == borad[1][0] && borad[2][0] || borad[0][1]
== borad[1][1] && borad[1][1] == borad[2][1] || borad[0][2] == borad[1][2] && borad[1][2] == borad[2][2] || borad[0][0]
== borad[1][1] && borad [1][1] == borad[2][2] || borad[0][2] == borad[1][1] && borad[1][1] == borad[2][2])
{
cout << "you won player " << player << endl;
gameover = true;

}
if (player == 1)
{
player = 2;
}
else
{
player = 1;
}

}

return 0;
}




[Edited by - burgert on January 26, 2009 9:00:48 PM]

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