職場での掃海艇


18

Windows XPに同梱されている古い掃海艇ゲームは誰でも知っています。これは、番号(それに隣接する地雷の数を示す)または地雷のいずれかを含む9x9のセルのマトリックスを持つ単純なグリッドです。

ここに画像の説明を入力してください

課題は、PRNGを自分で実装する場合、整数シード(マシン/言語の最大のintが何であれ)を与えられた10個の爆弾でランダムな9x9グリッドを生成することです。

出力例:セルには0〜8の数字または地雷の*が含まれます

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

バイト単位の最短コードが勝ちます。標準ルールなど。


3
数字の意味を示す必要があります:)
ネイサンメリル

4
Microsoft MinesweeperはXPよりもずっと古いもので、掃海艇のようなゲームは少なくとも60年代に遡ります。
AdmBorkBork

11
また、仕事中に掃海艇をプレイする時間がありません-PPCGで忙しすぎます。;-)
AdmBorkBork

1
正確にPRNGとしてカウントされるものは何ですか?いくつの異なる構成を作成できる必要がありますか?私たちはすることができない私たちの言語がされるPRNGがある場合、シードを使用し、ちょうど別の設定を毎回生成し、自動的に「ランダム」の種子にinitallizedを?
ルイスメンドー

1
@TimmyDしかし、XPのバージョンは9x9グリッドを備えた最初のバージョンです。古いものはすべて、初心者向けに8x8​​グリッドを使用します。#outnerded;)
mbomb007

回答:


3

Dyalog APL、40バイト

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

(想定⎕io←0

1中には⎕rl←1種子であります

右から左へ:

?⍨81と同じ81?81-ランダムな順列

9≥ ランダムな位置に10個の1を含むビットマスクが生成され、残りは0です

a←9 9⍴ 9行9列の正方形に変形し、「a」と呼びます

{ }⍣2 次を2回実行します。

⍉3+/0,⍵,0 3列のスライディングウィンドウ合計(外部で0を想定)、次に転置

(1,¨a)⍕¨それぞれフォーマット(文字列に変換)です。左の引数は、結果の文字と小数文字の総数を指定します。その仕様に従ってフォーマットできない場合は*、この問題の幸運な偶然を出力します。a地雷が存在する場合は1になります-整数部分と小数部分を1つの文字に合わせるのは不可能なので、それらは*s として表示されます。


⎕io←0仮定を説明できますか?私はDyalog APLに慣れていません...
アーロン

1
Dyalogの配列インデックスは、デフォルトで1ベースです。設定⎕io(「インデックス原点を 0にする」)彼らは0ベースになり、従って例えば、いくつかのプリミティブを変更する⍳3だろう0 1 2、ではありません1 2 3。これは、プログラムで(⎕io←0)またはGUIの設定から行うことができます。この選択は、50年前の間違いであり、今日の小さなAPLコミュニティを分裂させています。
-ngn

5

MATLAB、94 93バイト

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

実行例(コードの後の最初の行はユーザーが入力した入力です):

>> 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

説明

rng(input(''));

整数を受け取り、それをシードとして使用します。(これは、最新のMATLABバージョンで機能します。古いバージョンでは、異なる構文が必要になる場合があります。)

x(9,9)=~1;

論理式0、またはfalse(論理的に否定することで得られる1)を(9,9)行列のエントリに割り当てxます。残りのエントリも自動的に論理的に初期化され0ます。

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

割り当ては、1(autoomatically論理的にキャスト1、またはtrueに対して)1081のエントリをx置換せずにランダムに選択され、。これらのエントリは、爆弾を含むものです。

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

はの略語ですconv2(+x,ones(3),'same')。を含む3×3近傍で行列x(をdouble使用してキャストする必要があります)を畳み込みます。これは、各エントリに隣接する爆弾の数をカウントします。爆弾を含むエントリの場合、その爆弾が含まれますが、その値は後で上書きされます。+1

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

値に48を追加して、数値からASCIIコードに変換します。空のマトリックスと連結すると、これらのASCIIコードがcharsにキャストされます。

y(x)=42;

'*'爆弾の位置に42(ASCIIコード)を割り当てます。これらの位置はによって与えられx、ここでは論理インデックスとして使用されます。

disp(y)

結果を表示します。


4

Javascript(ES6)、204または198バイト

カスタムPRNG(204バイト)

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`
`

このコードは、乗数22695477と増分を備えた線形合同ジェネレーターを使用しています1(これはBorland C / C ++実装です)。

ウォームアップ段階でのPRNGの効率が悪いため、1行に1発の爆弾を配置する必要がありました(シャッフルされていないアレイの最初に10個、最後に10個ではなく)。そのため、爆弾は9個しかありません。後で修正しようとするかもしれません。

また、「アウトオブボード」チェックを処理するためのよりシンプルで短い方法が必要ですが、(x=p%9-(n+=p)%9)*x-64今はそれを理解できません。

Math.random()の使用(198バイト)

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`
`

これには、要求に応じて10個の鉱山が含まれます。

デモ

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())


'**********'+'0'に等しいです'**********'+0。これにより、198バイトバージョンで2バイト節約できます。
ポールシュミッツ

@PaulSchmitz-残念ながら、これ'0'は繰り返されることになっており、0.repeat()動作しません。
アーナルド

おっと、私はそれがのように実行されると思い...('**********'+0).repeat(71)ますが。ごめんなさい。
ポールシュミッツ

3

Python 2、269 266 264バイト

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))

ideone.comでお試しください

アーロンのおかげで2バイト節約できました。

おそらくまだゴルフ可能です。

説明

randomseedPRNGをシードし、sampleランダムに10個の爆弾の場所を選択するために使用するためにインポートされます。mボードを節約する9 x 9マトリックスです。爆弾の場所ごとに、対応するエントリmが設定され-9、すべての隣接エントリが増加します。この方法にmは、非爆弾セルの隣接爆弾の数と爆弾セルの負の数が含まれます。最終のprintすべての行を反復することによりプリント基板全体lm、すべての細胞cにおいてl


「ランダム」とは正確に何のために使用されますか?
clismique

@ Qwerp-Derpは、おそらく間接的に使用される乱数ジェネレータをシードするためにsample()
パトリックロバーツ

for a in z:ブロック内でタブのインデントを混在させることで2バイトを節約します(python 2.xのみ)
アーロン

3

R、187バイト

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

Ideoneでお試しください

説明:

set.seed() cstシードを取ります。

x 11 * 11マトリックスのインデックスです

y 11 * 11マトリックス内の9 * 9マトリックスのインデックス

z 爆弾のインデックスです

x=x*0 行列値を初期化する

隣接する爆弾の場合、ループはxに1を加算します。


1
入力としてset.seed()の引数を取る必要があると思います。
BLT

2

JavaScript ES6、244バイト

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>


どの部分がコードであるかを詳しく説明することもできます。
-NoOneIsHere

@NoOneIsHere最初の244バイト、できれば;-)最初の行の長さは242バイトで、改行と`文字が必要です。
ニール


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.