這個井字棋遊戲專案採用 Python 語言開發,結合了基礎遊戲邏輯和 AI 演算法,讓玩家可以與電腦進行對戰。遊戲介面以文字形式呈現,玩家透過輸入數字選擇落子位置。電腦 AI 則會根據當前棋盤狀態,選擇最佳落子策略,力求獲勝或阻止玩家獲勝。程式碼中包含了遊戲初始化、玩家輸入處理、AI 策略實作、勝利判斷、平局判斷以及遊戲迴圈等核心功能。此外,程式碼也進行了最佳化,提升遊戲執行效率。

人工智慧在井字棋中的應用

井字棋是一種簡單卻富有挑戰性的遊戲,人工智慧(AI)可以被應用於此以建立一個可以與人類玩家對戰的智慧對手。以下是如何實作這一點的詳細解釋。

遊戲環境設定

首先,我們需要設定遊戲環境。這包括定義遊戲板、玩家選擇和可用位置等。

def print_board(board, avail):
    print(" " + "-----------" + " " + "-----------")
    print(" " + " {} | {} | {} ".format(board[1], board[2], board[3]) + " "
          + " {} | {} | {} ".format(avail[1], avail[2], avail[3]))

玩家選擇

玩家可以透過輸入1-9之間的數字來選擇他們的下一步位置。

def player_choice(board, name, choice):
    position = 0
    while position not in [1, 2, 3, 4, 5, 6, 7, 8, 9] or not space_check(board, position):
        position = int(input(f'\n{name} ({choice}), Choose your next position: (1-9) \t'))
        if position not in [1, 2, 3, 4, 5, 6, 7, 8, 9] or not space_check(board, position) or position == "":
            print(f"INVALID INPUT. Please Try Again!\n")
    return position

AI 選擇

現在,我們來實作 AI 的選擇。AI 會掃描所有可能的位置,並根據贏得遊戲或阻止對手贏得遊戲的策略進行選擇。

def CompAI(board, name, choice):
    position = 0
    possibilities = [x for x, letter in enumerate(board) if letter == ' ' and x != 0]
    
    for let in ['O', 'X']:
        for i in possibilities:
            boardCopy = board[:]
            boardCopy[i] = let
            if win_check(boardCopy, let):
                # 如果找到贏得遊戲的位置,立即傳回
                if let == choice:
                    return i
                # 如果找到對手贏得遊戲的位置,阻止對手
                elif let != choice:
                    return i
    # 如果沒有找到贏得或阻止對手贏得的位置,隨機選擇一個位置
    import random
    return random.choice(possibilities)

贏得遊戲的檢查

最後,我們需要實作一個函式來檢查是否有一方贏得了遊戲。

def win_check(board, letter):
    winning_combos = [(1, 2, 3), (4, 5, 6), (7, 8, 9), (1, 4, 7), (2, 5, 8), (3, 6, 9), (1, 5, 9), (3, 5, 7)]
    for combo in winning_combos:
        if board[combo[0]] == board[combo[1]] == board[combo[2]] == letter:
            return True
    return False

空間檢查

我們還需要一個函式來檢查一個位置是否空。

def space_check(board, position):
    return board[position] == ' '

主遊戲迴圈

現在,我們可以實作主遊戲迴圈了。

def main():
    board = [' ' for _ in range(10)]
    avail = [' ' for _ in range(10)]
    while True:
        print_board(board, avail)
        player_pos = player_choice(board, 'Player', 'X')
        board[player_pos] = 'X'
        if win_check(board, 'X'):
            print_board(board, avail)
            print("Player wins!")
            break
        avail_pos = CompAI(board, 'Computer', 'O')
        board[avail_pos] = 'O'
        if win_check(board, 'O'):
            print_board(board, avail)
            print("Computer wins!")
            break

if __name__ == "__main__":
    main()

這個實作提供了一個基本的井字棋遊戲,玩家可以與 AI 對戰。AI 的選擇根據簡單的贏得或阻止對手贏得的策略,未來可以進一步最佳化。

Tic Tac Toe 遊戲開發

Tic Tac Toe 是一種簡單的棋盤遊戲,兩位玩家輪流下棋,先形成三棋子連線的玩家獲勝。以下是使用 Python 開發的 Tic Tac Toe 遊戲邏輯。

遊戲邏輯

import random

