пишу хрестики-нолики, задание на 1 курсе, знаком с языком недавно

самое волнительное происходит в функциях game_over... мне нужно передавать их значения в функцию 'prova', чтобы выяснять в мэйне, продолжится игра или будет иной исход. Подскажите, как это сделать с помощью указателей (тема мимо меня прошла). Буду очень благодарен.

#include <iostream>
#include <windows.h>
#include <math.h>
#include <ctime>
#include <conio.h>
#include <string>

using namespace std;

int map[3][3]; //нули

void map_show() //вывод массива
{
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            if (map[i][j] == 0)
                cout << "| ";
            if (map[i][j] == 1)
                cout << "|X";
            if (map[i][j] == 2)
                cout << "|0";
        }
        cout << "|" <<endl;
        cout << "--------" <<endl;
    }
}


void newmap()
{
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            map[i][j]=0;
        }
    }
}


void hodkomp(int n)
{
    int i, j, k = 0; //строки,столбцы,переменная определяющая ходил ли копм
        int vs; //соперник
    if (n == 1)
    {
        vs = 2;
    }
    if (n == 2)
    {
        vs = 1;
    }//проверяем против кого мы играем
    //прописываем победные ходы по строкам
    for (i = 0; i < 3; i++)
    {
        if (map[i][0] == n && map[i][1] == n && map[i][2] == 0 && k == 0)
        {
            map[i][2] = n;
            k = 1;
        }
        if (map[i][0] == n && map[i][1] == 0 && map[i][2] == n && k == 0)
        {
            map[i][2] = n;
            k = 1;
        }
        if (map[i][0] == 0 && map[i][1] == n && map[i][2] == n && k == 0)
        {
            map[i][0] = n;
            k = 1;
        }
    }
    //победные ходы по столбцам
    for (j = 0; j < 3; j++)
    {
        if (map[0][j] == n && map[1][j] == n && map[2][j] == 0 && k == 0)
        {
            map[2][j] = n;
            k = 1;
        }
        if (map[i][j] == n && map[1][j] == 0 && map[2][j] == n && k == 0)
        {
            map[1][j] = n;
            k = 1;
        }
        if (map[0][j] == 0 && map[1][j] == n && map[2][j] == n && k == 0)
        {
            map[0][j] = n;
            k = 1;
        }
    }
    //проверка диагоналей на победный ход
    if (map[0][0] == n && map[1][1] == n && map[2][2] == 0 && k == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    if (map[0][0] == n && map[1][1] == 0 && map[2][2] == n && k == 0)
    {
        map[1][1] = n;
        k = 1;
    }
    if (map[0][0] == 0 && map[1][1] == n && map[2][2] == n && k == 0)
    {
        map[0][0] = n;
        k = 1;
    }
    if (map[0][0] == n && map[1][1] == n && map[2][2] == 0 && k == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    if (map[0][0] == n && map[1][1] == n && map[2][2] == 0 && k == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    // блокируем противника
// проверяем все строки и выбираем оптимальный ход для компьютера
    for (j = 0; j < 3; j++)
    {
        if (map[0][j] == vs && map[1][j] == vs && map[2][j] == 0 && k == 0)
        {
            map[2][j] = n;
            k = 1;
        }
        if (map[0][j] == vs && map[1][j] == 0 && map[2][j] == vs && k == 0)
        {
            map[1][j] = n;
            k = 1;
        }
        if (map[0][j] == 0 && map[1][j] == vs && map[2][j] == vs && k == 0)
        {
            map[0][j] = n;
            k = 1;
        }
    }
    for (i = 0; i < 3; i++)
    {
        if (map[i][0] == vs && map[i][1] == vs && map[i][2] == 0 && k == 0)
        {
            map[i][2] = n;
            k = 1;
        }
        if (map[i][0] == vs && map[i][1] == 0 && map[i][2] == vs && k == 0)
        {
            map[i][1] = n;
            k = 1;
        }
        if (map[i][0] == 0 && map[i][1] == vs && map[i][2] == vs && k == 0)
        {
            map[i][0] = n;
            k = 1;
        }
    }
    //блок диагоналей
    if (map[0][0] == vs && map[1][1] == vs && map[2][2] == 0 && k == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    if (map[0][0] == vs && map[1][1] == 0 && map[2][2] == vs && k == 0)
    {
        map[1][1] = n;
        k = 1;
    }
    if (map[0][0] == 0 && map[1][1] == vs && map[2][2] == vs && k == 0)
    {
        map[0][0] = n;
        k = 1;
    }
    if (map[0][0] == vs && map[1][1] == vs && map[2][2] == 0 && k == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    if (map[0][0] == vs && map[1][1] == vs && map[2][2] == 0 && k == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    // если свободен центр, занимаем его
    if (k == 0 && map[1][1] == 0)
    {
        map[1][1] = n;
        k = 1;
    }
    // если свободно занимаем углы
    if (k == 0 && map[0][0] == 0)
    {
        map[0][0] = n;
        k = 1;
    }
    // если свободно занимаем углы
    if (k == 0 && map[0][2] == 0)
    {
        map[0][2] = n;
        k = 1;
    }
    // если свободно занимаем углы
    if (k == 0 && map[2][0] == 0)
    {
        map[2][0] = n;
        k = 1;
    }
    // если свободно занимаем углы
    if (k == 0 && map[2][2] == 0)
    {
        map[2][2] = n;
        k = 1;
    }
    // случайный выбор свободного места
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            if (map[i][j] == 0 && k == 0)
            {
                map[i][j] = n;
                k = 1;
            }
        }
    }
    if (k == 0)
    {
        for (i = 0; i < 3; i++)
        {
            for (j = 0; j < 3; j++)
            {
                if (map[i][j] == 0 && k == 0)
                {
                    map[i][j] = n;
                    k = 1;
                }
            }
        }
    }
}


int game_over_krest()
{
    int keystr = 0; //счетчтк заполненных строк
    int keystb = 0;
    int keydiaglav = 0;
    int keydiapob = 0;
    int chek = 0;

    //проверка выигрыша строчек

    for (int j = 0; j < 3; j++)
    {
        for (int i = 0; i < 3; i++)
        {
            if (map[i][j] == 1) //подсчет единиц в строке
                keystr++;

            if (map[j][i] == 1) //подсчет единиц в стлб
                keystb++;

            if (map[i][i] == 1) //подсчет единиц в главной диагонали
                keydiaglav++;

            if (map[2 - i][i] == 1)
                keydiapob++;
        }

        if (keystr == 3 || keystb == 3 || keydiaglav == 3 || keydiapob == 3)
        {
            chek = 1; //крестик
            break; //чтобы внешний цикл не выводил 3 раза
        }
        keystr = 0;
        keystb = 0;
        keydiaglav = 0;
        keydiapob = 0;
    }
    return chek; 
}


int game_over_null()
{
    int keystr = 0; //счетчтк заполненных строк
    int keystb = 0;
    int keydiaglav = 0;
    int keydiapob = 0;
    int chek = 0;

    //проверка выигрыша строчек

    for (int j = 0; j < 3; j++)
    {
        for (int i = 0; i < 3; i++)
        {
            if (map[i][j] == 2) //подсчет единиц в строке
                keystr++;

            if (map[j][i] == 2) //подсчет единиц в стлб
                keystb++;

            if (map[i][i] == 2) //подсчет единиц в главной диагонали
                keydiaglav++;

            if (map[2 - i][i] == 2)
                keydiapob++;
        }

        if (keystr == 3 || keystb == 3 || keydiaglav == 3 || keydiapob == 3)
        {
            chek = 2; //крестик
            break; //чтобы внешний цикл не выводил 3 раза
        }
        keystr = 0;
        keystb = 0;
        keydiaglav = 0;
        keydiapob = 0;
    }
    return chek; 
}


int game_over_all()
{
    int chek=0;
    if (chek == 0 && map[0][0] * map[0][1] * map[0][2] & map[1][0] * map[1][1] * map[1][2] * map[2][0] * map[2][1] * map[2][2] > 0)
         chek = 3;
    return chek;
}


void chel(int n)
{
    int i=0, j=0;
    int x = 0;
    int y = 0; //переменные для координат

    cout << "Enter x and y: ";
    cin >> x >> y;

    if (n == 1 && map[i][j] == 0)
    {
        map[x-1][y-1] = 1;
    }
    if (n == 2 && map[ i][j] == 0)
    {
        map[x-1][y-1] = 2;
    }
}


int prova(int chek)
{
    while (chek == 0) //действия человека
    {

        if (game_over_krest() == 1)
        {
            chek == 1;
            break;
        }

        if (game_over_null() == 2)
        {
            chek = 2;
            break;
        }
      

        if (game_over_all() == 3)
        {
            chek = 3;
            break;
        }
    }
    return chek;
}



//первый индекс x, второй у (i столб)
int main()
{
  
    setlocale(LC_ALL, "rus");
    int n;//за кого играем
    int v;//будем ли играть ещё
    int igra;// состояние игры если победил нолик то 1, если победил крестик то 2
    int prvvod;//проверка ввода
    v = 1;
    while (v == 1)
    {
            cout << "За кого хотите начать? крестики-1, нолики-2\n";
            cin >> n;
       
        newmap();
        map_show();
        igra = 0;
        while (igra == 0) //пока никто не победил
        {

            if (n == 1) //крестики
            {
                chel(1);
                map_show();
                igra = prova(1 || 2 || 3);

                if (igra == 0)
                {
                    cout << "Ходит компьютер\n";
                    hodkomp(2);
                    map_show();
                    igra = prova(1 || 2 || 3);
                }
            }
            if (n == 2) //нолики
            {
                cout << "Ходит компьютер\n";
                hodkomp(1);
                map_show();
                igra = prova(1||2||3);

                if (igra == 0)
                {
                    chel(2);
                    map_show();
                    igra = prova(1 || 2 || 3);
                }
            }
        }
        if (igra == 1)
        {
            cout << "Победил крестик\n";
        }
        if (igra == 2)
        {
            cout << "Победил нолик\n";
        }
        if (igra == 3)
        {
            cout << "Ничья\n";
        }
        cout << "Сыграем ещё? 1-да. 2-нет\n";
        cin >> v;
    }

}

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

Автор решения: Павел Ериков

Если я правильно вас понял, то вы хотите вместо return возвращает результат функции через указатель. (Если это не так отпишите)

Тогда приведу пример на одной из вашей функции game_over_all (с другими аналогично).

Для начала заголовок функции должен иметь следующий вид:

void game_over_all(int* res)

То есть теперь функцию ничего не будет возвращать, но будет принимать указатель на переменную куда запишет свой результат.

В самой функции вместо return нужно присвоить res посчитанное значение chek. Для этого нужно использовать операцию разыменования.

*res = check;

*res - операция разыменования указателя. При помощи этой операции вы можете или присвоить, или получить значение на которое указывает указатель.

В функции prova вам обязательно нужно создать проинициализированную переменную и передавать в функцию game_over_all указатель на неё, примерно так.

int res = 0;
...
    game_over_all(&res)
    if(res == 3) ...

& - оператор адреса. Логично предположить, что этот оператор позволяет получить адрес переменной.

Поподробней сразу и об операторе адреса и об операторе разыменования можете почитать тут

И все таки порекомендовал бы пожалеть своего преподавателя и заодно самому потренироваться, и написать более красивый и понятный код.

→ Ссылка
Автор решения: Руслан Рус

Лови готовый код

"use strict";

let ticTakToe = { gameTableElement: document.getElementById('game'), status: 'playing', mapValues: [ ['', '', ''], ['', '', ''], ['', '', ''], ], phase: 'X',

/**
 * Инициализация игры.
 */
init() {
    // Выводим все ячейки.
    this.renderMap();
    // Инициализируем обработчики событий.
    this.initEventHandlers();
},

/**
 * Вывод ячеек в html.
 */
renderMap() {
    for (let row = 0; row < 3; row++) {
        const tr = document.createElement('tr');
        this.gameTableElement.appendChild(tr);
        for (let col = 0; col < 3; col++) {
            let td = document.createElement('td');
            td.dataset.row = row.toString();
            td.dataset.col = col.toString();
            tr.appendChild(td);
        }
    }
},

/**
 * Инициализация обработчиков событий.
 */
initEventHandlers() {
    // Ставим обработчик, при клике на таблицу вызовется функция this.cellClickHandler.
    this.gameTableElement.addEventListener('click', event => this.cellClickHandler(event));
},

/**
 * Обработчик события клика.
 * @param {MouseEvent} event
 */
cellClickHandler(event) {
    // Если клик не нужно обрабатывать, уходим из функции.
    if (!this.isCorrectClick(event)) {
        return;
    }

    // Заполняем ячейку.
    this.fillCell(event);
    // Если кто-то выиграл, заходим в if.
    if (this.hasWon()) {
        // Ставим статус в "остановлено".
        this.setStatusStopped();
        // Сообщаем о победе пользователя.
        this.sayWonPhrase();
    }

    // Меняем фигуру (крестик или нолик).
    this.togglePhase();
},

/**
 * Проверка был ли корректный клик, что описан в событии event.
 * @param {Event} event
 * @returns {boolean} Вернет true в случае если статус игры "играем", клик что описан в объекте event был
 * по ячейке и ячейка куда был произведен клик был по пустой ячейке.
 */
isCorrectClick(event) {
    return this.isStatusPlaying() && this.isClickByCell(event) && this.isCellEmpty(event);
},

/**
 * Проверка что мы "играем", что игра не закончена.
 * @returns {boolean} Вернет true, статус игры "играем", иначе false.
 */
isStatusPlaying() {
    return this.status === 'playing';
},

/**
 * Проверка что клик был по ячейке.
 * @param {Event} event
 * @param {HTMLElement} event.target
 * @returns {boolean} Вернет true, если клик был по ячейке, иначе false.
 */
isClickByCell(event) {
    return event.target.tagName === 'TD';
},

/**
 * Проверка что в ячейку не ставили значение (крестик или нолик).
 * @param {Event} event
 * @param {HTMLElement} event.target
 * @returns {boolean} Вернет true, если ячейка пуста, иначе false.
 */
isCellEmpty(event) {
    // Получаем строку и колонку куда кликнули.
    let row = +event.target.dataset.row;
    let col = +event.target.dataset.col;

    return this.mapValues[row][col] === '';
},

/**
 * Заполняет ячейку в которую кликнул пользователь в событии event.
 * @param {Event} event
 * @param {HTMLElement} event.target
 */
fillCell(event) {
    // Получаем строку и колонку куда кликнули.
    let row = +event.target.dataset.row;
    let col = +event.target.dataset.col;

    // Заполняем ячейку и ставим значение в массиве, в свойстве mapValues.
    this.mapValues[row][col] = this.phase;
    event.target.textContent = this.phase;
},

/**
 * Проверка есть ли выигрышная ситуация на карте.
 * @returns {boolean} Вернет true, если игра выиграна, иначе false.
 */
hasWon() {

    return this.isLineWon({ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }) ||
        this.isLineWon({ x: 0, y: 1 }, { x: 1, y: 1 }, { x: 2, y: 1 }) ||
        this.isLineWon({ x: 0, y: 2 }, { x: 1, y: 2 }, { x: 2, y: 2 }) ||

        this.isLineWon({ x: 0, y: 0 }, { x: 0, y: 1 }, { x: 0, y: 2 }) ||
        this.isLineWon({ x: 1, y: 0 }, { x: 1, y: 1 }, { x: 1, y: 2 }) ||
        this.isLineWon({ x: 2, y: 0 }, { x: 2, y: 1 }, { x: 2, y: 2 }) ||

        this.isLineWon({ x: 0, y: 0 }, { x: 1, y: 1 }, { x: 2, y: 2 }) ||
        this.isLineWon({ x: 0, y: 2 }, { x: 1, y: 1 }, { x: 2, y: 0 });
},

/**
 * Проверка есть ли выигрышная ситуация на линии.
 * @param {{x: int, y: int}} a 1-ая ячейка.
 * @param {{x: int, y: int}} b 2-ая ячейка.
 * @param {{x: int, y: int}} c 3-я ячейка.
 * @returns {boolean} Вернет true, если линия выиграна, иначе false.
 */
isLineWon(a, b, c) {
    let value = this.mapValues[a.y][a.x] + this.mapValues[b.y][b.x] + this.mapValues[c.y][c.x];
    return value === 'XXX' || value === '000';
},

/**
 * Ставит статус игры в "остановлена".
 */
setStatusStopped() {
    this.status = 'stopped';
},

/**
 * Сообщает о победе.
 */
sayWonPhrase() {
    let figure = this.phase === 'X' ? 'Крестики' : 'Нолики';
    alert(`${figure} выиграли!`);
},

/**
 * Меняет фигуру (крестик или нолик).
 */
togglePhase() {
    this.phase = this.phase === 'X' ? '0' : 'X';
},

};

ticTakToe.init();

→ Ссылка