Понравилась задача, расскажу как сделал в итоге я.
Программа работает слева -> направо, сверху -> вниз.
Первый кусок, нам известен.
Берем правую сторону первого элемента, находим его связь, далее для следующего элемента надо найти элемент противоположной стороны.
Для примера правая сторона вот такая:
`left: { edgeTypeId: 38, type: 'outside' }`
Надо искать где edgeTypeId :38 и type:'inside'.
Элемент который будет найден, надо обратить внимание, на его сторону, и получить противоположный.
К примеру мы нашли 38 и inside, оно лежало в элементе с id:33, сторона: top, нам надо искать след элемент который будет в bottom, так как он противоположный.
И так проходим всю строку до конца.
Находим нижний элемент первого элемента первого ряда, и далее так же как и было выше, ищем связь для противоположной стороны.
Прикреплю код, его можно сделать более читабельным, но решение рабочие для этой задачи.
Осторожно код
function solvePuzzle(pieces) {
// initial
let result = [pieces[0].id];
let next = {
edgeTypeId: pieces[0].edges.bottom.edgeTypeId,
type: pieces[0].edges.bottom.type,
};
for(let rowIndex = 0, step = -10;rowIndex < 10;rowIndex++, step += 10) {
if (rowIndex !== 0) {
next = getDownPiece(result[step], pieces)
result.push(next.id)
next = next.edges.bottom
}
for(let i = 0;i < 9;i++) {
next = findNextEdge(next, pieces, i === 8);
result.push(next.id)
}
}
return result;
}
function findNextEdge(previousEdge, pieces, isLast = false) {
let typeOpposite = getTypeOpposite(previousEdge.type);
let result = {};
for (var i = 0; i < pieces.length; i++) {
let nextEdge = Object.entries(pieces[i].edges).find(function(edge) {
let [, nextEdgeCandidate] = edge
return nextEdgeCandidate !== null && previousEdge.edgeTypeId === nextEdgeCandidate.edgeTypeId && nextEdgeCandidate.type === typeOpposite;
});
if (nextEdge !== undefined) {
[typeSide] = nextEdge
if (isLast === false) {
result = Object.assign(pieces[i].edges[getOppositePosition(typeSide)], {id:pieces[i].id})
} else if(isLast){
result = Object.assign(pieces[i].edges[typeSide], {id:pieces[i].id})
}
}
}
return result;
}
function findConnectedEdge(leftEdge, pieces) {
let typeOpposite = getTypeOpposite(leftEdge.type);
return pieces.find(function(piece){
return Object.entries(piece.edges).find(function(edge) {
let [, rightEdgeCandidate] = edge
return rightEdgeCandidate !== null && leftEdge.edgeTypeId === rightEdgeCandidate.edgeTypeId && rightEdgeCandidate.type === typeOpposite;
});
});
}
function getTypeOpposite(type){
return type === 'inside' ? 'outside':'inside';
}
function getOppositePosition(position) {
if (position === 'bottom') {
return 'top';
} else if(position === 'top') {
return 'bottom'
} else if (position === 'left') {
return 'right';
} else {
return 'left';
}
}
function getDownPiece(idUpPiece, pieces) {
return findConnectedEdge(pieces.find(edge => {
return edge.id === idUpPiece;
}).edges.left, pieces)
}
// Не удаляйте эту строку
window.solvePuzzle = solvePuzzle;