ฉันจะรู้ได้อย่างไรว่าเกมไขปริศนาของฉันเป็นไปได้หรือไม่?


68

ฉันได้สร้างเกมไขปริศนาขึ้นมาโดยมีจุดประสงค์เพื่อกำจัดแผ่นกระเบื้องสีขาวทั้งหมด คุณสามารถลองได้ในตอนท้ายของคำถาม

แต่ละครั้งกระดานจะถูกสุ่มสร้างด้วยแผ่นสีขาวในสถานที่สุ่มบนตาราง 5 * 5 คุณสามารถคลิกที่ไทล์ใดก็ได้บนกริดนั้นและมันจะสลับสีของมันและไทล์ทั้งหมดที่แตะที่ด้านข้าง ภาวะที่กลืนไม่เข้าคายไม่ออกของฉันคือความจริงที่ว่าฉันไม่ทราบว่ามันจะสร้างบอร์ดเป็นไปไม่ได้ วิธีที่ดีที่สุดในการตรวจสอบสิ่งต่าง ๆ เช่นนี้คืออะไร?

function newgame() {
 moves = 0;
    document.getElementById("moves").innerHTML = "Moves: "+moves;

  for (var i = 0; i < 25; i++) {
   if (Math.random() >= 0.5) {
$(document.getElementsByClassName('block')[i]).toggleClass("b1 b2")
   }
}
}
newgame();
function toggle(a,b) {  
  moves += 1;
  document.getElementById("moves").innerHTML = "Moves: "+moves;
$(document.getElementsByClassName('block')[a+(b*5)]).toggleClass("b1 b2");

if (a<4) {$(document.getElementsByClassName('block')[(a+1)+(b*5)]).toggleClass("b1 b2")}
  
  
if (a>0) {$(document.getElementsByClassName('block')[(a-1)+(b*5)]).toggleClass("b1 b2")}
  
  
if (b<4) {$(document.getElementsByClassName('block')[a+((b+1)*5)]).toggleClass("b1 b2")}
  
if (b>0) {$(document.getElementsByClassName('block')[a+((b-1)*5)]).toggleClass("b1 b2")}
}
body {
  background-color: #000000;
}

.game {
  float: left;
  background-color: #000000;
  width: 300px;
  height: 300px;
  overflow: hidden;
  overflow-x: hidden;
  user-select: none;
  display: inline-block;
}

.container {
  border-color: #ffffff;
  border-width: 5px;
  border-style: solid;
  border-radius: 5px;
  width: 600px;
  height: 300px;
  text-align: center;
}

.side {
  float: left;
  background-color: #000000;
  width: 300px;
  height: 300px;
  overflow: hidden;
  overflow-x: hidden;
  user-select: none;
  display: inline-block;
}

.block {
  transition: background-color 0.2s;
  float: left;
}

.b1:hover {
  background-color: #444444;
  cursor: pointer;
}

.b2:hover {
  background-color: #bbbbbb;
  cursor: pointer;
}

.row {
  width: 300px;
  overflow: auto;
  overflow-x: hidden;
}

.b1 {
  display: inline-block;
  height: 50px;
  width: 50px;
  background-color: #000000;
  border-color: #000000;
  border-width: 5px;
  border-style: solid;
}




.b2 {
  display: inline-block;
  height: 50px;
  width: 50px;
  background-color: #ffffff;
  border-color: #000000;
  border-width: 5px;
  border-style: solid;
}



.title {
  width: 200px;
  height: 50px;
  color: #ffffff;
  font-size: 55px;
  font-weight: bold;
  font-family: Arial;
  display: table-cell;
  vertical-align: middle;
}

.button {
  cursor: pointer;
  width: 200px;
  height: 50px;
  background-color: #000000;
  border-color: #ffffff;
  border-style: solid;
  border-width: 5px;
  color: #ffffff;
  font-size: 25px;
  font-weight: bold;
  font-family: Arial;
  display: table-cell;
  vertical-align: middle;
  border-radius: 5px;
  transition: background-color 0.3s, color 0.3s;
}

.button:hover {
  background-color: #ffffff;
  color: #000000;
}

.sidetable {
  padding: 30px 0px;
  height: 200px;
}


