257 lines
12 KiB
C++
257 lines
12 KiB
C++
#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;
|
||
}
|