เกม Domino ที่มี AI แบบง่ายด้วย Python
Published: 2023-04-11 08:46:02

_บางที่ก็ไม่จำเป็นต้องใช้ AI หรือ Machine learning, deep learning เสมอไป บางครั้งมันก็แค่การวางกฎอะไรที่ง่าย ๆ_

Domino คือเกมที่เล่นด้วยตัวหมาก ตัวหมากจะถูกแบ่งออกเป็น 2 ฝั่ง ที่มีเลขตั่งแต่ 0-6 ทั้ง 2 ด้าน มีทั้งหมด 28 ชิ้น
ถึงมันอาจจะดูเหมือนว่า มีทั้ง 49 ชิ้น เพราะ 7*7 =49 แต่ว่า Domino แบบ [1, 2] และ [2, 1] นับว่าเป็นตัวเดียวกันจึงไม่นับว่ามี 49 ชิ้น

ก่อนอื่น นี่คือวิธีที่ใช้ในการสร้าง deck ขึ้นมา

```

from random import shuffle
from itertools import combinations_with_replacement
# กำหนดจำนวน domino
dominoes = list(combinations_with_replacement(range(0, 7), 2))
# convert list of tuples to list of lists
dominoes = [list(x) for x in dominoes]
# สับ domino
shuffle(dominoes)
# define coefficient equal to half of the number of dominoes
coefficient = len(dominoes) // 2
# เอาครึ่งหนึ่งของ domino
stock_pieces = dominoes[:coefficient]
# แบ่งให้หมากให้ผู้เล่น และ computer
computer_pieces = dominoes[coefficient:int(coefficient * 1.5)]
player_pieces = dominoes[int(coefficient * 1.5):]
# หาตัวที่เหมือนกัน
snake = max([[x, y] for x, y in computer_pieces + player_pieces if x == y])
# เอาตัวที่เหมือนกันออกจากผู้เล่นและ computer
computer_pieces.remove(snake) if snake in computer_pieces else player_pieces.remove(snake)
```

ในตอนนี้ deck ใด้ถูกสร้างขึ้นมาแล้ว ซึ่งตัวหมากเรียงกันเป็นลำดับ ทำการสับ deck ด้วยวิธี shuffle เพื่อให้ตัวหมากไม่เรียงกัน จากนั้นแบ่ง deck เป็น 2 ส่วน และแบ่งส่วนที่ 2 ออกอีกเป็น 2 ส่วน ซึ่งจะได้ออกมาเป็น Stock, ผู้เล่น, computer
ต่อไปเป็นการคำนวนว่าใครจะเป็นคนวางส่วนหัว โดยผู้ที่วางคือ double domino ที่มีค่ามากที่สุด อย่างเช่น [6, 6] หรือ [5, 5]

```
# แสดงหมากของ stock, ผู้เล่น และ computer
print("Stock pieces:", stock_pieces)
print("Computer pieces:", computer_pieces)
print("Player pieces:", player_pieces)
print("Domino snake:", [snake])
# กำหนดคนเริ่มก่อน
print("Status:", "player" if len(player_pieces) > len(computer_pieces) else "computer")

# Stock pieces: [[5, 5], [0, 2], [3, 4], [0, 3], [3, 5], [6, 6], [1, 2], [0, 4], [2, 6], [1, 4], [3, 3], [1, 5], [3, 6], [0, 5]]
# Computer pieces: [[1, 1], [4, 5], [1, 6], [2, 3], [2, 2], [4, 6]]
# Player pieces: [[0, 1], [2, 5], [1, 3], [2, 4], [0, 0], [0, 6], [5, 6]]
# Domino snake: [[4, 4]]
# Status: player
```

หลังจากนั้นกำหนดผู้ที่เริ่มก่อน ซึ่งก็คือผู้ที่มีหมากมากที่สุด

**Interface**
สร้างหน้าจอเล่นเกม

