Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <iostream>
- #include <time.h>
- #include <cstdlib>
- #include <ctime>
- #include <cstring>
- #define cout std::cout
- #define endl std::endl
- #define cin std::cin
- int N; // Кол-во ходов. Задаём в main
- void random_moves(int); // При выборе случайных перемещений
- void manual_moves(int); // С вводом перемещений вручную
- void KingMove(int, int); // Функция для перемещений короля по полю
- void answer_check(char[]); // Проверка правильности ввода ответа
- void checking(); // Поиск клеток, на которые король встал два раза
- void checking_true(int, int); // Вывод ответа
- void N_check(int);
- struct coordinates { // Запись координат, где был король
- int x;
- int y;
- };
- struct Moves {
- Moves() {
- Head = NULL; //Обозначили в конструкторе что голова пустая, ибо очередь пуста
- }
- int val;
- int size;
- Moves *Head, *Tail, *Next;
- void Add(const int x);
- void Show();
- void Del();
- };
- void Moves::Add(int x) {
- static int count = 0;
- /////////////////////////////////////////////
- Moves *temp = new Moves;
- Next = temp->Head;
- temp->val = x;
- if (Head != NULL) {
- Tail->Next = temp;
- Tail = temp;
- }
- else Head = Tail = temp;
- ////////////////////////////////////////////
- count++;
- size = count;
- }
- void Moves::Show() {
- Moves *temp = Head; //Получаем адрес начала очереди
- int count = 1;
- while (temp != Tail->Next) { //Пока адрес указателя не совпадет со следующим элементом за хвостом очереди
- cout << endl << "Шаг №: " << count-1 << endl;
- cout << "Действие №: " << temp->val << " " << "\n"; //Будем выбирать элементы, использя указатель temp
- KingMove(temp->val, count); //Передаём в функцию значение и счетчик для координат
- count++;
- temp = temp->Next; //Как только выбрали элемент, переходим по новому адресу к следующему элементу
- }
- }
- void Moves::Del() {
- Moves *temp = new Moves;
- int count = 0;
- while (temp != Tail) {
- temp = Head;//Нашли текущее начало очереди и запомнили адрес в сторонюю переменую
- Head = Head->Next; //Сместили фактическое начало на адрес следующего поступившего элемента
- cout << "Udalena swiaz s: " << temp->val << "\n"; //Для наглядности
- delete temp; //Очистили связь
- }
- }
- coordinates* coord = new coordinates[N]; // Выделим память под массив структур с координатами перемещения
- int main()
- {
- Moves mv; //Объявили переменную типа нашей очереди FIFO (имя структуры)
- mv.Head = NULL; //Обозначили что голова пустая, ибо очередь пуста (можно в конструкторе)
- setlocale(LC_ALL, "Russian");
- cout << "Введите кол-во ходов: ";
- //cin >> N; // Ввод количества перемещений
- while (!(cin >> N)) // проверка ввода с клавиатуры
- {
- cin.clear();
- while (cin.get() != '\n');
- cout << "Неверный ввод. Повторите." << endl;
- cout << "Введите колличество эллементов:";
- }
- N_check(N);
- for (int i = 0;i < N + 1;i++) {
- coord[i].x = 0;
- coord[i].y = 0;
- }
- char *answer = new char[4];
- cout << endl << "Изначально Король находится в координах (0;0). И поскольку поле бесконечное, то может двигаться в любом из направлений." << endl << "Будете ли Вы заполнять список случайными ходами? (yes/no) ";
- cin >> answer;
- answer_check(answer); // Проверим верность введенного ответа
- checking(); //Выведем ответ
- system("pause");
- return 0;
- }
- void random_moves(int nmoves) {
- Moves mv;
- srand(time(NULL));
- cout << "Сделаем случайные ходы...";
- int action;
- for (int i = 0;i < nmoves;i++) {
- action = rand() % 7 + 0;
- mv.Add(action);
- }
- mv.Show(); //Покажем наши команды
- system("pause");
- }
- void manual_moves(int nmoves) {
- Moves mv;
- cout << endl << "0 - Верх" << endl << "1 - Вниз" << endl << "2 - Влево" << endl << "3 - Вправо" << endl << "4 - Вверх-вправо" << endl << "5 - Вниз-вправо" << endl << "6 - Вниз-влево" << endl << "7 - Вверх-влево" << endl;
- int action;
- for (int i = 0;i < nmoves;i++) { // Вводим команды перемещения и сразу проверяем на наличие данной команды
- cin >> action;
- if (action > 7 || action < 0) { cout << "Не существует такого действия. Введите еще раз:"; }
- while (action > 7 || action < 0) { cin >> action; }
- mv.Add(action); // Помещаем команды в очереди FIFO
- }
- mv.Show(); //Покажем наши команды
- system("pause");
- }
- void KingMove(int move, int count) { // Перемещаем короля согласно командам
- coord[count].x += coord[count - 1].x;
- coord[count].y += coord[count - 1].y;
- if (move == 0) { coord[count].y++; }
- if (move == 1) { coord[count].y--; }
- if (move == 2) { coord[count].x--; }
- if (move == 3) { coord[count].x++; }
- if (move == 4) { coord[count].x++; coord[count].y++; }
- if (move == 5) { coord[count].x++; coord[count].y--; }
- if (move == 6) { coord[count].x--; coord[count].y--; }
- if (move == 7) { coord[count].x--; coord[count].y++; }
- cout << "X: " << coord[count].x << "\t" << "Y: " << coord[count].y << "\n" << "================" << endl; // Вывод новых координат короля
- }
- void answer_check(char answer[]) {
- char quest1[] = "yes";
- char quest2[] = "no";
- if (strcmp(quest1, answer) == 0) {
- random_moves(N);
- }
- else if (strcmp(quest2, answer) == 0) {
- manual_moves(N);
- }
- else {
- cout << "Неверный ответ. Введите 'yes' или 'no': " << endl;
- cin >> answer;
- answer_check(answer);
- }
- }
- void N_check(int num) { // Для того, чтобы не запускать наш алгоритм для проверки простейших значений выведем ответ сразу и завершим программу
- if (num < 0) { cout << "Количество шагов не может быть отрицательным"; system("pause"); system("exit(0)"); };
- if (num == 0) { cout << "Король остался на месте."; system("pause"); system("exit(0)"); }
- if (num == 1) { cout << "Король не вставал два раза на одну и ту же клетку."; system("pause"); system("exit(0)"); }
- }
- void checking() {
- int i,j, smallest_diff=1000, smallest_i=0, smallest_j=0; // smallest_diff=1000, даже при кол-ве шагов больше 100к будет меньший ответ
- for (i = 1;i < N + 1;i++) {
- for (j = 1;j < N + 1;j++) {
- if ((coord[i].x == coord[j].x) && (coord[i].y == coord[j].y) && (i != j)) { // Алгоритм для проверки кратчайшего кол-ва шагов и близости к началу очереди
- if ((abs(i - j) < smallest_diff) && (smallest_i < i || smallest_j < j)) { smallest_diff = abs(i - j); smallest_i = i; smallest_j = j; }
- }
- }
- }
- checking_true(smallest_i, smallest_j);
- }
- void checking_true(int x_true, int y_true) {
- if (x_true != 0 && y_true != 0) {
- cout << "Король встал на клетку, на которой был раньше." << endl;
- cout << "Король был на одинаковой клетке на " << (x_true-1) << " шаге и на " << (y_true-1) << " шаге.";
- system("pause");
- system("exit(0)");
- }
- else {
- cout << "Король не вставал два раза на одну и ту же клетку." << endl;
- system("pause");
- system("exit(0)");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement