#include <iostream>
#include <vector>
#include <string>
using namespace std;
// global parameters
const char X = 'x';
const char O = 'o';
const char EMPTY = ' ';
const char TIE = 'T';// ничья
const char NO_ONE = 'N';// остаются равные шансы на победу
#define BLUE "\033[34m"
#define RED "\033[31m"
//прототипы
void instructions();
char askYesNo(string questions);
int askNumber(string questions, int high, int low);
char humanPiece();
char opponent(char piece);
void displayBoard(const vector<char>& board); //vector<type> == array
char winner(const vector<char>& board);
bool isLegal(const vector<char>& board, int move);
int humanMove(const vector<char>& board, char human);
int computerMove(vector<char> board, char computer);
void announceWinner(char winner, char computer, char human);
int main() {
int move;
const int NUM_OF_SQ = 9;
vector<char> board(NUM_OF_SQ, EMPTY);
instructions();
char human = humanPiece();
char computer = opponent(human);
char turn = X;
displayBoard(board);
while (winner(board) == NO_ONE){
if (turn == human){
move = humanMove(board, human);
board[move] = human;
} else {
move = computerMove(board, computer);
board[move] = computer;
}
displayBoard(board);
turn = opponent(turn);
}
announceWinner(winner(board), computer, human);
return 0;
}
void instructions(){
cout << "Welcome to our game, here you can see your board" << endl;
cout << " 0 | 1 | 2 " << endl;
cout << " 3 | 4 | 5 " << endl;
cout << " 6 | 7 | 8 " << endl;
}
char askYesNo(string questions){
char response;
do{
cout << questions << " (y/n)? ";
cin >> response;
} while (response != 'y' && response != 'n');
return response;
}
int askNumber(string questions, int high, int low){
int number;
do{
cout << questions << " 0<=number<=8";
cin >> number;
} while (number > high || number < low);
return number;
}
char humanPiece() {
char responce = askYesNo("Do you want to make first move? ");
if (responce == 'y') return X;
return O;
}
char opponent(char piece){
if (piece == X) return O;
return X;
}
void displayBoard(const vector<char>& board){
cout << board[0] << " | " << board[1] << " | " << board[2] << " | " << endl;
cout << board[3] << " | " << board[4] << " | " << board[5] << " | " << endl;
cout << board[6] << " | " << board[7] << " | " << board[8] << " | " << endl;
}
char winner(const vector<char>& board){
const int WINNING_COMB[8][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 row = 0; row < 8; row++){
if((board[WINNING_COMB[row][0]] != EMPTY) && (board[WINNING_COMB[row][0]] == board[WINNING_COMB[row][1]]) &&
(board[WINNING_COMB[row][1]] == board[WINNING_COMB[row][2]])) return board[WINNING_COMB[row][0]];
}
for (int i = 0; i < 9; i++){
if (board[i] == EMPTY) return NO_ONE;
}
return TIE;
}
bool isLegal(const vector<char>& board, int move){
return (board[move] == EMPTY);
}
int humanMove(const vector<char>&board, char human) {
int move;
do {
move = askNumber("Choose move", 8, 0);
} while (!isLegal(board, move));
return move;
}
void announceWinner(char winner, char computer, char human){
if (winner == computer){
cout << "Computer won"<< endl;
} else if(winner == human){
cout << "Human won"<< endl;
} else cout << "It is a tie" << endl;
}
int computerMove(vector<char> board, char computer){
unsigned int move = 0;
bool found = false;
while(!found && move < board.size()){
if (isLegal(board, move)){
board[move] = computer;
found = winner(board) == computer;
board[move] = EMPTY;
}
if (!found){
move++;
}
}
if(!found){
move = 0;
char human = opponent(computer);
while(!found && move < board.size()){
if (isLegal(board, move)){
board[move] = human;
found = winner(board) == human;
board[move] = EMPTY;
}
if (!found){
move++;
}
}
}
if(!found) {
move = 0;
unsigned int i = 0;
const int BEST_MOVES[] = {4,0,2,6,8,1,3,5,7};
while(!found && i < board.size()){
move = BEST_MOVES[i];
if (isLegal(board,move)){
found = true;
}
i++;
}
}
cout << "I take number" << move << endl;
return move;
// если у компа есть возможность сделать ход, приносящий победу, делаем этот ход
// если человек может сделать ход, приносящий ему успех, заблокировать ход
// иначе занять лучшую из оставшихся клеток, приоритет с центра
}