```
from random import shuffle
from itertools import combinations_with_replacement
# กำหนด list domino
dominoes = list(combinations_with_replacement(range(0, 7), 2))
# เปลี่ยน list ของ tuples ให้เป็น list ของ lists
dominoes = [list(x) for x in dominoes]
# สับ domino
shuffle(dominoes)
# กำหนดค่า coefficient เท่ากับครึ่งหนึ่งของ domino
coefficient = len(dominoes) // 2
# เอาค่า domino ครึ่งแรก
stock_pieces = dominoes[:coefficient]
# เอาค่าหมากของ computer และผู้เล่น
computer_pieces = dominoes[coefficient:int(coefficient * 1.5)]
player_pieces = dominoes[int(coefficient * 1.5):]
# หางู(domino ที่วางเรียงกัน)
snake = max([[x, y] for x, y in computer_pieces + player_pieces if x == y])
# เอาตัวที่เหมือนกันออกจากผู้เล่นและ computer
computer_pieces.remove(snake) if snake in computer_pieces else player_pieces.remove(snake)
# ข้อความถึงผู้เล่น
player_turn = "It's your turn to make a move. Enter your command."
computer_turn = "Computer is about to make a move. Press Enter to continue..."
# แสดงหมากของ stock, ผู้เล่น และ computer
print('=' * 70)
print('Stock size:', len(stock_pieces))
print('Computer pieces:', len(computer_pieces), '\n')
print(snake, '\n')
# แสดงหมาดของผู้เล่น
print("Your pieces:")
for num, piece in enumerate(player_pieces):
    print(f"{num + 1}: {piece}")
# หาคนเริ่มก่อน
print("\nStatus:", player_turn if len(player_pieces) > len(computer_pieces) else computer_turn)

======================================================================
# Stock size: 14
# Computer pieces: 6
#
# [3, 3]
#
# Your pieces:
# 1: [1, 1]
# 2: [0, 6]
# 3: [0, 4]
# 4: [2, 6]
# 5: [4, 6]
# 6: [3, 5]
# 7: [0, 2]
#
# Status: It's your turn to make a move. Enter your command.

```
**ตัวเกม**
domino นั้นสามารถวางทางซ้ายหรือขวาก็ได้ของตัวงู และผู้เล่นสามารถหยิบหมากชิ้นใหม่จาก deck ได้
ที่นี้มาเขียนโค้ดที่เลือกชิ้นส่วนจากตัวงู ค่าลบหมายถึงทางซ้ายของหัวงู ค่าบวกคือชิ้นทางขวาจากหัวงู ซึ่งจะถือว่างูชนะถ้ามีเลขเดียวกันกับหัวงูอยู่ในตัวครบ 8 ครั้ง
นอกจากนี้ การชนะเกมดูจากการที่ผู้ลเล่นคนไหนหมดตัวหมากแล้ว
เริ่มจากการสร้าง AI ที่เคลื่อนตำแหน่งแบบสุ่ม

