A * อัลกอริทึมสำหรับ Tactical RPGs?


15

ฉันยุ่งกับการเขียน RPG ยุทธวิธีที่แย่จริงๆใน C ++ จนถึงขณะนี้ผมมีแผนที่กระเบื้อง 2D และเพียงแค่มีสายต่อ A * ขั้นตอนวิธีการทำงานใน pseudocode ในตามวิกิพีเดีย

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

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


5
ฉันไม่รู้ว่าทำไมช่วงการเคลื่อนที่เป็นปัญหา ค้นหาเส้นทางที่สั้นที่สุดแล้วหลังจากนั้นให้ย้ายสี่เหลี่ยม 'ความเร็ว' ไปตามเส้นทางนั้น
Mooing Duck

คำตอบ:


33

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

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


10
คะแนนที่ดีเกี่ยวกับ 'ตำแหน่งทางยุทธวิธี' แต่การตัดสินใจเหล่านั้นอาจนำไปใช้ในระดับที่สูงกว่าการค้นหาเส้นทางขั้นพื้นฐาน ในทางกลับกันการใช้ต้นทุนกับโหนดในอัลกอริทึมการค้นหาเส้นทางที่สร้างขึ้นโดยตัววิเคราะห์เชิงยุทธวิธีบางประเภทอาจเป็นตัวเลือกที่ดี ตัวอย่างเช่นหากศัตรูมีแนวสายตาข้ามภูมิประเทศทำให้โหนดบนภูมิประเทศนั้นมีค่าใช้จ่ายสูงมาก
DrMcCleod

1
@DrMcCleod: แน่นอนและนั่นคือสิ่งที่ฉันหมายถึงโดย "หรือถูกต้องมากขึ้นมันไม่ได้เป็นเรื่องที่สมบูรณ์" แน่นอนคุณอาจใช้ A * หรืออัลกอริทึมอื่นเพื่อทำส่วนหนึ่งของการประมวลผล แต่ฉันคิดว่าฉันจะหลีกเลี่ยงวิธีการเช่นพยายามหลีกเลี่ยงโหนดที่ถูกเฝ้าดูผ่านค่าใช้จ่ายในการเคลื่อนไหวตั้งแต่เคลื่อนที่ข้ามภูมิประเทศที่หน่วยหนึ่ง การคำนวณความเสี่ยง / ผลตอบแทน IMO
Jack Aidley

13

เมื่อคุณต้องการตัวเลือกการเคลื่อนไหวเป็นไปได้ทั้งหมดของหน่วยใช้Dijkstra ของอัลกอริทึม

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

ดังนั้นเมื่อคุณต้องการเส้นทางที่สั้นที่สุดจากจุด A ถึงจุด B ดังนั้น A * จึงเป็นตัวเลือกที่ดี แต่ถ้าคุณต้องการตัวเลือกการเคลื่อนไหวที่เป็นไปได้ทั้งหมดและเส้นทางที่สั้นที่สุดไปยังแต่ละตัว Dijkstra นั้นเป็นสิ่งที่คุณต้องการ

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

เกี่ยวกับการกระโดด: สิ่งเหล่านี้สามารถถูกแทนเป็นอีกขอบหนึ่งใน A * และ Dijkstra พวกเขาสามารถมีค่าใช้จ่ายเช่นเดียวกับการข้ามขอบปกติหรืออื่น ๆ นอกจากนี้คุณยังสามารถส่งพารามิเตอร์ "jump_height" ไปยังอัลกอริทึมที่บอกอัลกอริทึมให้ละเว้นการข้ามขอบซึ่งสูงเกินความสูงที่กำหนด


9
ควรค่าแก่การกล่าวถึงที่นี่ซึ่งA*เป็นเพียงลักษณะทั่วไปของ Dijkstra ดังนั้นหากคุณเข้าใจสิ่งหนึ่งมันไม่ควรยากเกินไปที่จะเข้าใจอีกสิ่งหนึ่ง
คิว

8
แน่นอนถ้าคุณมีฮิวริสติกที่ส่งคืนค่า 0 ในอัลกอริทึม A * ของคุณขอแสดงความยินดีด้วย! คุณเพิ่งเขียนอัลกอริทึมของ Dijkstra
Yann

9
"Dijkstra ช่วยให้คุณมีเส้นทางที่สั้นที่สุดที่เป็นไปได้ด้วยค่าใช้จ่ายที่กำหนดและหากไม่มีเส้นทางใดถึงปลายทางของคุณก็จะเพิ่มค่าใช้จ่ายและดำเนินการต่อ" - นั่นไม่ใช่วิธีการทำงานหรือสิ่งที่ส่งออก อันที่จริงมันเป็นเพียงการวางหลักเกณฑ์ทั่วไปของการค้นหาแบบกว้างแรกไปยังกราฟถ่วงน้ำหนัก พบเส้นทางที่สั้นที่สุดเพียงเส้นทางเดียว A * เป็นเพียงภาพรวมของสิ่งนั้นสำหรับเมื่อคุณมีระยะห่างระหว่างฮิวริสติก
BlueRaja - Danny Pflughoeft

