TRASA — laboratorium najkrótszej drogi
MiniaplikacjePodgląd
Ładowanie podglądu…
Rysowanie przeszkód i wyszukiwanie najkrótszej trasy krok po kroku.
Kod źródłowy
Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.
HTML
<main><header><h1>Znajdź przejście.</h1><p>Ustaw ściany między startem S i metą M.</p></header><div class="lab"><div id="maze" role="group" aria-label="Plansza labiryntu; strzałki zmieniają pole, spacja ustawia ścianę"></div><aside><div class="route-count"><strong id="distance">—</strong><span>kroków do mety</span></div><div class="legend"><p><i class="wall"></i> Ściana</p><p><i class="path"></i> Trasa</p></div><button type="button" id="solve">Znajdź trasę</button><button type="button" id="clear-walls">Usuń ściany</button><button type="button" id="example-maze">Przykładowy układ</button><p id="maze-status" class="status" role="status">Kliknij pole, aby dodać lub usunąć ścianę.</p></aside></div><footer>Ruch w czterech kierunkach. Algorytm przeszukuje planszę wszerz (BFS).</footer></main>
CSS
*{box-sizing:border-box}body{margin:0;font:16px/1.5 Arial,sans-serif}h1,h2,h3,p{margin:0}button,input,textarea,select{font:inherit;border-radius:0}button{cursor:pointer;min-height:44px}input,select{min-height:44px}button:disabled{cursor:default;opacity:.5}button:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible{outline:3px solid var(--focus,#1457d9);outline-offset:3px}label{display:block}textarea{resize:vertical;width:100%;max-width:100%}main{min-height:100vh}button:active:not(:disabled){filter:brightness(.9)}[hidden]{display:none!important}.status{min-height:1.5em;font-size:14px}footer{font-size:12px;margin-top:24px}.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}input,textarea,select{color:inherit}h1{line-height:1.05;letter-spacing:-.04em}button{transition:background-color .15s,color .15s}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}body{background:#f1f6fc;color:#173f78;--focus:#9f174c}main{max-width:1000px;padding:32px 5%;margin:auto}header{border-bottom:2px solid #173f78;padding-bottom:22px}h1{font-size:clamp(32px,4vw,52px);margin-bottom:12px}.lab{display:grid;grid-template-columns:1fr 240px;gap:40px;margin-top:30px}#maze{display:grid;grid-template-columns:repeat(6,1fr);border:2px solid #173f78;align-self:start;max-width:420px;width:100%}.cell{aspect-ratio:1;min-height:0;background:white;border:1px solid #b8c9df;color:#173f78;font-weight:bold;font-size:20px;padding:0}.cell.wall{background:#173f78;color:white}.cell.path{background:#efb1c6;color:#54203b}.cell.endpoint{background:#d4e5ff;opacity:1}.route-count strong{font:70px/1 monospace;display:block}.route-count span{font-size:13px}.legend{display:flex;gap:20px;margin:24px 0;font-size:13px}.legend i{display:inline-block;width:14px;height:14px;vertical-align:middle}.legend .wall{background:#173f78}.legend .path{background:#efb1c6}aside button{display:block;width:100%;margin:8px 0;background:none;border:1px solid #173f78;color:inherit;padding:10px}#solve{background:#173f78;color:white}#maze-status{margin-top:20px}@media(max-width:650px){main{padding:24px 16px}.lab{grid-template-columns:1fr;gap:24px}#maze{max-width:370px;margin:auto}aside{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px}.route-count,.legend,#maze-status{grid-column:1/-1}.route-count strong{display:inline;margin-right:12px;font-size:50px}.legend{margin:0}aside button{margin:0}.cell{font-size:18px}}
JavaScript
function shortestPath(walls,size=6){const blocked=new Set(walls),end=size*size-1,parents=new Map([[0,null]]),queue=[0];if(blocked.has(0)||blocked.has(end))return [];for(let cursor=0;cursor<queue.length;cursor++){const current=queue[cursor];if(current===end){const path=[];for(let at=end;at!==null;at=parents.get(at))path.push(at);return path.reverse();}const row=Math.floor(current/size),col=current%size;for(const [r,c] of [[row-1,col],[row+1,col],[row,col-1],[row,col+1]]){const n=r*size+c;if(r>=0&&r<size&&c>=0&&c<size&&!blocked.has(n)&&!parents.has(n)){parents.set(n,current);queue.push(n);}}}return [];}
$(function(){const sample=[2,8,14,20,27,28];let walls=new Set(sample),timer;const grid=$('#maze');for(let i=0;i<36;i++)grid.append($('<button type="button" class="cell">').attr({'data-cell':i,tabindex:i===1?0:-1}));function render(){clearInterval(timer);grid.children().each(function(i){$(this).removeClass('path').toggleClass('wall',walls.has(i)).toggleClass('endpoint',i===0||i===35).text(i===0?'S':i===35?'M':walls.has(i)?'×':'').attr({'aria-label':i===0?'Start':i===35?'Meta':'Pole '+(i+1)+(walls.has(i)?', ściana':', wolne'),'aria-pressed':walls.has(i)?'true':'false'});});$('#distance').text('—');}grid.on('click','button',function(){const i=Number(this.dataset.cell);if(i===0||i===35)return;walls.has(i)?walls.delete(i):walls.add(i);render();$('#maze-status').text('Układ zmieniony. Znajdź nową trasę.');});grid.on('keydown','button',function(e){const steps={ArrowUp:-6,ArrowDown:6,ArrowLeft:-1,ArrowRight:1};if(!(e.key in steps))return;e.preventDefault();const next=Math.max(0,Math.min(35,Number(this.dataset.cell)+steps[e.key]));grid.children().attr('tabindex',-1).eq(next).attr('tabindex',0).trigger('focus');});$('#solve').on('click',function(){render();const path=shortestPath([...walls]);if(!path.length){$('#maze-status').text('Brak przejścia. Usuń przynajmniej jedną ścianę.');return;}$('#distance').text(path.length-1);$('#maze-status').text('Najkrótsza trasa: '+(path.length-1)+' kroków.');if(matchMedia('(prefers-reduced-motion: reduce)').matches){path.forEach(i=>grid.children().eq(i).addClass('path'));return;}let index=0;timer=setInterval(()=>{grid.children().eq(path[index++]).addClass('path');if(index===path.length)clearInterval(timer);},60);});$('#clear-walls').on('click',function(){walls.clear();render();$('#maze-status').text('Plansza bez ścian.');});$('#example-maze').on('click',function(){walls=new Set(sample);render();$('#maze-status').text('Przywrócono przykładowy układ.');});render();});
Edytuj swój pen
Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.