```

from random import shuffle, choice
from itertools import combinations_with_replacement
# function กำหนด turn
def turn_func(func_input, func_pieces):
    # หยุดถ้าไม่มีหมากแล้ว
    if int(func_input) == 0 and len(stock_pieces) == 0:
        return None
    # เอาหมากให้ผู้เล่น
    elif int(func_input) == 0 and len(stock_pieces) > 0:
        func_pieces.append(stock_pieces[-1])
        stock_pieces.remove(stock_pieces[-1])
        return None
    # วางหมากทางขวางู
    if len(func_input) == 1:
        snake.append(func_pieces[int(func_input) - 1])
        func_pieces.remove(func_pieces[int(func_input) - 1])
    # วางหมากทางซ้ายงู
    else:
        snake.insert(0, func_pieces[-int(func_input) - 1])
        func_pieces.remove(func_pieces[-int(func_input) - 1])
# ตรวจว่างูชนะหรือไม่
def win_snake(func_snake):
    if func_snake[0][0] == func_snake[-1][-1] and sum(x.count(func_snake[0][0]) for x in func_snake) == 8:
        return True
# กำหนด list domino
dominoes = list(combinations_with_replacement(range(0, 7), 2))
# เปลี่ยน list ของ tuples ให้เป็น list ของ lists
dominoes = [list(x) for x in dominoes]
# สับ domino
shuffle(dominoes)
# เอาค่าหมากของ computer และผู้เล่น
coefficient = len(dominoes) // 2
# เอาค่า domino ครึ่งแรก
stock_pieces = dominoes[:coefficient]
# เอาค่าหมากของ computer และผู้เล่น
computer_pieces = dominoes[coefficient:int(coefficient * 1.5)]
player_pieces = dominoes[int(coefficient * 1.5):]
# หางู(domino ที่วางเรียงกัน)
snake = max([[x, y] for x, y in computer_pieces + player_pieces if x == y])
# เอาตัวที่เหมือนกันออกจากผู้เล่นและ computer
computer_pieces.remove(snake) if snake in computer_pieces else player_pieces.remove(snake)
# ข้อความถึงผู้เล่น
player_turn = "It's your turn to make a move. Enter your command."
computer_turn = "Computer is about to make a move. Press Enter to continue..."
# กำหนดคนเริ่ม
turn_num = 0 if len(player_pieces) > len(computer_pieces) else 1
# เริ่มเกม
while True:
    # แสดงหมากของ stock, player และ computer
    print('=' * 70)
    print('Stock size:', len(stock_pieces))
    print('Computer pieces:', len(computer_pieces), '\n')
    print(*snake, '\n', sep='') if len(snake) <= 6 else print(*snake[:3], '...', *snake[-3:], '\n', sep='')
    print("Your pieces:")
    for num, piece in enumerate(player_pieces):
        print(f"{num + 1}: {piece}")
    # กำหนดผูเ้ล่นเป็นคนชนะเมื่อไม่มีหมากแล้ว
    if len(player_pieces) == 0:
        print("\nStatus: The game is over. You won!")
        break
    # กำหนด computer เป็นคนชนะเมื่อไม่มีหมากแล้ว
    if len(computer_pieces) == 0:
        print("\nStatus: The game is over. The computer won!")
        break
    # กำหนดผูเ้ล่นเป็นคนชนะเมื่องูชนะ
    if win_snake(snake) and turn_num == 0:
        print("\nStatus: The game is over. You won!")
        break
    # กำหนด computer เป็นคนชนะเมื่องูชนะ
    if win_snake(snake) and turn_num == 1:
        print("\nStatus: The game is over. The computer won!")
        break
    # กำหนด turn ผู้เล่น
    if turn_num % 2 == 0:
        # นับ turn
        turn_num += 1
        # แสดงข้ออความถึงผู้เล่น
        print("\nStatus:", player_turn)
        # รับค่าจากผู้เล่น
        user_input = input()
        # ตรวจว่าผู้เล่นใส่ค่าถูกหรือไม่
        if user_input.isdigit() and int(user_input) in range(-len(player_pieces), len(player_pieces) + 1):
            turn_func(user_input, player_pieces)
        else:
            print("Invalid input. Please try again.")
            turn_num -= 1
            continue
    # กำหนด turn computer
    else:
        # นับ turn
        turn_num += 1
        # แสดงข้อความถึง computer
        print("\nStatus:", computer_turn)
        # wait for player's input
        input()
        # รับค่าจาก computer
        computer_choice = str(choice(range(-len(computer_pieces), len(computer_pieces) + 1)))
        # computer วางหมาก
        turn_func(computer_choice, computer_pieces)
```
ฟังก์ชันแรกที่เพิ่มเข้ามาจะใช้ในการจั่วหมากจาก deck และวางหมากทางซ้ายงู หรือทางขวางู ฟังก์ชันที่ 2 ใช้ในการตรวจสอบว่างูชนะหรือไม่
ที่นี้ลองเล่น 3 ตาดู
ซึ่ง game loop ได้ใส่เข้ามาเพิ่มเพื่อเช็กคนที่ชนะ และตรวจสอบการวางหมากของผู้เล่น
ผลที่ได้:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htr7zauxluofdzp5vbh0.jpg)
ซึ่งตอนนี้มันยังไม่เสร็จจึงยังมีข้อผิดพลาดอยู่ ทำให้วางหมากแบบที่ค่าไม่ต่อกันได้ 
ซึ่งต่อไปคือการใส่กฎการเล่น