#moves {
  width: 200px;
  height: 50px;
  color: #aaaaaa;
  font-size: 30px;
  font-weight: bold;
  font-family: Arial;
  display: table-cell;
  vertical-align: middle;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<center>
  <div class="container">
  
  
  <div class="game"><div class="row"><div onclick="toggle(0,0);" class="block b1"></div><div onclick="toggle(1,0);" class="block b1"></div><div onclick="toggle(2,0);" class="block b1"></div><div onclick="toggle(3,0);" class="block b1"></div><div onclick="toggle(4,0);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,1);" class="block b1"></div><div onclick="toggle(1,1);" class="block b1"></div><div onclick="toggle(2,1);" class="block b1"></div><div onclick="toggle(3,1);" class="block b1"></div><div onclick="toggle(4,1);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,2);" class="block b1"></div><div onclick="toggle(1,2);" class="block b1"></div><div onclick="toggle(2,2);" class="block b1"></div><div onclick="toggle(3,2);" class="block b1"></div><div onclick="toggle(4,2);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,3);" class="block b1"></div><div onclick="toggle(1,3);" class="block b1"></div><div onclick="toggle(2,3);" class="block b1"></div><div onclick="toggle(3,3);" class="block b1"></div><div onclick="toggle(4,3);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,4);" class="block b1"></div><div onclick="toggle(1,4);" class="block b1"></div><div onclick="toggle(2,4);" class="block b1"></div><div onclick="toggle(3,4);" class="block b1"></div><div onclick="toggle(4,4);" class="block b1"></div></div></div>
    
    <div class="side">
      <center class="sidetable">
        <div class="title">Tiles</div>
        <br>
        <div class="button" onclick="newgame()">New Game</div>
        <br><br>
        <div id="moves">Moves: 0</div>
      </center>
    </div>
    
  </div>
    </center>


9
หากคุณสนใจในรูปแบบของเกมปริศนานี้มีลักษณะที่เก็บปริศนา Simon Tatham ของแบบพกพา นอกเหนือจากเกมประเภทนี้ (เรียกว่า Flip นั่นเอง) คุณสามารถพบกับปริศนาญี่ปุ่นและปริศนาอื่น ๆ ได้อีกมากมาย ทุกอย่างอยู่ภายใต้ใบอนุญาต BSD และน่าจะอ่านน่าสนใจ
Dubu

10
แล้ววิศวกรรมย้อนกลับล่ะ? เริ่มต้นด้วยกระดานเปล่าจากนั้นอัตโนมัติพูด 20 คลิกในช่องสุ่ม ในแบบที่คุณรู้ว่าจะต้องมีทางออกในตอนท้าย
AJFaraday

3
ฉันต้องการเล่นต่อ แต่เนื่องจากคำถามของคุณความไม่แน่ใจว่าจริง ๆ แล้วฉันจะชนะหรือไม่ก็คือการกินที่ฉัน! เกมที่สนุก :)
MrDuk

@MrDuk codepen.io/qwertyquerty/pen/WMGwVWนี่คือโครงการที่เสร็จสมบูรณ์! อันนี้ได้รับการแก้ไขและขัดขึ้น ฉันทำแอพอิเล็กตรอนด้วย
Qwerty

@Qwerty เมื่อฉันพยายามที่จะดูปากกาของคุณในมุมมองแบบเต็มหน้าฉันได้รับข้อความ "เจ้าของปากกานี้ต้องยืนยันที่อยู่อีเมลของพวกเขาเพื่อเปิดใช้งานมุมมองแบบเต็มหน้า" โปรดยืนยันที่อยู่อีเมลของคุณบน CodePen เพื่อที่ฉันจะได้สนุกกับเกมของคุณแบบเต็มหน้าต่าง! :)
stephenwade

คำตอบ:


161

