はじめに
前回は、コンピュータとじゃんけんを1回するプログラムを作りました。
もちろん、前回のプログラムでも目的の「じゃんけん」は行えました。
しかし、勝敗の判定をゴリ押しで記述していたり、1回勝負のみであったりと改善の余地はありそうです。
今回は、前回のプログラムを元にして、新しい機能を追加しましょう。
改修ポイントを整理しよう!
今回のプログラミングで作成したいことをまとめました。
「勉強のため」という思いもありますが、プログラムの改善としては至って普通な発想だと思います。
(2) 関数を使って、処理の別箇所に纏めて整理する
(3) 繰り返しを使って、3勝先取のゲームにする
(1)と(2)はリファクタリングと呼ばれ、プログラムをキレイに整える作業です。
これは、後々プログラムを見返したとき、「何書いてあるか分からない」と困らないようにために行います。
※何事も、整理整頓が大事ですね(笑)
(3)は機能追加(アップデート)となります。
※スマホゲームで、新しいステージやキャラクター、アイテムが追加されるのと同じです。
「じゃんけんプログラム(改)」の全体像
今回も、プログラムの全体を眺めるところから始めましょう。
なんか記述量が増えたような、減ったような感じですね・・・
#########################
# パッケージのインポート #
#########################
import random
##################
# 関数の定義 #
##################
# 勝敗判定の関数
def judgment(player, com):
# ジャンケンの勝敗ルールを設定
rules =(("あいこ", "勝ち", "負け"),
("負け", "あいこ", "勝ち"),
("勝ち", "負け", "あいこ"))
# プレイヤーとコンピュータの出手の組み合わせで勝敗を決定
return rules[player][com]
# 結果表示の関数
def showResult(com_hand, player_hand, result):
print(f"コンピュータは、「{com_hand}」を出しました")
print(f"あなたは、「{player_hand}」を出したので、「{result}」です")
########################
# 出し手の種類を設定 #
########################
hands = ["グー", "チョキ", "パー"]
#############################
# コンピュータと3勝先取の勝負 #
#############################
win = 0
lose = 0
while win < 3 and lose < 3 :
# コンピュータの出し手を決定
com = random.randint(0, 2)
# プレイヤーの出し手を決定
print("0:グー 1:チョキ 2:パー")
player = int(input("じゃんけん・・・"))
# 勝敗判定の関数を実行
result = judgment(player, com)
# 結果表示の関数
showResult(hands[com], hands[player], result)
# 勝敗のカウント
if result == "勝ち":
win +=1
elif result == "負け":
lose +=1
# 勝敗数の表示
print(f"プレイヤーは、{win}勝 {lose}負 です")
print("-------------------------------------------------")
Jupyter Notebookで書く場合の注意ですが、インデントで纏まった処理単位は1つのセルに記載します。
改修ポイントごとにプログラムを説明
タプルを使って、勝敗判定の処理をシンプルにする
前回は、両者の出し手「グー」「チョキ」「パー」を文字列とし比較すること勝敗判定を行っていました。
しかし、これではあまりにも複雑で分かりにくいです。
なにより、「そもそも文字列で比較する必要はあるのか?」も疑問に思います。
そこで、今回はタプルを使ってこの判定処理をシンプルにすることを目指します!
まず、じゃんけんの出し手の組み合わせと勝敗を整理すると、次の表のようになります。
これを、高校数学で習った行列と見立てます。
※ピンと来ない場合は、ただの表と同じだと思ってください、、、
Pythonでは、複数の要素をまとめて管理する場合、先頭を0番目と設定します。
すると、行番号と列番号から設定された要素を指定することができます。
・「0行、0列」は、”あいこ”
・「0行、1列」は、”勝ち”
〜〜〜〜
・「3行、2列」は、”負け”
・「3行、3列」は、”あいこ”
これを、タプルで記述すると次のようになります。
※( )の中に( )を重ねるとタプルの中に「行」を増やすことができます。
# ジャンケンの勝敗ルールを設定
rules =(("あいこ", "勝ち", "負け"),
("負け", "あいこ", "勝ち"),
("勝ち", "負け", "あいこ"))
要素の指定は、「変数名[行番号][列番号]」で指定できます。
今回は、「行」をプレイヤーの出し手、「列」をコンピュータの出し手に見たているので次のように記載します。
※「retrun」の意味は、「関数」の中で解説します。
rules[player][com]
前回の条件分岐のゴリ押しよりも、ずいぶんスッキリした気がしますね♪
関数を使って、処理の別箇所に纏めて整理する
まず、関数とは何かを説明します。
関数とは、「ある処理を1つに纏めたモノ」になります。
今回であれば、「勝敗判定」や「結果表示」を1つの纏まりと捉えて関数にしました。
関数の作り方と呼び出し方(使用方法)次のようになります。
# 関数の作り方
def 関数名(引数①, 引数②, ・・・):
〜〜 処理 〜〜
return 返り値
# 関数の呼び出し方
関数名(引数①, 引数②, ・・・)
引数とは、関数の処理で使う値のことです。
たとえば、「judgment(player, com)」では「player」と「com」を処理内で使用します。
その「player」と「com」は、関数を呼び出すときに値を設定しておく必要があります。
※今回は引数を、関数の作成時と呼び出し時で同じ変数にしましたが、データ型が同じであれば変数名を変えても大丈夫です。
返り値とは、関数の処理結果を受け取る時の値のことです。
たとえば、「judgment(player, com)」では関数内で処理した後、勝敗判定の結果を後続処理で使用します。
その後続処理で使用する値を返り値として、関数の最後に設定します。
※「showResult」のように必要な処理を関数内で完結させ、処理結果を後続処理で使用しない場合は返り値を設定する必要はありません。
繰り返しを使って、3勝先取のゲームにする
最後に、繰り返しについて説明します。
今回の、「どちらかが3回勝つまで勝負を続ける」ことを行いたい場合、同じプログラムを何回も書くことはナンセンスです。
※そもそも、何回繰り返したらどちらかが3回勝つかは分からないです。
そこで、「条件を満たすまで処理を行う繰り返し処理」を使用します。
Pythonでの繰り返し処理は次のように記載します。
(1) forループ
オブジェクト(配列など)の中身を変数に代入し、全ての中身を順番に使い終わるまで処理を繰り返す。
for 変数 in オブジェクト:
〜〜 処理 〜〜
(2) whileループ
条件式が真であり続ける時、処理を繰り返す。
while 条件式:
〜〜 処理 〜〜
今回は「(2) whileループ」を使用し、「勝ちが3より少ない かつ 負けが3より少ない」ときは処理(じゃんけん)を繰り返すように設定しました。
※すなわち、どちらもプレイヤーとコンピュータのどちらも3勝していない間は勝負を続けます。
勝敗の管理は、「win」「lose」で行います。
最初に、誤った値が混入しないように両者に”0″を代入します。
その後、勝ちと負けに応じて、どちらかに”+1″加算します。
※「win += 1」とは、「win = win + 1」のように自分自身に右辺の値を加算する場合の省略表現です。
最後に
ここまでで、プログラミングにおける基本的な概念を学ぶことができました。
意外かもしれませんが、どんなに複雑なプログラムであっても以下の組み合わせで成り立っています。
・条件分岐で必要な処理を実行する。
・類似する処理を必要な分だけ繰り返す。
・関数を用いて処理を纏める。
・有用なパッケージはインポートして使用する。
あとは、どんなに単純なプログラムでも良いのでどんどん作ってみて経験値を上げましょう。
プログラミングの本質は単純ですが、使いこなすには慣れや場数が必要です。
このブログでも、面白そうなプログラムを作成しますので、一緒に勉強していきましょう!!
コメント