【アプリ開発】オセロバージョンアップ【ど素人】

オセロの盤面 アプリ開発

前回との変更点

コンピューターとの対戦機能をつけてみました

コンピューターは、基本的に最も多くの駒をひっくり返せる手を選びます

# オセロ(リバーシ)人間 vs コンピューター・ターミナル版

import random

BOARD_SIZE = 8
EMPTY, BLACK, WHITE = '.', '●', '○'

DIRECTIONS = [(-1, -1), (-1, 0), (-1, 1),
              (0, -1),          (0, 1),
              (1, -1),  (1, 0), (1, 1)]

def create_board():
    board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
    mid = BOARD_SIZE // 2
    board[mid - 1][mid - 1], board[mid][mid] = WHITE, WHITE
    board[mid - 1][mid], board[mid][mid - 1] = BLACK, BLACK
    return board

def print_board(board):
    print("  " + " ".join(map(str, range(BOARD_SIZE))))
    for i, row in enumerate(board):
        print(i, " ".join(row))

def on_board(x, y):
    return 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE

def valid_moves(board, player):
    opponent = WHITE if player == BLACK else BLACK
    moves = []
    for x in range(BOARD_SIZE):
        for y in range(BOARD_SIZE):
            if board[x][y] != EMPTY:
                continue
            for dx, dy in DIRECTIONS:
                nx, ny = x + dx, y + dy
                flipped = False
                while on_board(nx, ny) and board[nx][ny] == opponent:
                    nx += dx
                    ny += dy
                    flipped = True
                if flipped and on_board(nx, ny) and board[nx][ny] == player:
                    moves.append((x, y))
                    break
    return moves

def make_move(board, x, y, player):
    opponent = WHITE if player == BLACK else BLACK
    board[x][y] = player
    for dx, dy in DIRECTIONS:
        nx, ny = x + dx, y + dy
        line = []
        while on_board(nx, ny) and board[nx][ny] == opponent:
            line.append((nx, ny))
            nx += dx
            ny += dy
        if on_board(nx, ny) and board[nx][ny] == player:
            for px, py in line:
                board[px][py] = player

def count_discs(board):
    black = sum(row.count(BLACK) for row in board)
    white = sum(row.count(WHITE) for row in board)
    return black, white

def ai_move(board, player):
    moves = valid_moves(board, player)
    if not moves:
        return None

    def flip_count(x, y):
        temp_board = [row[:] for row in board]
        make_move(temp_board, x, y, player)
        new_black, new_white = count_discs(temp_board)
        old_black, old_white = count_discs(board)
        return (new_black - old_black) + (new_white - old_white)

    return max(moves, key=lambda move: flip_count(*move))

def main():
    board = create_board()
    player = BLACK  # 人間は黒(●)

    while True:
        print_board(board)
        moves = valid_moves(board, player)
        if not moves:
            print(f"{player} は打てる場所がありません。パスします。")
            player = WHITE if player == BLACK else BLACK
            if not valid_moves(board, player):
                print("どちらも打てる手がありません。ゲーム終了。")
                break
            continue

        print(f"{player} の番です。")
        print("可能な手:", moves)

        if player == WHITE:
            move = ai_move(board, player)
            if move:
                print(f"コンピューター({player})は {move} に打ちました。")
                x, y = move
        else:
            try:
                x, y = map(int, input("行 列 を入力(例: 2 3): ").split())
                if (x, y) not in moves:
                    print("その位置には打てません。")
                    continue
            except:
                print("入力エラー。例: 2 3 のように入力してください。")
                continue

        make_move(board, x, y, player)
        player = WHITE if player == BLACK else BLACK

    b, w = count_discs(board)
    print_board(board)
    print(f"●: {b}, ○: {w}")
    if b > w:
        print("●(黒)の勝ち!")
    elif w > b:
        print("○(白)の勝ち!")
    else:
        print("引き分け!")

if __name__ == "__main__":
    main()

Chat GPTからの提案

Chat GPTから

  • 難易度調整
  • 先手、後手の変更
  • グラフィカルな画面に変更

といった内容の提案がありました

この中でも特に気になったのが

グラフィカルな画面に変更です

これを実行すると盤面を直接クリックすることでプレイできるようになるとのことで、

よりゲームっぽさが出てくるのかなと思います

ただし、実装にはTkinterというものを使用する必要があるとのことで

初心者の僕にはさっぱりです

また時間のある時に試してみようと思います

コメント

タイトルとURLをコピーしました