ขณะนี้ฉันมีเกมเหมือน Tetris ที่เรียบง่ายและพบปัญหาที่ฉันไม่สามารถแก้ไขได้
ซึ่งแตกต่างจาก Tetris ที่มีรูปทรงล้มเดียวฉันมีรูปทรงหลายรูปที่เชื่อมต่อกันที่อาจต้องตก ฉันต้องคำนวณตำแหน่งสุดท้ายของพวกเขา พิจารณาสิ่งต่อไปนี้:
ในการคำนวณตำแหน่งสุดท้ายของรูปร่างสีเขียวฉันเพียงแค่สแกนหาทุก ๆ ตารางจนกว่าฉันจะไปถึงอีกสี่เหลี่ยมจัตุรัสหรือขอบของกระดาน เสร็จสิ้น
สำหรับรูปร่างที่เรียบง่ายหลาย ๆ แบบฉันกำลังไต่ขึ้นบอร์ด ดังนั้นสีแดงจึงไม่จำเป็นต้องเคลื่อนไหวสีส้มจะลดลงทีละหนึ่งสีเขียวลดลงสาม เสร็จสิ้น
ฉันไม่รู้วิธีรักษารูปร่างสีเขียวและสีแดงที่เชื่อมต่อกัน การใช้ตรรกะของ # 2 เราจะท้าย "ติด" ลอยกลางอากาศ หากฉันสแกนหารูปร่างสีเขียวฉันจะพบกับสีแดงและไม่เคลื่อนไหวและในทางกลับกันสำหรับสีแดง วิธีแก้ปัญหาอาจใช้รูปร่างสองแบบเป็นหนึ่งเดียว
คล้ายกับ # 3 ในสถานการณ์นี้ฉันสามารถประสบความสำเร็จได้ด้วยการปฏิบัติต่อวัตถุเป็นหนึ่งเดียว
แตกต่างจาก # 3 และ # 4 ฉันไม่สามารถรักษารูปร่างเป็นหนึ่งเป็นรูปร่างสีส้มจะจบลงหนึ่งตารางลอยสูงเกินไป ...
อีกรูปแบบของปัญหา # 6
อาจมีสถานการณ์อื่น ๆ ที่ฉันมีหลายรูปร่างที่คลุกเคล้าในสถานการณ์ที่ซับซ้อนมากขึ้น แต่ฉันคิดว่าข้างต้นครอบคลุมส่วนพื้นฐานที่สุดของปัญหา
ฉันรู้สึกว่ามีวิธีการแก้ปัญหาที่สง่างามที่ฉันยังไม่ได้พบ / คิดและจะขอบคุณมากที่ข้อมูลเชิงลึกความคิดหรือทรัพยากรใด ๆ
สารละลาย
วิธีแก้ปัญหาที่ฉันคิดขึ้นมานั้นสวยงามจริงๆโดยอิงจากคำตอบของ @ user35958 ด้านล่างฉันได้สร้างฟังก์ชั่นแบบเรียกซ้ำต่อไปนี้ (รหัสหลอก)
function stop(square1, square2){
// Skip if we're already stopped
if(square1.stopped){
return;
}
// Are we comparing squares?
if(!square2){
// We are NOT comparing squares, simply stop.
square1.stopped = true;
} else {
// Stop IF
// square1 is directly above square2
// square1 is connected to square2 (part of the same complex shape)
if(square1.x == square2.x && square1.y == (square2.y+1) || isConnected(square1, square2)){
square1.stopped = true;
}
}
// If we're now stopped, we must recurse to our neighbours
stop(square1, squareAbove);
stop(square1, squareBelow);
stop(square1, squareRight);
stop(square1, squareDown);
}
Animated GIF แสดงการแก้ปัญหาแต่ละรอบ
เพื่อสรุป:
- เมื่อ "หยุด" สี่เหลี่ยมเราก็หยุด:
- ตารางข้างต้นใด ๆ เสมอ.
- สี่เหลี่ยมใกล้เคียงที่เราเชื่อมต่อกับ (เช่นรูปร่างเดียวกัน)
- เราหยุดแถวด้านล่างทั้งหมดและฟังก์ชั่นเกิดขึ้นอีกครั้งผ่านช่องสี่เหลี่ยม
- เราทำซ้ำจนกว่าจะหยุดสี่เหลี่ยมทั้งหมด
- จากนั้นเราเคลื่อนไหว