def selectRandom(possibilities):
    # 選擇一個隨機位置
    ln = len(possibilities)
    r = random.randrange(0, ln)
    return possibilities[r]

def place_marker(board, avail, choice, position):
    # 在棋盤上放置棋子
    board[position] = choice
    avail[position] = ' '

def space_check(board, position):
    # 檢查位置是否空閒
    return board[position] == ' '

def full_board_check(board):
    # 檢查棋盤是否滿
    for i in range(1, 10):
        if space_check(board, i):
            return False
    return True

def get_open_corners(board):
    # 取得空閒的角落位置
    openCorners = [x for x in [1, 3, 7, 9] if x in board]
    return openCorners

def get_open_edges(board):
    # 取得空閒的邊緣位置
    openEdges = [x for x in [2, 4, 6, 8] if x in board]
    return openEdges

def get_position(board):
    # 取得下一步的位置
    possibilities = [x for x in range(1, 10) if space_check(board, x)]
    openCorners = get_open_corners(possibilities)
    if len(openCorners) > 0:
        position = selectRandom(openCorners)
        return position
    if 5 in possibilities:
        position = 5
        return position
    openEdges = get_open_edges(possibilities)
    if len(openEdges) > 0:
        position = selectRandom(openEdges)
        return position

內容解密:

上述程式碼定義了 Tic Tac Toe 遊戲的基本邏輯,包括選擇隨機位置、放置棋子、檢查位置是否空閒、檢查棋盤是否滿,以及取得空閒的角落和邊緣位置。這些函式將被用於實作遊戲的 AI 玩家。

圖表翻譯:

  flowchart TD
    A[開始] --> B[取得空閒位置]
    B --> C[檢查角落位置]
    C --> D[檢查邊緣位置]
    D --> E[選擇隨機位置]
    E --> F[放置棋子]
    F --> G[檢查棋盤是否滿]
    G --> H[遊戲結束]

圖表翻譯:

此圖表展示了 Tic Tac Toe 遊戲的基本流程,從取得空閒位置開始,然後檢查角落位置和邊緣位置,選擇隨機位置,放置棋子,檢查棋盤是否滿,最後結束遊戲。

程式碼解說:

程式碼使用 Python 實作,定義了多個函式來實作遊戲邏輯。selectRandom 函式用於選擇隨機位置,place_marker 函式用於放置棋子,space_check 函式用於檢查位置是否空閒,full_board_check 函式用於檢查棋盤是否滿。get_open_cornersget_open_edges 函式用於取得空閒的角落和邊緣位置。get_position 函式用於取得下一步的位置。

Tic Tac Toe 遊戲實作

遊戲邏輯與實作

Tic Tac Toe 是一種簡單的兩人遊戲,玩家輪流在 3x3 的棋盤上放置符號(通常為 X 和 O)。以下是遊戲的基本邏輯和實作:

棋盤初始化

def initialize_board():
    # 建立一個 3x3 的棋盤
    board = [' ']*10
    return board

玩家輸入與棋盤更新

def update_board(board, player, position):
    # 更新棋盤上的玩家符號
    board[position] = player
    return board

勝利條件檢查

def win_check(board, player):
    # 檢查水平、垂直和對角線勝利條件
    winning_conditions = [
        (1, 2, 3), (4, 5, 6), (7, 8, 9),  # 水平
        (1, 4, 7), (2, 5, 8), (3, 6, 9),  # 垂直
        (1, 5, 9), (3, 5, 7)  # 對角線
    ]
    for condition in winning_conditions:
        if board[condition[0]] == board[condition[1]] == board[condition[2]] == player:
            return True
    return False

遊戲迴圈

def game_loop():
    board = initialize_board()
    players = ['X', 'O']
    current_player = 0
    while True:
        # 顯示棋盤
        print_board(board)
        # 玩家輸入
        position = input("Player {}, enter your position: ".format(players[current_player]))
        # 更新棋盤
        board = update_board(board, players[current_player], int(position))
        # 檢查勝利條件
        if win_check(board, players[current_player]):
            print("Player {} wins!".format(players[current_player]))
            break
        # 切換玩家
        current_player = (current_player + 1) % 2

程式碼最佳化與重構

