Крестики нолики(баг)

Короче, делаю крестики нолики на с++. Есть баг, если выигрывает второй игрок, то партия не закончится пока не выиграет первый, и тогда выводится что победил второй игрок(что верно так как он победил) Помогите исправить баг.

#include <iostream>
#include <string>
#include <cstdlib>
#include <windows.h>
using namespace std;

char map[3][3];

// Эта функция отрисовывать поле(для красоты)
void DrawPlaceForMenu(){
    int length = 3;
    for(int i = 0; i < length; i++)
    {
        for(int j = 0; j < length; j++)
            {
             map[i][j] = '#';
            }
    }
    for(int i = 0; i < length; i++)
        {
         for(int j = 0; j < length; j++)
         {
            
            cout << map[i][j];
         }
         cout << endl;
        }
}

///////////////////

//Я надеюсь вы ещё не повесились.
//Эта функция отслеживает в каких яцейках находится "х" и "о"
bool WinState(int player){
    if(player == 1){
        if((map[0][0] == 'x' && map[0][1] == 'x' && map[0][2] == 'x') || (map[1][0] == 'x' && map[1][1] == 'x' && map[1][2] == 'x') || (map[2][0] == 'x' && map[2][1] == 'x' && map[2][2] == 'x') || (map[0][0] == 'x' && map[1][0] == 'x' && map[2][0] == 'x') || (map[0][1] == 'x' && map[1][1] == 'x' && map[2][1] == 'x') || (map[0][2] == 'x' && map[1][2] == 'x' && map[2][2] == 'x') || (map[0][0] == 'x' && map[1][1] == 'x' && map[2][2] == 'x') || (map[0][2] == 'x' && map[1][1] == 'x' && map[2][0] == 'x')){
            cout << "Игрок номер 1 закончил партию быстрее!" << endl;
            cout << "Победа игрока номер 1" << endl;
            return true;
        }
        
    }
    else if(player == 2){
        if((map[0][0] == 'o' && map[0][1] == 'o' && map[0][2] == 'o') || (map[1][0] == 'o' && map[1][1] == 'o' && map[1][2] == 'o') || (map[2][0] == 'o' && map[2][1] == 'o' && map[2][2] == 'o') || (map[0][0] == 'o' && map[1][0] == 'o' && map[2][0] == 'o') || (map[0][1] == 'o' && map[1][1] == 'o' && map[2][1] == 'o') || (map[0][2] == 'o' && map[1][2] == 'o' && map[2][2] == 'o') || (map[0][0] == 'o' && map[1][1] == 'o' && map[2][2] == 'o') || (map[0][2] == 'o' && map[1][1] == 'o' && map[2][0] == 'o')){
            cout << "Игрок номер 2 закончил партию быстрее!" << endl;
            cout << "Победа игрока номер 2" << endl;
            return true;
        }
    }
     
}

// Эта функция уже отрисовывает игровое поле
void DrawPlace(char icon, int x, int y){
    int length= 3;
    if ((map[x][y] != icon)){
        map[x][y] = icon;
    }else{
        
        cout << "Клетка занята"<< endl;     Sleep(2000);
    }
    system("cls");
    for(int i = 0; i < length; i++)
        {
         for(int j = 0; j < length; j++)
         {
            
            cout << map[i][j];
         }
         cout << endl;
        }
}



int main(int argc, char *argv[])
{
    int length = 3;
    for(int i = 0; i < length; i++)
    {
        for(int j = 0; j < length; j++)
            {
             map[i][j] = '#';
            }
    }
    int x,y;
    bool win;
    int player = 1;
    DrawPlaceForMenu();
    while(true){
        printf("Игрок #%i",player);
        
        cout << endl;
        cout << "Введите номер строки: ";
        cin >> x;
        cout << "Введите номер столбца: ";
        cin >> y;
        if(player == 1){
            DrawPlace('x',x,y);
        }
        if(player == 2){
            DrawPlace('o',x,y);
        }
        if (player > 2){
            player -= 2;
        }else{
            player += 1;
        }
        win = WinState(player);
        if (win){
            break;
        } 
        
        
    }
}
////////////////////////

Ответы (1 шт):

Автор решения: needKVAS

А вас не смутило, что у вас есть некий игрок 3?

Несколько ошибок:

  1. Вы определяете выиграл ли игрок после того, как смените игрока. Из-за этого, после того как выигрывает второй игрок, ход передаётся игроку 1 и происходит проверка на то, победил ли он.
  2. Когда вы меняете игрока ваши переусложнённые махинаци приводят к появлению 3-го игрока. В данной ситуации проще менять напрямую.

Т.о:

win = WinState(player);
if (win){
    break;
}
if (player == 2){
    player = 1;
}else{
    player = 2;
}
  1. В конце метода WinState недостаёт return false;.
  2. Проверка на то, что клетка не занята не учитывает, что клетка может быть занята иконкой другого игрока. Проверяйте map[x][y] == '#'
  3. В случае, если клетка занята, ход всё равно перейдёт следующему игроку. Ввод одного игрока следует повторять до получения корректного хода.
  4. Вы дважды заполняете массив map.

// Эта функция уже отрисовывает игровое поле

Если бы она отрисовывала игровое поле вы бы могли использовать её для отрисовки пустого поля (оно тоже игровое), но вам потребовалась на это отдельная функция. По сути она меняет поле и отрисовывает его. Так и просится разбить на две функции.

А ещё определение победителя (map[0][0] == 'o' && map[0][1] == 'o' && map[0][2] == 'o') ... тоже молит об отдельной функции.

→ Ссылка