Крестики-нолики C ++ перезаписывают плату - PullRequest
0 голосов
/ 02 июля 2018

Привет, поэтому у меня все настроено так, как я хочу. Последняя часть, которую я пытаюсь реализовать, - это чтобы она не перезаписывалась при вводе либо X, либо 0. Если бы кто-то мог взглянуть на это и сказать мне, что именно я сделал не так с моей функцией noRepeat, я был бы очень признателен. Спасибо.

#include <iostream>

using namespace std;
const int ROWS = 3;
const int COLS = 3;
char Player1 = 'X';
char Player2 = 'O';
int row, col;
char board[3][3]= { '*', '*', '*', '*', '*', '*', '*', '*', '*'};  //Game board


//Prototypes

void noRepeat();
void drawBoard();
void selection(int&, int&);
char winner();
void switchPlayer();

int main()
{
    cout << "Tic Tac Toe!" << endl << endl;

    drawBoard();
    cout << endl << endl;
    while (1)
    {

        if ( noRepeat() )
        {
            selection(row, col);
            drawBoard();
            switchPlayer();
        }
        if (winner() == 'X')
        {
            cout << "Player 1 wins!" << endl;
            break;
        }
        else if (winner() == 'O')
        {
            cout << "Player 2 wins!" << endl;
            break;
        }

    }


    return 0;
}


// input function
void selection(int &row, int &col)
{
    cout << "Enter a number for row between 0 - 2" << endl;
    cin >> row;
    if (row < 0 || row > 2) {
        cout << "Invalid selection select a row between 0 - 2" << endl;
        cin >> row;
    }

    cout << "Enter a number for col between 0 - 2" << endl;
    cin >> col;
    if (col < 0 || col > 2) {
        cout << "Invalid selection select a row between 0 - 2" << endl;
        cin >> col;
    }



    if (row == 0 && col == 0)
        board[0][0] = Player1;
    else if (row == 0 && col == 1)
        board[0][1] = Player1;
    else if (row == 0 && col == 2)
        board[0][2] = Player1;
    else if (row == 1 && col == 0)
        board[1][0] = Player1;
    else if (row == 1 && col == 1)
        board[1][1] = Player1;
    else if (row == 1 && col == 2)
        board[1][2] = Player1;
    else if (row == 2 && col == 0)
        board[2][0] = Player1;
    else if (row == 2 && col == 1)
        board[2][1] = Player1;
    else if (row == 2 && col == 2)
        board[2][2] = Player1;


}


//Board function
 void drawBoard() {
    for (int i = 0; i < ROWS; i++) {

        for (int j = 0; j < COLS; j++) {
            cout << board[i][j];
        }
        cout << endl;
    }
}


//Function to switch between X's and O's

void switchPlayer() {

    char temp = Player1;
    if (Player1) {
        Player1 = Player2;
    }

    if (Player2)
    {
        Player2 = temp;
    }
}