**กฎการเล่น**
กฎก็คือการวางตัวแรกที่เหมือนกันให้ต่อกัน เช่น [3, 4], [4, 4], [4, 2] นอกจากนี้ยังสามารถสลับฝั่งตัวหมากเพื่อวางตัวเลขที่เหมือนกันได้

```
from random import shuffle
from itertools import combinations_with_replacement
# function กำหนด turn
def turn_func(func_input, func_pieces):
    # หยุดเมื่อไม่มีหมากแล้ว
    if int(func_input) == 0 and len(stock_pieces) == 0:
        return None
    # เอาหมากให้ผู้เล่น
    elif int(func_input) == 0 and len(stock_pieces) > 0:
        func_pieces.append(stock_pieces[-1])
        stock_pieces.remove(stock_pieces[-1])
        return None
    # วางหมากทางขวางู
    if int(func_input) > 0:
        # รับหมากจากผู้เล่นหรือ computer
        piece_to_end = func_pieces[int(func_input) - 1]
        # สลับด้านหมาด
        if piece_to_end[1] == snake[-1][-1]:
            piece_to_end.reverse()
        # วางหมาก
        snake.append(piece_to_end)
        # เอาหมากออกจากผู้เล่นหรือ computer
        func_pieces.remove(func_pieces[int(func_input) - 1])
    # วางหมากทางซ้ายงู
    else:
        # รับหมากจากผู้เล่นหรือ computer
        piece_to_start = func_pieces[-int(func_input) - 1]
        # สลับด้านหมาด
        if piece_to_start[0] == snake[0][0]:
            piece_to_start.reverse()
        # วางหมาก
        snake.insert(0, piece_to_start)
        # เอาหมากออกจากผู้เล่นหรือ computer
        func_pieces.remove(func_pieces[-int(func_input) - 1])
# ตรวจสอบว่างูขนะหรือไม่
def win_snake(func_snake):
    if func_snake[0][0] == func_snake[-1][-1] and sum(x.count(func_snake[0][0]) for x in func_snake) == 8:
        return True
# กำหนด list domino
dominoes = list(combinations_with_replacement(range(0, 7), 2))
# เปลี่ยน list ของ tuples ให้เป็น list ของ lists
dominoes = [list(x) for x in dominoes]
# สับ domino
shuffle(dominoes)
# เอาค่าหมากของ computer และผู้เล่น
coefficient = len(dominoes) // 2
# เอาค่า domino ครึ่งแรก
stock_pieces = dominoes[:coefficient]
# เอาหมากจากผู้เล่นหรือ computer
computer_pieces = dominoes[coefficient:int(coefficient * 1.5)]
player_pieces = dominoes[int(coefficient * 1.5):]
# หางู
snake = [max([[x, y] for x, y in computer_pieces + player_pieces if x == y])]
# เอาตัวที่เหมือนกันออกจากผู้เล่นและ computer
computer_pieces.remove(snake[0]) if snake[0] in computer_pieces else player_pieces.remove(snake[0])
# ข้อความถึงผู้เล่นและ computer
player_turn = "It's your turn to make a move. Enter your command."
computer_turn = "Computer is about to make a move. Press Enter to continue..."
player_won = 'The game is over. You won!'
computer_won = 'The game is over. The computer won!'
# กำหนดคนเริ่ม
turn_num = 0 if len(player_pieces) > len(computer_pieces) else 1
# เริ่มเกม
while True:
    # แสดงหมากของ stock, player และ computer
    print('=' * 70)
    print('Stock size:', len(stock_pieces))
    print('Computer pieces:', len(computer_pieces), '\n')
    print(*snake, '\n', sep='') if len(snake) <= 6 else print(*snake[:3], '...', *snake[-3:], '\n', sep='')
    print("Your pieces:")
    for num, piece in enumerate(player_pieces):
        print(f"{num + 1}: {piece}")

    # กำหนดผู้เล่นเป็นคนชนะเมื่อไม่มีหมากแล้ว
    if len(player_pieces) == 0:
        print("\nStatus:", player_won)
        break
    # กำหนด computer เป็นคนชนะเมื่อไม่มีหมากแล้ว
    if len(computer_pieces) == 0:
        print("\nStatus:", computer_won)
        break
    # กำหนดผู้เล่นเป็นคนชนะเมื่องูชนะ
    if win_snake(snake) and turn_num == 0:
        print("\nStatus:", player_won)
        break
    # กำหนด computer เป็นคนชนะเมื่องูชนะ
    if win_snake(snake) and turn_num == 1:
        print("\nStatus:", computer_won)
        break
    # กำหนดส่วนสุดท้ายของงู
    connection_keys = [snake[0][0], snake[-1][-1]]
    # เงื่อนไขในการจั่ว
    if len(stock_pieces) == 0 and \
            any([verb[1] for verb in player_pieces + computer_pieces if verb[0] in connection_keys]):
        print("\nStatus: The game is over. It's a draw!")
        break
    # turn ของผู้เล่น
    if turn_num % 2 == 0:
        # นับ turn
        turn_num += 1
        # แสดงข้อความ
        print("\nStatus:", player_turn)
        # รับค่าของผู้เล่น
        user_input = input()
        # ตรวจสอบว่าผู้เล่นให้ค่าถูกหรือไม่
        if user_input.lstrip("-").isdigit() and int(user_input) in range(-len(player_pieces), len(player_pieces) + 1):
            # นำหมากให้ผู้เล่น
            if int(user_input) == 0:
                turn_func(user_input, player_pieces)
                continue
            # กำหนดค่าหมากปัจจุบัน
            current_piece = player_pieces[int(user_input) - 1] if int(user_input) > 0 \
                else player_pieces[-int(user_input) - 1]
            # ตรวจสอบว่าหมากถูกต้องไหม
            if connection_keys[-1] in current_piece and int(user_input) > 0 or \
                    connection_keys[0] in current_piece and int(user_input) < 0:
                turn_func(user_input, player_pieces)
            else:
                print("Illegal move. Please try again.")
                turn_num -= 1
                continue
        else:
            print("Invalid input. Please try again.")
            turn_num -= 1
            continue
    # turn ของ computer
    else:
        # นับ turn
        turn_num += 1
        # แสดงข้อความ
        print("\nStatus:", computer_turn)
        # รอค่าจากผู้เล่น
        input()
        # ให้ computer วางหมาก
        for piece in computer_pieces:
            # จรวจสอบว่าหมากนั้นเลขตรงกันไหม
            if piece[0] == connection_keys[-1]:
                turn_func(str(computer_pieces.index(piece) + 1), computer_pieces)
                break
            elif piece[1] == connection_keys[0]:
                turn_func(str(-computer_pieces.index(piece) - 1), computer_pieces)
                break
        # นำหมากให้ computer
        else:
            turn_func('0', computer_pieces)
```