นี่คือประเภทของเกมที่การเคลื่อนไหวแบบเดียวกันที่ทำไปสองครั้งจะทำให้กระดานกลับสู่สถานะเดิม ดังนั้นเพื่อให้แน่ใจว่าบอร์ดสามารถแก้ไขได้ให้สร้างโดยการเล่นในสิ่งที่ตรงกันข้าม เริ่มต้นด้วยบอร์ดที่แก้ไขแล้ว (ว่าง) จากนั้นเริ่มเขียนโปรแกรมโดยคลิกที่ "สุ่ม" ทั้งจำนวนครั้งหรือจนกว่าบอร์ดจะมีจำนวนสี่เหลี่ยมสีขาวที่ต้องการ วิธีแก้ปัญหาหนึ่งก็คือการเคลื่อนที่แบบเดียวกันในลำดับย้อนกลับ อาจมีวิธีแก้ไขที่สั้นกว่านี้ แต่คุณรับประกันว่าจะมีอย่างน้อยหนึ่งวิธี

อีกวิธีการแก้ที่ซับซ้อนมากขึ้นคือการกำหนดอัลกอริทึมการแก้ปัญหาที่จะผ่านทุกสถานะเกมที่เป็นไปได้จากตำแหน่งเริ่มต้นของคุณเพื่อพยายามหาวิธีแก้ปัญหา สิ่งนี้จะใช้เวลานานกว่าในการติดตั้งและใช้งาน แต่จะอนุญาตให้บอร์ดสร้างขึ้นแบบสุ่มอย่างแท้จริง ฉันจะไม่เจาะจงเฉพาะของโซลูชันนี้เพราะมันเป็นแนวคิดที่ไม่ดีนัก


22
@Qwerty: สำหรับปัญหาเฉพาะของคุณให้คลิกที่ช่องสี่เหลี่ยมเดียวกันสองครั้งเพื่อยกเลิกตัวเองดังนั้นจึงไม่มีเหตุผลใดที่จะคลิกที่ช่องสี่เหลี่ยมมากกว่าหนึ่งครั้ง คุณอาจต้องการเลือกจำนวนสี่เหลี่ยมที่ต้องการให้คลิกโดยไม่ต้องทำซ้ำหรือพิจารณาวิธีแก้ปัญหาที่กำหนดโอกาสในการคลิก XX% ให้กับแต่ละช่องบนกระดาน (Ed: คำตอบที่ดี +1!)
Jeff Bowman

3
ฉันทำเกมเดียวกันเกือบทั้งที่มาก่อนและจบลงด้วยการใช้วิธีนี้ ฉันรวมอนิเมชั่นตั้งแต่เริ่มต้นเพื่อแสดงสถานะที่แก้ไขแล้วไปยังสถานะที่ยังไม่แก้ในแบบรวดเร็ว มันสวย
Jared Goguen

1
@ JaredGoguen แปลกฉันเพิ่มและกลับมาที่นี่เพื่อดูความคิดเห็นของคุณ
Qwerty

4
@JeffBowman แน่นอนชุดของเกมที่แก้ไขได้สามารถถือว่าเป็นค่า 25 บิตโดยแต่ละบิตที่สอดคล้องกับสี่เหลี่ยมจัตุรัสซึ่งเป็นจำนวนครั้งที่มันถูกดัดแปลง mod 2 ดังนั้นเราสามารถสร้างตัวเลขสุ่มในช่วง 0 .33,554,432 และคำนวณค่าของแต่ละช่องบนกระดานจากลำดับสั้น ๆ
Monty Harder

7
สำหรับสิ่งที่คุ้มค่าในขณะที่นี่คือคำตอบที่ถูกต้องสำหรับคำถามทางคณิตศาสตร์ของวิธีการตอบปัญหานี้มักจะเป็นวิธีปฏิบัติที่น่าสงสัยจากมุมมองการออกแบบ การสร้างแบบนี้โดยไม่ต้องมีแผนเฉพาะใด ๆ โดยทั่วไปจะนำไปสู่ปริศนาที่ให้ความรู้สึก 'เหมือนกันมาก' โดยไม่มีจุดสนใจหรือรูปแบบที่เป็นหนึ่งเดียว เป็นไปได้ที่จะสร้าง 'อินสแตนซ์ของปัญหา' ที่น่าสนใจสำหรับเกมไขปริศนา แต่โดยทั่วไปแล้วจะต้องดูให้ยากขึ้นว่าคุณสมบัติที่น่าสนใจของปริศนาของคุณคืออะไร
Steven Stadnicki

