#include "stdafx.h"
#include <iostream>
#include <cstdio>
using namespace std;
//---------------------------------------------------------------------------
/*
если один из игроков заполнил всю горизонталь / вертикаль / диагональ,
возвращает символ, которым он играет
если никто еще на заполнил линию, возвращает пробел
*/
int check(char** field, int size) {
// итераторы
int i, j;
// первый символ по горизонтали и первый по вертикали
int g, v;
// диагонали
int d1, d2;
// начинается цикл в n заходов, n равно размеру поля
for (i = 0; i < size; i++) {
// ПРОВЕРКА ПО ГОРИЗОНТАЛИ
// запоминаем символ из начала i строки поля
g = field[i][0];
// проходимся по i строке поля
for (j = 0; j < size; j++) {
// если натенемся на несовпадение с первым символом
// или если первый символ был пробелом, то
if (field[i][j] != g || g == ' ') {
// забиваем на проверку, записываем в g символ ' '
g = ' ';
// и выходим цикла принудительно
break;
}
}
// если в g хранится символ, отличный от пробела, это значит что в начале
// строки был крестик или нолик, и проходя по всей строке (в цикле выше)
// мы не наткнулись на символ, отличающийся от того, что в начале
// иными словами, один из игроков заполнил всю строку одним символом
// и выйграл
if (g != ' ') {
// если это условие выполнено, просто возвращаем символ, которым
// заполнена вся строка
return g;
}
// ПРОВЕРКА ПО ВЕРТИКАЛИ
// записываем символ из начала i столбца поля
v = field[0][i];
// проходим по i столбцу
for (j = 0; j < size; j++) {
// если натенемся на несовпадение с первым символом
// или если первый символ был пробелом, то
if (field[j][i] != v || v == ' ') {
// забиваем на проверку, записываем в v символ ' '
v = ' ';
// и выходим цикла принудительно
break;
}
}
// если в v хранится символ, отличный от пробела, это значит что в начале
// строки был крестик или нолик, и проходя по всей строке (в цикле выше)
// мы не наткнулись на символ, отличающийся от того, что в начале
// иными словами, один из игроков заполнил всю строку одним символом
// и выйграл
if (v != ' ') {
// в таком случае возвращаем этот символ
// это означает, что игрок с этим символом выйграл
return v;
}
}
// Записываем, какие символы в начале основной и побочной диагонали
d1 = field[0][0];
d2 = field[0][size - 1];
// проверка по основной диагонали
// ?##
// #?#
// ##?
for (i = 0; i < size; i++) {
// если наткнемся на несовпадение
if (field[i][i] != d1) {
// забиваем на проверку, записываем в d1 символ ' '
d1 = ' ';
// принудительно выходим их цикла
break;
}
}
// если все знаки на диагонали одинаковые, и знак не пробел, возвращаем знак
if (d1 != ' ') {
return d1;
}
// проверка по побочной диагонали
// ##?
// #?#
// ?##
for (i = 0; i < size; i++) {
// если наткнемся на несовпадение
if (field[i][size - 1 - i] != d2) {
// забиваем на проверку, записываем в d1 символ ' '
d2 = ' ';
// принудительно выходим их цикла
break;
}
}
// если все знаки на диагонали одинаковые, и знак не пробел, возвращаем знак
if (d2 != ' ') {
return d2;
}
// если ни одна из полос не заполнена, возвращаем пробел
return ' ';
}
// вывод поля
void out(char** field, int size) {
int i, j;
// очистка экрана
system("cls");
// верхняя граница поля
for (j = 0; j < size; j++) {
cout << "--";
}
cout << "-\n";
// выводим по очереди все ряды и деления
for (i = 0; i < size; i++) {
// ряд символов
for (j = 0; j < size; j++) {
cout << "|" << field[i][j];
}
cout << "|\n";
// деление
for (j = 0; j < size; j++) {
cout << "--";
}
cout << "-\n";
}
}
int main() {
// поле (массив массивов), размер
int size;
// текущий игрок
int player = 'x';
// результат проверки игрового поля на заполнение полосы
int result;
// индикатор работы игры
int running = 1;
// итераторы
int i, j;
// вводим размер поля
cout << "Enter field size: ";
cin >> size;
// выделяем память под массив из size указателей на массивы
// (читай size строк)
////////////////////////////field = malloc(size * sizeof(int*));
char **field = new char*[size];
// заполняем массив указателей указателями на новые массивы
// (читай size ячеек в каждой строке)
for (i = 0; i < size; i++) {
//field[i] = malloc(size * sizeof(int));
field[i] = new char[size];
// заполняем каждую ячейку пробелом
for (j = 0; j < size; j++)
field[i][j] = ' ';
}
// пока игра продолжается
while (running) {
do {
// выводим поле
out(field, size);
// выводим чей ход
if (player == 'x') {
cout << "x turn\n";
}
else {
cout << "o turn\n";
}
// вводим координаты хода (от 1 до size)
cout << "Type x y (separated by space): ";
cin >> i >> j;
// если пользователь введет что-то неправильно, цикл продолжается
// и спрашивает заново
// как только игрок введет координаты правильно, цикл остановится
} while (i > size || j > size || i < 0 || j < 0 || field[i - 1][j - 1] != ' ');
// зачеркиваем ячейку поля
field[i - 1][j - 1] = player;
// проверяем поле
result = check(field, size);
// если result не пробел, значит кто-то выйграл
if (result != ' ') {
// выводим символ победителя (хранится в result)
cout << result << "wins!";
// останавливаем игру
running = 0;
}
// передаем ход другому игроку
if (player == 'x') {
player = 'o';
}
else {
player = 'x';
}
}
return 0;
}