Saper W Pracy

18

Wszyscy znają starą grę Saper, która jest dostarczana z Windows XP. Jest to prosta siatka z matrycą 9 x 9 komórek zawierającą albo liczbę (wskazującą, ile min sąsiaduje z nią) lub kopalnię.

wprowadź opis zdjęcia tutaj

Wyzwanie polega na wygenerowaniu losowej siatki 9x9 z 10 bombami o dowolnym ziarnie całkowitym (do dowolnej liczby całkowitej maszyny / języka) z punktami brownie, jeśli sam zaimplementujesz PRNG

przykładowe dane wyjściowe: komórki zawierają cyfry 0–8 lub * dla kopalni

*101*1000
110111000
123210000
1***10000
123210011
00000002*
00000114*
000112*3*
0001*2121

Najkrótszy kod w bajtach wygrywa .. standardowe reguły itp. Itp.

Aaron
źródło
3
Powinieneś wskazać, co oznaczają liczby :)
Nathan Merrill,
4
Microsoft Minesweeper jest o wiele starszy od XP, a gry podobne do minesweeper sięgają co najmniej lat 60.
AdmBorkBork
11
Poza tym nie mam czasu grać w Saper podczas pracy - jestem zbyt zajęty PPCG. ;-)
AdmBorkBork
1
Co dokładnie liczy się jako PRNG? Ile różnych konfiguracji musi być w stanie wyprodukować? Czy nie możemy użyć zarodka i generować za każdym razem inną konfigurację, jeśli nasz język ma PRNG, który jest automatycznie inicjowany do „losowego” zarodka?
Luis Mendo,
1
@TimmyD Ale wersja XP to pierwsza wersja z siatką 9x9. Cokolwiek starszego korzysta z siatki 8x8 dla początkującego. #outnerded;)
mbomb007

Odpowiedzi:

3

Dyalog APL, 40 bajtów

⎕rl←1⋄(1,¨a)⍕¨{⍉3+/0,⍵,0}⍣2⊢a←9 9⍴9≥?⍨81

(zakłada ⎕io←0 )

1się ⎕rl←1to ziarno

z prawej do lewej:

?⍨81jest taki sam jak 81?81- losowa permutacja

9≥ powoduje, że maska ​​bitowa zawiera dziesięć jedności w losowych pozycjach, reszta to 0

a←9 9⍴ przekształć w kwadrat 9 na 9 i nazwij go „a”

{ }⍣2 wykonaj następujące czynności dwa razy:

⍉3+/0,⍵,0 przesuwane okno suma 3 kolumn (zakładaj 0 na zewnątrz), a następnie transponuj

(1,¨a)⍕¨każdy ma format (konwertuj na ciąg). Lewy argument określa całkowitą liczbę znaków i znaków ułamkowych w wyniku. Jeśli nie można sformatować zgodnie z tą specyfikacją, generuje *- szczęśliwy zbieg okoliczności dla tego problemu. aw miejscu, w którym znajdują się kopalnie, będzie 1 - próba dopasowania całości i części ułamkowej do jednego znaku jest niemożliwa, więc pojawią się one jako *s.

ngn
źródło
Czy możesz wyjaśnić ⎕io←0założenie? Nie znam Dyalog APL ...
Aaron
1
Indeksy tablic w Dyalog są domyślnie oparte na 1. Ustawienie ⎕io(„ Początek indeksu ”) na 0 powoduje, że są one oparte na 0 i odpowiednio zmienia niektóre prymitywy, np. ⍳3Będzie0 1 2 , nie 1 2 3. Można to zrobić programowo ( ⎕io←0) lub z preferencji w GUI. Wybór ten jest 50-letnim błędem, który wciąż dzieli małą społeczność APL.
ngn 10.04.17
5

MATLAB, 94 93 bajty

rng(input(''));x(9,9)=~1;x(randperm(81,10))=1;y=[conv2(+x,ones(3),'s')+48 ''];y(x)=42;disp(y)

Przykład uruchomienia (pierwszy wiersz po kodzie to dane wpisane przez użytkownika):

>> rng(input(''));x(9,9)=~1;x(randperm(81,10))=1;y=[conv2(+x,ones(3),'s')+48 ''];y(x)=42;disp(y)
99
*10001*2*
220001232
*201111*1
*312*1111
12*211000
011211000
0001*1000
000112110
000001*10

