การที่เราจะเขียน AI ให้สามารถมาเป็นคู่แข่งกับเราในเกมได้ที่เขาเรียกกันว่าบอท(ฺBot)ในจะต้องผ่านการ tainning ต่าง ๆ นานา เพื่อให้สามารถมีความรู้ ความสามารถมากพอที่จะให้บอทมาเป็นคู่ต่อสู้กับเราได้หรือต้องสร้างเงื่อนไขอะไรบางอย่างเพื่อที่จะให้หาทุกวิถึทางเพื่อทำให้สามารถชนะคนได้เกมที่ผมนำมาใช้ในการศึกษาครั้งนี้คือ Connect 4
เกม Connect 4 คือเกมที่ต้องมีผู้เล่น 2 คน ในการเล่น โดยผู้เล่นจะต้องทำยังไงก็ได้ให้หยอดเหรียญที่เป็นสี ๆ เรียงกันได้แก่ แนวตั้ง แนวนอน และแนวเฉียง ในช่องที่มีขนาด 6 * 7 ดังภาพ
โหลด Library ที่ต้องใช้
ในส่วนของ pygame
ใช้สำหรับแสดงภาพเกม เช่น กระดาน, หมาก, แอนิเมชัน และการรับอินพุตจากผู้เล่น
pip install pygame==1.9.3
และ
pip install -r requirements.txt
Algorithm ที่ใช้คือ Minimax และ Alpha-Beta Pruning
Minimax คือการจำลองทุกทางที่เป็นไปได้ในเกมและเลือกทางเดินที่พลาดน้อยที่สุดในกรณีที่ฝ่ายตรงข้ามเล่นได้ดีเหมือนกัน
Alpha-Beta Pruning คือเทคนิคที่ช่วยลดจำนวนการจำลองลง โดยไม่ต้องดูทุกทางเดินหากรู้ว่ามีทางที่ดีสุดอยู่แล้ว
ด้วยความที่สถานการณ์ที่เป็นไปได้มีทั้งหมด 4,531,985,219,092 วิธี ซึ่งทำให้ยากต่อการคำนวณกับโครงสร้างเกม ดังนั้นเจึงใช้ Algorithm ของ Minimax ร่วมกับ Alpha-Beta Pruning
ขั้นตอนที่ 1 การนำเข้า Module และSetting
from fourInARowGUI import fourInARowGUI as GUI
infinity = float('inf')
เป็นการนำเข้าโมดูลfourInARowGUI.py
ซึ่งอยู่ในโฟลเดอร์เดียวกัน ใน Module นี้จะมีฟังก์ชันทั้งหมดที่ใช้จัดการ กราฟิก, อินพุตของผู้เล่น และการแสดงผลเกม
ขั้นตอนที่ 2 สร้างคลาสในการควบคุมเกม
class Game:
AI = -1
PLAYER = 0
def __init__(self, game_board):
self.current_state = State(0, 0)
self.turn = self.AI
self.first = self.turn
self.board = game_board
โค้ดในส่วนนี้จะเป็นจะเป็นฟังก์ชั่นในการเริ่มเกม การตั้งให้บอทเล่นก่อน และเป็นการเก็บบอร์ดเกมไว้ใช้งานต่ออีกด้วย
def next_turn(self):
if self.turn == self.AI:
self.query_AI()
else:
self.query_player()
self.turn = ~self.turn
โค้ดในส่วนนี้เป็นฟังก์ชั่นใช้ในการสลับเทิร์นของผู้เล่นและบอท
column = GUI.getHumanInteraction(self.board)
โค้ดส่วนนี้ใช่ในการตรวจสอบการวางหมากของผู้เล่นว่าตำแหน่งนั้นถูกต้องหรือไม่ และอัปเดตสถานะเกมปัจจุบันว่าเป็นอย่างไร
self.current_state = alphabeta_search(self.current_state, self.first, d=7)
โค้ดส่วนนี้ใช้ในการให้บอทนั้นใช้ Minimax และ Alpha-Beta Pruning ในการตัดสินใจในการในการเดินในทางที่ดีที่สุด
ขั้นตอนที่ 3 ตรวจสอบสถานะของเกม
def __init__(self, ai_position, game_position, depth=0):
self.ai_position = ai_position
self.game_position = game_position
self.depth = depth
โค้ดในส่วนนี้ตรวจสอบว่าในบอร์ดต่างๆ ของบอทในบอร์ดเช่นการลง bitboard ของผู้เล่น, จำนวณ bitboard และความลึกของ tree
ขั้นตอนที่ 4 ระบบการตัดสินใจของบอท
self.current_state = alphabeta_search(self.current_state, self.first, d=7)
โค้ดในส่วนนี้เป็นการตัดสินใจในการเล่นของบอทที่จะค้นหาที่ดีที่สุด โดยใช้ควบคู่ไปกับ Alpha-Beta Pruning ที่มีระดับความลึก 7 ขั้น
ขั้นตอนที่ 5 ระบบหน้าต่าง GUI ของเกม
if __name__ == "__main__":
print("Welcome to Connect Four!")
GUI.run()
while True:
# Set up a blank board data structure.
game_board = GUI.getNewBoard()
GUI.drawBoard(game_board)
GUI.updateDisplay()
# Start game data structure
game = Game(game_board)
while not game.is_game_over():
game.next_turn()
print_board(game.current_state)
GUI.drawBoard(game.board)
GUI.updateDisplay()
# Necessary for GUI
WINNER = '' if game.draw() else GUI.COMPUTER if ~game.turn == -1 else GUI.HUMAN
GUI.processGameOver(WINNER, game.board)
โค้ดส่วนนี้ทำหน้าที่ควบคุมหน้าต่าง GUI ตั้งแต่การเปิดหน้าต่างเกม การสลับเทิร์นผู้เล่น ขึ้นหน้า UI ผู้แพ้ชนะหรือเสมอ และการทำให้เกมนั้นเริ่มใหม่ได้ทันที่โดยไม่ต้องกด Run ใหม่
ตัวอย่างเพิ่มเติม
ในส่วนนี้เราจะทำการทดลองระบบเกม Connect 4 ในเครื่องของเราใน visual studio โดยใช้ python เวอร์ชั่น 3.10.9 เพื่อให้ library ทำงานได้ปกติ
ขั้นตอนที่ 1 การนำเข้า Module และSetting
from fourInARowGUI import fourInARowGUI as GUI
infinity = float('inf')
เป็นการนำเข้าโมดูลfourInARowGUI.py
ซึ่งอยู่ในโฟลเดอร์เดียวกัน ใน Module นี้จะมีฟังก์ชันทั้งหมดที่ใช้จัดการ กราฟิก, อินพุตของผู้เล่น และการแสดงผลเกม
ขั้นตอนที่ 2 สร้างคลาสในการควบคุมเกม
class Game:
AI = -1
PLAYER = 0
def __init__(self, game_board):
self.current_state = State(0, 0)
self.turn = self.AI
self.first = self.turn
self.board = game_board
โค้ดในส่วนนี้จะเป็นจะเป็นฟังก์ชั่นในการเริ่มเกม การตั้งให้บอทเล่นก่อน และเป็นการเก็บบอร์ดของเกมไว้ใช้งานต่ออีกครั้ง
def next_turn(self):
if self.turn == self.AI:
self.query_AI()
else:
self.query_player()
self.turn = ~self.turn
โค้ดในส่วนนี้เป็นฟังก์ชั่นใช้ในการสลับเทิร์นของผู้เล่นและบอท
column = GUI.getHumanInteraction(self.board)
โค้ดส่วนนี้ใช่ในการตรวจสอบการวางหมากของผู้เล่นว่าตำแหน่งนั้นถูกต้องหรือไม่ และอัปเดตสถานะเกมปัจจุบันว่าเป็นอย่างไร
self.current_state = alphabeta_search(self.current_state, self.first, d=7)
โค้ดส่วนนี้ใช้ในการให้บอทนั้นใช้ Minimax และ Alpha-Beta Pruning ในการตัดสินใจในการในการเดินในทางที่ดีที่สุด
ขั้นตอนที่ 3 ตรวจสอบสถานะของเกม
def __init__(self, ai_position, game_position, depth=0):
self.ai_position = ai_position
self.game_position = game_position
self.depth = depth
โค้ดในส่วนนี้ตรวจสอบว่าในบอร์ดต่างๆ ของบอทในบอร์ดเช่นการลง bitboard ของผู้เล่น, จำนวณ bitboard และความลึกของ tree
ขั้นตอนที่ 4 ระบบการตัดสินใจของบอท
self.current_state = alphabeta_search(self.current_state, self.first, d=7)
โค้ดในส่วนนี้เป็นการตัดสินใจในการเล่นของบอทที่จะค้นหาที่ดีที่สุด โดยใช้ควบคู่ไปกับ Alpha-Beta Pruning ที่มีระดับความลึก 7 ขั้น
ขั้นตอนที่ 5 ระบบหน้าต่าง GUI ของเกม
if __name__ == "__main__":
print("Welcome to Connect Four!")
GUI.run()
while True:
# Set up a blank board data structure.
game_board = GUI.getNewBoard()
GUI.drawBoard(game_board)
GUI.updateDisplay()
# Start game data structure
game = Game(game_board)
while not game.is_game_over():
game.next_turn()
print_board(game.current_state)
GUI.drawBoard(game.board)
# Necessary for GUI
WINNER = '' if game.draw() else GUI.COMPUTER if ~game.turn == -1 else GUI.HUMAN
GUI.processGameOver(WINNER, game.board)
โค้ดส่วนนี้ทำหน้าที่ควบคุมหน้าต่าง GUI ตั้งแต่การเปิดหน้าต่างเกม การสลับเทิร์นผู้เล่น ขึ้นหน้า UI ผู้แพ้ชนะหรือเสมอ และการทำให้เกมนั้นเริ่มใหม่ได้ทันที่โดยไม่ต้องกด Run ใหม่
ผลลัพธ์ที่ได้
จาก 2 ภาพนี้เราใช่วิธีเล่นเหมือนเดิมแต่ว่าบอทในภาพที่ 2 จะมีการเล่นที่ต่างจากภาพที่ 1 เล็กน้อย
ตัวอย่างอื่นๆที่เราทำการเล่นให้ชนะ
สรุปผล
จาการที่เราได้ทำการทดลองเล่นเกม Connect 4 แล้วทำให้เห็นว่าบอทนั้นมีความฉลาดเป็นอย่างมากเมื่อไหร่เราลงพลาด บอทก็จะสามารถชนะให้เราได้ทันทีเพราะว่าเส้นทางที่บอทที่ใช้ในการชนะเรามากกว่า 1 เส้นทางโดยใช้ Minimax และ Alpha-Beta Purring ในการหาเส้นทางที่สุดแต่อย่างไรก็ตามเราก็ยังสามารถชนะบอทได้เช่นกันถ้าเราสามารถคิดได้ว่าถ้าเราเลือกเส้นทางที่ดีที่สุดเหมือนกันก็จะเป็นตัดโอกาสให้บอทไม่สามารถชนะหรืออาจจะสามารถก็เป็นได้
Top comments (0)