def print_board(board):
    # 顯示棋盤
    print(" {} | {} | {} ".format(board[1], board[2], board[3]))
    print("---+---+---")
    print(" {} | {} | {} ".format(board[4], board[5], board[6]))
    print("---+---+---")
    print(" {} | {} | {} ".format(board[7], board[8], board[9]))

def game_loop():
    board = [' ']*10
    players = ['X', 'O']
    current_player = 0
    while True:
        print_board(board)
        position = input("Player {}, enter your position: ".format(players[current_player]))
        board[int(position)] = players[current_player]
        if (
            (board[1] == board[2] == board[3] == players[current_player]) or
            (board[4] == board[5] == board[6] == players[current_player]) or
            (board[7] == board[8] == board[9] == players[current_player]) or
            (board[1] == board[4] == board[7] == players[current_player]) or
            (board[2] == board[5] == board[8] == players[current_player]) or
            (board[3] == board[6] == board[9] == players[current_player]) or
            (board[1] == board[5] == board[9] == players[current_player]) or
            (board[3] == board[5] == board[7] == players[current_player])
        ):
            print("Player {} wins!".format(players[current_player]))
            break
        current_player = (current_player + 1) % 2

game_loop()

圖表翻譯:

此圖示為 Tic Tac Toe 遊戲的勝利條件檢查流程。

  flowchart TD
    A[開始] --> B[玩家輸入]
    B --> C[更新棋盤]
    C --> D[檢查勝利條件]
    D --> E[勝利]
    E --> F[結束遊戲]
    D --> G[繼續遊戲]
    G --> B

內容解密:

Tic Tac Toe 遊戲的實作涉及到棋盤的初始化、玩家輸入與棋盤更新、勝利條件檢查等。遊戲迴圈中,玩家輪流輸入位置,更新棋盤,並檢查勝利條件。如果勝利條件滿足,遊戲結束。否則,繼續遊戲。

遊戲模式選擇

在開始一場井字棋遊戲之前,玩家需要選擇遊戲模式。這個選擇決定了遊戲的參與者是人類還是電腦。

遊戲模式選擇程式碼

print("\n[0]. Player vs. Computer")
print("[1]. Player vs. Player")
print("[2]. Computer vs. Computer")

mode = int(input("\nSelect an option [0]-[2]: "))

這段程式碼列出三種遊戲模式,並要求玩家輸入一個數字來選擇模式。

玩家對戰模式

如果玩家選擇模式1,則需要輸入兩個玩家的名字,並選擇各自的棋子(X或O)。

if mode == 1:
    # Asking Names;
    p1_name, p2_name = names()

    # Asking Choices; Printing choices; X or O;
    p1_choice, p2_choice = choice()

    print(f"\n{p1_name}:", p1_choice)
    print(f"{p2_name}:", p2_choice)

這段程式碼呼叫names()函式來取得兩個玩家的名字,並呼叫choice()函式來取得各自的棋子選擇。

玩家對戰電腦模式

如果玩家選擇模式0,則需要輸入玩家的名字,電腦將作為對手。

elif mode == 0:
    p1_name = input("\nEnter NAME of PLAYER who will go against the Computer:\t").capitalize()
    p2_name = "Computer"

    # Asking Choices; Printing choices; X or O;
    p1_choice, p2_choice = choice()

    print(f"\n{p1_name}:", p1_choice)
    print(f"{p2_name}:", p2_choice)

這段程式碼要求玩家輸入名字,並設定電腦為對手。

電腦對戰電腦模式

如果玩家選擇模式2,則電腦將與電腦對戰。

else:
    # 電腦對戰電腦模式
    p1_name = "Computer1"
    p2_name = "Computer2"

    # Asking Choices; Printing choices; X or O;
    p1_choice, p2_choice = choice()

    print(f"\n{p1_name}:", p1_choice)
    print(f"{p2_name}:", p2_choice)

這段程式碼設定兩個電腦為對手,並取得各自的棋子選擇。

內容解密:

這段程式碼使用了三種遊戲模式,讓玩家可以選擇與另一個玩家或電腦對戰。程式碼使用了names()choice()函式來取得玩家的名字和棋子選擇。電腦對戰電腦模式使用了兩個電腦作為對手。

基礎遊戲架構

在這個基礎的遊戲架構中,我們可以看到兩個玩家,Computer1Computer2,分別使用 “X” 和 “O” 作為他們的符號。遊戲的流程包括隨機決定哪個玩家先開始,然後根據玩家的選擇更新遊戲板。