ตอนนี้ฟังก์ชันได้ถูกเพิ่มเข้ามาแล้ว ทำให้สามารถสลับด้านตัวหมากได้เพื่อต่อเข้ากับปลายงูให้ถูกต้อง 
มีการเพิ่มเงื่อนไขของผู้เล่น และศัตรูให้สามารถวางหมากได้ตามที่กฎกำหนดเอาไว้เท่านั้น
ตอนนี้เกมพร้อมแล้ว คุณสามารถอัปโหลดโค้ดด้านบนไปยัง IDE ของคุณแล้วเล่นได้เลย ซึ่ง AI ทำงานได้ดีมากในการเล่นแบบสุ่ม ขอรับประกัน

**AI**
กลยุทธ์ในเกมนี้คือการเลือกว่า domino ตัวไหนมีค่าน้อยที่สุดและกำจัดมันไป เพื่อลดโอกาศที่จะเล่นพลาดลงผู้เล่นต้องทำให้หมากในมือมีความหลากหลายมาก ด้วยแนวคิดนี้ AI จะคำนวนโอกาศที่หมากแต่ละตัวจะลงได้ผ่านความหายากของตัวหมาก ยิ่งหายากยิ่งค่าน้อย ตัวหมากที่หาได้ง่ายจะมีค่าที่มากกว่า

