tic tac toe

im stuck writing the players input with this program. if fine with writing it if there were two players but i was told to use one player so im confused on what to write. if you got any ideas please let me know. thanks

#include <iostream>

using namespace std;

void input (char board [3] [3]);
void print (char board [3] [3]);
bool win (char board [3] [3], char player);


int rows;
int cols;

int main ()
{


//declare player

char player;
char player_input;
cout<< "Player please make your move.";
cin >> player_input;

//input and print functions
input(board);
print(board);

//if statements for winner
//if ()

system("PAUSE");
return 0;
}

void input (char board [3] [3])
{
// for (board = 0; board < 3; board++)
{

}

//cin, for loops

}


void print (char board [3] [3])
{
cout<<"\n\nThe board is:\n\n";

for (rows = 0; rows < 2; rows++)
{
for (cols =0; cols < 2; cols++)
{
cout<<" |";
cout <<board[rows][cols];
}
cout <<"\n";
cout<<"---------\n";

}
}

bool win (char board [3] [3], char player)
{

/* //straight across columns
if (char board [0][0]==player,char board [0][1]==player,char board [0][2]==player)
cout<<"Player " << player1 <<" has won!"
else
if (char board [1][0]==player,char board [1][1]==player,char board [1][2]==player)
cout<<"Player " << player1 <<" has won!"
else
if (char board [2][0]==player,char board [2][1]==player,char board [2][2]==player)
cout<<"Player " << player1 <<" has won!"

//straight up and down rows
else
if (char board [0][0]==player,char board [1][0]==player,char board [2][0]==player)
cout<<"Player " << player1 <<" has won!"
else
if (char board [0][1]==player,char board [1][1]==player,char board [2][1]==player)
cout<<"Player " << player1 <<" has won!"
else
if (char board [0][2]==player,char board [1][2]==player,char board [2][2]==player)
cout<<"Player " << player1 <<" has won!"

// diagonal win
else
if (char board [0][0]==player,char board [1][1]==player,char board [2][2]==player)
cout<<"Player " << player1 <<" has won!"


// need to "return true; and winner should be announced in main
*/
}
If you were told to use one player, I would assume the other player is the computer.
no it's a two player and it's suppose to pass through as player x or player o somehow
closed account (9y8C5Di1)
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
void print_board(char array[]){
system("cls");
 for(unsigned x = 0;x<9;++x){
  if(x==2||x==5) cout<<array[x]<<"\n";
   else cout<<array[x];

 }

}


int main(){
 char xoro='o';
  unsigned pos;
   bool done=false;
    char array[9];
     for(unsigned x = 0;x<9;++x){array[x]=48+x;}

while(done==false){
 re:;
  cout<<"\n\nenter pos: ";
   cin>>pos;
    if(array[pos]!='x'&&array[pos]!='o') array[pos]=xoro;
     else goto re;
      print_board(array);
pos=0;
for(char x='x';pos<2;++pos,x='o'){
//do the evaluation
//if true done=true
}
 if(done==false)
  if(xoro=='x')
   xoro='o';
    else xoro='x';
}
 cout<<xoro<<" wins."<<endl;
  cin.get();
   return 0;}



Else, with comp opponent, you could:

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

using namespace std;

void print_board(char array[]){
system("cls");
 for(unsigned x = 0;x<9;++x){
  if(x==2||x==5) cout<<array[x]<<"\n";
   else cout<<array[x];

 }

}


int main(){
 char xoro='o';
  unsigned pos;
   bool done=false;
    char array[9];
     for(unsigned x = 0;x<9;++x){array[x]=48+x;}
      srand(time(NULL));

while(done==false){
 re:;
  cout<<"\n\nenter pos: ";
   if(xoro=='x')
    cin>>pos;
     else pos=0+rand()%8;
      if(array[pos]!='x'&&array[pos]!='o') array[pos]=xoro;
       else goto re;
        print_board(array);
pos=0;
for(char x='x';pos<2;++pos,x='o'){
//do the evaluation
//if true done=true
}
 if(done==false)
  if(xoro=='x')
   xoro='o';
    else xoro='x';
}
 cout<<xoro<<" wins."<<endl;
  cin.get();
   return 0;}
