user1190294
user1190294

Reputation:

May I use goto in such situation?

I'd like to know, if using goto ok in such situation? Can you suggest better solution? I see the only one to make second while cicle but then it would be necessary to call "makeMove" two times.

void BoardView::startGame()
{
    int currStep=0;
    int x,y;
    while (board_->isWin()==none)
    {
        currStep++;
        show();
    wrong:
        std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
        std::cin >> x;
        y=x%10;
        x/=10;
        if (!board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        {
            std::cout << "Wrong move! Try again.\n";
            goto wrong;
        }
    }
}

Upvotes: 1

Views: 260

Answers (7)

user2044859
user2044859

Reputation: 391

Two loops, no constant conditional expression, and only one call to makeMove:

void BoardView::startGameLoop()
{
    int currStep = 0;
    int x,y;
    while (none == board_->isWin())
    {
        ++currStep;
        show();

        for (;;)
        {
            std::cout << " Player " << ((currStep & 1) + 1) << ": ";
            std::cin >> x;
            y = x % 10;
            x /= 10;
            if (!board_->makeMove(x, y, (currStep & 1) ? zero : cross))
            {
                std::cout << "Wrong move! Try again.\n";
                continue;
            }
            break;
        }
    }
}

Upvotes: 0

James Kanze
James Kanze

Reputation: 153909

What's wrong with:

std::pair<int, int> BoardView::getNextMove()
{
    std::cout << " Player " << (currStep & 2 == 0 ? 1 : 2) << ": ";
    int tmp;
    std::cin >> temp;
    return std::pair<int, int>( tmp / 10, tmp % 10 );
}

void BoardView::startGame() 
{
    int currentStep = 0;
    while ( myBoard->isWin() == none ) {
        std::pair<int, int> move = getNextMove();
        while ( ! myBoard->makeMove( move, (currentStep % 2 == 0 ?  cross : zero) ) {
            std::cout << "Wrong move! Try again" << std::endl;
            move = getNextMove();
        }
    }
}

(Although I'd prefer an explicit class for the Move type, rather than just std::pair. Members row and column are a lot more explicit than first and second.)

Usually, if you're tempted by a goto (or even a continue or a break), it's a symptom of putting too much in a single function.

Upvotes: 0

user1237385
user1237385

Reputation:

you should avoid goto as much as you can.use only when using in large nested programs. otherwise use of goto makes the program unreliable,unreadable,and hard to debug. one more big problem with goto is that when we do use them we can never be sure how we got to certain point in our code.they obscure the flow of control. so avoid them.

I suggest use two while loops.... it will be better...

Upvotes: 0

alkber
alkber

Reputation: 1436

General Advice is to avoid GOTO statement, However, see the modified code with do while

    void BoardView::startGame()
{
    int currStep=0;
    int x,y;
    while (board_->isWin()==none) {

        currStep++;
        show();
        int retry = 0; /* So that 'retry' is visible to do while loop */ 
        do {
              retry = 0;
              std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
              std::cin >> x;
              y=x%10;
              x/=10;
             if (!board_->makeMove(x,y,(currStep%2==0 ? cross : zero))) {

                std::cout << "Wrong move! Try again.\n";
                retry = 1
             } 

       } while (retry);
    }
}

Upvotes: 1

CygnusX1
CygnusX1

Reputation: 21779

Yes, you are allowed to make such jump, although it is usually better to avoid goto. You could rewrite it like this for example:

void BoardView::startGame()
{
    int currStep=1;
    int x,y;
    show();
    while (board_->isWin()==none)
    {
        std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
        std::cin >> x;
        y=x%10;
        x/=10;
        if (board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        {
            currStep++;
            show();
        }
        else
        {
            std::cout << "Wrong move! Try again.\n";
        }
    }
}

Upvotes: 1

Pawel Zubrycki
Pawel Zubrycki

Reputation: 2713

Maybe:

void BoardView::startGame()
{
    int currStep=1;
    int x,y;
    show();
    while (board_->isWin()==none)
    {
        std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
        std::cin >> x;
        y=x%10;
        x/=10;
        if (!board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        {
            std::cout << "Wrong move! Try again.\n";
            continue;
        }
        ++currStep;
        show();
    }
}

It's not exactly the same, but it doesn't use goto.

Upvotes: 1

Fred Foo
Fred Foo

Reputation: 363547

Don't use goto. Use a while (true) loop and break out of it when you've made a successful move.

while (true) {
    std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
    std::cin >> x;
    y=x%10;
    x/=10;
    if (board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        break;
    std::cout << "Wrong move! Try again.\n";
}

Upvotes: 4

Related Questions