Wyjaśnienie

rng(input(''));

przyjmuje liczbę całkowitą i używa jej jako materiału siewnego. (Działa to w nowoczesnych wersjach MATLAB. Stare wersje mogą wymagać innej składni.)

x(9,9)=~1;

przypisuje wartość logiczną 0lub false(uzyskaną przez logiczne negowanie 1) do wpisu (9,9)macierzy x. Pozostałe wpisy są automatycznie inicjowane również na logiczne 0.

x(randperm(81,10))=1; 

cesjonariusze 1(autoomatically rzutować na logiczne 1lub true), aby 10z 81wpisów x, wybranych losowo, bez zastąpienia. Te wpisy zawierają bomby.

conv2(+x,ones(3),'s')

to skrót od conv2(+x,ones(3),'same'). Zwija matrycę x(do której należy użyć double, używając +) z otoczeniem 3 × 3 zawierającym 1. To liczy, ile bomb sąsiaduje z każdym wejściem. Wpisy zawierające bombę obejmują tę bombę, ale wartość zostanie później zastąpiona.

y=[...+48 ''];

dodaje 48 do wartości, aby przekonwertować z numeru na kod ASCII. Łączenie z pustą macierzą powoduje rzutowanie tych kodów ASCII na znaki.

y(x)=42;

przypisuje 42 (kod ASCII dla '*') do pozycji bomb. Te pozycje są podawane przez x, który jest tutaj używany jako indeks logiczny.

disp(y)

wyświetla wynik.

Luis Mendo
źródło
4

JavaScript (ES6), 204 lub 198 bajtów

Niestandardowy PRNG (204 bajty)

s=>(p=-1,S=n=>(x=p%9-(n+=p)%9)*x-64&&b[n]=='*',T=n=>S(n)+S(-n),b=[...'*00000000'.repeat(9)]).sort(_=>(s=(22695477*s+1)>>>0)&1||-1).map(c=>(p++,c=='0'?T(1)+T(8)+T(9)+T(10):c)).join``.match(/.{9}/g).join`
`

Ten kod używa liniowego generatora kongruencjalnego z mnożnikiem 22695477 i przyrostem1 (jest to implementacja Borland C / C ++).

Ze względu na słabą wydajność PRNG podczas fazy rozgrzewania musiałem umieścić jedną bombę w rzędzie (zamiast 10 na początku lub 10 na końcu niewyasowanego układu). Zatem jest tylko 9 bomb. Mogę spróbować to naprawić później.

Ponadto musi istnieć prostszy / krótszy sposób przetworzenia czeku „poza planszą”, (x=p%9-(n+=p)%9)*x-64ale nie mogę tego teraz zrozumieć.

Korzystanie z Math.random () (198 bajtów)

s=>(p=-1,S=n=>(x=p%9-(n+=p)%9)*x-64&&b[n]=='*',T=n=>S(n)+S(-n),b=[...'**********'+'0'.repeat(71)]).sort(_=>Math.random()-.5).map(c=>(p++,c=='0'?T(1)+T(8)+T(9)+T(10):c)).join``.match(/.{9}/g).join`
`

Ten obejmuje 10 kopalń zgodnie z życzeniem.

Próbny

let f =
_=>(p=-1,S=n=>(x=p%9-(n+=p)%9)*x-64&&b[n]=='*',T=n=>S(n)+S(-n),b=[...'**********'+'0'.repeat(71)]).sort(_=>Math.random()-.5).map(c=>(p++,c=='0'?T(1)+T(8)+T(9)+T(10):c)).join``.match(/.{9}/g).join`
`
console.log(f())

Arnauld
źródło
'**********'+'0'jest równy '**********'+0; co oszczędza dwa bajty w wersji 198 bajtów.
Paul Schmitz
@PaulSchmitz - Niestety, '0'należy to powtórzyć i 0.repeat()nie zadziała.
Arnauld
Ups, myślałem, że zostanie to wykonane jak ...('**********'+0).repeat(71). Przepraszam.
Paul Schmitz
3

Python 2, 269 266 264 bajtów

