この記事の練習問題で使用する知識:
レッスン1の知識、比較演算子と論理演算子、if文による条件分岐、while文による繰り返し処理、繰り返しの制御、関数の定義と使用、戻り値とデフォルト引数
Pythonのゲームコード一覧はこちら
<<前の問題 | 問題集Top |
次の問題>> |
練習問題3-☆2:石取りゲームを作ろう
石取りゲームは2人のプレイヤーが交互に石を取るターン制のゲームです。
このゲームでは15個の石を山に置き、プレイヤーが1ターンに取れる石の数は1個から3個までです。
プレイヤーは交互に石を取り、最後の石を取ったプレイヤーが負けとなります。Pythonでこのゲームを実装してみましょう。
この問題の要件
以下の要件に従ってコードを完成させてください。
is_valid_move
関数: プレイヤーが1ターンに取れる石の数(1〜3個)を判定し、適切かどうかを確認すること。take_turn
関数: プレイヤーが石を選んで取るロジックを実装し、プレイヤーが取った石の数を残りの石から減らすこと。play_game
関数: ゲームの進行を管理するメインループを作成し、2人のプレイヤーが交互に石を取ること。最後の石を取ったプレイヤーが負けたことを表示すること。- 変数の使用: 石の数(
stones
)、プレイヤーのターン(turn
)を変数で管理すること。 - 入力の使用:
input
関数を使って、プレイヤーが取る石の数を入力すること。 - 出力の使用:
print
関数を使って、ゲームの進行状況や勝敗を表示すること。
ただし、以下のような実行結果となるコードを書くこと。
*****↓↓正解コードの実行結果の例↓↓*****
石取りゲームへようこそ! プレイヤー1の番です。残りの石は 15 個です。 プレイヤー1, 何個の石を取りますか?(1~3個まで選べます):2 プレイヤー2の番です。残りの石は 13 個です。 プレイヤー2, 何個の石を取りますか?(1~3個まで選べます):3 ... プレイヤー1が最後の石を取りました。プレイヤー1の負けです!
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)
1:関数 is_valid_move
の定義
□ return
文でプレイヤーが選択した石の数が有効かどうかを判定し、戻り値として返す
2:関数 take_turn
の定義
□ print
関数でプレイヤーの番と残りの石の数を表示
□ input
関数でプレイヤーに石の数を入力させ、int
関数で数値に変換し move
に代入
□ while
文で is_valid_move
関数を使い、選択された石の数が有効でない場合に再入力させる
□ □ print
関数で無効な選択であることを表示し、再度入力を促す
□ 石の数を減らし、その結果を返す
3:関数 play_game
の定義
□ print
関数でゲームの開始メッセージを表示
□ 変数 stones
に15を代入(石の初期値)
□ 変数 turn
に1を代入(プレイヤー1のターンを示す)
□ while
文で stones
が0より大きい間ゲームを続ける
□ □ if
文で turn
が1ならプレイヤー1、それ以外ならプレイヤー2とし、current_player
に代入
□ □ take_turn
関数を呼び出し、プレイヤーが石を取る操作を行い、残りの石の数を更新
□ □ if
文で残りの石が0ならゲーム終了メッセージを表示し、ループを終了
□ □ ターンをプレイヤー2に交代し、次のループに進む
4:if __name__ == "__main__":
によるメインプログラムの実行
□ play_game
関数を呼び出してゲームを開始
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
# 石取りゲームの開始 def is_valid_move(stones, move): """【穴埋め問題1】ここに石の数が有効かどうかを判定して返すコードを書いてください。""" def take_turn(player, stones): # 各プレイヤーのターンを処理する関数 """【穴埋め問題2】ここにプレイヤーに石の数を入力させ、選択が有効であることを確認するコードを書いてください。""" """【穴埋め問題3】ここでプレイヤーが取った石の数を残りの石から引いて返すコードを書いてください。""" def play_game(): # 石取りゲームのメイン関数 print("石取りゲームへようこそ!") stones = 15 # ゲーム開始時の石の数 turn = 1 # 1ならプレイヤー1、2ならプレイヤー2 # 石が残っている限りゲームを続ける while stones > 0: """【穴埋め問題4】ここにプレイヤーを切り替えるコードを書いてください。""" """【穴埋め問題5】ここで現在のプレイヤーのターンを実行し、残りの石の数を更新するコードを書いてください。""" """【穴埋め問題6】ここに石が0になった場合、ゲームを終了するコードを書いてください。""" """【穴埋め問題7】ここにターンを交代するコードを書いてください。""" # ゲームの実行 if __name__ == "__main__": """【穴埋め問題8】ここにゲームを開始するコードを書いてください。"""
この問題の穴埋めコードは以上です。
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
解答例と解説
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
# 石取りゲームの開始 def is_valid_move(stones, move): # プレイヤーの選択した石の数が有効かどうかを判定する関数 return 1 <= move <= 3 and move <= stones def take_turn(player, stones): # 各プレイヤーのターンを処理する関数 print(f"\n{player}の番です。残りの石は {stones} 個です。") move = int(input(f"{player}, 何個の石を取りますか?(1~3個まで選べます):")) # プレイヤーが有効な数を選択するまで繰り返し while not is_valid_move(stones, move): print("無効な選択です。もう一度選んでください。") move = int(input(f"{player}, 何個の石を取りますか?(1~3個まで選べます):")) # 石を減らす stones -= move return stones def play_game(): # 石取りゲームのメイン関数 print("石取りゲームへようこそ!") stones = 15 # ゲーム開始時の石の数 turn = 1 # 1ならプレイヤー1、2ならプレイヤー2 # 石が残っている限りゲームを続ける while stones > 0: # プレイヤーの切り替え if turn == 1: current_player = "プレイヤー1" else: current_player = "プレイヤー2" # 現在のプレイヤーのターンを実行 stones = take_turn(current_player, stones) # 石が0になったらゲーム終了 if stones == 0: print(f"\n{current_player}が最後の石を取りました。{current_player}の負けです!") break # ターンを交代 if turn == 1: turn = 2 else: turn = 1 # ゲームの実行 if __name__ == "__main__": play_game()
正解コードの解説
この解説では、Pythonの基本構文を使用したシンプルな「石取りゲーム」を、各部分ごとにわかりやすく説明します。
is_valid_move
関数の定義
def is_valid_move(stones, move): return 1 <= move <= 3 and move <= stones
- 関数の定義:
def
キーワードでis_valid_move
という関数を定義しています。この関数は、プレイヤーが取る石の数が正しいかどうかを判定する役割を持ちます。 - 引数:
stones
とmove
という2つの引数を受け取ります。stones
は残りの石の数で、move
はプレイヤーが選んだ石の数です。 - 条件式:
return
文で「1以上3以下の数で、残りの石より少ないか同じである」ことを確認し、True
またはFalse
を返します。1 <= move <= 3 and move <= stones
は条件式で、Pythonの基本的な論理演算(and
)を使用しています。
take_turn
関数の定義
def take_turn(player, stones): print(f"\n{player}の番です。残りの石は {stones} 個です。") move = int(input(f"{player}, 何個の石を取りますか?(1~3個まで選べます):")) while not is_valid_move(stones, move): print("無効な選択です。もう一度選んでください。") move = int(input(f"{player}, 何個の石を取りますか?(1~3個まで選べます):")) stones -= move return stones
- プレイヤーのターン:この関数は、プレイヤーが石の数を選ぶ手順を管理します。
input
とprint
:input
関数で入力を受け取り、print
関数で残りの石数を表示します。また、f文字列
でメッセージの中に変数の値を挿入します。while
ループ:条件に合わない数を選んだ場合(例えば、4個以上取ろうとした場合)、無効な選択を表示し、再入力を求めます。- 石の数の更新:プレイヤーが選んだ数の石を減らし、残りの石の数を返します。
play_game
関数の定義
def play_game(): print("石取りゲームへようこそ!") stones = 15 turn = 1 while stones > 0: if turn == 1: current_player = "プレイヤー1" else: current_player = "プレイヤー2" stones = take_turn(current_player, stones) if stones == 0: print(f"\n{current_player}が最後の石を取りました。{current_player}の負けです!") break if turn == 1: turn = 2 else: turn = 1
- ゲームの開始メッセージ:
print
関数でゲームの開始を表示し、石の初期数を15個に設定します。 while
ループ:stones
が0より大きい限りゲームを続けます。プレイヤーのターンを管理し、交代させるためにturn
という変数を使用しています。- プレイヤーの交代:
if
文でターンの管理を行い、turn
の値に基づいてプレイヤーを切り替えます。 - ゲームの終了:
stones
が0になった場合はゲーム終了のメッセージを表示し、break
でループを抜けます。
メインプログラムの実行
if __name__ == "__main__": play_game()
この部分では、play_game
関数を呼び出し、ゲームが開始されます。
if __name__ == "__main__":
はPythonでよく使われる構文で、直接実行されるときだけプログラムを動かす役割を持ちます。
まとめ
この石取りゲームのコードは、関数、条件分岐、ループ処理、そしてユーザー入力を使ってシンプルなゲームを作る方法を学ぶ良い例です。
Pythonの基本的な文法を実践するための良い練習問題にもなります。
繰り返しコードを読み解き、手を動かしながら理解を深めていくことで、Pythonプログラミングへの自信がついていくでしょう。
Pythonのゲームコード一覧はこちら
<<前の問題 |
問題集Top |
次の問題>> |
この記事への質問・コメント
この記事を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。