玩家設定

p1_name = "Computer1"
p2_name = "Computer2"
p1_choice, p2_choice = "X", "O"

遊戲初始化

遊戲開始時,系統會隨機決定哪個玩家先開始,並根據玩家的選擇更新遊戲板。

if first_player():
    turn = p2_name
else:
    turn = p1_name
print(f"\n{turn} will go first!")

遊戲迴圈

遊戲迴圈中,玩家會輪流進行遊戲,直到有一個玩家贏得遊戲。

while play_game:
    # PLAYER1
    if turn == p1_name:
        # 顯示遊戲板
        display_board(theBoard, available)
        # 得到玩家的選擇
        if mode != 2:
            position = player_choice(theBoard, p1_name, p1_choice)
        else:
            position = CompAI(theBoard, p1_name, p1_choice)
        print(f'\n{p1_name} ({p1_choice}) has placed on {position}\n')
        # 更新遊戲板
        place_marker(theBoard, available, p1_choice, position)
        # 檢查玩家是否贏得遊戲
        # ...

內容解密:

在這個遊戲架構中,first_player() 函式用於隨機決定哪個玩家先開始。display_board() 函式用於顯示遊戲板,player_choice() 函式用於得到玩家的選擇,place_marker() 函式用於更新遊戲板。CompAI() 函式用於得到電腦玩家的選擇。

圖表翻譯:

  flowchart TD
    A[遊戲初始化] --> B[隨機決定先開始的玩家]
    B --> C[顯示遊戲板]
    C --> D[得到玩家的選擇]
    D --> E[更新遊戲板]
    E --> F[檢查玩家是否贏得遊戲]

這個圖表顯示了遊戲的流程,從遊戲初始化到檢查玩家是否贏得遊戲。

遊戲過程分析

在這個遊戲過程中,我們可以看到兩個玩家,p1_namep2_name,輪流進行遊戲。遊戲的主要目標是填滿一個板子,theBoard,並且根據玩家的選擇進行勝負的判斷。

勝負判斷

當玩家 p1_name 的選擇 p1_choice 被確認為勝利時,遊戲會顯示祝賀訊息,並宣佈 p1_name 為贏家。如果是電腦玩家贏了,則會顯示電腦贏了的訊息。

if win_check(theBoard, p1_choice):
    display_board(theBoard, available)
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    if(mode): 
        print(f'\n\nCONGRATULATIONS {p1_name}! YOU HAVE WON THE GAME!\n\n')
    else:
        print('\n\nTHE Computer HAS WON THE GAME!\n\n')
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    play_game = False

平局判斷

如果板子已經被填滿,但沒有玩家贏得遊戲,則會宣佈平局。

if full_board_check(theBoard):
    display_board(theBoard, available)
    print("~~~~~~~~~~~~~~~~~~")
    print('\nThe game is a DRAW!\n')
    print("~~~~~~~~~~~~~~~~~~")
    break

玩家交替

如果沒有玩家贏得遊戲,也沒有平局,則會交替到下一個玩家。

else:
    turn = p2_name

玩家2的回合

當玩家2的回合開始時,會顯示板子,並且根據遊戲模式決定玩家2的選擇。

elif turn == p2_name:
    display_board(theBoard, available)
    if(mode == 1):
        position = player_choice(theBoard, p2_name, p2_choice)
    else:
        # ...

內容解密:

上述程式碼展示了遊戲過程中的勝負判斷、平局判斷和玩家交替的邏輯。這些邏輯是根據遊戲的規則和玩家的選擇進行的。透過這些邏輯,遊戲可以根據玩家的行為進行勝負的判斷和遊戲的推進。

圖表翻譯:

以下是遊戲過程的流程圖:

  flowchart TD
    A[遊戲開始] --> B[玩家1的回合]
    B --> C[勝負判斷]
    C --> D[平局判斷]
    D --> E[玩家交替]
    E --> F[玩家2的回合]
    F --> G[遊戲結束]

這個流程圖展示了遊戲過程中的主要步驟,包括玩家1的回合、勝負判斷、平局判斷、玩家交替和玩家2的回合。這個流程圖可以幫助我們瞭解遊戲的邏輯和流程。

遊戲迴圈與勝利條件檢查

