「オセロ風ゲーム作って」生成AIにお願いしたら驚きの結果が!「テトリス風ゲーム」にも挑戦

夢書房 夢書房

2022年にOpen AI社からChatGPTが発表されて以来、わずか2年で生成AIは驚くほどの進化を遂げた。例えば、実際の人物のような画像を生成したり、作曲や動画制作までお手の物だ。簡単なゲームであればすぐにコードが生成され、遊ぶことができる。そこで生成AIに「オセロ風ゲームを作って」とお願いしたら作ってくれるのか試してみた。

オセロ風ゲームを作るために使った生成AIはGoogle社の「Gemini 1.5 Pro」が。AIにおこなった指示は「Pythonで動くオセロ風ゲームのコードを書いてください」というもの。そのコードの内容は記事の最後に添付しておく。

GoogleのColaboratoryを新規で開き、指示された通りにスクリプトエディタを動作させてコードを実行すると、見事にオセロ風の画面が生成された。このコードを実行すると人間同士でオセロ風ゲームを楽しむことができる。操作に慣れてしまえば、ほんの数分で制作完了する。

ゲーム制作の素人でもオセロ風ゲームが作れるのだから、プロがAIを活用すればもっと高度なゲームが作れるのではないだろうか。実際にValve社が提供しているゲームやストリーミングビデオなどをダウンロードできるプラットフォーム「Steam」では、すでに1000以上のゲームが生成AIによって制作されたものだ。

このあとも筆者は、Geminiに対して「テトリス風ゲームを作ってください」といった命令文を出し、さまざまなゲームのコードを生成させてみた。コードを実行させようとするとエラーが生じることもあったが、エラーの内容をGeminiに確認すると対処方法を教えてくれるので、プログラミングの勉強にもなる。

20年近く前にプログラマーとして働いていた筆者からすると、こんなに簡単に動くコードが生成されるとは驚きだ。間違いなく生成AIがプログラミングの世界を変えたといっていいだろう。もしも現役プログラマーだった当時、筆者が同じようにオセロ風ゲームを作れといわれていたら、環境設定からなにやらで1日以上の時間をかけることが予想される。

世間を騒がせた名作ゲームが実は生成AIによって作られていたなんて時代は、もうすぐそこまで迫っているのかもしれない。

<オセロ風ゲームのコード>

import copy
# 盤面のサイズ
BOARD_SIZE = 8
# プレイヤーの色
BLACK = 1
WHITE = 2
EMPTY = 0
# 方向
DIRECTIONS = [(0, 1), (1, 0), (0, -1), (-1, 0), (1, 1), (-1, -1), (1, -1), (-1, 1)]
def create_board():
    """盤面を初期化する"""
    board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
    board[3][3] = board[4][4] = WHITE
    board[3][4] = board[4][3] = BLACK
    return board
def print_board(board):
    """盤面を表示する"""
    print("  " + " ".join([str(i + 1) for i in range(BOARD_SIZE)]))
    for i in range(BOARD_SIZE):
        print(str(i + 1) + " " + " ".join(["." if cell == EMPTY else "●" if cell == BLACK else "○" for cell in board[i]]))
def is_valid_move(board, player, row, col):
    """指定された場所に石を置けるか判定する"""
    if board[row][col] != EMPTY:
        return False
    opponent = 3 - player  # 相手の色を取得
    for dr, dc in DIRECTIONS:
        r, c = row + dr, col + dc
        flipped = False
        while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE:
            if board[r][c] == opponent:
                flipped = True
            elif board[r][c] == player:
                if flipped:
                    return True
                break
            else:
                break
            r += dr
            c += dc
    return False
def flip_stones(board, player, row, col):
    """石を置いて、挟まれた石をひっくり返す"""
    board[row][col] = player
    opponent = 3 - player
    for dr, dc in DIRECTIONS:
        r, c = row + dr, col + dc
        stones_to_flip = []
        while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE:
            if board[r][c] == opponent:
                stones_to_flip.append((r, c))
            elif board[r][c] == player:
                for flip_row, flip_col in stones_to_flip:
                    board[flip_row][flip_col] = player
                break
            else:
                break
            r += dr
            c += dc
def get_valid_moves(board, player):
    """有効な手のリストを取得する"""
    valid_moves = []
    for row in range(BOARD_SIZE):
        for col in range(BOARD_SIZE):
            if is_valid_move(board, player, row, col):
                valid_moves.append((row, col))
    return valid_moves
def count_stones(board):
    """黒と白の石の数をカウントする"""
    black_count = sum([row.count(BLACK) for row in board])
    white_count = sum([row.count(WHITE) for row in board])
    return black_count, white_count
def main():
    """ゲームのメインループ"""
    board = create_board()
    current_player = BLACK
    while True:
        print_board(board)
        black_count, white_count = count_stones(board)
        print(f"黒: {black_count}, 白: {white_count}")
        valid_moves = get_valid_moves(board, current_player)
        if not valid_moves:
            print(f"{current_player}の手番ですが、置ける場所がありません。パスします。")
            current_player = 3 - current_player
            continue
        print(f"{current_player}の手番です。")
        while True:
            try:
                row, col = map(int, input("行と列を入力してください(例:1 2):").split())
                row -= 1
                col -= 1
                if (row, col) in valid_moves:
                    break
                else:
                    print("無効な入力です。もう一度入力してください。")
            except (ValueError, IndexError):
                print("無効な入力です。もう一度入力してください。")
        flip_stones(board, current_player, row, col)
        current_player = 3 - current_player
        # ゲーム終了判定
        if not get_valid_moves(board, current_player) and not get_valid_moves(board, 3 - current_player):
            print("ゲーム終了です。")
            black_count, white_count = count_stones(board)
            print_board(board)
            print(f"黒: {black_count}, 白: {white_count}")
            if black_count > white_count:
                print("黒の勝ちです!")
            elif white_count > black_count:
                print("白の勝ちです!")
            else:
                print("引き分けです!")
            break
if __name__ == "__main__":
    main()

おすすめニュース

気になるキーワード

新着ニュース