92

ในขณะที่คำตอบข้างต้นนั้นฉลาด (และอาจเป็นไปได้ว่าฉันจะทำต่อไป) เกมนี้เป็นที่รู้จักกันดี มันเรียกว่าLights Outและได้รับการแก้ไขทางคณิตศาสตร์ มีวิธีแก้ปัญหาถ้าหากมีผลรวมขององค์ประกอบต่าง ๆ จำนวนสองค่า (ที่ระบุในหน้า wikipedia) ให้เพิ่มเป็นศูนย์ mod 2 (เช่นจำนวนคู่) โดยทั่วไปพีชคณิตเชิงเส้นเล็กน้อยควรให้เงื่อนไขการแก้ปัญหาที่คล้ายกันสำหรับเกมบนกระดานใด ๆ


2
มันเป็นเรื่องน่าเศร้าที่พบว่ามันถูกสร้างขึ้นมาแล้ว ฉันคิดว่าฉันกำลังจะทำอะไรบางอย่าง
Qwerty

39
@Qwerty มีความคิดดั้งเดิมน้อยมากและแน่นอนคุณไม่จำเป็นต้องมีหนึ่งที่จะประสบความสำเร็จ (cf Rovio, King)
OrangeDog

14
เกมนี้มีอยู่โดยเฉพาะ แต่คุณสามารถขยายความคิดได้เสมอ! เพิ่มคุณสมบัติอื่น ๆ ! เพิ่มกฎที่แตกต่างกันสำหรับสิ่งที่เกิดขึ้นเมื่อคุณคลิกที่ใดที่หนึ่งเช่นสีที่รวมเข้าด้วยกันโดยขึ้นอยู่กับทิศทางที่เปิดใช้งาน / ปิดใช้งาน เพิ่ม "เครื่องมือ" อื่น ๆ ที่คุณต้องใช้ เพิ่มบอร์ดที่ไม่ใช่สี่เหลี่ยม! มีกิจกรรมสนุก ๆ ให้ทำมากมาย เพียงจำไว้ว่าการเคลื่อนไหวต้องย้อนกลับเสมอ
Ed Marty

7
@OrangeDog: แม้แต่ 'Lights Out' ก็ไม่ได้เป็นต้นฉบับนั่นเป็นเพียงชื่อแบรนด์ที่ได้รับความนิยมในยุค 90 ตัวอย่างเช่นบทความวิกิพีเดียแสดงรายการสิ่งนี้และสิ่งนี้
BlueRaja - Danny Pflughoeft

1
คำตอบใดที่คุณอ้างถึงว่าเป็น "คำตอบข้างต้น" มันไม่ชัดเจนอย่างสมบูรณ์ตั้งแต่บนหน้าจอของฉันมีเพียงหนึ่งคำตอบของคุณข้างต้น โปรดจำไว้ว่าคำตอบเปลี่ยนลำดับขึ้นอยู่กับคะแนนโหวตและตัวเลือกผู้ใช้ คุณควรลิงก์ไปยังคำตอบเฉพาะแทนที่จะอ้างอิงถึงบางสิ่งที่ "เหนือ"
David Richerby

13

ไปทางอื่น ๆ เมื่อสร้างปริศนาของคุณ

แทนการสุ่มเลือกไพ่และเปลี่ยนจากสีขาวเป็นสีดำเริ่มจากกระดานชนวนว่างเปล่าจากนั้นเลือกกระเบื้อง แต่แทนที่จะเปลี่ยนกระเบื้องนั้นเป็นสีดำทำให้มันราวกับว่าผู้ใช้เลือกมันทำให้กระเบื้องอื่น ๆ พลิกทั้งหมด รอบ ๆ มัน.

วิธีนี้คุณจะรับประกันได้ว่าจะมีทางออกอย่างน้อยหนึ่งอย่าง : ผู้ใช้จะต้องยกเลิกสิ่งที่ผู้เล่น "AI" ของคุณทำเพื่อสร้างระดับ


7

เอ็ดและอเล็กซานเดมีสิทธิของมัน

แต่ถ้าคุณไม่ต้องการที่จะทราบว่าวิธีการแก้ปัญหาทุกความเป็นไปได้ที่มีวิธีการ

