-1
\$\begingroup\$

Below is the game code written in cpp. This is the first time I have consciously used pointers. I can't handle the logic of winning. I have no idea how to solve this in a different, more accessible way. I know that such straining of if statements is bad and the code is unmaintable. I realize that for some reasons you can't use cls. What's the alternative?

#include <iostream>


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

int Checkwin();
void Board();
int Choice(char mark, char* square, int choice);
void showLeftNumbers(char sqiare[]);


int main()
{
    int player = 1, i, choice;


    char mark;
    do
    {
        int correctChoice = 1;
        Board();
        player = (player % 2) ? 1 : 2;

        mark = (player == 1) ? 'X' : 'O';
        int triesCount = 0;
        do
        {
            std::cout << "Player " << player << ", enter a number:  ";
            std::cin >> choice;
            correctChoice = Choice(mark, &square[choice], choice);
            triesCount++;
            if (triesCount > 2) showLeftNumbers(square);
        } while (correctChoice == 1);


        i = Checkwin();

        player++;
    } while (i == -1);
    Board();
    if (i == 1)

        std::cout << "==>\aPlayer " << --player << " win ";
    else
        std::cout << "==>\aGame draw";

    std::cin.ignore();
    std::cin.get();
    return 0;
}

/*********************************************
    FUNCTION TO JUDGE THE MOVE
    IF MOVE IS RIGHT THEN IT RETURNS 0 AND
    CHANGES THE VALUE
    IF MOVE IS FORBIDEN THEN IT  RETURNS 1
**********************************************/

int Choice(char mark, char* square, int choice) {
    int compare = *square - '0';
    if (choice < 1 || choice > 10)
    {
        std::cout << "Wrong choice! You have to choose number between 1 and 9. Number " << choice << " is out of scope!\n";
        return 1;
    }
    if (compare == choice) {
        *square = mark;
        return 0;
    }
    else
    {
        std::cout << "Already shoot in this place\n";
        return 1;
    }
}

/*********************************************
    FUNCTION TO SHOW PLAYERS LEFT NUMBERS 
    AFTER 3 FAILED ATTEMPTS
**********************************************/

void showLeftNumbers(char sqiare[])
{
    std::cout << "Man, you can choose just between ";
    for (int i = 1; i < 10; i++)
    {
        if (square[i] != 'X' && square[i] != 'O')
        {
            std::cout << i << " ";
        }
    }
    std::cout << "! ";
}

/*********************************************
    FUNCTION TO RETURN GAME STATUS
    1 FOR GAME IS OVER WITH RESULT
    -1 FOR GAME IS IN PROGRESS
    O GAME IS OVER AND NO RESULT
**********************************************/

int Checkwin()
{
    if (square[1] == square[2] && square[2] == square[3])

        return 1;
    else if (square[4] == square[5] && square[5] == square[6])

        return 1;
    else if (square[7] == square[8] && square[8] == square[9])

        return 1;
    else if (square[1] == square[4] && square[4] == square[7])

        return 1;
    else if (square[2] == square[5] && square[5] == square[8])

        return 1;
    else if (square[3] == square[6] && square[6] == square[9])

        return 1;
    else if (square[1] == square[5] && square[5] == square[9])

        return 1;
    else if (square[3] == square[5] && square[5] == square[7])

        return 1;
    else if (square[1] != '1' && square[2] != '2' && square[3] != '3'
        && square[4] != '4' && square[5] != '5' && square[6] != '6'
        && square[7] != '7' && square[8] != '8' && square[9] != '9')

        return 0;
    else
        return -1;
}


/*******************************************************************
     FUNCTION TO DRAW BOARD OF TIC TAC TOE WITH PLAYERS MARK
********************************************************************/


