ばぁど・うぉっちんぐ

セキュリティに強いWeb屋。自由と春を求めて羽ばたく渡り鳥。

このブログはGoogle Analyticsを利用しています

ChatGPTにプログラムを書かせてみて、色々と検証してみました。プログラマはAIにより駆逐されてしまうのか?

どーも。ばぁどです。

ChatGPTが話題になり数ヶ月ですが、やっとアカウント登録して使ってみました。 プログラマの仕事が奪われるとか、色々SNSで見たりしましたが、 百聞は一見にしかず!と言うことで!

ポーカープログラムについて

筆者もPythonの練習がてら、ポーカープログラムを2,3年前に書いていました。 デッキからカードを引いたり、役を判定したりはできるのですが、まだ対戦機能は追加しておりません。(2023/03/26時点)

github.com

今回は、業務ロジックや業務知識などは必要ない、このポーカーのロジックをPythonで書いてもらいました。

ChatGPTによるポーカープログラム

最初のご挨拶

次に、ChatGPTが出して来てくれたポーカープログラム

出力されたPython

import random

# デッキの初期化
suits = ["ハート", "ダイヤ", "スペード", "クラブ"]
ranks = ["エース", "2", "3", "4", "5", "6", "7", "8", "9", "10", "ジャック", "クイーン", "キング"]
deck = [(rank, suit) for suit in suits for rank in ranks]
random.shuffle(deck)

# ゲームに参加するプレイヤーの数を入力
num_players = int(input("プレイヤーの数を入力してください: "))

# プレイヤーの手札を初期化
player_hands = [[] for _ in range(num_players)]

# カードを配る
for i in range(5):
    for j in range(num_players):
        card = deck.pop()
        player_hands[j].append(card)

# プレイヤーの手札を表示
for i, hand in enumerate(player_hands):
    print(f"プレイヤー{i+1}の手札: {hand}")

ChatGPTも言っていますが、デッキやカードを引くなどをしているだけで、役の評価や対戦ロジックはありません。 しかし上記コードだけだとトランプのデッキを作って、手札を配っているだけになります。 (それだけでも十分すごいのですが・・・) 変数の付け方がとても綺麗。 無駄なfor文もありません

# プレイヤーの手札を初期化
player_hands = [[] for _ in range(num_players)]

個人的に上のような書き方ではなく冗長に書かれた方が好きなのですが、今回は複数人での対戦を想定しているため、これは一つの形として良いですね。

次に評価ロジックも書いてもらいました。

出力されたPython

# 5カードドローの手札の役を判定する関数
def evaluate_hand(hand):
    # 手札をカードのランクとスートに分ける
    ranks = [card[0] for card in hand]
    suits = [card[1] for card in hand]
    
    # ランクの出現回数をカウントする
    rank_count = {rank: ranks.count(rank) for rank in ranks}
    
    # 手札にエースが含まれるかどうかを判定する
    has_ace = "A" in ranks
    
    # ストレートを判定するために、ランクを数値に変換する
    rank_values = {
        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9,
        "T": 10, "J": 11, "Q": 12, "K": 13, "A": 14
    }
    
    # ストレートの判定
    sorted_ranks = sorted(set(ranks), key=lambda x: rank_values[x])
    is_straight = False
    if len(sorted_ranks) == 5 and (int(rank_values[sorted_ranks[-1]]) - int(rank_values[sorted_ranks[0]]) == 4):
        is_straight = True
    elif sorted_ranks == ["2", "3", "4", "5", "A"]:
        is_straight = True
    
    # フラッシュの判定
    is_flush = len(set(suits)) == 1
    
    # ロイヤルフラッシュの判定
    is_royal_flush = False
    if is_flush and has_ace and set(ranks) == {"T", "J", "Q", "K", "A"}:
        is_royal_flush = True
    
    # ストレートフラッシュの判定
    is_straight_flush = False
    if is_straight and is_flush:
        is_straight_flush = True
    
    # フォーカードの判定
    is_four_of_a_kind = False
    if 4 in rank_count.values():
        is_four_of_a_kind = True
    
    # フルハウスの判定
    is_full_house = False
    if set(rank_count.values()) == {2, 3}:
        is_full_house = True
    
    # スリーカードの判定
    is_three_of_a_kind = False
    if 3 in rank_count.values():
        is_three_of_a_kind = True
    
    # ツーペアの判定
    is_two_pair = False
    if list(rank_count.values()).count(2) == 2

こう言ったロジックを、確実に人間が書くよりも素早く的確に出してくれるのは驚嘆します。 ポーカーのロジック判定って、初学者にとっては良い勉強ツールだと思っています。 配列の扱い方や、ツーペアなどの現実で人間が判定しているロジックを、プログラムに落とし込むと言う練習は非常に重要です。 ただ、そう言ったロジックを学ぶのではなく、単純に作るだけなのであればAIが圧倒的に有利と言ったところ。

ただ、単純にPythonでコードを書くと、あまり保守性がないように見受けられます。 特にDeckやCardなど、クラス化できるような部分が、個人的には不満です。

そこで、ChatGPTにこう言った指示を出してみました。

出力されたPython

import random

# カードのランクとスートを表す定数
RANKS = ["2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"]
SUITS = ["C", "D", "H", "S"]

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
    
    def __repr__(self):
        return f"{self.rank}{self.suit}"
    