Last edited on
@sebelius

You can use the continue statement instead of the thoroughly bad goto.
closed account (9y8C5Di1)
How is goto bad?
Goto is so bad that you should forget that C++ even has such a facility. There is no need for it in C++ - use loops with break or continue, or use functions, return a value or throw an exception.

In C programming there are a small number of cases where it might be used, with some restrictions: like go a short distance down through the code (the label comes after the goto). The most common use is to get out of nested loops.

My main point is not to use goto routinely, when there are plenty of other valid & better ways of achieving the same thing.

You can google to see what other people think.
> How is goto bad?

goto is not bad, per se. What is bad is writing code that is convoluted and not easy to understand. That we think of using a goto is the symptom, not the disease.

Write poorly structured code, and eliminate all use of goto with labyrinthine constructs involving loops, break, continue etc,. And what you would be left with is bad code without goto instead of bad code with goto.

There has been far too much emphasis on go to elimination instead of on the really important issues; people have a natural tendency to set up an easily understood quantitative goal like the abolition of jumps, instead of working directly for a qualitative goal like good program structure…. Probably the worst mistake any one can make with respect to the subject of go to statements is to assume that “structured programming” is achieved by writing programs as we always have and then eliminating the go to‘s
Donald Knuth in “Structured Programming with go to Statements” (1974)
closed account (9y8C5Di1)
What you are saying is that there's nothing wrong with the efficiency of the goto statement. However, overuse may result in the perceivance of messy code to any other than the writer.
I didnt really get your point, but i don't care as long as it works, and no major performance is lost.
but i don't care as long as it works, and no major performance is lost.


Now to invoke the saying: "Just because it works, doesn't mean it is right".

As I said you could have used the continue statement (restarts the current iteration of a loop) instead of the goto, for exactly the same effect. If you had have done that it wouldn't have drawn a comment from me.

The other thing is that, beginners look at these posts, see someone using goto - start using it themselves, which then easily leads to poorly structured code that JLBorges mentioned.

Imagine you have a job as a C++ programmer, if your boss & colleagues regularly see you using goto, they might be entitled to think that you don't really know what you are doing. Any maintenance programmer is bound to complain.

If someone did a survey of a bunch of experienced programmers, and asked them how often they used goto statements, I am guessing the answer would be very seldom.

As for what Donald Knuth said, the problem is that it is very easy to finish up with messy code using goto. I can't help thinking the only valid use in C (not C++) is to jump out of nested loops. That may have been the reason why goto was left in the C language. It 's only there in C++ because C++ is a superset of C.

A good example of what Knuth is talking about is the following which I have mentioned in other posts.

Some students, in preparation for a class on asm were asked to convert a simple C program into code which only used if statements and goto - no else if, else, loops, switches or functions . So, upon finishing that, you have a well structured program with goto's everywhere.

That is fine for getting an idea of how asm works, but is so easily abused otherwise.

Any way there have been huge debates about this in the past. As I said there is plenty of comment out there on the web.
> What you are saying is that there's nothing wrong with the efficiency of the goto statement.

I didn't specifically say that in my earlier post. But, yes, there's nothing wrong with the efficiency of the goto statement.

That compilers optimized flow control constructs better than jumps was probably true at some point in history; around the time that compilers would generate more efficient code if a program used a shift operation instead of a multiply. Current C++ compilers perform data flow analysis; it makes no difference to the optimiser whether a goto was used or a break or continue was used. (Unless the over-zealous banishment of a goto resulted in a needless exception being thrown; in which case the removing the goto would degrade performance.)

Perhaps I didn't say it very well. What I intended to say was this:

Dijkstra's "Go To Statement Considered Harmful" letter to the CACM was written some 55 years ago; at a time when many of the widely used programming languages did not have (or had limited forms of) the kind control flow constructs that we now routinely use. Dijkstra's main point was that languages should support better control structures than what was prevalent at that time. And that programmers who were moving to the newer languages should start using the newer control flow constructs.

In C/C++ code, "goto" is limited to the scope of a single function (unlike setjmp and longjmp), and the control flow is as easy to follow as a continue or break. Unless the function has 237 lines of code; in which case just eliminating a "goto" does nothing to make the code better. Bad programmers write bad code; and the magic wand of banish "goto" is not going to change that.

"goto" is one of the many tools in the toolset, and it can be abused; one could even say that it has a proclivity towards being abused. There are people who believe that a lot of other tools too are unmitigated evil - pointers, operator overloading, exceptions, static members, metaprogramming, C++ ... Any useful tool is used well by people who know how to use it, and abused by people who don't.

Over a short distance with meaningful labels, "goto" can be as (sometimes more) effective, clean and understandable than an assemblage of flags in nested looping constructs.

Would this real-life (so I believe, it was on the internet, in a discussion of goto) C code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int parse()
{
    Token tok ;

    reading:
        tok = gettoken() ;
        if( tok == END ) return ACCEPT ;

    shifting:
        if( shift(tok) ) goto reading ;

    reducing:
        if( reduce(tok) ) goto shifting ;

    return ERROR ;
}

become simpler or more elegant if we banished the gotos?


If while writing C++, I find myself considering the use of a "goto", there are these possibilities:

a. I have written bad code; I need to take a hard look at it; see how it can be restructured (most likely).

b. "goto" is the simplest, most elegant way in which I can express the intent of this code (less likely).

c. Somehow, anyhow, just eliminate that evil "goto", and my grotesque code will magically transmogrify itself into an art form of sublime beauty (so unlikely, that this situation is almost non-existent.)


My suggestion to beginners would be:
If you find yourself using a "goto", have a re-look at the structure of your code; chances are that it can be improved.
closed account (9y8C5Di1)
using continue, goto, break, still asks your mind to go from point a, to point b when reading the code

if you use continue, you need to go from the continue statement to the beginning of a preceeding loop.

if you goto, it's the same prompt, only you need to locate the matching label.
Most text editors supports "find word", which in fact makes it even easier to locate a goto label, than to scroll up to the begining of a loop using continue.

I agree that i could have used continue, but if a goto is as efficient, and as in this example not very hard to read, i see no reason why not.

Imagine you have a job as a C++ programmer, if your boss & colleagues regularly see you using goto, they might be entitled to think that you don't really know what you are doing. Any maintenance programmer is bound to complain.


That's basically the equivalent of meeting a beautiful girl, but discarding her for the wart in her face.
but i don't care as long as it works

What you're really saying is that you don't care about the quality of your code.

But if you've come here to learn and improve the quality of your code, then your should really listen to what more experienced programmers are telling you.

As I said in another recent tic-tac-toe thread on the use of gotos,
http://www.cplusplus.com/forum/beginner/92944/

If you think gotos are easy, you've never had do debug a program with hundreds of gotos pointing backwards and forwards, and try and figure out how you got to a certain point in the code.

The problem with gotos is not where does it go, but rather "how did I get here"? Consider a program with 14 gotos that all jump to the same label. No way to tell how you got to the label. By comparison, a structured loop (while, do while, for) has an explicit entrance and an explicit exit. No question about the flow of the program.

As a programming manager, if I found one of my programmers using gotos instead of a structured loop, he wouldn't be working for me for very long.

and
The use of gotos is the result of either being lazy, lack of coding discipline, not understanding structured programming, or not understanding how to code a proper loop.


I agree with JLBorges' post in that there can be appropriate places to use gotos. If you look at the code generated by state machine generators or parser generators (a type of state machine), you'll see that they do use gotos, but the author of the code generator clearly knows what he's doing.

As a beginning programer, gotos are something that you should stay away from. The use of gotos encourage bad programming habits.
That's basically the equivalent of meeting a beautiful girl, but discarding her for the wart in her face.


Well you are entitled to your view, but I am trying to point out that those in industry probably won't agree, and this might have a negative effect on your perceived ability. Perceptions are more important than what a lot of people think. If you were to show code like that in a job interview situation - you might not get the job. If you use goto in code for university assignments - you are likely to be marked down.

Do you do any study at University or know any programmers in industry? It would be interesting to see what the professors / programmers say.

The fact you have used goto when such a simple (and more valid IMO) alternative exists, means that you haven't thought about the proper way of doing it, and reverted to the very easy goto. That's what JLBorges advice was about:

My suggestion to beginners would be:
If you find yourself using a "goto", have a re-look at the structure of your code; chances are that it can be improved.

> That's what JLBorges advice was about:

What I was attempting to convey was that

A (original)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
while(done==false)
{
repeat: cout<<"\n\nenter pos: ";
        if(xoro=='x')
            cin>>pos;
        else pos=0+rand()%8;
        if(array[pos]!='x'&&array[pos]!='o') array[pos]=xoro;
        else goto repeat ;
        print_board(array);
        pos=0;
        for(char x='x'; pos<2; ++pos,x='o')
        {
             //do the evaluation
             //if true done=true
        }
        if(done==false)
            if(xoro=='x')
                xoro='o';
            else xoro='x';
}

cout<<xoro<<" wins."<<endl;

is not qualitatively improved by
B (replace goto with continue)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
while(done==false)
{
    cout<<"\n\nenter pos: ";
    if(xoro=='x')
        cin>>pos;
    else pos=0+rand()%8;
    if(array[pos]!='x'&&array[pos]!='o') array[pos]=xoro;
    else continue ;
    print_board(array);
    pos=0;
    for(char x='x'; pos<2; ++pos,x='o')
    {
         //do the evaluation
         //if true done=true
    }
    if(done==false)
        if(xoro=='x')
            xoro='o';
        else xoro='x';
}

cout<<xoro<<" wins."<<endl;


But if the presence of the goto had lead to something a bit more meaningful than: 'goto is evil; remove it from the code', we might have ended up with two small functions
1
2
3
bool player_wins( char array[], char player ) ; // return result of evaluation

inline char other_player( char xoro ) { return xoro == 'x' ? 'o' : 'x' ; }

and then
C (re-structure the code)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
char mover ;
do
{
    mover = xoro ;
    cout<<"\n\nenter pos: ";
    if(xoro=='x') cin>>pos;
    else pos=0+rand()%8;
    if(array[pos]!='x'&&array[pos]!='o')
    {
        array[pos]=xoro; 
        print_board(array);
        pos=0;
        xoro = other_player(xoro) ;
    } 
} while( !player_wins(array, mover ) ) ;

cout << mover << " wins." << endl ;


which IMHO is an improvement.

In other words, the goal should be to write clear, succint, well-structured code. The mantra of 'avoid goto' focusses on suppressing one symptom, without any attempt to eradicate the cause.
Last edited on
closed account (9y8C5Di1)
but i don't care as long as it works

What you're really saying is that you don't care about the quality of your code.


No, what i am saying is that i don't find it essential to study for an hour how my code is formatted, but rather how it functions.

I agree on this simple concept:
If a more elegant/better/efficient solution is found, then discard the previous, unless of course a more valuable factor opposes. So i agree i should have used continue.


Do you do any study at University or know any programmers in industry? It would be interesting to see what the professors / programmers say.


No, i'm teaching myself, i don't know any other programmers, and that's probably why i never get to hear about this sort of stuff, until of course i post one of my codes onto a forum.

But thanks for making me rethink if i should use goto/break/continue or not.
Topic archived. No new replies allowed.