С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
#1

Крестики-нолики - C++

01.08.2013, 22:52. Просмотров 1413. Ответов 16
Метки нет (Все метки)

Добрый вечер. Хочу попробовать написать свои крестики-нолики. Игру еще не дописал, но уже появилась следующая проблема. По идее, если я ввожу координаты 1 4 или 2 4, то должно вывести сообщение о неправильном вводе, на деле же символ просто переносится на следующую строку. В чем проблема?

Код
#pragma warning(disable:4996);
#include <iostream>
#include <conio.h>

using namespace std;

char matrix[3][3];

void init_matrix(); // инициализация матрицы
void display_matrix(); // нарисовать матрицу
void get_player_move(); // получить координаты
bool is_nothing(int, int); // проверить координаты

int main()
{
	setlocale(LC_ALL, "Russian");
	init_matrix();
	for (;;)
	{
		system("cls");
		display_matrix();
		get_player_move();
	}
	system("pause");
	return 0;
}

void init_matrix()
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			matrix[i][j] = ' ';
		}
	}
}

void display_matrix()
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << matrix[i][j] << ' ';
		}
		cout << endl;
	}
}

void get_player_move()
{
	int x, y;
	cout << "Введите координаты: ";
	cin >> x >> y;
	if (is_nothing(x, y)) // проверяем верны ли координаты
	{
		matrix[--x][--y] = 'X';
	}
	else
	{
		cout << "Неверный ход. " << endl;
		get_player_move(); // запрашиваем координаты еще раз
	}
}

bool is_nothing(int x, int y)
{
	return (matrix[--x][--y] == ' ') ? true : false; 
}
Добавлено через 1 минуту
И сразу же такой вопрос. Может кто нибудь натолкнет на мысль, как лучше было бы создать "интеллект" для компа, чтобы не просто рандомно тыкал 0.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2013, 22:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Крестики-нолики (C++):

Крестики нолики на С - C++
Здраствуйте. Помогите пожалуйста написать игру в консоли. Это крестики нолики поле 3х3. Буду благодарен если поможете и объясните. ...

Крестики-нолики - C++
Захотелось написать игру Крестики-нолики но тут возник один вопрос, как будет ходить компютер, если пользоватся rand-ом то компютер будет...

Крестики-нолики - C++
#include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; void show_cells(); void make_move(int num); void result(); ...

“Крестики-нолики” - C++
Напишите игру “Крестики-нолики”. Программа выводит игровое поле для двух игроков, проверяет правильность ходов, следит за ситуацией на...

Крестики нолики - C++
Нужно написать программу крестики нолики.

Крестики нолики - C++
Доброго времени суток, недавно я решил написать игру крестики нолики, написал, но код в ~1300 строк, что очень много, в коде много похожих...

16
Nikitko_Cent
144 / 114 / 12
Регистрация: 27.10.2011
Сообщений: 686
Завершенные тесты: 3
01.08.2013, 23:03 #2
Цитата Сообщение от dima55501 Посмотреть сообщение
И сразу же такой вопрос. Может кто нибудь натолкнет на мысль, как лучше было бы создать "интеллект" для компа, чтобы не просто рандомно тыкал 0.
В общем так:
Первый ход делать в центр\углы

далее:
1. сканируешь игровое поле на наличие прямых (т.е. столбцов, строк или диагоналей) с двумя твоими (считай, что ты - компьютер) значками и пустой ячейкой. Если такая прямая есть - втыкай третий свой значек -> win
2. если таких прямых не оказалось, то аналогично ищи прямые с двумя вражескими значками и пустой ячейкой. Если нашел - то втыкай в эту пустую ячейку свой значек, дабы предотвратить проигрыш.
3.если и таких прямых не нашлось, то пихай свой значек рандомно с приоритетом в центр\углы

При такой стратегии в свое время при написании крестиков ноликов, я столкнулся с одной проблемой - игрок может поставить "ловушку", когда у него будет одновременно две предвыигрышные ситуации. Но рассмотреть этот частный случай не составит особого труда (в плане написания кода).

Пример самой ловушки:

O.X
.O.
X.X