มีจำนวน จำกัด ของปริศนาที่เป็นไปได้

การคลิกที่ช่องสี่เหลี่ยมเดียวกันสองครั้งจะให้ผลลัพธ์เดียวกันกับที่ไม่คลิกเลยไม่ว่าจะมีการคลิกกี่ครั้งก็ตาม นั่นหมายความว่าทุกโซลูชันสามารถอธิบายได้โดยให้แต่ละค่าไบนารีของ 'คลิก' หรือ 'ไม่ได้คลิก' ในทำนองเดียวกันปริศนาแต่ละตัวสามารถอธิบายได้โดยให้แต่ละค่าไบนารีของ 'toggled' หรือ 'ไม่ toggled' นั่นหมายความว่ามีตัวต่อที่เป็นไปได้ 2 ^ 25 ตัวและวิธีแก้ปัญหาที่เป็นไปได้ 2 ^ 25 หากคุณสามารถพิสูจน์ได้ว่าวิธีแก้ปัญหาแต่ละแก้ปริศนาที่ไม่ซ้ำกันแล้วจะต้องมีวิธีแก้ปัญหาสำหรับทุกปริศนา ในทำนองเดียวกันหากคุณพบวิธีแก้ปัญหาสองอย่างที่ไขปริศนาตัวเดียวกันคุณจะไม่สามารถไขปัญหาได้ทุกตัว

นอกจากนี้ 2 ^ 25 คือ 33,554,432 ค่อนข้างมาก แต่ก็ไม่ใช่ตัวเลขที่ไม่สามารถจัดการได้ อัลกอริทึมที่ดีและคอมพิวเตอร์ที่เหมาะสมอาจจะดุร้ายในอีกไม่กี่ชั่วโมงโดยเฉพาะอย่างยิ่งเมื่อคุณพิจารณาว่าครึ่งหนึ่งของจิ๊กซอว์เป็นสิ่งที่ตรงกันข้ามกับอีกครึ่งหนึ่ง


4
มากกว่าครึ่งเป็น "ผู้รุกราน" - นอกเหนือจากการสะท้อนแนวนอนคุณมีการสะท้อนแนวตั้งและการหมุน
Clockwork-Muse

@ Clockwork-Muse ใช่ แต่มันยากที่จะคำนวณจำนวนที่แน่นอนเพราะในขณะที่การออกแบบแบบอสมมาตรสามารถหมุนและพลิกได้ใน 8 พีชคณิตการออกแบบแบบสมมาตรมีการเรียงสับเปลี่ยนน้อยลง ดังนั้นฉันจึงพูดถึงการสลับสีขาว / ดำเท่านั้นเนื่องจากทุกคำตอบมี 1 ค่าผกผัน (แม้ว่าจะตรงกันข้ามกับการทำงานคุณต้องพิสูจน์ว่าคุณสามารถพลิกกระดานทั้งหมด)
Arcanist Lupus

ปรากฎดังที่ Robert Mastragostino พูดถึงในคำตอบของเขานี่เป็นปัญหาที่เป็นที่รู้จักและมีการศึกษาดี แต่ละตัวแก้ปัญหามี 4 โซลูชั่นที่แน่นอนและบอร์ดสุ่มส่วนใหญ่ไม่สามารถแก้ไขได้ การค้นหาพื้นที่ทั้งหมดนั้นอาจสนุก แต่เนื่องจากมีหลักฐานอยู่แล้ว ( math.ksu.edu/math551/math551a.f06/lights_out.pdf ) คุณสามารถทำผลิตภัณฑ์ dot ได้สองสามอย่างและมีคำตอบเดียวกันในไม่กี่ข้อ microseconds :)
GrandOpener

