Как сделать игру Крестики/Нолики в консоли.

Забаненный
Забаненный
Статус
Оффлайн
Регистрация
6 Ноя 2016
Сообщения
589
Реакции
311
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сразу говорю, что гайд будет долгим.Буду подробно описывать.Если кому то лень читать то качайте исходник.Я буду писать частями и объяснять каждую часть.

Начнём.
1) Открываем Visual Studio и создаём пустой проект с++.
2)Создаём файл source.cpp
Код:
Expand Collapse Copy
#include <iostream>

#include <string>


char board[9] = {};            

                           
void clearscreen()              
{
    for (int i = 0; i<100; i++)
    {
        std::cout << std::endl;
    }
}


void clearboard()          
{
    for (int i = 0; i<9; i++)
    {
        board[i] = '-';
    }

}
char board[9] = {}; Чтобы отобразить ход(ввод)пользователя на доске. Доска будит состоять из 9-и однобуквенных стрингов char
void clearscreen() очищает окно консоли, функция clearscreen ни чего не возвращает.
for (int i = 0; i<100; i++) цикл for(int i = 0; i<100; i++) который отсчитывает от 0 до 100 и при каждом повторении цикла выводит на экран std::cout<<std::endl; новую строчку
std::cout << std::endl; выводит на экран std::cout<<std::endl; новую строчку


Код:
Expand Collapse Copy
bool has_wonQ(char player)                                     

{
    int wins[][3] = { { 0,1,2 },{ 3,4,5 },{ 6,7,8 },{ 0,3,6 },{ 1,4,7 },
    { 2,5,8 },{ 0,4,8 },{ 2,4,6 }
    };
   
   
    for (int i = 0; i<8; i++)    
    {
        int count = 0;          ]
        for (int j = 0; j<3; j++)
        {
            if (board[wins[i][j]] == player)
                count++;
        }
        if (count == 3)
        {
            return true;
        }
    }
    return false;