//conditional winner checker
char winner() {
    if (board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X')
        return 'X';
    if (board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X')
        return 'X';
    if (board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X')
        return 'X';

    if (board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X')
        return 'X';
    if (board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X')
        return 'X';
    if (board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X')
        return 'X';

    if (board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X')
        return 'X';
    if (board[2][0] == 'X' && board[1][1] == 'X' && board[0][2] == 'X')
        return 'X';

//Player 2
    if (board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O')
        return 'O';
    if (board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O')
        return 'O';
    if (board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O')
        return 'O';

    if (board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O')
        return 'O';
    if (board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O')
        return 'O';
    if (board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O')
        return 'O';

    if (board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O')
        return 'O';
    if (board[2][0] == 'O' && board[1][1] == 'O' && board[0][2] == 'O')
        return 'O';
}


//Function to prevent overwriting.
void noRepeat() {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            if (board[i][j] == Player1 || board[i][j] == Player2) {
                cout << "Invalid selection, please choose a row and column 
again."
            }
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

(1) Когда игрок выбирает Row / Col, необходимо убедиться, что в массиве в этом выделении есть символ '*' (т.е. еще не использованный). (2) Добавьте переменную int «выборки» и при любом действительном выборе увеличивайте ее на 1. Когда выбор достигает 9, доска заполнена. Таким образом, вам вообще не нужно noRepeat().

Функция noRepeat() просто печатает, но возвращает void. Так в чем же смысл спрашивать if (noRepeat())?

Функция switchPlayer() ничего не делает. Например, этот ниже, если вы передаете «текущий игрок», возвращает другой: .. Использование: (1) Добавить переменную char currentPalayer = Player1; и (2) currentPalayer = switchPlayer(currentPalayer);, когда вы хотите переключить игрока , Используйте переменную currentPalayer, когда Player1 и Player2 могут быть const char из #define

char switchPlayer(char currentPlayer) {

    const int K = Player1 + Player2;

    return (char) (K - currentPlayer);
}

Я думаю, есть еще проблемы.

Кстати: урезать до 1/2 функции победителя ():

//conditional winner checker
char winner() {
    if (board[0][0] == board[0][1] && board[0][1] == board[0][2])
        return board[0][0];
    if (board[1][0] == board[1][1] && board[1][1] == board[1][2])
        return board[1][0];
    if (board[2][0] == board[2][1] && board[2][1] ==board[2][2]))
        return board[2][0];

    if (board[0][0] == board[1][0] && board[1][0] == board[2][0])
        return board[0][0] ;
    if (board[0][1] == board[1][1] && board[1][1] == board[2][1])
        return board[0][1];
    if (board[0][2] == board[1][2] && board[1][2] == board[2][2])
        return board[0][2];

    if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
        return board[0][0];
    if (board[2][0] == board[1][1] && board[1][1] == board[0][2])
        return board[2][0];
}
0 голосов
/ 02 июля 2018

Мы все можем предложить улучшения в вашем коде, и, возможно, его следует обработать на https://codereview.stackexchange.com/. Если не делать серьезного перекодирования, давайте посмотрим на внесение незначительных изменений в одну из ваших функций:

void selection(int &row, int &col)
{
    cout << "Enter a number for row between 0 - 2" << endl;
    cin >> row;
    while (row < 0 || row > 2) {
        cout << "Invalid selection select a row between 0 - 2" << endl;
        cin >> row;
    }

    cout << "Enter a number for col between 0 - 2" << endl;
    cin >> col;
    while (col < 0 || col > 2) {
        cout << "Invalid selection select a row between 0 - 2" << endl;
        cin >> col;
    }

    board[row][col] = Player1;
}

Что я сделал с вашей функцией, так это изменил логику проверки с if на while цикл, так как вы хотите продолжать спрашивать, пока не получите действительный ввод. Другое дело, что я реорганизовал твой сеттер. Почему есть все эти if варианты, когда один однострочный board[row]col] = Player; может выполнять ту же работу?

В целом, мне не понравилась эта функция, потому что здесь упущена возможность выполнить проверку для '*'. Я не могу продемонстрировать это, не переписав большую часть этой функции.

У меня были другие проблемы с кодом:

  • Обработка «X» и «O». Я бы пошел с int currentPlayer, значение которого было бы 0 или 1. Вы могли бы реализовать поиск char playerMarker[2] = { 'X', 'O' };, чтобы при выполнении перемещения использовался правильный символ.
  • Логика переключения проигрывателя неверна. Вам нужна только одна переменная, у вас есть две, и это более сложные вещи. Если у вас есть только одна переменная, вы могли бы реализовать ее в виде 1 строки: например, currentPlayer = 1 - currentPlayer;
  • Сама доска, я бы пошел с char board[ROW][COL + 2]; и добавил терминатор LF и NUL, тогда для печати платы было бы просто напечатать 3 строки: puts(board[0]); puts(board[1]); puts(board[2]);
  • Условия победы уже были рефакторированы другим пользователем
  • Там нет проверки на тупик. Который, большинство игроков TIC-TAC-TOE быстро достигает
  • Реализация noRepeat не имеет смысла.
0 голосов
/ 02 июля 2018

Ваша функция noRepeat() возвращает void. Но должен вернуть boolean тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...