1
ไม่แน่ใจว่าทำไม upvote นี้ถึงได้มาก จากมุมมองในทางปฏิบัติ Dijkstra ล้าสมัย มันสอนใน CS ด้วยเหตุผลทางการศึกษาและประวัติศาสตร์ แม้แต่ A * จะล้าสมัยในการทำงานหนัก Google แผนที่ไม่ได้ใช้อย่างแน่นอน คุณต้องการดูตัวแปรของ ArcGraph ทุกวันนี้
MSalters

2
@MSalters Dijkstra และ A * เป็นอัลกอริธึมที่สมบูรณ์แบบสำหรับปัญหาง่าย ๆ เช่นยุทธวิธี RPG มีการเคลื่อนไหวที่ถูกต้องในระยะที่แคบมาก (กระเบื้อง) และมีวิธี จำกัด จำนวนมากในการเคลื่อนย้ายข้ามแผ่นกระเบื้องดังกล่าว (แนวทแยงบางแนวทแยง) และมักจะเป็นเส้นทางที่สั้นที่สุด: SQRT (ArenaWidth² * ArenaHeight²) ความแตกต่างนั้นเล็กน้อยในเครื่องที่ทันสมัยสำหรับสิ่งที่มีค่าค่อนข้างเล็กดังนั้นทำไมต้องกังวลกับการใช้งานที่ซับซ้อนมากขึ้นเมื่อสิ่งที่เรียบง่ายเพียงพอสำหรับวัตถุประสงค์ที่ระบุไว้ที่นี่?
Valthek

2

คำตอบอื่น ๆ มีข้อมูลที่ดีดังนั้นโปรดอ่าน

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

ตัวอย่างเช่น:

if (edge == JUMP && !unit.canJump()) 
    return INF;
if (tile.Type == Forest && unit.moveType == HORSE) 
    return 2;
//Other cases here
//-----
else 
    return 1;

นี่จะให้เส้นทางของคุณ จากนั้นคุณเพียงแค่ย้ายหน่วยไปตามเส้นทางของพวกเขาในขณะที่ใช้คะแนนการเคลื่อนไหวและหยุดพวกเขาเมื่อเหลือคะแนน <edgeCost โปรดทราบว่านี่อาจไม่เหมาะสมอย่างสมบูรณ์หากคุณจบด้วย leftPoints = 1 แต่ควรจะดีพอสำหรับเกม RPG ฝึกหัด ในความเป็นจริงคุณต้องการยุทธวิธีมากขึ้นอย่างที่แจ็กดอดลีย์ชี้


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


1

การปีนเขาและช่องว่างนั้นค่อนข้างเล็กน้อยเนื่องจากพวกเขาเพียงแค่ปรับราคา Pathfinding (และ AI ส่วนใหญ่เกี่ยวกับยุทธวิธี) คือทั้งหมดที่เกี่ยวกับการสรุปค่าใช้จ่ายสำหรับโหนดที่ต้องไปเยี่ยมชมทั้งหมดและลดให้น้อยที่สุด หน้าผาที่ไม่สามารถใช้ได้จะมีค่าใช้จ่ายที่ไม่ จำกัด (มาก, สูงมาก), ความลาดชันจะมีค่าใช้จ่ายสูงกว่าปกติ ฯลฯ

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

การจำลองที่ดีจงใจไม่พบเส้นทางที่ดีที่สุด อัลกอริธึมที่ดีกว่านั้นอาจจะทำลำดับชั้นพา ธ - ถ้าไม่มีอะไรอีกแล้วโดยการวาดเส้นตรงบนแผนที่และรับ 4-5 waypoints จากนั้นหาเส้นทางจากจุดเดียวไปยังจุดถัดไปโดยพิจารณาเฉพาะน้ำหนักของโหนดที่อยู่ห่างไกล เป็นที่รู้จักและตั้งค่าโหนดอื่น ๆ ทั้งหมดให้เป็น "ไม่แยแส" หรือคุณสามารถรัน A * บนกริด coarser ก่อนจากนั้นหาเส้นทางจากโหนดขนาดใหญ่หนึ่งไปยังโหนดถัดไป (แต่ฉันเดาว่าการวาดเส้นบนแผนที่นั้นก็ดีเหมือนกัน)

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


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

@MSalters: สามารถเกิดขึ้นได้กับวิธี "วาดเส้น" แม้หลังจากความพยายามครั้งแรกใช่ มันไม่น่าจะเกิดขึ้นได้มากกว่าหนึ่งครั้งด้วยวิธีการลำดับชั้นของกริดหยาบ (ซึ่งเช่นใช้ค่าเฉลี่ยหรือค่ามัธยฐานหรือแม้กระทั่งค่าต้นทุนสูงสุดของโหนดภายใน) มันน่าจะเป็นวิธีที่ศัตรูของมนุษย์จะเล่น - หลีกเลี่ยงอุปสรรคใหญ่ ๆที่คุณรู้หรือมองจากระยะไกลเหมือนห่วงโซ่ภูเขาและวางแผนเส้นทางที่หยาบที่สุดตรงและกัดผ่านทางของคุณ เว้นแต่คุณจะรู้ว่ามีภูเขาคุณเดินตรงไปที่มัน
Damon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.