void Board()
{
    system("cls");
    std::cout << "\n\n\tTic Tac Toe\n\n";

    std::cout << "Player 1 (X)  -  Player 2 (O)\n\n\n";

    std::cout << "     |     |     \n";
    std::cout << "  " << square[1] << "  |  " << square[2] << "  |  " << square[3] << "\n";

    std::cout << "_____|_____|_____" << "\n";
    std::cout << "     |     |     " << "\n";

    std::cout << "  " << square[4] << "  |  " << square[5] << "  |  " << square[6] << "\n";

    std::cout << "_____|_____|_____" << "\n";
    std::cout << "     |     |     " << "\n";

    std::cout << "  " << square[7] << "  |  " << square[8] << "  |  " << square[9] << "\n";

    std::cout << "     |     |     \n\n";
}

/*******************************************************************
                END OF PROJECT
********************************************************************/
\$\endgroup\$
4
  • \$\begingroup\$ Because the code is not working as expected the question is off-topic on Code Review. We only review code that is working as expected, there are other sites that will help you debug your code. Please read Where can I get help? and How do I ask a good question?. \$\endgroup\$
    – pacmaninbw
    Commented Oct 23, 2022 at 14:50
  • \$\begingroup\$ Hint the call to Checkwin() needs to be in the loop. \$\endgroup\$
    – pacmaninbw
    Commented Oct 23, 2022 at 14:50
  • \$\begingroup\$ I was able to play a game against myself. I'm not sure where the "not working as expected" comes from. \$\endgroup\$
    – aghast
    Commented Oct 24, 2022 at 17:24
  • \$\begingroup\$ What's the meaning of "I can't handle the logic of winning."... \$\endgroup\$
    – JimmyHu
    Commented Oct 25, 2022 at 1:58

1 Answer 1

1
\$\begingroup\$

Some issues I can see:

  1. I don't see many pointers. If you don't want to use them, maybe change the title of this post.

  2. It's not clear what your naming convention is for functions. You have Checkwin and showLeftNumbers and main. I'll suggest that you should use a convention where main is not a rule violation, so either snake_case or camelCase (or even, God forbid, Ada_Case_Oh_No_Make_It_Stop_Please).

  3. Don't use the same naming style for variables and functions.

  4. You can use cls, but only where cls works -- which would be on Windows. For Unix, the corresponding program is clear. You can use the pre-processor #ifdef to check whether you are compiling a Windows or Unix program.

main

  1. Please don't bulk-declare unrelated variables, especially with initializers mixed in.

  2. Don't mix "high level" code and "low level" code. Your main makes good use of calling high-level functions, but then grabs std::cout to do post-game wrap up. Write another function for that.

  3. It looks like you just discovered the do{}while loop and you're over-using it a bit. Don't be afraid to (a) not use it at all; or (b) mix the while-do and do-while forms.

  4. Your inner loop (with triesCount) should probably be a separate function (getMove or something).

  5. Why are you referring to "Player 1" and "Player 2"? The sides are "X" and "O" and everyone knows them that way.

Choice

  1. DON'T USE ALL UPPER CASE FOR FUNCTION HEADER COMMENTS. IT'S HARDER TO READ THAN JUST NORMAL TEXT, AND YOUR GIANT LINE OF ASTERISKS HAS ALREADY WARNED ME THAT THE HEADER IS NOT REGULAR CODE.

  2. You are validating your input (choice) in this function, but you should have done that in the function where you collected the input (main, in this case, but that should also change).

  3. You return 0 or 1, but I think you mean to return true or false.

showLeftNumbers

  1. (minor) This may be an ESL problem, but this should probably be named showRemainingNumbers or showNumbersLeft.

  2. You never print a newline.

Checkwin

  1. You mean CheckWin or checkWin.

  2. You return either 0, 1, or -1, but only test for -1 in main. You are using this function in a way that it was not intended to be used.

  3. Your comment about ifs makes sense mainly in this function. IMO, this is a valid way to check for a win, but there's another opportunity for pointers here: write a function that takes a pointer to an array of three integers, and then call it eight times.

  4. For extra credit, you might consider a tri-valued function that returns win, no-win, and not-yet-but-could-still-happen. Then if you ever get no-win you can stop the game immediately instead of requiring it to play out.

Board

  1. Move your system("cls") call into a separate function. Put the "cls" into a preprocessor macro or constant.

  2. Write functions for printing a row, and printing other lines, and use them. (Hint: here's a chance to pass pointers again!)

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.