Przejdź do treści
<code>pen.pl

SEKTOR — mały saper

Gry

Podgląd

Ładowanie podglądu…

Odkryj 30 bezpiecznych pól na planszy 6 × 6. Pierwszy ruch jest bezpieczny, a flagi można stawiać również na telefonie.

0,0 / 5 Brak ocen

Kod źródłowy

Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.

HTML
<main><header><span class="eyebrow">Saper</span><h1>SEKTOR<br>6 × 6</h1></header><div class="desktop-split"><section><div id="board" class="board" aria-label="Pole minowe 6 na 6"></div><p id="status" class="status" role="status">Odkryj pierwsze pole. Jest bezpieczne.</p></section><aside><p><strong>6 min. 30 bezpiecznych pól.</strong><br>Liczba oznacza miny w ośmiu sąsiednich polach.</p><div class="metric" id="score">0 / 30</div><p>Wybierz tryb i kliknij pole. Strzałki przesuwają fokus, Enter odkrywa pole.</p><div class="actions"><button type="button" id="flag" aria-pressed="false">Tryb flagi</button><button type="button" id="reset">Nowy teren</button></div><p id="flags">Flagi: 0 / 6</p></aside></div></main>
CSS
*{box-sizing:border-box}body{margin:0;font-family:system-ui,sans-serif;background:var(--bg);color:var(--ink)}main{width:min(100% - 32px,980px);margin:32px auto}h1{font-size:clamp(32px,7vw,64px);line-height:1;margin:12px 0 20px;letter-spacing:-.045em}p{line-height:1.55}button{font:inherit;min-height:44px;padding:10px 16px;border:1px solid currentColor;border-radius:0;background:transparent;color:inherit;cursor:pointer}button:hover{background:var(--ink);color:var(--bg)}button:disabled{cursor:default;opacity:.55}button:focus-visible,canvas:focus-visible{outline:3px solid var(--focus);outline-offset:3px}button[aria-pressed="true"]{background:var(--ink);color:var(--bg)}.eyebrow{font:12px ui-monospace,monospace;letter-spacing:.16em;text-transform:uppercase}.status{min-height:48px;font-weight:600}.actions{display:flex;flex-wrap:wrap;gap:8px}.metric{font:700 28px ui-monospace,monospace}small{line-height:1.5}canvas{display:block;width:100%;height:auto;border:1px solid currentColor;touch-action:none}.controls{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0}.controls button{min-width:54px;touch-action:none;user-select:none}.board{display:grid;gap:5px}.board button{padding:0;aspect-ratio:1;min-width:0;font-size:clamp(18px,5vw,30px)}@media(max-width:600px){main{width:calc(100% - 24px);margin:20px auto}h1{margin-bottom:16px}.desktop-split{display:block!important}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
:root{--bg:#e4ddc9;--ink:#353e2e;--focus:#963315}body{font-family:Georgia,serif}h1{letter-spacing:-.06em}header{border-top:2px solid;padding-top:14px}.desktop-split{display:grid;grid-template-columns: minmax(0,440px) 1fr;gap:60px}#board{grid-template-columns:repeat(6,1fr);border:8px solid #5c6248;background:#5c6248;gap:3px}#board button{background:#d3c9af;border:0;font-family:ui-monospace,monospace;min-height:38px}#board button.open{background:#f6f0df}#board button.mine{background:#923726;color:#fff}#board button:hover{background:#fff;color:#353e2e}aside{border-left:1px solid;padding-left:24px}@media(max-width:600px){aside{border-left:0;padding:0}}
JavaScript
function mineNeighbors(index,size=6){const cells=[];for(let y=-1;y<=1;y++)for(let x=-1;x<=1;x++){const r=Math.floor(index/size)+y,c=index%size+x;if((x||y)&&r>=0&&c>=0&&r<size&&c<size)cells.push(r*size+c);}return cells;}
function mineLayout(first,random=Math.random){const options=Array.from({length:36},(_,i)=>i).filter(i=>i!==first);for(let i=options.length-1;i>0;i--){const j=Math.floor(random()*(i+1));[options[i],options[j]]=[options[j],options[i]];}return options.slice(0,6);}
$(function(){
    let mines,opened,flags,flagMode,over;
    function render(){
        $('#board button').each(function(i){const open=opened.has(i),mine=mines&&mines.includes(i),count=mines?mineNeighbors(i).filter(n=>mines.includes(n)).length:0;
            $(this).toggleClass('open',open).toggleClass('mine',over&&mine).text(over&&mine?'×':flags.has(i)?'⚑':open?(count||'·'):'').attr('aria-label','Pole '+(i+1)+': '+(over&&mine?'mina':flags.has(i)?'flaga':open?(count+' min w sąsiedztwie'):'zakryte')).attr('aria-disabled',over||open?'true':'false');
        });$('#score').text(opened.size+' / 30');$('#flags').text('Flagi: '+flags.size+' / 6');
    }
    function reset(){mines=null;opened=new Set();flags=new Set();flagMode=false;over=false;$('#flag').attr('aria-pressed','false');$('#board').empty();for(let i=0;i<36;i++)$('<button>',{type:'button',tabindex:i===0?0:-1,'data-cell':i}).appendTo('#board');$('#status').text('Odkryj pierwsze pole. Jest bezpieczne.');render();}
    $('#flag').on('click',function(){flagMode=!flagMode;$(this).attr('aria-pressed',String(flagMode));});
    $('#board').on('click','button',function(){const i=Number($(this).attr('data-cell'));if(over||opened.has(i))return;
        if(flagMode){if(flags.has(i))flags.delete(i);else if(flags.size<6)flags.add(i);else $('#status').text('Wykorzystano wszystkie 6 flag.');render();return;}
        if(flags.has(i))return;if(!mines)mines=mineLayout(i);
        if(mines.includes(i)){over=true;$('#status').text('Mina. Spróbuj ponownie.');render();return;}
        const queue=[i];while(queue.length){const p=queue.pop();if(opened.has(p)||flags.has(p)||mines.includes(p))continue;opened.add(p);const near=mineNeighbors(p);if(!near.some(n=>mines.includes(n)))queue.push(...near);}
        if(opened.size===30){over=true;$('#status').text('Teren oczyszczony. Wygrana!');}else $('#status').text('Bezpiecznie. Szukaj kolejnego pola.');render();
    }).on('keydown','button',function(event){const i=Number($(this).attr('data-cell')),next={ArrowRight:Math.min(35,i+1),ArrowLeft:Math.max(0,i-1),ArrowDown:Math.min(35,i+6),ArrowUp:Math.max(0,i-6)}[event.key];if(next!==undefined){event.preventDefault();$('#board button').attr('tabindex',-1).eq(next).attr('tabindex',0).trigger('focus');}});
    $('#reset').on('click',reset);reset();
});
Biblioteki

JavaScript

Edytuj swój pen

Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.

Link jest ważny przez 30 minut.