Исходный код
//разметка матрицы
while ((founded==1)&&(mat[nx][ny]<=0)) {
founded=0;
iii=y-i;
while (((i==0)&&(iii==y))||((iii<=y+i))){
ii=x-i;
while ((ii<=x+i)){
if ((mat[ii][iii]==i)&&((ii<70)&&(ii>=0))&&((iii<70)&&(iii>=0))) {
bii=ii;
biii=iii;
if ((mat[bii+1][biii]==-1)&&(bii+1<70)&&(bii+1>=0)) {
mat[bii+1][biii]=i+1;
founded=1;
}
if ((mat[bii-1][biii]==-1)&&(bii-1<70)&&(bii-1>=0)) {
mat[bii-1][biii]=i+1;
founded=1;
}
if ((mat[bii][biii+1]==-1)&&(biii+1<70)&&(biii+1>=0)) {
mat[bii][biii+1]=i+1;
founded=1;
}
if ((mat[bii][biii-1]==-1)&&(biii-1<70)&&(biii-1>=0)) {
mat[bii][biii-1]=i+1;
founded=1;
}
}
ii++;
}
iii++;
}
i++;
}
if (mat[nx][ny]>=0) {
if ((nx==40)&&(ny==57)) {
nx=nx;
}
ik=i;
ii=nx;
iii=ny;
<em>//поиск пути</em>while (ik>1) {
if ((mat[ii-1][iii]==ik-1)&&(ii-1<70)&&(ii-1>=0)) {
ii--;
mat[ii][iii]=-3;
}
if ((mat[ii][iii-1]==ik-1)&&(iii-1<70)&&(iii-1>=0)) {
iii--;
mat[ii][iii]=-3;
}
if ((mat[ii+1][iii]==ik-1)&&(ii+1<70)&&(ii+1>=0)) {
ii++;
mat[ii][iii]=-3;
}
if ((mat[ii][iii+1]==ik-1)&&(iii+1<70)&&(iii+1>=0)) {
iii++;
mat[ii][iii]=-3;
}
ik--;
}
ax=ii*10+5;
ay=iii*10+5;
//out_to_file(mat,"d:\\out.txt");
i++;
ii=0;
iii=0;
while ((iii>-1)&&(iii<70)){
ii=0;
while ((ii>-1)&&(ii<70)){
if ((mat[ii][iii]>-1)||(mat[ii][iii]==-3)) {
mat[ii][iii]=-1;
}
ii++;
}
iii++;
}
nx=ax;
ny=ay;
}
Что не так в этом коде
Ни и чём не говорящие названия переменных
Названия iii
, ii
, biii
, bii
выбраны крайне неудачно, так как ничего не говорят о том, к какой координате матрицы они имеют отношение — x или y.
Ненужные переменные
Вероятно, переменные biii
, bii
являются избыточными, так как я не вижу мест, где бы они принимали значения, отличные от исходных.
Если переменные ничего не делают — от них необходимо избавиться, иначе они будут вносить путаницу.
Не оптимально выбраны операторы циклов
Везде по коду применяются циклы while
, хотя по алгоритму здесь больше подходит for
.
Сравни:
iii=y-i;
while (((i==0)&&(iii==y))||((iii<=y+i))) {
// ...
iii++;
}
и
for (int iii=y-i; ((i==0)&&(iii==y))||((iii<=y+i)); iii++) {
// ...
}
Некорректная проверка на выход из диапазона
if ((mat[bii+1][biii]==-1)&&(bii+1<70)&&(bii+1>=0)) {
Здесь сначала выполняется доступ к клетке mat[bii+1][biii]
, а потом делается проверка на принадлежность bii+1
к правильному диапазону (bii+1<70)&&(bii+1>=0)
.
Аналогично с
if ((mat[ii-1][iii]==ik-1)&&(ii-1<70)&&(ii-1>=0)) {
Правильно будет так:
if ((bii+1<70)&&(bii+1>=0)&&(mat[bii+1][biii]==-1)) {
if ((ii-1<70)&&(ii-1>=0)&&(mat[ii-1][iii]==ik-1)) {
Почему нужно сначала проверять, потом обращаться.
Булевы выражения вычисляются слева направо. Сначала будет вычислена проверка, если она истинна, то только тогда вычислится выражение с обращением к ячейке. Если же проверка будет ложна, то обращения к ячейке вовсе не произойдёт.
Нарушены принципы единственного знания и единственной сущности
Одна функция, которую мы даже видим очевидно не всю, а лишь фрагмент, заключает в себе и работу с матрицей в целом, и работу с ячейками, и различные виды операций с матрицей.
Вместо одной большой функции должны быть несколько поменьше, каждая из которых выполняет отдельный вид операции.
Магический литерал
В коде многократно применяется литерал 70.
Похоже, что он означает размер матрицы 70×70.
Если так, что следовало хотя бы поместить это значение в константу, а ещё лучше — в параметр функции, причём отдельно ширину и высоту.
Плохое форматирование
Чтение кода дополнительно затрудняется маленькими отступами, которые в некоторых местах и вовсе отсутствуют.
Также в булевых выражениях недостаёт пробелов, зато содержится чрезмерное количество скобок.
Вариант рефакторинга исходного кода
int markupMatrix(int** matrix, int width, int height, int i) {
int found = 0;
for (int iy = y - i; i == 0 && iy == y || iy <= y + i; iy++) {
for (int ix = x - i; ix <= x + i; ix++) {
if (ix < width && ix >= 0 && iy < height && iy >= 0 && matrix[ix][iy] == i) {
founded = markupNeighbourCells(matrix, width, height, ix, iy, i);
}
}
}
return found;
}
int markupNeighbourCells(int** matrix, int width, int height, int ix, int iy, int i) {
int found = 0;
if (ix + 1 < width && ix + 1 >= 0 && matrix[ix + 1][iy] == -1) {
matrix[ix + 1][iy] = i + 1;
found = 1;
}
if (ix - 1 < width && ix - 1 >= 0 && matrix[ix - 1][iy] == -1) {
matrix[ix - 1][iy] = i + 1;
found = 1;
}
if (iy + 1 < height && iy + 1 >= 0 && matrix[ix][iy + 1] == -1) {
matrix[ix][iy + 1] = i + 1;
found = 1;
}
if (iy - 1 < height && iy - 1 >= 0 && matrix[ix][iy - 1] == -1) {
matrix[ix][iy - 1] = i + 1;
found = 1;
}
return found;
}
void resetCellWeights(int** matrix, int width, int height, int* ix, int* iy, int i) {
for (int ik = i; ik > 1; ik--) {
if (*ix - 1 < width && *ix - 1 >= 0 && matrix[*ix - 1][*iy] == ik - 1) {
matrix[--*ix][*iy] =- 3;
}
if (*iy - 1 < height && *iy - 1 >= 0 && matrix[*ix][*iy - 1] == ik - 1) {
matrix[*ix][--*iy] = -3;
}
if (*ix + 1 < width && *ix + 1 >= 0 && matrix[*ix + 1][*iy] == ik - 1) {
matrix[++*ix][*iy] = -3;
}
if (*iy + 1 < height && *iy + 1 >= 0 && matrix[*ix][*iy + 1] == ik - 1) {
matrix[*ix][++*iy] = -3;
}
}
}
// разметка матрицы
for (int found = 1; found == 1 && matrix[nx][ny] <= 0; i++) {
found = markupMatrix(matrix, width, height, ix, iy, i);
}
if (matrix[nx][ny] >= 0) {
ix = nx;
iy = ny;
// поиск пути
resetCellWeights(matrix, width, height, &ix, &iy, i++);
ax = ix * 10 + 5;
ay = iy * 10 + 5;
//out_to_file(matrix,"d:\\out.txt");
while (iy = 0; iy > -1 && iy < height; iy++) {
for (ix = 0; ix > -1 && ix < width; ix++) {
if (matrix[ix][iy] > -1 || matrix[ix][iy] == -3) {
matrix[ix][iy] = -1;
}
}
}
nx = ax;
ny = ay;
}