Thread: TicTacToe board problem

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102

    Unhappy TicTacToe board problem

    Hello, i'm having a problem with a tic tac toe game. If CPU tries to put 'O' where already is 'O' or 'X', the program crashes.

    Code:
    /*Here is the board, each letter is a variable
      a | b  | c
    ____|____|____
      d | e  | f  
    ____|____|____
      g | h  | i  
        |    |    
    */
    
    void CPUp() //function to put in CPU's choice
    {
    cgennum(); //generates random number for variable cpu_line
         
    switch(cpu_line)
    {
                    case 1: if(a=='a') a = 'O'; else {again();} break;
                    case 2: if(b=='b') b = 'O'; else {again();} break;
                    case 3: if(c=='c') c = 'O'; else {again();} break;
                    case 4: if(d=='d') d = 'O'; else {again();} break;
                    case 5: if(e=='e') e = 'O'; else {again();} break;
                    case 6: if(f=='f') f = 'O'; else {again();} break;
                    case 7: if(g=='g') g = 'O'; else {again();} break;
                    case 8: if(h=='h') h = 'O'; else {again();} break;
                    case 9: if(i=='i') i = 'O'; else {again();} break;
    }
    }
    
    void again() //function to generate another number if the current slot is already full
    {
    cpu_line = backup;
    while (cpu_line == backup)
    {
          cgennum();
    } //when cpu_line changes, try to put 'O' again
    CPUp();
    }
    I hope you understand me, any help would be grateful. If you want, I can post the whole source code here.

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Code:
    cpu_line = backup;
    while (cpu_line == backup)
    {
          cgennum();
    }
    This while loop never ends.

    EDIT: Actually it may end, assuming cpu_line and backup are globals... Can you show the definition of cgennum()?
    Last edited by Mario F.; 07-17-2006 at 10:02 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    It would probably be easier too if you labelled the elements of the TTT game area from 0 to 8 (or 1 to 9). I see why you used letters though.

    How long is the whole source?

  4. #4
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102
    Here it is, all the code. Compile it, it works, but the program crashes when CPU attempts to put in 'O', where it already is.
    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <time.h>
    using namespace std;
    
    
    
    const int LOW = 1;
    const int HIGH = 9;
    char location;
    char location1;
    char winningsuccess='y';
    char state='n';
    int cpu_line;
    int backup;
    int q=0;
    char a = 'a', b = 'b', c = 'c', d = 'd', e = 'e', f = 'f', g = 'g', h = 'h', i = 'i';
    
    
    
    void showmap();
    void cgennum();
    void check();
    void again();
    void user();
    void CPUp();
    
    /*laukums
    
    cout<<"  a | b  | c
    cout<<"____|____|____"<<endl;
    cout<<"  d | e  | f  "<<endl;
    cout<<"____|____|____"<<endl;
    cout<<"  g | h  | i  "<<endl;
    cout<<"    |    |    "<<endl;
    */
    
    
    int main()
    
    {cout<<"Sveicinati spele desas!\nSaciet spelet!\n\n";
    do{
    
    
    showmap();
    
    cin>>location;
    
    cin.ignore();
    
    system("cls");
    
    user();
    
    CPUp();
    
    check();
    
    
    } while (state!=winningsuccess);
    showmap();
    cout<<"Uzvara!";
    cin.get();
    return 1;
    }
    
    void showmap()
    {
    cout<<"laukuma karte:\n";
    cout<<"  "<<a<<" | "<<b<<"  | "<<c<<" "<<endl;
    cout<<"____|____|____"<<endl;
    cout<<"  "<<d<<" | "<<e<<"  | "<<f<<"  "<<endl;
    cout<<"____|____|____"<<endl;
    cout<<"  "<<g<<" | "<<h<<"  | "<<i<<"  "<<endl;
    cout<<"    |    |    \n";
    }
    
    void user()
    {
    switch(location)
    {
                    case 'a': if(a=='a') a = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'b': if(b=='b') b = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'c': if(c=='c') c = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'd': if(d=='d') d = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'e': if(e=='e') e = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'f': if(f=='f') f = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'g': if(g=='g') g = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'h': if(h=='h') h = 'X'; else cout<<"Tur jau ir ielikts"; break;
                    case 'i': if(i=='i') i = 'X'; else cout<<"Tur jau ir ielikts"; break;
    }
    }
    
    void cgennum() //changes cpu_line
    {
    time_t seconds;
    time(&seconds);
    srand((unsigned int)seconds);
    cpu_line = rand() % ( HIGH - LOW + 1) + LOW;
    }
    
    void CPUp()
    {
    cgennum();
         
         switch(cpu_line)
    {
                    case 1: if(a=='a') a = 'O'; else {again();} break;
                    case 2: if(b=='b') b = 'O'; else {again();} break;
                    case 3: if(c=='c') c = 'O'; else {again();} break;
                    case 4: if(d=='d') d = 'O'; else {again();} break;
                    case 5: if(e=='e') e = 'O'; else {again();} break;
                    case 6: if(f=='f') f = 'O'; else {again();} break;
                    case 7: if(g=='g') g = 'O'; else {again();} break;
                    case 8: if(h=='h') h = 'O'; else {again();} break;
                    case 9: if(i=='i') i = 'O'; else {again();} break;
    }
    }
    
    void again()
    {
    cpu_line = backup;
    while (cpu_line == backup)
    {
          cgennum();
    }
    CPUp();
    }
    
    void check()
    {
         if((a==b && b==c) || (d==e && e==f) || (g==h && h==i) || (a==d && d==g) || (b==e && e==h) || (c==f && f==i) || (a==e && e==i) || (g==e && e==c))
         state = 'y';
    }
    Last edited by Overlord; 07-17-2006 at 10:38 AM.

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ugh! you really have to review your indentation policy

    Anyways, the program flow seems faulty. When the computer makes his move, it generates a random number between 1 and 9. It checks that location. If there is something there already (0 or X) it calls again(). Again() generates a new number and calls the CPup() again... but yet a new number is generated at the top of CPUp()...
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You don't need again(), just make a loop inside CPUp.

    Also, you should only be calling srand once, at the beginning of your program.

  7. #7
    Registered User mrafcho001's Avatar
    Join Date
    Jan 2005
    Posts
    483
    I wrote this TTT a while ago when i was learning...
    http://martin.thejefffiles.com/TTT.rar
    My Website
    010000110010101100101011
    Add Color To Your Code!

  8. #8
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102
    I tried with a loop, the same...

    Code:
    void CPUp()
    {
    cgennum();
         
         switch(cpu_line)
    {
                    case 1: if(a=='a') a = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 2: if(b=='b') b = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 3: if(c=='c') c = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 4: if(d=='d') d = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 5: if(e=='e') e = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 6: if(f=='f') f = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 7: if(g=='g') g = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 8: if(h=='h') h = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
                    case 9: if(i=='i') i = 'O'; else {cpu_line = backup; while (cpu_line == backup){CPUp();}} break;
    }
    }
    If my loop isn't correct, just say.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    No, don't call any function, just put the whole thing in a single loop. There is no need for backup either. If the space is unoccupied, then return from the function, otherwise the loop will continue.

  10. #10
    Registered User
    Join Date
    Feb 2006
    Posts
    43
    Shouldn't this
    Code:
    cpu_line = backup;
    be
    Code:
    backup = cpu_line;
    Because backup never gets initiated. And i'm guessing that the while(cpu_line==backup) loop is supposed to keep looping until you get something for cpu_line that isn't the value you just tried. So therefore you want backup to equal the value that cpu_line just had. Make sense?

  11. #11
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102

    Smile

    Thanks man! Now the program works! Thanks to you all! Now you can add another working ticTacToe game to your collection.

  12. #12
    Registered User
    Join Date
    Feb 2006
    Posts
    43
    Haha that makes two
    Glad I could help

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Now that its working, you should consider trying to get rid of the again() function as an exercise. That design will cause problems if you use it more complex games (if there is only one space left you could easily get a stack overflow). It shouldn't be too hard to get it to work with a single while loop, so it might be worth it to try.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  2. Problem with my file opener
    By kzar in forum C Programming
    Replies: 7
    Last Post: 04-20-2005, 04:20 PM
  3. Possible problem with board? (again)
    By biosninja in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 09-25-2002, 02:43 PM
  4. Problem with user count on board?
    By biosninja in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 09-13-2002, 05:49 AM