Где игрок играет крестиками
1
Wolkodav
605 / 458 / 32
Регистрация: 18.09.2012
Сообщений: 1,685
01.08.2013, 23:10 #3
dima55501, почитай в интернете, там есть описания алгоритмов для ии в крестики-нолики, если правильно напишите, то сами никогда не выйграете).
1) Переписал бы уж так,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void get_player_move()
{
    int x, y;
    cout << "Введите координаты: ";
    cin >> x >> y;
    if (is_nothing(x, y)) // проверяем верны ли координаты
    {
        matrix[--x][--y] = 'X';
    }
    else
    {
        cout << "Неверный ход. " << endl;
        return get_player_move(); // запрашиваем координаты еще раз
    }
}
Или вообще:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void get_player_move()
{
    int x, y;
    cout << "Введите координаты: ";
    cin >> x >> y;
    while (!is_nothing(x, y))
    {
         cout << "Неверный ход. " << endl;
         cout << "Введите координаты: ";
         cin >> x >> y;
    }
    matrix[--x][--y] = 'X';
}
Всё таки вы тут не граф обходите. Решения с рекурсией элегантный, но ей злоупотреблять не надо.

Добавлено через 2 минуты
И проверка координат:
C++
1
2
3
4
5
6
bool is_nothing(int x, int y)
{
    if ((x > 3) || (y > 3) || (y < 0) || (x < 0))
        return false;
    return (matrix[--x][--y] == ' ') ? true : false; 
}
2
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
01.08.2013, 23:12  [ТС] #4
Цитата Сообщение от Wolkodav Посмотреть сообщение
Всё таки вы тут не граф обходите. Решения с рекурсией элегантный, но ей злоупотреблять не надо.
Ну я вообще увидел код в книжке и пытаюсь по аналогии свой сделать. В чем минус использования рекурсии в моем случае?
0
Wolkodav
605 / 458 / 32
Регистрация: 18.09.2012
Сообщений: 1,685
01.08.2013, 23:16 #5
dima55501, в вашем, ну как минимум она у вас тут не совсем правильно была составлена. А так, ресурсы используемы при рекурсии больше. При очень глубоких рекурсиях комп запросто может повиснуть( особенно винда).
Какую проблему не решает?

Добавлено через 41 секунду
При каких координатах?
0
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
01.08.2013, 23:22  [ТС] #6
Wolkodav, да не, я просто не сразу увидел Ваш вариант функции is_nothing(). А так вроде все работает, спасибо.
0
Nikitko_Cent
144 / 114 / 12
Регистрация: 27.10.2011
Сообщений: 686
Завершенные тесты: 3
01.08.2013, 23:24 #7
Имхо, насчёт рекурсии Wolkodav прав. Лично я придерживаюсь такого правила - если я вижу, что некую задачу можно решить без использования рекурсии (т.е. циклами), и это решение будет легко пониматься при чтении и не будет громоздким, то я использую именно это решение, т.к. рекурсия - более затратный и потенциально опасный метод решения задач, нередко приводящий к переполнению стека.
Не могу утверждать, что моя точка зрения абсолютно верная, но посоветую тебе придерживаться её
1
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
01.08.2013, 23:26  [ТС] #8
Nikitko_Cent, спасибо, буду иметь ввиду.
0
Wolkodav
605 / 458 / 32
Регистрация: 18.09.2012
Сообщений: 1,685
01.08.2013, 23:29 #9
dima55501, практика была у меня очень печальная, не на С++, на питоне правда. Был сервер (web), надо был там короче с файлами работать. Как самый деловой сделал всё рекурсией ( а имеенно копирование), и в один прекрасный момент сервак не выдержал и рухнул( нагрузка было действительно неподъёмная), было пичально. С тех пор очень аккуратен с рекурсией.
0
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
01.08.2013, 23:31  [ТС] #10
Wolkodav, нда... Не думал, что рекурсия так коварна.
0
Wolkodav
605 / 458 / 32
Регистрация: 18.09.2012
Сообщений: 1,685
01.08.2013, 23:33 #11
dima55501, да вообщем везде надо с головой подходить и стараться не особо по шаблону идти.
0
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
02.08.2013, 00:10  [ТС] #12
В общем очередная проблема возникла Вроде программу дописал, условие проверки конца игры специально полностью списал из книги, а вот все равно где то есть ошибка. Заключается она в проверке окончания игры. Чтобы легче было проверять, ходы совершает только компьютер и выиграть он может в разных условиях, вот скрины:
1ый - нолики и в строке, и в столбце. Игра не закончилась вовремя.
2ой - нету 3ех ноликов ни в строке, ни в столбце.

Был бы очень благодарен за помощь.

Код
#pragma warning(disable:4996);
#include <iostream>
#include <conio.h>
#include <time.h>

using namespace std;

char matrix[3][3];

