มีอัลกอริธึมที่มีอยู่ไหมถ้าหากพลังการประมวลผลที่ไม่มีขีด จำกัด คอมพิวเตอร์สามารถเล่นหมากรุกได้อย่างสมบูรณ์แบบ
ถ้าเป็นเช่นนั้นฉันจะหารหัสหลอกได้จากที่ไหน?
มีอัลกอริธึมที่มีอยู่ไหมถ้าหากพลังการประมวลผลที่ไม่มีขีด จำกัด คอมพิวเตอร์สามารถเล่นหมากรุกได้อย่างสมบูรณ์แบบ
ถ้าเป็นเช่นนั้นฉันจะหารหัสหลอกได้จากที่ไหน?
คำตอบ:
มีอัลกอริทึมหรือไม่? ใช่. ตามทฤษฎีบทของ Zermeloมีสามความเป็นไปได้สำหรับเกมสองผู้เล่นที่มีข้อมูล จำกัด แน่นอนเช่นหมากรุก: ผู้เล่นคนแรกมีกลยุทธ์ในการชนะหรือผู้เล่นคนที่สองมีกลยุทธ์ในการชนะหรือผู้เล่นทั้งสองสามารถบังคับให้เสมอ เรายังไม่รู้ว่ามันคือหมากรุกอะไร (ตัวตรวจสอบได้ถูกแก้ไขแล้ว : ผู้เล่นทั้งสองสามารถบังคับให้เสมอกันได้)
แนวคิดอัลกอริทึมค่อนข้างง่าย: สร้างแผนผังเกมที่สมบูรณ์วิเคราะห์โหนดใบไม้ (ตำแหน่งสิ้นสุดเกม) และทำการย้ายครั้งแรกชนะชนะลาออกหรือเสนอผลเสมอ
ปัญหาอยู่ในรายละเอียด: มีประมาณ 10 43ตำแหน่งที่เป็นไปได้และจำนวนการเคลื่อนไหวที่มากขึ้น (ตำแหน่งส่วนใหญ่สามารถเข้าถึงได้มากกว่าหนึ่งวิธี) คุณต้องใช้คอมพิวเตอร์ที่ทรงพลังอย่างไร้ขีด จำกัด เพื่อใช้ประโยชน์จากสิ่งนี้เนื่องจากคอมพิวเตอร์ที่สามารถใช้ประโยชน์จากอัลกอริทึมนี้อาจไม่เหมาะกับเอกภพที่รู้จัก
ดูhttps://en.wikipedia.org/wiki/Endgame_tablebase
ด้วยพลังของคอมพิวเตอร์ที่ไม่มีที่สิ้นสุดใคร ๆ ก็สามารถสร้างโต๊ะสำหรับตำแหน่งเริ่มต้นและแก้ปัญหาหมากรุกได้
ในทางปฏิบัติมีเพียงตำแหน่งที่มี "ผู้ชาย" มากถึงเจ็ดคน (เบี้ยและชิ้นส่วนการนับกษัตริย์) ได้รับการแก้ไขโดยใช้ซูเปอร์คอมพิวเตอร์ปัจจุบันดังนั้นเราจึงห่างไกลจากการแก้หมากรุกมาก ความซับซ้อนของปัญหาเพิ่มขึ้นอย่างทวีคูณตามจำนวนชิ้น
หากคุณมีพลังการประมวลผลที่ไม่ จำกัดจริงๆอัลกอริธึมดังกล่าวจะเป็นเรื่องเล็กน้อยที่จะเขียน เนื่องจากหมากรุกมีสถานะที่เป็นไปได้ค่อนข้างจำกัดคุณจึงสามารถทวนซ้ำมันได้จนกว่าจะพบเส้นทางการเล่นที่สมบูรณ์แบบ มันจะไม่มีประสิทธิภาพอย่างน่ากลัว แต่ถ้าคุณมีพลังในการประมวลผลที่ไม่สิ้นสุด
หากต้องการตอบคำถามโดยตรง: ใช่มีอัลกอริทึมดังกล่าว มันเรียกว่า minimax (endgame tablebases สร้างขึ้นโดยใช้อัลกอริธึมนี้ (ย้อนหลัง!) แต่อัลกอริธึมมินิแม็กซ์แบบธรรมดาที่เรียบง่ายนั้นเป็นสิ่งที่คุณต้องการ) อัลกอริทึมนี้สามารถเล่นเกมผลรวมศูนย์ผู้เล่นสองคนได้อย่างสมบูรณ์แบบ ค้นหารหัสเทียมได้ที่นี่:
https://en.wikipedia.org/wiki/Minimax
โปรดทราบว่าตัวแปรของอัลกอริทึมนี้ถูกใช้โดยโปรแกรมหมากรุกคอมพิวเตอร์สมัยใหม่
ไม่เพียง แต่จะมีขั้นตอนวิธีการเล่นหมากรุกที่สมบูรณ์แบบก็เป็นไปได้ที่จะเขียนโปรแกรมสั้น ๆ ที่จะ (ได้รับทรัพยากรที่ไม่มีที่สิ้นสุด) เล่นที่สมบูรณ์แบบของความรู้ จำกัด ระยะเวลาเกมที่สองผู้เล่นคนใดที่กำหนดได้อย่างสมบูรณ์แบบ
เอ็นจิ้นเกมไม่จำเป็นต้องรู้กฎของเกมที่กำลังเล่นอยู่ สิ่งที่จำเป็นต้องมีคือการเป็นตัวแทนของ "เกมแห่งรัฐ" และฟังก์ชั่นทึบแสงที่ (a) ให้สถานะเกมใด ๆ ระบุรายชื่อเกมถัดไปทางกฎหมายและ (b) ให้สถานะเกมตัดสินใจว่าจะชนะสำหรับผู้เล่น 1 หรือไม่ การชนะสำหรับผู้เล่น 2 การเสมอหรือมันไม่ใช่สถานะสิ้นสุด
ให้ฟังก์ชั่นเหล่านั้นเป็นอัลกอริทึมแบบเรียกซ้ำง่าย ๆ "แก้ปัญหา" เกม
ความจริงเรื่องนี้ได้รับการกล่าวถึงในคำตอบก่อนหน้านี้โดย chessprogrammer (minimax) และโดย Acccumulation (ซึ่งเป็นผู้ให้โปรแกรมรุ่นหนึ่งในไพ ธ อน)
ฉันเขียนโปรแกรมเช่นนี้เมื่อ 20 กว่าปีที่แล้ว ฉันทดสอบโดยเล่น noughts-and-crosses (โอเอกซ์หากคุณเป็นคนอเมริกัน) มันเล่นเกมที่สมบูรณ์แบบนั่นเอง
แน่นอนว่าสิ่งนี้จะล้มลงบนคอมพิวเตอร์ที่จินตนาการได้อย่างรวดเร็วสำหรับเกมที่จริงจัง เนื่องจากเป็นการเรียกซ้ำมันเป็นการสร้างทรีเกมทั้งหมดบนสแต็คอย่างมีประสิทธิภาพดังนั้นคุณจะได้รับ "สแต็คล้น" (เล่นสำนวนมาก ๆ ) ก่อนที่คุณจะเข้าใกล้การวิเคราะห์หมากรุก 10 ^ 123 ที่อ้างถึงในคำตอบอื่น ๆ แต่มันสนุกที่จะรู้ว่าในหลักการโปรแกรมขนาดเล็กนี้จะทำงาน
สำหรับฉันนี่ยังบอกว่าสิ่งที่น่าสนใจเกี่ยวกับ AI: "ปัญญา" มากที่คุณคิดว่าจัดแสดงโดย Deep Blue หรือ Go Zero หรือโดยการเล่นหมากรุกของมนุษย์หรือ Go มีความรู้สึกว่าเกมเหล่านี้มีความสำคัญ การแก้ปัญหา ความท้าทายคือทำอย่างไรจึงจะได้ทางออกที่ดีแม้ว่าจะไม่ใช่ทางออกที่ดีที่สุดในเวลาที่เหมาะสม
ฉันจะเพิกเฉยต่อความเป็นไปได้ในการดึงหรือลำดับของการเคลื่อนไหวเพื่อความเรียบง่าย เมื่อเข้าใจอัลกอริทึมแล้วก็ไม่ยากที่จะขยายไปยังกรณีเหล่านั้น
ก่อนคำจำกัดความบางอย่าง:
การเคลื่อนไหวใด ๆ ที่ชนะเกมสำหรับผู้เล่นที่ทำการย้ายนั้นเป็นการเคลื่อนที่ที่ชนะ
การเคลื่อนไหวใด ๆ ที่แพ้เกมสำหรับผู้เล่นที่ทำการย้ายนั้นเป็นการสูญเสีย
การย้ายใด ๆ ที่ทำให้ผู้เล่นคนอื่น ๆ ชนะอย่างน้อยหนึ่งครั้งก็เป็นการแพ้ (เนื่องจากฝ่ายตรงข้ามสามารถรับการเคลื่อนไหวนั้นและบังคับให้สูญเสีย)
การเคลื่อนไหวใด ๆ ที่ทำให้ผู้เล่นคนอื่นเสียการเคลื่อนไหวเพียงอย่างเดียวก็เป็นการชนะที่ดีเช่นกัน (ไม่ว่าฝ่ายตรงข้ามจะทำอะไรคุณก็จะเป็นผู้ชนะ)
กลยุทธ์ที่สมบูรณ์แบบหมายถึงการเคลื่อนไหวให้ชนะเสมอหากมีสิ่งใดเหลืออยู่และลาออกเมื่อมีเพียงการสูญเสียการเคลื่อนไหว
ทีนี้มันเป็นเรื่องเล็กน้อยที่จะเขียนกลยุทธ์ที่สมบูรณ์แบบ เพียงแค่กระจายลำดับการย้ายที่เป็นไปได้ทั้งหมดและระบุการย้ายที่ชนะ / แพ้ การละเว้นทางตันในที่สุดจะระบุว่าทุกการเคลื่อนไหวเป็นการย้ายที่ชนะหรือการแพ้
ตอนนี้กลยุทธ์เป็นเรื่องเล็กน้อย ดูการเคลื่อนไหวที่เป็นไปได้ทั้งหมดของคุณ หากการเคลื่อนไหวที่ชนะใด ๆ ยังคงอยู่ให้ใช้เวลาหนึ่งและชนะ หากการสูญเสียการเคลื่อนไหวยังคงอยู่ให้ลาออกเนื่องจากฝ่ายตรงข้ามสามารถบังคับให้คุณแพ้ได้
มันไม่ยากที่จะปรับกลยุทธ์เพื่อรวมความเป็นไปได้ของทางตัน
อัปเดต : ในกรณีที่ยังไม่ชัดเจนว่าสิ่งนี้ระบุว่าการย้ายทุกครั้งเป็นการชนะที่มากขึ้นหรือการแพ้ให้พิจารณา:
n
จำนวนการเคลื่อนไหวในเกมหมากรุกที่ยาวที่สุดที่เป็นไปได้ (เราไม่สนใจลำดับที่ไม่มีขอบเขตในตอนนี้แม้ว่าการรวมไว้ด้วยกันนั้นไม่ใช่เรื่องยาก)n
เคลื่อนไหวก่อนหน้านี้ที่เราต้องพิจารณาn-1
เคลื่อนไหวก่อนหน้านั้นเป็นการเคลื่อนไหวที่ชนะหรือการแพ้เนื่องจากการn
เคลื่อนไหวจบลงด้วยเกมที่ยาวที่สุดn-2
จะเป็นไปตามการย้ายที่ชนะเท่านั้นหรือการสูญเสียการเคลื่อนไหว1. d4
ด้วย...resigns
หรือไม่?
สมมติว่าคุณมีสามฟังก์ชั่น: win_state
, และget_player
next_states
อินพุตสำหรับwin_state
เป็นสถานะของเกมและเอาต์พุตคือ -1 หากสีขาวอยู่ในรุกฆาต 0 ถ้าเป็นรูปวาด 1 หากสีดำอยู่ในรุกฆาตและเป็นNone
อย่างอื่น อินพุตสำหรับget_player
เป็นสถานะเกมและเอาต์พุตคือ -1 หากเป็นตาดำและ 1 ถ้าเป็นตาขาว อินพุตสำหรับnext_states
คือรายการของสถานะเกมถัดไปที่เป็นไปได้ซึ่งอาจเป็นผลมาจากการย้ายทางกฎหมาย จากนั้นฟังก์ชั่นต่อไปนี้เมื่อได้รับสถานะเกมและผู้เล่นควรบอกให้คุณทราบว่ารัฐเกมใดที่จะย้ายไปเล่นเพื่อให้ผู้เล่นนั้นชนะ
def best_state(game_state,player)
def best_result(game_state):
if win_state(game_state):
return(win_state)
else:
player = get_player(game_state)
return max([best_result(move)*player for move in next_states(game_state)])*player
cur_best_move = next_states(games_state)[0]
cur_best_outcome = -1
for state in next_states(game_state):
if best_result(state)*player > cur_best_outcome:
cur_best_outcome = best_result(state)*player
cur_best_move = state
return(best_move)
ใช่. มันเป็นเรื่องง่าย. คุณไม่ต้องการพลังการประมวลผลที่ไม่มีขีด จำกัด สิ่งที่คุณต้องมีคือตารางการค้นหาที่มีตำแหน่งกระดานที่เป็นไปได้แต่ละตำแหน่งท่าที่ดีที่สุดในการเล่นในตำแหน่งนั้น นี่คือรหัสเทียม:
def play-move(my-color, board-position):
return table-of-best-moves[my-color, board-position]
สิ่งเดียวที่จับได้คือตารางค้นหานี้จะต้องมีขนาดใหญ่มาก - อาจใหญ่กว่ากาแลคซีทางช้างเผือก - และมันต้องใช้เวลานานกว่าจะสร้างมันขึ้นมา - อาจจะนานกว่ายุคปัจจุบันของเอกภพเว้นแต่จะมี ความสม่ำเสมอของหมากรุกที่ยังไม่ได้เปิดซึ่งทำให้ง่ายกว่าที่เราเห็นในตอนนี้ แต่ถ้าคุณมีตารางค้นหานี้รูทีนย่อยเพื่อเลือกการย้ายที่สมบูรณ์แบบทุกครั้งสามารถนำไปใช้ในการเรียนการสอนซีพียูเพียงครั้งเดียว
ด้วยความรู้ในปัจจุบันของหมากรุกเราไม่มีทางที่จะแน่ใจได้ว่าการเล่นที่สมบูรณ์แบบรับประกันได้ว่าคุณจะไม่แพ้ ตัวอย่างเช่นหากการเล่นที่สมบูรณ์แบบรับประกันการชนะให้กับ White ดังนั้น Black จะแพ้แม้ว่า Black จะเล่นได้อย่างสมบูรณ์แบบ