2012-03-12 24 views
1

このような状況でgoto okを使用している場合、私は知っておきたいのですか?あなたはより良い解決策を提案できますか?私はcicleの間に2番目にする唯一のものを見ますが、それから2回 "makeMove"を呼び出す必要があります。このような状況でgotoを使うことができますか?

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; 
     } 
    } 
} 
+3

ループまたは別の関数。 – PlasmaHH

+0

gotoを使用しないでください。 –

+1

@PlasmaHHループ*と*は別個の機能です。入力は実際に別の関数に組み込む必要があります。 –

答えて

4

gotoを使用しないでください。あなたが成功したときにwhile (true)ループとbreakを使ってください。

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"; 
} 
+1

もちろん、別の名前の下に隠れているのはちょうど「goto」です。 –

+4

@JamesKanze:はい、しかし、プログラム内のランダムな場所の代わりにスコープの終わりにジャンプするものです。それに加えて、すべての制御構造は偽装されています。 –

+0

しかし、元の問題は修正されておらず、彼はその機能であまりにも多くのことをやろうとしています。 –

1

多分:

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(); 
    } 
} 

それはまったく同じではないのですが、それは後藤を使用しません。

1

はい、このようなジャンプをすることはできますが、通常はgotoを避ける方がよいです。あなたは、例えば、このようにそれを書き換えることができます:

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"; 
     } 
    } 
} 
1

一般的なアドバイスは

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); 
    } 
} 
0

は、あなたが同じくらいすることができますように後藤を避ける必要がありながら行うと変更されたコードを参照してください、ただし、GOTO文を避けるためです。大規模なネストされたプログラムで使用する場合にのみ使用してください。そうでなければgotoを使用すると、プログラムが信頼できなくなり、読めなくなり、デバッグが困難になります。 gotoのもう一つの大きな問題は、コードを使用するときに、コードの特定の点にどのように到達したかを決して確かめることができないことです。制御の流れをあいまいにしています。だから避けてください。私はwhileループ2を使用することをお勧め

....それは間違っていると何...

0

良くなります。

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(); 
     } 
    } 
} 

(私は移動タイプの明示的なクラスを好むだろうが、いうよりも だけstd::pair。メンバーrowcolumnは、より多くの 明示firstsecondよります。)

通常、あなたがしている場合トンgoto(またはさらにcontinueまたは break)によって払い戻された場合、それは1つの機能にあまりにも多くを置くという症状です。

+0

私はあなたがイデオロギー的に正しいと思います。しかし、効率はどうですか?ペアの使用、関数呼び出し、戻り値... –

+0

@Fippo効率はどうですか?コードが遅すぎますか?プロファイラはこれをボトルネックと見なしましたか?実際には、ボトルネックが特定されると、最も効率的なコードが最もカプセル化されたコードになります。これにより、アルゴリズムとデータ構造に対する最も根本的な変更が可能になるからです。 –

0

二つのループのない一定の条件式、及び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; 
     } 
    } 
} 
関連する問題