เวลาคณิตศาสตร์: หากคุณต้องการคำนวณจำนวนกระดานที่แตกต่างกัน (โดยไม่คำนึงถึงความสามารถในการแก้ปัญหา) คำนึงถึงความสมมาตรทั้งหมดจากนั้นบทแทรกของ Burnside คือหนทางที่จะไป: มี 16 symmetries (หนึ่งเรื่องเล็กน้อยสามรอบ แต่ละ 8 เหล่านั้นรวมกับการเปิด / ปิด) และสำหรับแต่ละ symmetries จำนวนบอร์ดบางอย่างไม่เปลี่ยนแปลงทั้งหมด หากคุณใช้ค่าเฉลี่ยของบอร์ดที่ไม่เปลี่ยนแปลงโดยสิ้นเชิงต่อสมมาตรนั่นเท่ากับจำนวนบอร์ดที่แตกต่างกัน
อาร์เธอร์

1
@PeterTaylor แน่นอนว่าจะใช้เวลานานกว่าในการเขียนรหัสจำลองมากกว่าที่จะรันผลลัพธ์
corsiKa

4

คำตอบทั่วไป:

  1. สร้างเมทริกซ์ที่มีขนาด (# ย้าย) x (# lights)
  2. ใส่ 1 ในเซลล์ถ้าทำการย้ายที่สอดคล้องกับแถวนั้นสลับแสงที่สอดคล้องกับคอลัมน์นั้นมิฉะนั้น 0
  3. ดำเนินการกำจัดเกาส์ - จอร์แดน (โมดูโล 2) บนเมทริกซ์
  4. หากเมทริกซ์ที่ให้ผลลัพธ์มี 1 ตัวเดียวในแต่ละคอลัมน์และทุกแถวมีค่าได้มากที่สุด 1 ตัวดังนั้นทุกตารางสามารถแก้ไขได้

1

คนอื่น ๆ ได้กล่าวถึงวิธีในการค้นหาว่าปริศนาที่สร้างแบบสุ่มของคุณนั้นสามารถแก้ไขได้หรือไม่ คำถามที่คุณควรถามด้วยคือคุณต้องการปริศนาที่สร้างขึ้นแบบสุ่มหรือไม่

ปริศนาที่สร้างขึ้นแบบสุ่มล้วนมีจุดบกพร่องหลักเหมือนกัน: ความยากของพวกเขานั้นคาดเดาไม่ได้ ปริศนาที่เป็นไปได้ที่คุณอาจได้รับอยู่ในช่วงตั้งแต่การแก้ปัญหาไปจนถึงเรื่องไม่สำคัญ (การแก้ปัญหาชัดเจน) ไปจนถึงยาก (การแก้ปัญหาไม่ชัดเจน) จนเป็นไปไม่ได้ เนื่องจากความยากลำบากนั้นคาดเดาไม่ได้มันทำให้เกิดประสบการณ์ที่ไม่น่าพึงพอใจสำหรับผู้เล่นโดยเฉพาะอย่างยิ่งถ้าพวกเขาทำปริศนาหลายอย่างต่อเนื่องกัน ไม่น่าจะเป็นไปได้ที่จะเกิดความยากลำบากในการเข้าโค้งซึ่งอาจทำให้พวกเขาเบื่อหรือหงุดหงิดทั้งนี้ขึ้นอยู่กับปริศนาที่พวกเขาได้รับ

อีกปัญหาของการสร้างแบบสุ่มคือเวลาที่ใช้ในการเริ่มต้นตัวต่อปริศนานั้นไม่สามารถคาดเดาได้ โดยทั่วไปแล้วคุณจะได้รับปริศนาที่แก้ไขได้ (เกือบ) ในทันที แต่ด้วยความโชคร้ายบางอย่างปริศนาที่คุณสร้างขึ้นแบบสุ่มอาจจบลงด้วยการไขปริศนาที่แก้ไม่ตก

วิธีหนึ่งในการแก้ปัญหาทั้งสองอย่างนี้ก็คือการมีเวกเตอร์ที่กำหนดไว้ล่วงหน้าของตัวต่อที่สามารถแก้ไขได้ทั้งหมดจัดเป็นกลุ่มความยากลำบากแล้วเลือกตัวต่อแบบสุ่มจากตัวต่อที่สามารถแก้ไขได้ตามความยากลำบาก ด้วยวิธีนี้คุณจะมั่นใจได้ว่าปริศนาทุกชิ้นสามารถแก้ไขได้ความยากลำบากสามารถคาดเดาได้และการสร้างจะดำเนินการในเวลาที่แน่นอน

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