Szukam pomocy w analizie kodu prostej gry "Kółko i krzyżyk"

0

Znalazłem w sieci taki prosty kod gry konsolowej "Kółko i krzyżyk", ale mam problem z jego całą analizą.

#include <iostream>
#include <stdlib.h>
#include <conio.h>

using namespace std;

char board[3][3];

bool isRunning = true;

void printBoard();
void userInput(char c);
bool checkWin(char c);
bool checkRow(char c, int r);
bool checkColumn(char c, int r);


int main()
{
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            board[i][j] = ' ';
        }
    }

    while(isRunning)
    {
        printBoard();
        userInput('x');
        printBoard();
        userInput('o');
        printBoard();

        if(checkWin('x'))
        {
            cout << "Wygral X";
            isRunning = false;
        }
        if(checkWin('o'))
        {
            cout << "Wygralo O!";
            isRunning = false;
        }
    }


    return 0;
}

void printBoard()
{
    system("cls");

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

void userInput(char c)
{
    int x = 0, y = 0;

    cout << "[" << c << "]Podaj pozycje x: ";
    cin >> x;
    cout << "[" << c << "]Podaj pozycje y: ";
    cin >> y;

    x--;
    y--;

    if(board[x][y] == ' ')
        board[x][y] = c;
    else
        userInput(c);
}

bool checkWin(char c)
{
    for(int i = 0; i < 3; i++)
    {
        bool ret = checkRow(c , i);
        if(ret)
            return true;
    }

    for(int i = 0; i < 3; i++)
    {
        bool ret = checkColumn(c , i);
        if(ret)
            return true;
    }

    if(board[0][0] == c && board[1][1] == c && board[2][2] == c)
    {
        return true;
    }

    if(board[2][0] == c && board[1][1] == c && board[0][2] == c)
    {
        return true;
    }

    return false;
}

bool checkRow(char c, int r)
{
    int ret = 0;

    for(int i = 0; i < 3; i++)
    {
        if(board[i][r] == c)
            ret++;
    }

    if(ret == 3)
        return true;

    return false;
}

bool checkColumn(char c, int r)
{
    int ret = 0;

    for(int i = 0; i < 3; i++)
    {
        if(board[r][i] == c)
            ret++;
    }

    if(ret == 3)
        return true;

    return false;
}

Nie rozumiem tego fragmentu:

bool checkWin(char c)
{
    for(int i = 0; i < 3; i++)
    {
        bool ret = checkRow(c , i);
        if(ret)
            return true;
    }

    for(int i = 0; i < 3; i++)
    {
        bool ret = checkColumn(c , i);
        if(ret)
            return true;
    }

    if(board[0][0] == c && board[1][1] == c && board[2][2] == c)
    {
        return true;
    }

    if(board[2][0] == c && board[1][1] == c && board[0][2] == c)
    {
        return true;
    }

    return false;
}

bool checkRow(char c, int r)
{
    int ret = 0;

    for(int i = 0; i < 3; i++)
    {
        if(board[i][r] == c)
            ret++;
    }

    if(ret == 3)
        return true;

    return false;
}

bool checkColumn(char c, int r)
{
    int ret = 0;

    for(int i = 0; i < 3; i++)
    {
        if(board[r][i] == c)
            ret++;
    }

    if(ret == 3)
        return true;

    return false;
}


Wiem, że te 3 funkcje służą do: sprawdza wygraną, sprawdza czy w kolumnie są trzy takie same znaki i czy w wierszu są trzy takie same znaki. Nie wiem co przechowuje zmienna 
```cpp
bool ret

i co do funkcji podaje się w zmiennej int r

. Najbardziej nie rozumiem tego: 
```cpp
bool ret = checkRow(c , i);
        if(ret)
            return true;

i

bool ret = checkColumn(c , i);
        if(ret)
            return true;
1

Wygląda na to, że w przypadku wiersza r jest to nr tego wiersza a zmienna i przesuwa się po kolejnych elementach w tym wierszu i analogicznie w przypadku kolumny.

1
bool checkRow(char c, int r) 

sprawdź czy w wierszu r są 3 znaki c, jeśli tak zwróc true

 bool ret = checkRow(c , i);
        if(ret)
            return true;

wykonaj checkRow dla znaku c i wiersza i, jeśli funkcja zwróciła true, to zwróć true (wygraliśmy).

Analogicznie dla kolumn.

0

Czyli

 for(int i = 0; i < 3; i++)
    {
        bool ret = checkRow(c , i);
        if(ret)
            return true;
    }

odwołuje się do funkcji

bool checkRow(char c, int r)
{
    int ret = 0;
 
    for(int i = 0; i < 3; i++)
    {
        if(board[i][r] == c)
            ret++;
    }
 
    if(ret == 3)
        return true;
 
    return false;

czyli 'i' w funkcji checkWin to 'r' w funkcji checkRow, na początku 'r' ma 0(bo 'i' w checkWin ma 0) czyli sprawdza pierwszy wiersz, 'i' sprawdza odpowiednio 3 pola(i < 3), jeśli nie ma w wierszu trzech pól z takim samym znakiem, zwraca false i w tedy 'i' w funkcji checkWin wzrasta o wartość 1, wysyła znowu do funkcji checkRow 'r' o wartości 1 i znowu sprawdza trzy pola i tak 3 razy.
Dobrze rozumuje?

1

Ostatnia sprawa. Jak zmodyfikować kod, bo gdy X wygra to jeszcze trzeba czekać aż O wykona ruch.

    while(true)   // nie potrzebujesz już zmiennej isRunning
    {
        printBoard();
        userInput('x');
        printBoard();
        if(checkWin('x'))
        {
            cout << "Wygral X";
            break;                     // jak x wygrał wyjdź z pętli
        }

        userInput('o');
        printBoard(); 
        if(checkWin('o'))
        {
            cout << "Wygralo O!";
            break;
        }
    }

1 użytkowników online, w tym zalogowanych: 0, gości: 1