bool has_wonQ(char player) функция bool has_wonQ(char player)которая проверяет когда игра закончилась. Функция has_wonQ возвращает bool(правда или ложь, т.е. bool это переменная с двумя состояниями либо 0(ноль) если состояние ложь и либо 1(единица) если состояние правда)
int wins[][3] = { { 0,1,2 },{ 3,4,5 },{ 6,7,8 },{ 0,3,6 },{ 1,4,7 },
{ 2,5,8 },{ 0,4,8 },{ 2,4,6 }
двухмерный массив wins[8][3](8 по 3) в котором перечисляются все выигрышные варианты
{ 2,5,8 },{ 0,4,8 },{ 2,4,6 }
int count = 0; переменнаяint счётчикcount и задаётся ей значение =0. Грубо говоря цикл for(int i = 0; i<8; i++)проверяет массив[8], а цикл for(int j = 0; j<3; j++) проверяет массив [3]
for (int j = 0; j<3; j++) в этом цикле запускается ещё цикл for который повторяется 3 раза (int j = 0; j<3; j++)
if (board[wins[j]] == player) If если(на boardдоске на квадратике который задан в массиве[wins]по элементу и [j] будит ровняться player (проверяемого X или О (char player))
count++; Если на этом месте в массиве доска стоит X то увеличивается count на единицу ++.
if (count == 3) If если(счётчик count ровняется == 3) т.е. к примеру проходится троечка {0,1,2} и все три ровняются крестику(Х) или нолику(О) то возвращается return
return true; правда true(он победитель)
return false; если это не произошло то возвращается return ложь false(он не выиграл)


Код:
Expand Collapse Copy
void print_board(std::string indent) 

{
    std::cout << "Game board\n";      
    std::cout << indent << "-" << board[6] << "-|-" << board[7] << "-|-" << board[8] << "- \n";
    std::cout << indent << "-" << board[3] << "-|-" << board[4] << "-|-" << board[5] << "- \n";
    std::cout << indent << "-" << board[0] << "-|-" << board[1] << "-|-" << board[2] << "- \n";
}


int get_move()
{
    std::cout << "\nMenu hodov: \n";    
    std::cout << "-7-|-8-|-9-" << std::endl;
    std::cout << "-4-|-5-|-6-" << std::endl;
    std::cout << "-1-|-2-|-3-" << std::endl;
    std::cout << "\n";                    

    print_board("");
    std::cout << "\nVvod chisla: ";


    int move;
    std::cin >> move;
    while (move > 9 || move < 1 || board[move - 1] != '-')
    {
        std::cout << "Vvedite chislo ot (1 do 9):\n";
        std::cin >> move;

    }
    return move;
}
int get_move() Создаётся функция “get_move()“(Получить ввод пользователя)

std::cout << "\nMenu hodov: \n"; С помощью std::cout в окно выводится заголовок Menu hodov:
std::cout << "-7-|-8-|-9-" << std::endl; и нумерацию ячеек "-7-|-8-|-9-" и т.д.
std::cout << "-4-|-5-|-6-" << std::endl; Строки заканчиваются операторами \n(оператор перехода на новую строчку) и endl в конце строк (;)
std::cout << "-1-|-2-|-3-" << std::endl;
std::cout << "\n"; Пропуск строки
print_board(""); в скобках пишется пустой стринг (два двоеточие)
std::cout << "\nVvod chisla: "; Выводится сообщение Vvod chisla: объектом cout
int move; Что бы получить вход пользователя создаётся переменная move
std::cin >> move; Просим что бы пользователь ввёл эту переменную (число)
while (move > 9 || move < 1 || board[move - 1] != '-') Цикл while проверяет вход который дал пользователь больше 9 (move > 9) или (|| ) вход меньше 1 (move < 1 )
std::cout << "Vvedite chislo ot (1 do 9):\n"; Если пользователь ввёл число меньше 1 и больше 9 то выводится на экран сообщение "Vvedite chislo ot 1 do 9:"
std::cin >> move; Запрашиваем с помощью std::cin >> у пользователя другой вход move(ввод числа от 1 до 9)
return move; Возвращаем оператором return значение “move”


Код:
Expand Collapse Copy
char play_and_get_winner() 

{
    int turn = 1;

    while (!has_wonQ('X') && !has_wonQ('0'))
    {
        clearscreen();
        int move = get_move();

        clearscreen();
        if (turn % 2 == 1)
        {
            board[move - 1] = 'X';
            if (has_wonQ('X'))
            {
                std::cout << "X,Pozdravlyau vi vuigrali!\n";
                return 'X';
            }

        }
        else                    
        {
            board[move - 1] = '0';
            if (has_wonQ('0'))
            {
                std::cout << "O,Pozdravlyau vi vuigrali!\n";
                return '0';      
            }
        }
        turn++;                
        if (turn == 10)        
        {
            std::cout << "nechya\n";
            return 'D';            
        }
    }
}

char play_and_get_winner() функция play_and_get_winner() она будит возвращать char(символ) т.е. сыграть в игру и получить выигравшего
int turn = 1; переменная turn(ход) типа int изначально будит первой ход и ровняться= 1
while (!has_wonQ('X') && !has_wonQ('0')) while(не! выиграл пользовательhas_wonQ играющий иксом(X)('x') и&& не! выиграл пользовательhas_wonQ играющий ноликом(О)('О'))
clearscreen(); очищает окно консоли
int move = get_move(); Вызывается функция get_move()и помещается то что она вернет в переменную
clearscreen(); очищает окно консоли
if (turn % 2 == 1) Строкой if(i%2 == 0) проверяется чётное или нечётное число ввёл пользователь т.е. если i по модулю 2 равняется 1, то это чётный ход,
board[move - 1] = 'X'; то тогда задаётся значение ='X'
if (has_wonQ('X')) if если(has_wonQ('X')пользователь играющий за 'X' если он выиграл
std::cout << "X,Pozdravlyau vi vuigrali!\n"; то печатается поздравление "X,Pozdravlyau vi vuigrali!"
return 'X'; возвращаетreturn из функции'X' что пользователь играющий 'X' выиграл
else Все остальные ходы будут нечётные,
board[move - 1] = '0'; то тогда задаётся значение ='О'
if (has_wonQ('0')) if если(has_wonQ('X')пользователь играющий за 'X' если он выиграл
std::cout << "O,Pozdravlyau vi vuigrali!\n"; то печатается поздравление "O,Pozdravlyau vi vuigrali!"
return '0'; возвращаетreturn из функции'X' что пользователь играющий 'X' выиграл
turn++; В конце цикла говорится turn(ход) увеличить на единицу++
if (turn == 10) if если(turnвход ==ровняется 10). Ecли ввод равен 10, то НиЧЬЯ. T.е. ставить крестик или нолик некуда
std::cout << "nechya\n"; тогда выводится на экран сообщение "nechya"
return 'D'; и оператор return возвращает значение D


Код:
Expand Collapse Copy
int main()                         

{
    std::cout << "Privetstvuyu\n\n";
    std::string reply = "y";
    int x_wins = 0, o_wins = 0, ties = 0;

    while (reply == "y")
    {
        clearboard();
        char winner = play_and_get_winner();
        print_board("\t  ");

        switch (winner)
        {
        case 'X':  
            x_wins++;
            break;    
        case '0':    
            o_wins++;
            break;    
        case 'D':    
            ties++;  
            break;    
        }

        std::cout << "\n\t*Winer statistic*\nPlayer X: " << x_wins
            << ", Player 0: " << o_wins << " and Ties: " << ties << "\n\n";
        std::cout << "\n would you like to play again? (y/n): ";
        std::cin >> reply;
        while (reply != "y" && reply != "n") //цикл while(пока значениеreply(ответ)  !=не равно "y" или&& пока значениеreply(ответ) !=не равно "n") то цикл бесконечен
        {
            std::cout << "please inter a valid reply (y/n):";
            std::cin >> reply;
        }

    }//


    return 0;
}

int main() Главная функция main
std::cout << "Privetstvuyu\n\n"; выводится приветственное сообщения "Privetstvuyu" средством std::cout и оператором <<
std::string reply = "y"; декларируется стринг reply(ответ). reply(ответ) по началу "y"(то бишь ДА(YES))
int x_wins = 0, o_wins = 0, ties = 0; перечень переменных типаint x_wins=0(это количество раз когда пользователь играющий иксами выиграл), o_wins=0(это количество раз когда пользователь играющий ноликами выиграл), ties=0(количество ничьих)и всем присвоено нулевое значение
while (reply == "y") Строится цикл while пока ответ положительный, т.е. пока ответ ==ровняется "y"
clearboard(); функция void clearboard()которая очищает доску.
char winner = play_and_get_winner(); play_and_get_winner()(главный цикл), и дать char winner(выигравший). char winner ровняется= play_and_get_winner()
print_board("\t "); пишется строка print_board() т.е. используется функция чтобы ещё раз напечатать доску(board), а в функции main талб\t print_board("\t ")
switch (winner) Пишется switch(это конструкция “если, то” при разных значениях ((winner)выигравший) будут выполнятся разные куски кода)
case 'X': Первое значениеcase 'X', если выиграл пользователь играющий иксами
x_wins++; тогда переменная x_wins увеличивается на единицу++
break; и останавливается break
case '0': Второе значениеcase 'О', если выиграл пользователь играющий ноликами
o_wins++; тогда переменная o_wins увеличивается на единицу++
break; и останавливается break
case 'D': Третье значениеcase 'D', если ничья
ties++; тогда переменнаяties увеличивается на единицу++
break; и останавливается break
std::cout << "\n\t*Winer statistic*\nPlayer X: " << x_wins Прописывается статистика,выводится статистика на экран/в окно консоли с помощью std::cout << "Winer statistic\nPlayer X: " << x_wins, это сколько раз пользователь играющий Х выиграл
<< ", Player 0: " << o_wins << " and Ties: " << ties << "\n\n"; "Player 0: "<<o_wins << " and Ties: "<<ties<<" это сколько раз пользователь играющий О выиграл. Сколько ничьих,
std::cout << "\n would you like to play again? (y/n): "; "would you like to play again? (y/n):" задаётся вопрос: “желаете продолжить игру?”,
std::cin >> reply; а с помощью объекта cin пользователь может ввести значениеreply(ответ) y, а если пользователь не хочет играть то нужно ввести n
while (reply != "y" && reply != "n") цикл while(пока значениеreply(ответ) !=не равно "y" или&& пока значениеreply(ответ) !=не равно "n") то цикл бесконечен
std::cout << "please inter a valid reply (y/n):"; строка просит пользователя ввести ещё значение,если до этого не было введено y или n
std::cin >> reply; с помощью объекта cin выводит на экран введённое пользователем значение и опять проверяется в цикле.
return 0; Оператор return возвращает функции main() 0(ноль)

3)Ставим настройки проекта : Release x86.
4)Компилируем проект.
uYuCot8.png


Так же можно изменить цвет текста и сделать перевод текста на "Русский". В следующем гайде расскажу как это сделать.
 
Последнее редактирование модератором:
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
пздц слишком много, ты сколько это писал? :kappa::kappa::kappa:
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
поставил бы лайк за труд,но не могу,вопрос в другом ,для чего это нужно?
 
Последнее редактирование:
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
поставил бы лайк на труд,но не могу,вопрос в другом для чего это нужно?
Базовое ознакомление с С# скорее всего
мне нрав, пойду катать xD
 
Го морской бой :D Я бы сыграл :3
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Назад
Сверху Снизу