C++ : Help understanding what this line of code is trying to do

Viewed 148

I am new to coding and I started with C++ in Codeacademy. This is a very basic doubt, so TIA for helping me out.

The point of the program is to build a TIC TAC TOC game. I was looking to understand the solution that is available. That's where I came across one of the functions in the program, called void set_position() which is to determine which position in the board (from 1 to 9) the player wants to play at. I will paste the entire code block below for context and then come to my query.

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

  }

My question is, how is the while(!(std::cin>>position)) ensuring that the number being entered is between 1 to 9?

Edited to add:

position is a user defined variable initialized to 0 in the beginning of the program. I did not find position being forced to take values between 1 and 9 at any point in the program. It is entirely possible I missed it, I will add the entire code below if that provides more clarity, the reason I did not do so initially was because this is a solution and I wasn't sure if I could paste it in public forums

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

}

3 Answers

It seems like position only allows numbers from 1 to 9, but this is not clear in your code. If it is this way, std::cin>>position reads the user's input and writes it into position if possible. If it is not possible, this operation evaluates to a false value. As it is negated by ! the loop does repeat the input until there is a valid input given. This pattern is quite common in C++.

My question is, how is the while(!(std::cin>>position)) ensuring that the number being entered is between 1 to 9?

It doesn't. It merely checks if the user entered a valid integer. Any additional checks must be done manually.

It does not ensure. I made this small program though which will guarantee it to be between 1 and 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;
}
Related