ฉันสร้างระบบที่คล้ายกับระบบที่คุณใช้ในแบบ 3 มิติ ฉันมีวิดีโอสั้น ๆ แสดงให้เห็นถึงโครงสร้างที่เรียบง่ายของมันที่นี่และบล็อกโพสต์ที่นี่
นี่คือ gif เล็กน้อยที่ฉันสร้างขึ้นจากกลไกความดันที่อยู่ด้านหลังกำแพงที่มองไม่เห็น (เล่นด้วยความเร็วสูง):
ให้ฉันอธิบายข้อมูลที่เกี่ยวข้องเพื่อให้ทราบถึงคุณสมบัติบางอย่างของระบบ ในระบบปัจจุบันแต่ละบล็อกของน้ำมีดังต่อไปนี้ใน 2 ไบต์:
//Data2 Data
//______________________________ _____________________________________
//|0 |0 |000 |000 | |0 |0 |000 |000 |
//|Extra|FlowOut|Active|Largest| |HasSource|IsSource|Direction|Height|
//------------------------------ -------------------------------------
Height
คือปริมาณน้ำในลูกบาศก์คล้ายกับความดันของคุณ แต่ระบบของฉันมีเพียง 8 ระดับ
Direction
เป็นทิศทางที่การไหลกำลังเกิดขึ้น เมื่อตัดสินใจว่าน้ำจะไหลไปทางใดมีแนวโน้มที่จะดำเนินต่อไปในทิศทางปัจจุบัน สิ่งนี้ยังใช้ในการย้อนกลับอย่างรวดเร็วติดตามการไหลกลับขึ้นไปที่คิวบ์ของแหล่งเมื่อจำเป็น
IsSource
บ่งชี้ว่าคิวบ์นี้เป็นคิวบ์ต้นทางหมายความว่าคิวบ์ไม่เคยขาดน้ำ ใช้สำหรับแหล่งที่มาของแม่น้ำสปริง ฯลฯ ลูกบาศก์ทางด้านซ้ายใน gif ด้านบนเป็นคิวบ์ต้นทางตัวอย่างเช่น
HasSource
บ่งชี้ว่าคิวบ์นี้เชื่อมต่อกับคิวบ์ต้นทางหรือไม่ เมื่อเชื่อมต่อกับแหล่งที่มาก้อนจะพยายามแตะแหล่งที่มาสำหรับน้ำมากขึ้นก่อนที่จะหาก้อนที่ไม่ใช่ "เต็ม" อื่น ๆ
Largest
บอก cube นี้ว่าการไหลที่ใหญ่ที่สุดระหว่างมันกับ cube ต้นทางคืออะไร ซึ่งหมายความว่าหากน้ำไหลผ่านช่องว่างแคบก็จะ จำกัด การไหลของลูกบาศก์นี้
Active
เป็นเคาน์เตอร์ เมื่อคิวบ์นี้มีโฟลว์ที่กำลังไหลผ่านมันไปหรือจากคิวบ์นั้นแอคทีฟจะเพิ่มขึ้น มิฉะนั้นการใช้งานจะลดลงแบบสุ่ม เมื่อแอ็คทีฟชนศูนย์ (หมายถึงไม่แอ็คทีฟ) ปริมาณน้ำจะเริ่มลดลงในลูกบาศก์นี้ การกระทำประเภทนี้เช่นการระเหยหรือการแช่ลงบนพื้น ( ถ้าคุณมีกระแสคุณควรจะลดลง! )
FlowOut
บ่งชี้ว่าคิวบ์นี้เชื่อมต่อกับคิวบ์ที่อยู่บนขอบโลก เมื่อเส้นทางสู่ขอบของโลกที่ทำน้ำมีแนวโน้มที่จะเลือกเส้นทางนั้นมากกว่าที่อื่น ๆ
Extra
เป็นบิตพิเศษสำหรับใช้ในอนาคต
ตอนนี้เรารู้ข้อมูลแล้วให้ดูที่ภาพรวมระดับสูงของอัลกอริทึม แนวคิดพื้นฐานของระบบคือการจัดลำดับความสำคัญของการไหลลงและออก อย่างที่ฉันอธิบายในวิดีโอฉันทำงานจากล่างขึ้นบน น้ำแต่ละชั้นจะถูกประมวลผลทีละระดับในแกน y ก้อนสำหรับแต่ละระดับจะถูกประมวลผลแบบสุ่มแต่ละก้อนจะพยายามดึงน้ำจากแหล่งที่มาในแต่ละรอบ
Flow cubes ดึงน้ำจากแหล่งกำเนิดโดยทำตามทิศทางการไหลของมันสำรองจนกระทั่งถึง cube ต้นทางหรือ cube ที่ไม่มีพาเรนต์ การจัดเก็บทิศทางการไหลในแต่ละคิวบ์นั้นจะติดตามเส้นทางไปยังแหล่งข้อมูลได้ง่ายเช่นเดียวกับการข้ามผ่านรายการที่เชื่อมโยง
โค้ดหลอกสำหรับอัลกอริทึมมีดังนี้:
for i = 0 to topOfWorld //from the bottom to the top
while flowouts[i].hasitems() //while this layer has flow outs
flowout = removeRandom(flowouts[i]) //select one randomly
srcpath = getPathToParent(flowout) //get the path to its parent
//set cubes as active and update their "largest" value
//also removes flow from the source for this flow cycle
srcpath.setActiveAndFlux()
//now we deal with regular flow
for i = 0 to topOfWorld //from the bottom to the top
while activeflows[i].hasitems() //while this layer has water
flowcube = removeRandom(activeflows[i]) //select one randomly
//if the current cube is already full, try to distribute to immediate neighbors
flowamt = 0
if flowcube.isfull
flowamt = flowcube.settleToSurrounding
else
srcpath = getPathToParent(flowcube) //get the path to its parent
flowamt = srcpath.setActiveAndFlux()
flowcube.addflow(flowamt)
//if we didn't end up moving any flow this iteration, reduce the activity
//if activity is 0 already, use a small random chance of removing flow
if flowamt == 0
flowcube.reduceActive()
refillSourceCubes()
กฎพื้นฐานสำหรับการขยายโฟลว์ที่ (เรียงตามลำดับความสำคัญ):
- หากลูกบาศก์ด้านล่างมีน้ำน้อยลงให้ไหลลง
- หากลูกบาศก์ที่อยู่ติดกันในระดับเดียวกันมีน้ำน้อยกว่าให้ไหลด้านข้าง
- หากลูกบาศก์ด้านบนมีน้ำน้อยและลูกบาศก์แหล่งที่มาสูงกว่าลูกบาศก์ด้านบนให้ไหลขึ้น
ฉันรู้ว่ามันค่อนข้างสูง แต่มันก็ยากที่จะได้รับลงในรายละเอียดมากขึ้นโดยไม่ได้รับวิธีการลงรายละเอียด
ระบบนี้ทำงานได้ค่อนข้างดี ฉันสามารถเติมน้ำได้อย่างง่ายดายซึ่งล้นไปด้านนอกเพื่อดำเนินการต่อ ฉันสามารถเติมอุโมงค์รูปตัวยูตามที่คุณเห็นใน gif ด้านบน อย่างไรก็ตามอย่างที่ฉันพูดระบบไม่สมบูรณ์และฉันยังไม่ได้ทำทุกอย่าง ฉันไม่ได้ทำงานกับระบบการไหลมานาน (ฉันคิดว่ามันไม่จำเป็นสำหรับอัลฟ่าและฉันจะหยุดไว้) อย่างไรก็ตามปัญหาที่ฉันจัดการเมื่อฉันพักไว้ที่:
สระว่ายน้ำ เมื่อได้รับสระน้ำขนาดใหญ่พอยน์เตอร์จากเด็กหนึ่งไปยังอีกคนหนึ่งนั้นดูราวกับเป็นบ้าที่บ้าคลั่งของสิ่งที่ลูกบาศก์สุ่มถูกเลือกให้ไหลไปในทิศทางใด เหมือนเติมอ่างอาบน้ำที่มีเส้นงี่เง่า เมื่อคุณต้องการระบายน้ำออกจากถังคุณควรทำตามเส้นทางของสายโง่กลับไปที่ต้นกำเนิด หรือคุณควรจะใช้สิ่งที่ใกล้เคียงที่สุด? ดังนั้นในสถานการณ์ที่ก้อนอยู่ในสระว่ายน้ำขนาดใหญ่พวกเขาควรจะละเลยการไหลของผู้ปกครองและดึงจากสิ่งที่อยู่เหนือพวกเขา ฉันมาพร้อมกับรหัสการทำงานขั้นพื้นฐานสำหรับเรื่องนี้ แต่ก็ไม่เคยมีทางออกที่สง่างามที่ฉันสามารถมีความสุขกับ
พ่อแม่หลาย สตรีมลูกสามารถป้อนได้อย่างง่ายดายโดยผู้ปกครองมากกว่าหนึ่งสตรีม แต่เด็กที่มีตัวชี้ไปยังผู้ปกครองคนเดียวจะไม่ยอมให้สิ่งนั้น สิ่งนี้สามารถแก้ไขได้โดยใช้บิตมากพอที่จะยอมให้บิตสำหรับทิศทางพาเรนต์ที่เป็นไปได้ และมีแนวโน้มที่จะเปลี่ยนอัลกอริทึมเพื่อเลือกเส้นทางแบบสุ่มในกรณีที่มีผู้ปกครองหลายคน แต่ฉันไม่เคยไปถึงเพื่อทดสอบและดูว่ามีปัญหาอื่น ๆ