class Deck:
    def __init__(self):
        self.cards = [Card(rank, suit) for rank in RANKS for suit in SUITS]
        self.shuffle()
    
    def shuffle(self):
        random.shuffle(self.cards)
    
    def draw(self):
        return self.cards.pop()
    
class Hand:
    def __init__(self, cards):
        self.cards = cards
    
    def add_card(self, card):
        self.cards.append(card)
    
    def discard(self, card_index):
        return self.cards.pop(card_index)
    
    def __repr__(self):
        return ", ".join(str(card) for card in self.cards)

しっかりと指示を出せば、カードやデッキなどをクラス化したPythonを出力してくれましたね! すごい!

そして、既存のコードを読み込んでもらって改善してもらうこともできました。

1.Playerクラスにプレイヤーの名前を保存するname属性を追加します。

class Player:
    def __init__(self, name):
        self.name = name
        self.hand = []

2.対戦するプレイヤーの名前を取得する関数を追加します。

def get_player_names():
    print("Enter player names (comma separated): ")
    names = input().strip().split(",")
    return names

3. プレイヤーの名前を取得して、Playerオブジェクトを作成する関数を追加します。

def create_players():
    names = get_player_names()
    players = []
    for name in names:
        player = Player(name.strip())
        players.append(player)
    return players

4. ゲームの進行を制御するmain関数内に、create_players関数を呼び出してプレイヤーを作成し、対戦させる処理を追加します。

def main():
    deck = Deck()
    players = create_players()
    for player in players:
        print("Player: {}".format(player.name))
        hand = deck.draw(5)
        player.hand = hand
        print("Hand: {}".format(hand))
    winner = determine_winner(players)
    print("Winner: {}".format(winner.name))

if __name__ == "__main__":
    main()

実際に上記コードを追加して、ソースコードが正しいかのチェックはまだしておりません。 今まで億劫だったので、やっていませんでした。 なので、ChatGPTに投げてみました!

import random

def deal(deck, num_cards):
    hand = []
    for i in range(num_cards):
        card = deck.pop(random.randint(0, len(deck) - 1))
        hand.append(card)
    return hand

deck = Deck()
deck.shuffle()
player1_hand = deal(deck.cards, 5)
player2_hand = deal(deck.cards, 5)
# 対戦
player1_score = judge(player1_hand)
player2_score = judge(player2_hand)

print("Player1 hand:", player1_hand, "Score:", player1_score)
print("Player2 hand:", player2_hand, "Score:", player2_score)

if player1_score > player2_score:
    print("Player1 wins!")
elif player1_score < player2_score:
    print("Player2 wins!")
else:
    print("It's a tie!")

内部のロジックなどは、書いてくれてはいませんがある程度機能の中身も理解できる。 こう言った、人間が必死に考えずともロジックを投げてくれるなーという感覚ではあります。

プログラマはAIにより駆逐されるのか?AIが普及してもプログラマに必要な技術とは?

個人的な答えは、平坦なプログラマは駆逐されます。 それこそ、指示待ちのプログラマやプログラムを書くだけのプログラマです。 しかし優秀なプログラマはChatGPTなどのAIを用いて、更に高度なエンジニアリングをできるようになるかなと思います。

プログラムの良し/悪しを判断する技術

AIが出してくれるプログラムが良いものかどうかを判断するのは人間です。 用件定義不足や、AIが間違える場合もあります。 それらのAIが出してきたコードが正しい動きをするのか?と言うのは非常に重要な部分だと思います。

今回はポーカーアプリを作ってもらいましたが、じゃあ今後プログラムにおいてプログラマがポーカーのロジックを考えなくて良いか?というと、そう言うわけではないと考えています。 やはりプログラムロジックを考える力がないと、 実業務をプログラムとして書き起こすことは難しいですし、複雑なビジネスロジックをどこまでAIに任せるかはまだ十分な議論がされていません。

ベンチャーであれば、あるほどAIの業務の取り組みは早いかもしれませんが、ガチガチなルールで縛られた企業ではAIの活用にはまだ数年かかるかもしれませんね。 どちらにせよ、AIはツールとして活用するべき強力なツールだと学びました。

IT領域にも”藤井聡太"のような異次元のエンジニアが現れる

チェス業界や将棋業界などの、ある特定のテーマにおけるAI研究は盛んに行われていました。 筆者が高校生の時には既に研究が始められており、チェスの王者がAIに負けたと言うコラムを読んだ覚えがあります。

そんな現在将棋界を席巻している藤井聡太さんは、子供の頃からAIを用いて将棋の勉学に励んでいたそうです。 もちろん現役の棋士の皆様もAIを用いた将棋研究は行なっていますが、幼少期の頃からAIによる将棋の研究をしていることから、積んでいるエンジンがそもそも違うといった各棋士のコメントをよく読みます。

ChatGPTなどのAIが今後更に普及することにより、プログラムの学習時点で効率よくAIを用いる超絶エンジニアが出てくる可能性があります。 そう言ったすごい若手エンジニアとも戦わなければいけないとなると、余計窮屈になってしまうなと考えるだけで頭が痛いですね。

最後にAIに聞いてみた

今のところは大丈夫っぽいですね(苦笑