在遊戲的迴圈中,我們需要不斷地檢查玩家的輸入並更新遊戲板。以下是相關的程式碼片段:

# 玩家2的回合
position = CompAI(theBoard, p2_name, p2_choice)
print(f'\n{p2_name} ({p2_choice}) has placed on {position}\n')

# 更新遊戲板
place_marker(theBoard, available, p2_choice, position)

# 檢查玩家2是否贏得遊戲
if win_check(theBoard, p2_choice):
    display_board(theBoard, available)
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    
    # 根據遊戲模式顯示贏家訊息
    if mode:
        print(f'\n\nCONGRATULATIONS {p2_name}! YOU HAVE WON THE GAME!\n\n')
    else:
        print('\n\nTHE Computer HAS WON THE GAME!\n\n')
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    
    # 結束遊戲迴圈
    play_game = False
else:
    # 檢查遊戲板是否已滿
    if full_board_check(theBoard):
        display_board(theBoard, available)
        print("~~~~~~~~~~~~~~~~~~")
        print('\nThe game is a DRAW!\n')
        print("~~~~~~~~~~~~~~~~~~")
        break
    else:
        # 切換到玩家1的回合
        turn = p1_name
        
        #詢問玩家是否要再玩一次
        if replay():
            # 如果是,繼續遊戲迴圈
            continue
        else:
            # 如果否,結束遊戲迴圈
            break

內容解密:

在這個程式碼片段中,我們可以看到遊戲迴圈的實作。首先,我們使用 CompAI 函式來計算玩家2的下一步位置。然後,我們更新遊戲板使用 place_marker 函式。接下來,我們檢查玩家2是否贏得遊戲使用 win_check 函式。如果玩家2贏得遊戲,我們顯示贏家訊息並結束遊戲迴圈。如果遊戲板已滿,我們顯示平局訊息並結束遊戲迴圈。否則,我們切換到玩家1的回合並詢問玩家是否要再玩一次。

圖表翻譯:

以下是這個程式碼片段的流程圖:

  flowchart TD
    A[玩家2的回合] --> B[計算下一步位置]
    B --> C[更新遊戲板]
    C --> D[檢查勝利條件]
    D -->|贏得遊戲| E[顯示贏家訊息]
    D -->|平局| F[顯示平局訊息]
    D -->|繼續遊戲| G[切換到玩家1的回合]
    G --> H[詢問玩家是否要再玩一次]
    H -->|是| I[繼續遊戲迴圈]
    H -->|否| J[結束遊戲迴圈]

這個流程圖顯示了遊戲迴圈的流程,包括玩家2的回合、更新遊戲板、檢查勝利條件、顯示贏家訊息或平局訊息、切換到玩家1的回合、詢問玩家是否要再玩一次等。

網站載入時間測試

這個指令碼可以測試網站載入的時間,讓使用者輸入網站的URL,然後計算載入該網站所需的時間。

從使用者經驗到商業價值,網頁載入速度都是網站成功的關鍵因素。這篇文章深入探討了建構井字棋遊戲的技術細節,包含遊戲邏輯、AI 設計、以及使用者介面。透過 Python 程式碼的逐步解說,我們理解了如何建立一個功能完善的井字棋遊戲,並探討了程式碼最佳化和不同遊戲模式的設計。

分析程式碼可以發現,AI 的決策邏輯採用了簡單的規則判斷,優先搶佔勝利位置或阻止對手獲勝,在沒有明顯策略的情況下則隨機選擇位置。這種設計雖然易於實作,但在面對更複雜的遊戲或更具策略性的對手時,其侷限性便會顯現出來。未來可以考慮整合更進階的搜尋演算法,例如 Minimax 或 Alpha-Beta Pruning,以提升 AI 的遊戲水平。此外,程式碼中對於使用者輸入的錯誤處理機制相對簡略,可以強化輸入驗證和錯誤提示,提升使用者經驗。

展望未來,這個井字棋遊戲可以作為一個基礎框架,進一步發展成更複雜的遊戲,或整合機器學習模型進行訓練,讓 AI 能夠自主學習並發展出更精妙的策略。同時,可以結合網頁技術,將遊戲佈署到線上平臺,讓更多使用者可以體驗與 AI 對戰的樂趣。玄貓認為,持續最佳化 AI 演算法和使用者介面,將能大幅提升遊戲的趣味性和挑戰性,使其更具吸引力。