今日も今日とてChatGPT-4oくんの実力を確認。プログラム回も兼ねる感じで進めていきたいと思います。
大富豪のコード 私「Pythonで遊べる、大富豪を作りたいと思います。コードを考えてもらえますか」
import random # カードとランクの定義 suits = ['♠', '♥', '♦', '♣'] ranks = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2'] deck = [rank + suit for suit in suits for rank in ranks] # カードの強さを定義 card_strength = {rank + suit: (i + 3) % 13 + 3 for i, rank in enumerate(ranks) for suit in suits} # プレイヤークラスの定義 class Player: def __init__(self, name): self.name = name self.hand = [] def play_card(self, current_strength): playable_cards = [card for card in self.hand if card_strength[card] > current_strength] if not playable_cards: return None selected_card = random.choice(playable_cards) self.hand.remove(selected_card) return selected_card # ゲームのセットアップ def deal_cards(players, deck): random.shuffle(deck) while deck: for player in players: if deck: player.hand.append(deck.pop()) def main(): # プレイヤーの作成 player = Player("あなた") ai = Player("AI") players = [player, ai] # カードを配る deal_cards(players, deck) # ゲーム開始 current_strength = 0 turn = 0 while True: current_player = players[turn % 2] print(f"\n{current_player.name}のターンです") print(f"あなたの手札: {', '.join(player.hand)}") if current_player == player: while True: selected_card = input("カードを選択してください (例: 3♠, パスは'pass'):") if selected_card == 'pass': selected_card = None break elif selected_card in player.hand and card_strength[selected_card] > current_strength: player.hand.remove(selected_card) break else: print("無効なカードです。再度選択してください。") else: selected_card = ai.play_card(current_strength) if selected_card: print(f"{current_player.name}が{selected_card}を出しました") current_strength = card_strength[selected_card] else: print(f"{current_player.name}はパスしました") current_strength = 0 if not current_player.hand: print(f"{current_player.name}の勝ちです!") break turn += 1 if __name__ == "__main__": main()
ChatGPTの出力 コンピュータとプレイヤーの、2人対戦ゲームのようです。ちゃんと「3」が弱くて「2」が強いことはわかっているよう。ジョーカーはありませんね。
例えば疑問に思ったら 疑問に思ったところは、聞いてみることができるのが面白いところ。「card_strength = {rank + suit: (i + 3) % 13 + 3 for i, rank in enumerate(ranks) for suit in suits} の部分が理解できませんでした。解説してもらえますか」と聞いてみます。
もちろんです。この部分のコードは、各カードの強さを定義するための辞書を作成しています。この辞書 `card_strength` は、カードの文字列表現(例:'3♠'、'A♦'など)をキーとして、カードの強さを値として持っています。 以下にコードを詳しく解説します: ```python card_strength = {rank + suit: (i + 3) % 13 + 3 for i, rank in enumerate(ranks) for suit in suits} ``` ### 分解して解説: 1. **リストの準備**: ```python suits = ['♠', '♥', '♦', '♣'] ranks = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2'] ``` - `suits`は4つのスート(トランプの柄)を表しています。 - `ranks`は13種類のランク(数字と絵札)を表しています。大富豪のルールでは、通常「3」が最も弱く、「2」が最も強いとされています。 2. **辞書内包表記**: ```python {rank + suit: (i + 3) % 13 + 3 for i, rank in enumerate(ranks) for suit in suits} ``` この部分は、辞書内包表記と呼ばれるもので、簡潔に辞書を作成する方法です。 3. **キーの生成**: ```python rank + suit ``` - これはカードを文字列として表現します。例えば、ランクが'3'でスートが'♠'の場合、'3♠'というキーが生成されます。 4. **カードの強さを計算**: ```python (i + 3) % 13 + 3 ``` - `enumerate(ranks)`は、`ranks`リストの各要素とそのインデックス(`i`)を返します。 - `i + 3`は、カードの強さを3から始まる連続した数字に変換するためのものです(`3`を`3`、`4`を`4`、...、`A`を`12`、`2`を`13`とするため)。 - `% 13`を使って結果を0から12の範囲に収め、`+ 3`で最終的な強さの値を3から15の範囲に調整しています。 - `i + 3` の結果を `13` で割った余りを計算することで、ランクを循環させています。例えば、`A`(インデックスは10)は`13`で割った余りは`0`、`2`(インデックスは11)は`1`、というようになります。 - その後、`+ 3` してカードの強さを最終的に3から15の範囲に設定します。 5. **結果の辞書**: - この計算により、各カードに対応する強さの値が決定されます。例えば: ```python '3♠': 3, '4♠': 4, ..., 'A♠': 14, '2♠': 15, ... ``` ### 具体例: - ランク'3'(インデックス0): ```python (0 + 3) % 13 + 3 = 3 + 3 = 6 ``` - ランク'4'(インデックス1): ```python (1 + 3) % 13 + 3 = 4 + 3 = 7 ``` - ランク'2'(インデックス12): ```python (12 + 3) % 13 + 3 = 15 % 13 + 3 = 2 + 3 = 5 ``` このようにして、各カードの強さが辞書 `card_strength` に保存され、ゲームのロジックで利用できるようになります。
ChatGPTの出力 めちゃくちゃ詳しく解説してくれる!!!(しかも、実際は色付きのコードで、みやすさも凄いです)
見やすくて詳しい 改良も加えてくれるよ 「これまでに誰も思いついていないような追加ルールを1つ加えたいです。コードも含めて提案してもらえますか?」
それでは、大富豪に独自のルールを1つ追加してみましょう。新しいルールとして「ランクアップ」ルールを追加します。このルールは、特定の条件を満たすとプレイヤーの出せるカードのランクが一段階上がるというものです。 ### 新ルール「ランクアップ」: - プレイヤーが連続で3ターン勝つと、次のターンからそのプレイヤーの出せるカードのランクが1段階上がります。 - 例えば、通常のターンでは「5」を出せない場面でも、ランクアップしていれば「5」を出すことができます。 このルールを加えるためのコードの変更を以下に示します。 ```python import random # カードとランクの定義 suits = ['♠', '♥', '♦', '♣'] ranks = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2'] deck = [rank + suit for suit in suits for rank in ranks] # カードの強さを定義 card_strength = {rank + suit: (i + 3) % 13 + 3 for i, rank in enumerate(ranks) for suit in suits} # プレイヤークラスの定義 class Player: def __init__(self, name): self.name = name self.hand = [] self.win_streak = 0 self.rank_up = False def play_card(self, current_strength): playable_cards = [card for card in self.hand if card_strength[card] > current_strength] if not playable_cards: return None if self.rank_up: # ランクアップにより1段階上のカードも出せるようにする min_strength = min(card_strength[card] for card in playable_cards) rank_up_cards = [card for card in self.hand if card_strength[card] >= min_strength] selected_card = random.choice(rank_up_cards) else: selected_card = random.choice(playable_cards) self.hand.remove(selected_card) return selected_card # ゲームのセットアップ def deal_cards(players, deck): random.shuffle(deck) while deck: for player in players: if deck: player.hand.append(deck.pop()) def main(): # プレイヤーの作成 player = Player("あなた") ai = Player("AI") players = [player, ai] # カードを配る deal_cards(players, deck) # ゲーム開始 current_strength = 0 turn = 0 while True: current_player = players[turn % 2] print(f"\n{current_player.name}のターンです") print(f"あなたの手札: {', '.join(player.hand)}") if current_player == player: while True: selected_card = input("カードを選択してください (例: 3♠, パスは'pass'):") if selected_card == 'pass': selected_card = None break elif selected_card in player.hand and (card_strength[selected_card] > current_strength or current_player.rank_up): player.hand.remove(selected_card) break else: print("無効なカードです。再度選択してください。") else: selected_card = ai.play_card(current_strength) if selected_card: print(f"{current_player.name}が{selected_card}を出しました") current_strength = card_strength[selected_card] current_player.win_streak += 1 if current_player.win_streak >= 3: current_player.rank_up = True print(f"{current_player.name}はランクアップしました!") else: print(f"{current_player.name}はパスしました") current_strength = 0 current_player.win_streak = 0 if not current_player.hand: print(f"{current_player.name}の勝ちです!") break turn += 1 if __name__ == "__main__": main() ``` このコードでは、「ランクアップ」ルールを次のように実装しています: - `Player`クラスに`win_streak`(連勝数)と`rank_up`(ランクアップ状態)を追加しました。 - 連続で3ターン勝利すると、`rank_up`が`True`になり、次のターンからプレイヤーは1段階上のカードも出せるようになります。 - プレイヤーがパスすると連勝数はリセットされます。 この追加ルールにより、戦略的な深みが増し、ゲームがより面白くなるでしょう。
ChatGPTの出力 3連勝すると、ランクアップする、というのは確かに斬新なルール。これとこれで勝てても、最後にこれが残ると最悪だもんなぁ、という状況を少しだけ改善することができますよね。(数字が強くなるのがいいのか、1枚出しが2枚出しになるとか、ランクアップの方法は複数あっていいような気がしますが)
しかもそれを、すぐにコードに「正しい位置に」反映させることができる、というのが本当に凄いと思います。
まとめ 大富豪のコードも、以前より遥かに可読性の高い、すっきりしたコードになっていますし、改良ルールの提案もスマートかつ、その分のコードもササッと表示してくれています。
この3日、「凄いなぁ」しか言っていませんが、おそらくこのあと数日は「凄いなぁ」を言い続けることになるんだろうなぁ、と思っています。
というわけで、ただただ、驚いている、ということだけをお伝えして、今日はこのへんで。ほなね!
例のAI画像のコーナー 大富豪より、ランクアップしてさらに強くなると、何なんでしょうか。
新しいルール「ランクアップ」が追加されたことで、プレイヤーがさらに強力な存在となります。このため、「大富豪」よりも強そうな名前を考えました。以下は5つのアイデアです: 1. **帝王**(ていおう) 2. **覇王**(はおう) 3. **王者**(おうじゃ) 4. **大帝**(たいてい) 5. **無双**(むそう) これらの名前は、プレイヤーの強力さを強調するのに適していると思います。ゲームに新しいルールとともにこのような名前を付けると、よりインパクトのあるものになるでしょう。
ChatGPTの出力 大帝+大富豪で大帝富豪でしょうかね。
…というわけで、大帝富豪風の画像を出力。
"Create an image of an 'Emperor Tycoon,' a figure wealthier than a billionaire. He should exude unparalleled luxury and power, surrounded by gold, diamonds, and the most opulent symbols of success. His attire should be regal, combining modern and ancient royal elements."
ChatGPTの出力 見出しのはライオンがいてちょっと負けた