```
from itertools import combinations_with_replacement, chain
from collections import Counter
# function กำหนด turn
def turn_func(func_input, func_pieces):
    # หยุดเมื่อไม่มีหมากแล้ว
    if int(func_input) == 0 and len(stock_pieces) == 0:
        return None
    # เอาหมากให้ผู้เล่น
    elif int(func_input) == 0 and len(stock_pieces) > 0:
        func_pieces.append(stock_pieces[-1])
        stock_pieces.remove(stock_pieces[-1])
        return None
    # วางหมากทางขวางู
    if int(func_input) > 0:
        # รับหมากจากผู้เล่นหรือ computer
        piece_to_end = func_pieces[int(func_input) - 1]
        # สลับด้านหมาด
        if piece_to_end[1] == snake[-1][-1]:
            piece_to_end.reverse()
        # วางหมาก
        snake.append(piece_to_end)
        # เอาหมากออกจากผู้เล่นหรือ computer
        func_pieces.remove(func_pieces[int(func_input) - 1])
    # วางหมากทางซ้ายงู
    else:
        # รับหมากจากผู้เล่นหรือ computer
        piece_to_start = func_pieces[-int(func_input) - 1]
        # สลับด้านหมาด
        if piece_to_start[0] == snake[0][0]:
            piece_to_start.reverse()
        # วางหมาก
        snake.insert(0, piece_to_start)
        # เอาหมากออกจากผู้เล่นหรือ computer
        func_pieces.remove(func_pieces[-int(func_input) - 1])
# ตรวจสอบว่างูขนะหรือไม่
def win_snake(func_snake):
    if func_snake[0][0] == func_snake[-1][-1] and sum(x.count(func_snake[0][0]) for x in func_snake) == 8:
        return True
# กำหนด list domino
dominoes = list(combinations_with_replacement(range(0, 7), 2))
# เปลี่ยน list ของ tuples ให้เป็น list ของ lists
dominoes = [list(x) for x in dominoes]
# สับ domino
shuffle(dominoes)
# เอาค่าหมากของ computer และผู้เล่น
coefficient = len(dominoes) // 2
# เอาค่า domino ครึ่งแรก
stock_pieces = dominoes[:coefficient]
# เอาหมากจากผู้เล่นหรือ computer
computer_pieces = dominoes[coefficient:int(coefficient * 1.5)]
player_pieces = dominoes[int(coefficient * 1.5):]
# หางู
snake = [max([[x, y] for x, y in computer_pieces + player_pieces if x == y])]
# เอาตัวที่เหมือนกันออกจากผู้เล่นและ computer
computer_pieces.remove(snake[0]) if snake[0] in computer_pieces else player_pieces.remove(snake[0])
# กำหนดคนเริ่ม
turn_num = 0 if len(player_pieces) > len(computer_pieces) else 1
# เริ่มเกม
while True:
    # แสดงหมากของ stock, player และ computer
    print('=' * 70)
    print('Stock size:', len(stock_pieces))
    print('Computer pieces:', len(computer_pieces), '\n')
    print(*snake, '\n', sep='') if len(snake) <= 6 else print(*snake[:3], '...', *snake[-3:], '\n', sep='')
    print("Your pieces:")
    for num, piece in enumerate(player_pieces):
        print(f"{num + 1}: {piece}")
    # เงื่อนไขการชนะของผู้เล่น
    if len(player_pieces) == 0 or win_snake(snake) and turn_num == 0:
        print("\nStatus: The game is over. You won!")
        break
    # เงื่อนไขการชนะของ computer
    if len(computer_pieces) == 0 or win_snake(snake) and turn_num == 1:
        print("\nStatus: The game is over. The computer won!")
        break
    # กำหนดปลายของงู
    connection_keys = [snake[0][0], snake[-1][-1]]
    # เงื่อนไขการเสมอ
    if len(stock_pieces) == 0 and \
            not any(item in connection_keys for item in list(chain(*(player_pieces + computer_pieces)))):
        print("\nStatus: The game is over. It's a draw!")
        break
    # turn ของผู้ล่น
    if turn_num % 2 == 0:
        # นับ turn
        turn_num += 1
        # แสดงข้อความ
        print("\nStatus: It's your turn to make a move. Enter your command.")
        # รับค่าจากผู้เล่น
        user_input = input()
        # ตรวจสอบค่าจากผู้เล่นว่าถูกต้องไหม
        if user_input.lstrip("-").isdigit() and int(user_input) in range(-len(player_pieces), len(player_pieces) + 1):
            # นำหมากให้ผู้เล่น
            if int(user_input) == 0:
                turn_func(user_input, player_pieces)
                continue
            # กำหนดค่าหมากปัจจุบัน
            current_piece = player_pieces[int(user_input) - 1] if int(user_input) > 0 \
                else player_pieces[-int(user_input) - 1]
            # ตรวจสอบว่าหมากถูกต้องไหม
            if connection_keys[-1] in current_piece and int(user_input) > 0 or \
                    connection_keys[0] in current_piece and int(user_input) < 0:
                turn_func(user_input, player_pieces)
            else:
                print("Illegal move. Please try again.")
                turn_num -= 1
                continue
        else:
            print("Invalid input. Please try again.")
            turn_num -= 1
            continue
    # turn ของ computer
    else:
        # นับ turn
        turn_num += 1
        # แสดงข้อความ
        print("\nStatus: Computer is about to make a move. Press Enter to continue...")
        # รอค่าจากผู้เล่น
        input()
        # นับจำนวนหมากของ computer และงู
        count_nums = Counter(chain(*(computer_pieces + snake)))
        # กำหนดค่าของหมากแต่ละตัว
        scores = list()
        # กำหนดค่าของหมากทั้งหมด
        for piece in computer_pieces:
            score = count_nums[piece[0]] + count_nums[piece[1]]
            scores.append(score)
        # เรียงละดับหมากตามคะแนน
        computer_pieces = [x for _, x in sorted(zip(scores, computer_pieces), reverse=True)]
        # computer วางหมาก
        for piece in computer_pieces:
            # ตรวจสอบว่าสามารถสาวหมากที่ปลายงูได้ไหม
            if connection_keys[-1] in piece:
                turn_func(str(computer_pieces.index(piece) + 1), computer_pieces)
                break
            elif connection_keys[0] in piece:
                turn_func(str(-computer_pieces.index(piece) - 1), computer_pieces)
                break
        # นำหมากให้ แนทยีะำพ
        else:
            turn_func('0', computer_pieces)
```
การปรับปรุงวิธีการเล่นของ computer เพียงเล็กน้อยทำให้มันเล่นได้ฉลาดมากขึ้น

