Files
TicTacToe/main.cpp

257 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <chrono>
#include <thread>
#include <string>
#include <random>
using namespace std;
typedef unsigned int unint;
int main() {
//
//ПЕРЕМЕННЫЕ
//
//МЭЙН
const int LINES = 3, COLUMNS = 3;
bool newgame=true, firstnumber;
int turn, humanwin=0, botwin=0, draw;
string wannaplay="y";
const string INCORRECT="INCORRECT VALUE, TRY AGAIN: ", ENDGAME="\nGame says: ''The game ends here.''";
const string XWON="Game says: ''X wins!''", OWON="Game says: ''O wins!''", DRAW="Game says: ''Nobody wins - DRAW!''";
const string BOTLOST="Bot says: ''Shee u beat me, I'm worry.''", HUMANLOST="Bot says: ''nahahaha lamer, look how I beat u!''";
const string SEP(40, '-');
const string BOTTHINK="Bot says: ''Wait, I'm thinking.''";
//
//КЛАССЫ
//Класс, отвечающий за формирование и вывод поля
class Board {
public:
bool Xwonflag=false;
bool Owonflag=false;
int drawcounter=1;
//ИГРОВОЕ ПОЛЕ
//первое число LINES характеризует строку
//второе число COLUMNS характеризует столбик
string board[LINES][COLUMNS] = {
{"e", "e", "e"},
{"e", "e", "e"},
{"e", "e", "e"}
};
//Функция вывода поля.
//Пустая клетка ("е") выводится координатами, а занятая - своим знаком.
void BoardShow() {
for (int countlines = 0; countlines < LINES; ++countlines) {
for (int countcolumns = 0; countcolumns < COLUMNS; ++countcolumns) {
if (board[countlines][countcolumns]=="e") {
cout << countlines << countcolumns << " ";
}
else {
cout << board[countlines][countcolumns] << " ";
}
}
cout << endl;
}
}
void BoardClr() {
for (int countlines = 0; countlines < LINES; ++countlines) {
for (int countcolumns = 0; countcolumns < COLUMNS; ++countcolumns) {
board[countlines][countcolumns] = "e";
}
}
}
void XWon() {
if (drawcounter>=4) {
if ((board[0][0])=="'X'") {
if ((board[0][1])=="'X'" and (board[0][2])=="'X'") {Xwonflag=true;}
else if ((board[1][1])=="'X'" and (board[2][2])=="'X'") {Xwonflag=true;}
else if ((board[1][0])=="'X'" and (board[2][0])=="'X'") {Xwonflag=true;}
}
if (((board[1][0])=="'X'") and ((board[1][1])=="'X'") and ((board[1][2]))=="'X'") {Xwonflag=true;}
if (((board[0][1])=="'X'") and ((board[1][1])=="'X'") and ((board[2][1]))=="'X'") {Xwonflag=true;}
if (((board[0][2])=="'X'") and ((board[1][2])=="'X'") and ((board[2][2]))=="'X'") {Xwonflag=true;}
if ((board[2][0])=="'X'") {
if ((board[2][1])=="'X'" and (board[2][2])=="'X'") {Xwonflag=true;}
else if ((board[1][1])=="'X'" and (board[0][2])=="'X'") {Xwonflag=true;}
}
}
}
void OWon() {
if (drawcounter>=4) {
if ((board[0][0])=="'O'") {
if ((board[0][1])=="'O'" and (board[0][2])=="'O'") {Owonflag=true;}
else if ((board[1][1])=="'O'" and (board[2][2])=="'O'") {Owonflag=true;}
else if ((board[1][0])=="'O'" and (board[2][0])=="'O'") {Owonflag=true;}
}
if (((board[1][0])=="'O'") and ((board[1][1])=="'O'") and ((board[1][2]))=="'O'") {Owonflag=true;}
if (((board[0][1])=="'O'") and ((board[1][1])=="'O'") and ((board[2][1]))=="'O'") {Owonflag=true;}
if (((board[0][2])=="'O'") and ((board[1][2])=="'O'") and ((board[2][2]))=="'O'") {Owonflag=true;}
if ((board[2][0])=="'O'") {
if ((board[2][1])=="'O'" and (board[2][2])=="'O'") {Owonflag=true;}
else if ((board[1][1])=="'O'" and (board[0][2])=="'O'") {Owonflag=true;}
}
}
}
void Draw() {
drawcounter=1;
for (int countlines = 0; countlines < LINES; ++countlines) {
for (int countcolumns = 0; countcolumns < COLUMNS; ++countcolumns) {
if (board[countlines][countcolumns]!="e") {
drawcounter++;
}
}
}
}
};
Board BoardObj;
//Ходы игрока и бота
class Turn {
public:
int turnLINEint, turnCOLint;
string Humancount, turnline, turncol;
Board BoardObj;
void HumanTurn() {
//ХОД ИГРОКА
//алгоритм на вычленение первого и второго значений координат
//получает строку вида "XY", первый символ кидает через at в строку для Х,
//второй символ также символ кидает в строку для Y,
//затем переводит обе строки в числа, с которыми можно вести вычисления.
cin >> Humancount;
turnline=Humancount.at(0);
turncol=Humancount.at(1);
turnLINEint=stoi(turnline);
turnCOLint=stoi(turncol);
//cout << "\nlineHUMAN: " << turnLINEint << " colHUMAN: " << turnCOLint << endl;
}
void BotTurn() {
//ХОД БОТА
//рандомит первое значение (строку), засыпает,
//рандомит второе значение (столбец)
srand((time(0)));
turnLINEint=(rand()%3);
chrono::milliseconds timespan((rand()/9));
this_thread::sleep_for(timespan);
mt19937 rng;
rng.seed(time(nullptr));
turnCOLint=(rng()%3);
cout << "Bot says:''I've occupied this cell:" << turnLINEint << turnCOLint << "''" << endl;
}
};
Turn Game;
//
//
//
//
//Заглавие игры. Инструкции для игрока. Выводится только при первом запуске.
cout << "Bot says:" << endl;
cout << "''Wolcome to TicTacToe choom." << endl;
cout << "Look at the clear board." << endl;
BoardObj.BoardShow();
cout << "When u wanna do ur turn - u should type coordinates of the any empty cell." << endl;
cout << "(For example '22' or '10')" << endl;
cout << "I afford I shouldn't explain u rules of the TicTacToe. So let's play brodie.''" << endl;
//
//Основной цикл игры
while (wannaplay=="y") {
//Объявление переменных при старте новой игры на основе булевого флага newgame.
//Флаг newgame становится TRUE на стадии "Заглавие игры",
//становится FALSE в начале цикла после присвоения переменных,
//и снова становится TRUE при окончании цикла (т.е. при чьей-то победе или ничье).
if (newgame) {
//
//Запрос на то, кто первый. 1=игрок, 0=бот.
//Выводит соответствующее сообщение после выбора.
//Обнуляет общие переменные.
//Также снимает флаг newgame, который возвращается в конце игры.
cout << "Bot asks: Wanna be an X? (1/0):";
cin >> firstnumber;
if (firstnumber) {cout << "Bot says: ''Well, u'll be an X.''" << endl; BoardObj.BoardShow();}
else {cout << "Bot says: ''OK, I'll be an X.''" << endl;}
turn=1;
newgame=false;
}
cout << SEP << endl;
//cout << "Game says: ''Now it's " << turn << " turn.''" << endl;
//turn++;
Game.turnLINEint=3;
Game.turnCOLint=3;
//Если первым номером (Х) выступает игрок
while (firstnumber) {
cout << "HUMAN TURN!\n" << "Enter ur coords:";
while ((BoardObj.board[Game.turnLINEint][Game.turnCOLint]!="e")) {
Game.HumanTurn();
if ((BoardObj.board[Game.turnLINEint][Game.turnCOLint]!="e")) {cout << INCORRECT;}
}
BoardObj.board[Game.turnLINEint][Game.turnCOLint] = "'X'";
BoardObj.BoardShow();
cout << SEP << endl;
BoardObj.XWon();
BoardObj.Draw();
if ((BoardObj.Xwonflag) or (BoardObj.drawcounter==9)) {break;}
Game.turnLINEint=3;
Game.turnCOLint=3;
cout << "BOT TURN!\n" << BOTTHINK << endl;
while ((BoardObj.board[Game.turnLINEint][Game.turnCOLint]!="e")) {Game.BotTurn();}
BoardObj.board[Game.turnLINEint][Game.turnCOLint] = "'O'";
BoardObj.BoardShow();
cout << SEP << endl;
BoardObj.OWon();
BoardObj.Draw();
if ((BoardObj.Owonflag) or (BoardObj.drawcounter==9)) {break;}
}
//Если игрок выступает вторым номером (O)
while (!firstnumber) {
cout << "BOT TURN!\n" << BOTTHINK << endl;
while ((BoardObj.board[Game.turnLINEint][Game.turnCOLint]!="e")) {Game.BotTurn();}
BoardObj.board[Game.turnLINEint][Game.turnCOLint] = "'X'";
BoardObj.BoardShow();
cout << SEP << endl;
BoardObj.XWon();
BoardObj.Draw();
if ((BoardObj.Xwonflag) or (BoardObj.drawcounter==9)) {break;}
cout << "HUMAN TURN!\n" << "Enter ur coords:";
Game.turnLINEint=3;
Game.turnCOLint=3;
while ((BoardObj.board[Game.turnLINEint][Game.turnCOLint]!="e")) {
Game.HumanTurn();
if ((BoardObj.board[Game.turnLINEint][Game.turnCOLint]!="e")) {cout << INCORRECT;}
}
BoardObj.board[Game.turnLINEint][Game.turnCOLint] = "'O'";
BoardObj.BoardShow();
cout << SEP << endl;
BoardObj.OWon();
BoardObj.Draw();
if ((BoardObj.Owonflag) or (BoardObj.drawcounter==9)) {break;}
}
cout << ENDGAME << endl;
newgame=true;
if (BoardObj.Xwonflag) {cout << XWON << endl;}
else if (BoardObj.Owonflag) {cout << OWON << endl;}
else if ((BoardObj.drawcounter==9) and (!BoardObj.Xwonflag) and (!BoardObj.Owonflag)) {cout << DRAW << endl;}
if ((firstnumber) and (BoardObj.Xwonflag)) {cout << BOTLOST << endl; humanwin++;}
else if ((!firstnumber) and (BoardObj.Owonflag)) {cout << BOTLOST << endl; humanwin++;}
else if (BoardObj.drawcounter==9) {cout << "Bot says: ''yeah dat was fairplay.''" << endl;}
else {cout << HUMANLOST << endl; botwin++;}
BoardObj.BoardClr();
BoardObj.Xwonflag=false;
BoardObj.Owonflag=false;
cout << SEP << endl;
cout << SEP << endl;
cout << "Wanna play another time?(y/n):";
cin >> wannaplay;
}
//
//СТАТИСТИКА ПРИ ЗАВЕРШЕНИИ ИГРЫ
cout << SEP << endl;
cout << "SOME STATS OF SESSION:" << endl;
cout << "Bot says: ''Hell u won me " << humanwin << " times.\nAnd I won u " << botwin << " times.''" << endl;
//
//компьютер респектует или лошит игрока
if (humanwin<botwin) {cout << "Bot says: ''fuckyeah go back home lamer, u need some training.''" << endl;}
else if (botwin<humanwin) {cout << "Bot says: ''well, dat was not bad how u beat me.''" << endl;}
else if (botwin==humanwin) {cout << "Bot says: ''yeah dat was fairplay.''" << endl;}
return 1488;
}