from random import*
seed(input())
z=1,0,-1
n=range(9)
m=[[0]*9 for _ in n]
for x,y in sample([[x,y]for x in n for y in n],10):
 m[x][y]=-9
 for a in z:
  for b in z:
    if 0<=x+a<9>0<=y+b<9:m[x+a][y+b]+=1 # it gets displayed as 4 spaces, but the beginning of this line is a single tab
print("\n".join("".join([`c`,'*'][c<0]for c in l)for l in m))

Wypróbuj na ideone.com

Zaoszczędzono 2 bajty dzięki Aaronowi.

Najprawdopodobniej nadal gra w golfa.

Wyjaśnienie

randomjest importowany w celu użycia seeddo wysiewu PRNG i samplelosowego wyboru dziesięciu lokalizacji bomb. mto matryca 9 x 9 zapisująca płytę. Dla każdej lokalizacji bomby odpowiedni wpis w mzostanie ustawiony na, -9a wszystkie sąsiednie wpisy zostaną zwiększone. W ten sposób motrzymujemy liczbę sąsiednich bomb dla komórek niebombowych i liczbę ujemną dla komórek bombowych. Finał printdrukuje całą planszę, iterując wszystkie linie ldo mi wszystkie komórki cw l.

LevitatingLion
źródło
Do czego dokładnie używa się słowa „losowy”?
clismique
@ Qwerp-Derp prawdopodobnie posadzi generator liczb losowych pośrednio używany przezsample()
Patrick Roberts
zapisz 2 bajty, mieszając wcięcia tabulatorów w for a in z:bloku (tylko python 2.x)
Aaron
3

R, 187 bajtów

set.seed();x=1:121;y=x[!(x%%11 %in% 0:1|(x-1)%/%11 %in% c(0,10))];z=sample(y,10);x=x*0;for(t in z){p=t+c(-10:-12,-1,1,10:12);x[p]=x[p]+1};x[z]=9;m=data.frame(matrix(x[y],9));m[m==9]='*';m

Wypróbuj na Ideone

Wyjaśnienie:

set.seed() weź ziarno cst.

x jest indeksem macierzy 11 * 11

y jest indeksem macierzy 9 * 9 w macierzy 11 * 11

z jest indeksem bomby

x=x*0 zainicjować wartość macierzy

Pętla dodaje 1 do x w przypadku sąsiedniej bomby.

YCR
źródło
1
Myślę, że musisz wziąć argument do set.seed () jako danych wejściowych.
BLT
2

JavaScript ES6, 244 bajty

f=(a=[...Array(11)].map(_=>Array(11).fill(0)),n=10,r=_=>Math.random()*9|0,x=r(),y=r())=>a[x+1][y+1]>8||[0,1,2].map(i=>[0,1,2].map(j=>a[x+i][y+j]++),a[x+1][y+1]=9)&&--n?f(a,n):a.slice(1,-1).map(a=>a.slice(1,-1).map(n=>n<9?n:`*`).join``).join`
`
;o.textContent=f()
<pre id=o>

Neil
źródło
Możesz zastanowić się, która część jest Twoim kodem.
NoOneIsHere
@NoOneIsHere Pierwsze 244 bajty, miejmy nadzieję ;-) Pierwszy wiersz powinien mieć 242 bajty, potem jest nowa linia i `znak.
Neil
1

Ruby , 181 194 183 + 1 = 184 bajty

Zapomniałem ustawić nasiona, ups. Używa -nflagi.

Wypróbuj online!

srand$_.to_i
a=[0]*81
[*0..80].sample(10).map{|i|w=i%9;h=i/9;a[i]=-99
(r=-1..1).map{|x|x+=w
x<0||x>8?0:r.map{|y|y+=h
y<0||y>8?0:a[9*y+x]+=1}}}
puts a.map{|c|c<0??*:c}.join.scan /.{9}/
Wartość tuszu
źródło
0

Python 2 , 172 bajty

from random import*
seed(input())
r=range
b=set(sample(r(81),10))
for j in r(9):print''.join([[`len({x-10,x-9,x-8,x-1,x+1,x+8,x+9,x+10}&b)`,'*'][x in b]for x in r(j,81,9)])

Wypróbuj online!

tsh
źródło