1. AI จะนับจำนวนหมายเลขของหมากแต่ละตัวใน deck และที่ลงไปแล้ว
2. AI จะกำหนดคะแนนให้ domino แต่ละตัวใน deck เท่ากับผลรวมของเลขที่ลงไปแล้วก่อนหน้านั้น

ตัวอย่าง:
หมาก Computer: [2, 5], [3, 5], [0, 5]
งู Domino: [4, 4], [4, 2], [2, 1], [1, 0], [0, 0], [0, 2]
นับว่าตัวเลขแต่ละตัวออกไปกี่ครั้งแล้ว: 0: 5, 1: 2, 2: 4, 3: 1, 4: 3, 5: 3, 6: 0.
คำนวนคะแนนหมาก:
[2, 5]: 4 + 3 = 7
[3, 5]: 1 + 3 = 4
[0, 5]: 5 + 3 = 8
Domino ที่มีคะแนนสูงสุด [0, 5] จะถูกนำไปเล่นก่อน เพราะต้องกำจัดมันเป็นสิ่งแร

**ผลที่ได้**

```
======================================================================
Stock size: 14
Computer pieces: 6
[1, 1]
Your pieces:
1: [3, 4]
2: [0, 1]
3: [5, 6]
4: [4, 6]
5: [1, 6]
6: [1, 5]
7: [1, 4]
Status: It's your turn to make a move. Enter your command.
> 2
======================================================================
Stock size: 14
Computer pieces: 6
[1, 1][1, 0]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 5]
6: [1, 4]
Status: Computer is about to make a move. Press Enter to continue...
>
======================================================================
Stock size: 14
Computer pieces: 5
[1, 1][1, 0][0, 0]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 5]
6: [1, 4]
Status: It's your turn to make a move. Enter your command.
> 6
Illegal move. Please try again.
======================================================================
Stock size: 14
Computer pieces: 5
[1, 1][1, 0][0, 0]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 5]
6: [1, 4]
Status: It's your turn to make a move. Enter your command.
>
Invalid input. Please try again.
======================================================================
Stock size: 14
Computer pieces: 5
[1, 1][1, 0][0, 0]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 5]
6: [1, 4]
Status: It's your turn to make a move. Enter your command.
> -5
======================================================================
Stock size: 14
Computer pieces: 5
[5, 1][1, 1][1, 0][0, 0]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 4]
Status: Computer is about to make a move. Press Enter to continue...
>
======================================================================
Stock size: 14
Computer pieces: 4
[5, 1][1, 1][1, 0][0, 0][0, 2]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 4]
Status: It's your turn to make a move. Enter your command.
> 2
Illegal move. Please try again.
======================================================================
Stock size: 14
Computer pieces: 4
[5, 1][1, 1][1, 0][0, 0][0, 2]
Your pieces:
1: [3, 4]
2: [5, 6]
3: [4, 6]
4: [1, 6]
5: [1, 4]
Status: It's your turn to make a move. Enter your command.
> -2
======================================================================
Stock size: 14
Computer pieces: 4
[6, 5][5, 1][1, 1][1, 0][0, 0][0, 2]
Your pieces:
1: [3, 4]
2: [4, 6]
3: [1, 6]
4: [1, 4]
Status: Computer is about to make a move. Press Enter to continue...
>
======================================================================
Stock size: 14
Computer pieces: 3
[6, 5][5, 1][1, 1]...[0, 0][0, 2][2, 6]
Your pieces:
1: [3, 4]
2: [4, 6]
3: [1, 6]
4: [1, 4]
Status: It's your turn to make a move. Enter your command.
> 2
======================================================================
Stock size: 14
Computer pieces: 3
[6, 5][5, 1][1, 1]...[0, 2][2, 6][6, 4]
Your pieces:
1: [3, 4]
2: [1, 6]
3: [1, 4]
Status: Computer is about to make a move. Press Enter to continue...
>
======================================================================
Stock size: 14
Computer pieces: 2
[6, 5][5, 1][1, 1]...[2, 6][6, 4][4, 5]
Your pieces:
1: [3, 4]
2: [1, 6]
3: [1, 4]
Status: It's your turn to make a move. Enter your command.
> -2
======================================================================
Stock size: 14
Computer pieces: 2
[1, 6][6, 5][5, 1]...[2, 6][6, 4][4, 5]
Your pieces:
1: [3, 4]
2: [1, 4]
Status: Computer is about to make a move. Press Enter to continue...
>
======================================================================
Stock size: 14
Computer pieces: 1
[3, 1][1, 6][6, 5]...[2, 6][6, 4][4, 5]
Your pieces:
1: [3, 4]
2: [1, 4]
Status: It's your turn to make a move. Enter your command.
> 1
Illegal move. Please try again.
======================================================================
Stock size: 14
Computer pieces: 1
[3, 1][1, 6][6, 5]...[2, 6][6, 4][4, 5]
Your pieces:
1: [3, 4]
2: [1, 4]
Status: It's your turn to make a move. Enter your command.
> -1
======================================================================
Stock size: 14
Computer pieces: 1
[4, 3][3, 1][1, 6]...[2, 6][6, 4][4, 5]
Your pieces:
1: [1, 4]
Status: Computer is about to make a move. Press Enter to continue...
>
======================================================================
Stock size: 14
Computer pieces: 0
[4, 3][3, 1][1, 6]...[6, 4][4, 5][5, 3]
Your pieces:
1: [1, 4]
Status: The game is over. The computer won!
```
Computer เป็นผู้ชนะ
โค้ดตัวเต็ม: https://github.com/AXEG0/dominoes_game_with_ai

Reference
https://medium.com/@axegggl/dominoes-game-with-simple-ai-in-python-df7f62feab4