เรือกวาดทุ่นระเบิดในที่ทำงาน


18

ทุกคนรู้เกมเรือกวาดทุ่นระเบิดเก่าที่มาพร้อมกับ Windows XP มันเป็นกริดเรียบง่ายที่มีเมทริกซ์ 9x9 ของเซลล์ที่มีตัวเลข (ระบุจำนวนเหมืองที่อยู่ติดกับมัน) หรือเหมือง

ป้อนคำอธิบายรูปภาพที่นี่

ความท้าทายคือการสร้างกริด 9x9 แบบสุ่มโดยมี 10 ระเบิดให้กับเมล็ดจำนวนเต็มใด ๆ (ขึ้นอยู่กับสิ่งที่เครื่องที่ใหญ่ที่สุดของภาษา / ของคุณ) กับจุดบราวนี่ถ้าคุณใช้ PRNG ด้วยตัวคุณเอง

ตัวอย่างเอาต์พุต: เซลล์มีตัวเลข 0-8 หรือ * สำหรับเหมือง

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

โค้ดที่สั้นที่สุดในหน่วยไบต์ชนะ .. กฎมาตรฐาน ฯลฯ ฯลฯ


3
คุณควรระบุความหมายของตัวเลข :)
นาธานเมอร์ริลล์

4
Microsoft Minesweeper นั้นเป็นเกมที่เก่ากว่า XPและเกมคล้ายสวีปเปอร์สวีทเป็นอย่างมากในยุค 60s
AdmBorkBork

11
นอกจากนี้ฉันไม่มีเวลาเล่น Minesweeper ในที่ทำงาน - ฉันยุ่งเกินไปกับ PPCG ;-)
AdmBorkBork

1
สิ่งใดที่นับว่าเป็น PRNG อย่างแน่นอน ต้องสามารถกำหนดค่าที่แตกต่างกันได้กี่แบบ เราไม่สามารถใช้เมล็ดพันธุ์และเพียงแค่สร้างการกำหนดค่าที่แตกต่างกันในแต่ละครั้งหากภาษาของเรามี PRNG ซึ่งเริ่มต้นโดยอัตโนมัติไปยังเมล็ดพันธุ์ "สุ่ม"
Luis Mendo

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≥ ส่งผลให้ bitmask มีสิบ 1s ที่ตำแหน่งสุ่มส่วนที่เหลือคือ 0

a←9 9⍴ เปลี่ยนรูปร่างเป็นสี่เหลี่ยมขนาด 9 คูณ 9 แล้วเรียกมันว่า "a"

{ }⍣2 ทำต่อไปนี้สองครั้ง:

⍉3+/0,⍵,0 ผลรวมหน้าต่างบานเลื่อน 3 คอลัมน์ (สมมติว่าเป็น 0 นอก) แล้วแปลง

(1,¨a)⍕¨คือรูปแบบ (แปลงเป็นสตริง) แต่ละรายการ อาร์กิวเมนต์ซ้ายเพื่อระบุจำนวนทั้งหมดของอักขระและเศษส่วนในผลลัพธ์ หากไม่สามารถจัดรูปแบบตามสเป็คนั้นจะส่งออก a *- บังเอิญโชคดีสำหรับปัญหานี้ aจะเป็น 1 ในที่ที่มีการขุด - พยายามที่จะใส่ส่วนที่เป็นเศษส่วนทั้งหมดลงในถ่านก้อนเดียวเป็นไปไม่ได้ดังนั้นสิ่งเหล่านั้นจะปรากฏเป็น*s


คุณสามารถอธิบาย⎕io←0สมมติฐานได้หรือไม่? ฉันไม่คุ้นเคยกับ Dyalog APL ...
แอรอน

1
ดัชนี Array ใน Dyalog จะขึ้นอยู่กับ 1 โดยค่าเริ่มต้น การตั้งค่า⎕io(ที่ " ดัชนีกำเนิด ") เพื่อทำให้พวกเขา 0 0-based และการเปลี่ยนแปลงพื้นฐานบางอย่างตามเช่น⍳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(ส่งโดยอัตโนมัติไปที่ลอจิคัล1หรือtrue) ให้10กับ 81รายการของx, สุ่มเลือกโดยไม่มีการแทนที่ รายการเหล่านี้เป็นรายการที่มีระเบิด

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

conv2(+x,ones(3),'same')เป็นคำย่อของ มัน convolves เมทริกซ์x(ซึ่งจะต้องมีการโยนไปdoubleใช้+) กับเขต 3 × 3 1มี สิ่งนี้นับว่ามีจำนวนระเบิดติดกับแต่ละรายการ สำหรับรายการที่มีระเบิดมันรวมถึงระเบิดนั้น แต่จะมีการเขียนทับค่าในภายหลัง

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

เพิ่ม 48 ให้กับค่าเพื่อแปลงจากตัวเลขเป็นรหัส ASCII การต่อกับเมทริกซ์ที่ว่างเปล่าจะใช้รหัส ASCII เหล่านี้กับตัวอักษร

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

รหัสนี้ใช้ตัวสร้าง Congruential เชิงเส้นที่มีตัวคูณ22695477และส่วนเพิ่ม1(นี่คือการนำ Borland C / C ++ มาใช้)

เนื่องจากประสิทธิภาพที่ต่ำของ PRNG ในระหว่างช่วง warmup ของมันฉันต้องวางระเบิดหนึ่งลูกต่อแถว (แทนที่จะเป็น 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- ไบต์
พอลชมิทซ์

@PaulSchmitz - น่าเสียดายที่นี่'0'ควรจะทำซ้ำและ0.repeat()จะไม่ทำงาน
Arnauld

...('**********'+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 ไบต์ขอบคุณ Aaron

ส่วนใหญ่ยังคงสามารถเล่นกอล์ฟได้

คำอธิบาย

randomถูกนำเข้าเพื่อใช้seedในการเพาะเมล็ด PRNG และsampleเพื่อเลือกสถานที่ทิ้งระเบิดสิบแห่งโดยการสุ่ม mเมทริกซ์ขนาด 9 x 9 ที่ช่วยประหยัดกระดาน สำหรับแต่ละตำแหน่งระเบิดรายการที่เกี่ยวข้องในmจะถูกตั้งค่าเป็น-9และรายการเพื่อนบ้านทั้งหมดจะเพิ่มขึ้น วิธีนี้mจบลงด้วยการนับจำนวนระเบิดที่อยู่ติดกันสำหรับเซลล์ที่ไม่ใช่ระเบิดและจำนวนลบสำหรับเซลล์ระเบิด สุดท้ายprintพิมพ์ทั้งกระดานโดยการทำซ้ำผ่านสายทั้งหมดlในmและเซลล์ทั้งหมดในcl


'สุ่ม' ใช้เพื่ออะไรกันแน่
clismique

@ Qwerp-Derp อาจจะสร้างตัวสร้างตัวเลขสุ่มโดยทางอ้อมโดยsample()
Patrick Roberts

บันทึก 2 ไบต์โดยการผสมแท็บเยื้องในfor a in z:บล็อก (เฉพาะหลาม 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 คือดัชนีของเมทริกซ์ 9 * 9 ในเมทริกซ์ 11 * 11

z เป็นดัชนีของระเบิด

x=x*0 เริ่มต้นค่าเมทริกซ์

การวนซ้ำเพิ่ม 1 ถึง x ในกรณีของการวางระเบิดที่อยู่ติดกัน


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 ไบต์จากนั้นจะมีบรรทัดใหม่และ`อักขระ
Neil


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.