void init_matrix(); // инициализируем матрицу
void display_matrix(); // выводим матрицу на экран
void get_player_move(); // ход игрока
void get_comp_move(); // ход компьютера
bool is_nothing(int, int); // проверка правильности хода
char is_over(); // проверка конца игры

int main()
{
	srand(time(NULL));
	setlocale(LC_ALL, "Russian");
	char over = ' ';
	init_matrix();
	do
	{
		system("cls");
		display_matrix();
		/*get_player_move();
		over = is_over();
		if (over != ' ')
		{
			break;
		}*/
		get_comp_move();
		over = is_over();
	}
	while (over == ' ');
	system("cls");
	display_matrix();
	if (over == 'X')
	{
		cout << "Ты выиграл. " << endl;
	}
	else if (over == 'O')
	{
		cout << "Ты проиграл. " << endl;
	}
	system("pause");
	return 0;
}

void init_matrix()
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			matrix[i][j] = ' ';
		}
	}
}

void display_matrix()
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << matrix[i][j] << ' ';
		}
		cout << endl;
	}
}

void get_player_move()
{
	int x, y;
	cout << "Введите координаты: ";
	cin >> x >> y;
	while (!is_nothing(x, y))
	{
		cout << "Неверный ход. " << endl;
		cout << "Введите координаты: ";
		cin >> x >> y;
	}
	matrix[--x][--y] = 'X';
}

void get_comp_move() // ставит О в случайную клетку
{
	int x, y;
	x = rand() % 3 + 1;
	y = rand() % 3 + 1;
	while (!is_nothing(x, y))
	{
		x = rand() % 3 + 1;
		y = rand() % 3 + 1;
	}
	matrix[--x][--y] = 'O';
}

bool is_nothing(int x, int y)
{
	if (x <= 0 || x > 3 || y <= 0 || y > 3) // если введены неверные координаты
	{
		return false;
	}
	return (matrix[--x][--y] == ' ') ? true : false; // если клетка уже занята
}

char is_over()
{
	int i;
	for (i = 0; i < 3; i++) // проверяем строки
	{
		if (matrix[i][0] == matrix[i][1] && matrix[i][0] == matrix[i][2])
		{
			return matrix[i][0];
		}
	}
	for (i = 0; i < 3; i++) // проверяем столбцы
	{
		if (matrix[0][i] == matrix[1][i] && matrix[0][i] == matrix[2][i])
		{
			return matrix[0][i];
		}
	}
	if (matrix[0][0] == matrix[1][1] && matrix[1][1] == matrix[2][2]) // проверяем главную диагональ
	{
		return matrix[0][0];
	}
	if (matrix[0][2] == matrix[1][1] && matrix[1][1] == matrix[2][0]) // проверяем побочную диагональ
	{
		return matrix[0][2];
	}
}
0
Миниатюры
Крестики-нолики   Крестики-нолики  
Wolkodav
605 / 458 / 32
Регистрация: 18.09.2012
Сообщений: 1,685
02.08.2013, 23:28 #13
dima55501, ой, тут что-то намучено, завтра разберусь...
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
03.08.2013, 00:32 #14
Крестики-нолики для поля 3 на 3 всегда можно свести как минимум к ничьей. Вот вам наглядное дерево ходов. Кодируете его в каком-нибудь удобном виде с точностью до поворотов. При каждом ходе игрока подбираете поворотом состояние ячеек и делаете свой ход в соответствии с деревом.
0
dima55501
30 / 34 / 6
Регистрация: 14.07.2013
Сообщений: 146
03.08.2013, 00:47  [ТС] #15
Wolkodav, ок, спасибо.
OhMyGodSoLong, да я сейчас даже не про ничью. Я про то, что в условии проверки конца игры есть ошибка, которую я никак не могу найти.
0
03.08.2013, 00:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2013, 00:47
Привет! Вот еще темы с ответами:

Крестики/нолики - C++
Я не понимаю почему не работает, и в этом моя проблема. Буду благодарен любой помощи, а так же любой конструктивной критике по коду. Если...

крестики-нолики - C++
Может у кого-то есть шаблон,чтобы расчертить поле в клетку,например 3x3. Покажите пожалуйста))

Крестики нолики - C++
Уж слишком запутался даже в такой простом коде: #include &lt;iostream&gt; #include &lt;cstring&gt; #include &lt;string&gt; #include &lt;iomanip&gt; ...

Крестики-нолики 10 на 10 - C++
Нужно написать игру крестики-нолики. Застрял на алгоритме проверки победителя, точнее я написал, она работает, но алгоритм проверки в плане...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.