Answer the question
In order to leave comments, you need to log in
How to remove a fragment of a condition?
Warning: not for the faint of heart! Complex algorithm and the same implementation :-(
Meaning of the question:
in my code (in some function that will be below) there is such a code fragment
if (y + 2 < SIZE && x - 1 >= 0 && way[step_num - 1].blocked < 2
&& field[x - 1][y + 2] == false)
{
way[step_num].y = way[step_num - 1].y + 2;
way[step_num].x = way[step_num - 1].x - 1;
way[step_num].setedByWay = 2;
field[x - 1][y + 2] = true;
chessIsMoved = true;
}
else if (y - 2 >= 0 && x + 1 < SIZE && way[step_num - 1].blocked < 3
&& field[x + 1][y - 2] == false)
{
way[step_num].y = way[step_num - 1].y - 2;
way[step_num].x = way[step_num - 1].x + 1;
way[step_num].setedByWay = 3;
field[x - 1][y + 2] = true;
chessIsMoved = true;
}
#include <iostream>
#include <conio.h>
#define SIZE 6//6x6 - размер доски
using namespace std;
struct coords {
short x;
short y;
short blocked = 0;//неверное направление пути
short setedByWay = 0;//направление, по которому конь переместился на данные координаты //(используется для отката)
/*
Направления:
1 - down(2)->right(1)
2 - down(2)->left(1)
3 - up(2)->right(1)
4 - up(2)->left(1)
5 - down(1)->right(2)
6 - down(1)->left(2)
7 - up(1)->right(2)
8 - up(1)->left(2)
*/
};
void getX(short* x);
void getY(short* y);
void setWay(coords* way, bool field[][SIZE], short step_num = 1);
bool setStep(coords* way, bool** field, short step_num);
void main()
{
short x, y;//кординаты, по которым изначально ставится конь на доске
coords way[SIZE*SIZE+1];//кординаты, по которым будет передвигаться конь
bool field[SIZE][SIZE] = { false };//отображение заполнённости игрового поля (false - ячейка свободна, true - на данной ячейке был конь)
getX(&x);
getY(&y);
while (x >= SIZE)
{
cout << "x must be <" << SIZE << '\n';
getX(&x);
}
while (y >= SIZE)
{
cout << "y must be <" << SIZE << '\n';
getY(&y);
}
//установка коня на начальную позицию (начало пути)
way[0].x = x;
way[0].y = y;
setWay(way, field);
for (short i = 0; i < SIZE*SIZE + 1; i++)
cout << way[i].x << '\t' << way[i].y << endl;
/*while ()
{
setStep(way, step_num);
}*/
_getch();
}
void getX(short* x)
{
cout << "x->";
cin >> *x;
}
void getY(short* y)
{
cout << "y->";
cin >> *y;
}
//записывает путь перемещения коня по доске в массив way
//step_num - номер перемещения (максимум SIZE^2) (индекс в массиве way), ибо 1 выполнение функции - 1 перемещение
void setWay(coords* way, bool field[][SIZE], short step_num)
{
//координаты, на которых сейчас стоит конь (с которых нужно сделать переход)
short y = way[step_num - 1].y;
short x = way[step_num - 1].x;
bool chessIsMoved = false;//true даёт разрешение на следующее перемещение коня
//если нету выхода за границы поля и данный путь (с каждой проверкой увеличивается значение) не заблокирован
//и поле, на которое планируется переход, нетронутое
if (y + 2 < SIZE && x + 1 < SIZE && way[step_num - 1].blocked < 1
&& field[x + 1][y + 2] == false)
{
//запись координат в путь
way[step_num].y = way[step_num - 1].y + 2;
way[step_num].x = way[step_num - 1].x + 1;
//установка пути, по которому выполнен переход на данную ячейку
way[step_num].setedByWay = 1;
//метка "ячейка занята"
field[x + 1][y + 2] = true;
//переход к следующему перемещению
chessIsMoved = true;
}
else if (y + 2 < SIZE && x - 1 >= 0 && way[step_num - 1].blocked < 2
&& field[x - 1][y + 2] == false)
{
way[step_num].y = way[step_num - 1].y + 2;
way[step_num].x = way[step_num - 1].x - 1;
way[step_num].setedByWay = 2;
field[x - 1][y + 2] = true;
chessIsMoved = true;
}
else if (y - 2 >= 0 && x + 1 < SIZE && way[step_num - 1].blocked < 3
&& field[x + 1][y - 2] == false)
{
way[step_num].y = way[step_num - 1].y - 2;
way[step_num].x = way[step_num - 1].x + 1;
way[step_num].setedByWay = 3;
field[x - 1][y + 2] = true;
chessIsMoved = true;
}
else if (y - 2 >= 0 && x - 1 >= 0 && way[step_num - 1].blocked < 4
&& field[x - 1][y - 2] == false)
{
way[step_num].y = way[step_num - 1].y - 2;
way[step_num].x = way[step_num - 1].x - 1;
way[step_num].setedByWay = 4;
field[x - 1][y + 2] = true;
chessIsMoved = true;
}
else if (y + 1 < SIZE && x + 2 < SIZE && way[step_num - 1].blocked < 5
&& field[x + 2][y + 1] == false)
{
way[step_num].y = way[step_num - 1].y + 1;
way[step_num].x = way[step_num - 1].x + 2;
field[x + 2][y + 1] = true;
way[step_num].setedByWay = 5;
chessIsMoved = true;
}
else if (y + 1 < SIZE && x - 2 >= 0 && way[step_num - 1].blocked < 6
&& field[x - 2][y + 1] == false)
{
way[step_num].y = way[step_num - 1].y + 1;
way[step_num].x = way[step_num - 1].x - 2;
way[step_num].setedByWay = 6;
field[x - 2][y + 1] = true;
chessIsMoved = true;
}
else if (y - 1 >= 0 && x + 2 < SIZE && way[step_num - 1].blocked < 7
&& field[x + 2][y - 1] == false)
{
way[step_num].y = way[step_num - 1].y - 1;
way[step_num].x = way[step_num - 1].x + 2;
way[step_num].setedByWay = 7;
field[x + 2][y - 1] = true;
chessIsMoved = true;
}
else if (y - 1 >= 0 && x - 2 >= 0 && way[step_num - 1].blocked < 8
&& field[x - 2][y - 1] == false)
{
way[step_num].y = way[step_num - 1].y - 1;
way[step_num].x = way[step_num - 1].x - 2;
way[step_num].setedByWay = 8;
field[x - 2][y - 1] = true;
chessIsMoved = true;
}
else //если нету свободных клеток, на которые можно переместиться, - блокировка данного пути,метка "данная клетка свободна" и откат (возврат на шаг назад)
{
way[step_num - 2].blocked = way[step_num - 1].setedByWay;
field[x][y] = false;
setWay(way, field, step_num - 1);
}
//if (way[SIZE*SIZE].x != way[0].x && way[SIZE*SIZE].y != way[0].y)//если все ходы выполнены, но конь стоит не в нужном месте
// setWay(way, field, step_num - 1);//откат
if (step_num == SIZE*SIZE && way[SIZE*SIZE].x != way[0].x && way[SIZE*SIZE].y != way[0].y)//полный возврат с рекурсии (ну и с функции) только при условии, если данная "итерация" - последняя и {конечная и начальная ячейки совпадают}
return;
if(chessIsMoved)
setWay(way, field, step_num + 1);
}
Answer the question
In order to leave comments, you need to log in
In fact, this problem is solved differently. In chess number grinders, as in any number grinders, you should try to reduce the number of conditions to a minimum. Instead of checking for out-of-bounds matrix (and this is 4 checks, or two if unsigned numbers and overflow are used), the matrix itself is expanded by one on each side and a flag or other "blocking" value is written there.
Although, your condition check begins with checking for out-of-bounds array and the problem with the error should not have been from the beginning ... if the order in the two-dimensional array had not been mixed up. Actually field[y][x].
This is a task for "Backtracking, backtracking". The condition says that it is necessary to use recursion. Cache paths. And when there is nowhere to go, finish the work. Then check the paths and look for the one in which the number of cells visited is 6*6.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question