C++:帮助理解此行代码的含义

3

我是编程新手,从Codeacademy开始学习C++。这是一个非常基础的问题,感谢您的帮助。

这个程序的目的是构建一个井字棋游戏。我想了解可用解决方案。在浏览程序时,我看到了其中一个函数,名为void set_position(),它用于确定玩家想要在棋盘上哪个位置(从1到9)进行游戏。为了更好地理解我的问题,我将在下面贴出整个代码块。

void set_position() {

  std::cout << "Player " << player << "'s Turn (Enter 1-9): ";
  while (!(std::cin>>position)) {

    std::cout << "Player " << player << ", please enter a valid number between 1 and 9: ";
    std::cin.clear();
    std::cin.ignore();

  }

我的问题是,while(!(std::cin>>position)) 如何确保输入的数字在1到9之间?
编辑后补充说明: 程序一开始将用户定义的变量 position 初始化为0。我没有在程序中找到 position 被强制限制在 1 到 9 之间的代码。这是完全有可能的,如果我确实漏看了,我会在下面添加整个代码。由于这是一个解决方案,我不确定是否可以在公共论坛上粘贴它。
#include <iostream>
#include "play.hpp"

std::string board[9] = {" ", " ", " ", " ", " ", " ", " ", " ", " "};
int player = 1;
int position = 0;

void introduction() {

  std::cout << "Press [Enter] to begin: ";
  std::cin.ignore();

  std::cout << "\n";

  std::cout << "===========\n";
  std::cout << "Tic-Tac-Toe\n";
  std::cout << "===========\n\n";
  
  std::cout << "Player 1) ✖\n";
  std::cout << "Player 2) ⊙\n\n";

  std::cout << "Here's the 3 x 3 grid:\n\n";

  std::cout << "     |     |      \n";
  std::cout << "  1  |  2  |  3   \n";
  std::cout << "_____|_____|_____ \n";
  std::cout << "     |     |      \n";
  std::cout << "  4  |  5  |  6   \n";
  std::cout << "_____|_____|_____ \n";
  std::cout << "     |     |      \n";
  std::cout << "  7  |  8  |  9   \n";
  std::cout << "     |     |      \n\n";

}

bool is_winner() {

  bool winner = false;
  // rows
  if ((board[0] == board[1]) && (board[1] == board[2]) && board[0] != " ") {
    winner = true;
  } else if ((board[3] == board[4]) && (board[3] == board[5]) && board[3] != " ") {
    winner = true;
  } else if ((board[6] == board[7]) && (board[6] == board[8]) && board[6] != " ") {
    winner = true;
  } 
  // columns
  else if ((board[0] == board[3]) && (board[0] == board[6]) && board[0] != " ") {
    winner = true;
  } else if ((board[1] == board[4]) && (board[1] == board[7]) && board[1] != " ") {
    winner = true;
  } else if ((board[2] == board[5]) && (board[2] == board[8]) && board[2] != " ") {
    winner = true;
  } // diagonals
  else if ((board[0] == board[4]) && (board[0] == board[8]) && board[0] != " ") {
    winner = true;
  }
  else if ((board[2] == board[4]) && (board[2] == board[6]) && board[2] != " ") {
    winner = true;
  }

  return winner;

}

bool filled_up() {

  bool filled = true;

  for (int i = 0; i < 9; i++) {

    if (board[i] == " ") {

      filled = false;

    }

  }

  return filled;

}
void draw() {

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

  std::cout << "  " << board[0] << "  |  " << board[1] << "  |  " << board[2] << "\n";

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

  std::cout << "  " << board[3] << "  |  " << board[4] << "  |  " << board[5] << "\n";

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

  std::cout << "  " << board[6] << "  |  " << board[7] << "  |  " << board[8] << "\n";
  std::cout << "     |     |      \n";

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

void set_position() {

  std::cout << "Player " << player << "'s Turn (Enter 1-9): ";
  
  while(!(std::cin>>position)) {

    std::cout << "Player " << player << ", please enter a valid number between 1 and 9: ";
    std::cin.clear();
    std::cin.ignore();

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

  while (board[position-1] != " ") {

    std::cout << "Oops, there's already something in that position!\n\n";

    std::cout << "Player " << player << "'s Turn (Enter 1-9): ";
    std::cin >> position;

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

}

void update_board() {

  if (player % 2 == 1) {

    board[position-1] = "✖";

  } else {

    board[position-1] = "⊙";

  }

}

void change_player() {

  if (player == 1) {

    player++;

  } else {
  
    player--;
  
  }

}

void take_turn() {

  while ( !is_winner() && !filled_up() ) {
  
    set_position();

    update_board();

    change_player();

    draw();
  
  }

}

void end_game() {

  if (is_winner()) {
    std::cout << "There's a winner!\n";
  }
  else if (filled_up()) {
    std::cout << "There's a tie!\n";
  }

}


2
你运行过程序来确认它是否真的执行了这个操作吗?请提供一个最小可重现示例。 - cigien
是的,我已经运行了程序,这似乎是代码的功能。此外,在阅读程序时,从更广泛的背景中,我理解了他们为什么使用它。只是我无法弄清楚如何做到这一点。 - SrirakshaVR
2
那么您需要展示相关的代码,例如 position 的定义。请参见第一个评论中的链接。 - cigien
这样会好很多,但最好有一个调用这段代码的主函数。此外,您可以删除大量代码,仍然能够复制行为。 - cigien
1
@SrirakshaVR 密切相关:https://dev59.com/rmAf5IYBdhLWcg3wlDYD 正如所提到的,您无法事先将std::cin输入限制在特定范围的数字内,您需要在从控制台提示输入后进行检查。 - πάντα ῥεῖ
根据您发布的内容,我不清楚它如何限制输入为1-9。您测试过其他数字吗?不仅是10,还有其他任意数字吗?请记住,尝试访问数组边界外的成员是未定义行为,这意味着它可能会或可能不会给您错误或执行任何操作。 - Ranoiaetep
3个回答

1
似乎position仅允许使用1到9之间的数字,但是在您的代码中并不清楚。如果是这样,std::cin>>position会读取用户的输入,并将其写入position(如果可能)。如果不可能,则此操作会计算为false值。由于它被!否定,因此循环会重复输入,直到有有效的输入为止。这种模式在C++中非常常见。

1
“Could it be the case that position uses an enum to force the interval from 1 to 9 being used?”这句话是什么意思?如果代码确实做到了操作员所说的那样,唯一的可能就是position是一个自定义类型,并且有一个istream重载函数>>以该自定义类型作为参数。 - George
是的,根据提供的片段,那应该是我的猜测。不过对于一门入门课程来说还是有些出乎意料的。 - jtbandes
我也这么想,但是当我查看代码时,我找不到任何地方表明position要以这种方式使用。在游戏开始时,position被初始化为0,然后只有在这一点上才会重新初始化。 - SrirakshaVR
然后程序不会检查数字是否在0到9之间,它只是检查它是否为数字。否则,您将不得不编辑您的问题以发布更多代码,以便其他人可以重现这个问题。 - jtbandes
我已经完整地发布了解决方案代码 @jtbandes。 - SrirakshaVR
@SrirakshaVR 但是我们也需要查看play.hpp和main函数。 - cigien

1
我的问题是,为什么while(!(std::cin>>position))可以确保输入的数字在1到9之间? 它并不能。它只是检查用户输入的是否是有效的整数。任何其他的检查都必须手动完成。

没有其他手动检查来确保数字在1到9之间,但是当我尝试通过输入大于9或小于1的值来测试程序时,我被要求输入不同的值(代码中所示:“玩家1,请输入1到9之间的值”)。 - SrirakshaVR
所示代码并没有做到那一点。它必须在其他地方,请在您的问题中包含它。 - Paul Sanders

1

它并不保证。但我写了一个小程序,可以确保其在1到9之间。

#include <iostream>

int main() {
    int player = 0;                                             //force integer
    while ((std::cin >> player) && (player < 1 || player > 9) || std::cin.fail()) {
        std::cout << "Player " << player << ", please enter a valid number between 1 and 9: ";
        std::cin.clear();
        std::cin.ignore();
    }
    return 0;
}

那个逻辑会将 z 计算为 1-9 之间的有效数字。同时,它并没有真正回答提问者的问题(尽管他们的问题不完整)。 - George
是的,这很有道理。但程序中没有明确的澄清,它仍然按照预期运行。position在代码开头被初始化为0,除此之外,在代码的这一点之前没有设置任何值。 - SrirakshaVR
它不需要被初始化,因为std::cin会初始化该值。 - pesuww

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接