[Python]作りたいものがない人に向けたプログラム集[初心者向け]

Python

このページは「Pythonで何か作ってみたいけど、作りたいものがない」という初心者の方に向けて、簡単に作れそうなものを紹介します。

  • おみくじ
  • じゃんけん
  • まるばつゲーム

この3つです。

順に難易度が上がるようになっています。

 Androidアプリを作成しました。
 感情用のメモ帳です。

スポンサーリンク
スポンサーリンク

おみくじ

おみくじは「大吉」、「」、「」、「大凶」の中からランダムに選んで表示させます。

ランダムに選ぶには標準ライブラリにピッタリのものがあるのでそれを使います。

random」をインポートし、randomのメソッド「choice」の引数に運勢を入れたリストを渡すと、ランダムでひとつ取り出してくれます。

import random


fortunes = ['大吉', '吉', '凶', '大凶']
fortune = random.choice(fortunes)
print(fortune)

実行しましょう。

$ python3 omikuji.py
吉
$ python3 omikuji.py
大吉
$ python3 omikuji.py
凶
$ python3 omikuji.py
大凶
$ python3 omikuji.py
大吉

実行するたびに運勢が変わっています。

しかし、これだけではあまりに味気ない気がしますね。
少し出力を変えてプログラムらしくしてみましょう。

import random
import time


fortunes = ['大吉', '吉', '凶', '大凶']
fortune = random.choice(fortunes)

print('おみくじを引きます・・・')
time.sleep(1)
for i in range(3):
    if i % 2 == 0:
        print('ガサッ')
    else:
        print('ゴソッ')
    time.sleep(1)
print('_人人人人人人人人人_')
print(f'>{fortune.center(16)}<')
print(' ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄')

標準ライブラリの「time」をインポートしました。
このtimeのメソッド「sleep」を使うと、引数に渡した数値分、プログラムが待機します。

for文のなかの「i % 2 == 0」は、iが偶数かどうかの判定です。
偶数なら「ガサッ」、奇数なら「ゴソッ」がprintされ、一秒間待ってループに戻っています。

print(f'>{fortune.center(16)}<')

上記のcenterは、文字列のメソッドで()内の数値分、横幅(width)を取った上で、fortuneの中身の文字列のセンター寄せを行います。

では、実行してみます。

$ python3 omikuji.py
おみくじを引きます・・・
ガサッ
ゴソッ
ガサッ
_人人人人人人人人人_
>       大吉       <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

実行すると、「ガサッ」、「ゴソッ」、「ガサッ」の間に一秒の間ができているため、おみくじを引く臨場感が出せているかなと思います。

最初のと比べるとだいぶプログラムらしくなりました。

「random」には他にもメソッドがあり、「randint」を使うと、擬似的なサイコロにすることもできます。

$ python3
Python 3.10.0 (default, Oct 12 2021, 16:02:08) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> random.randint(1, 6)
3
>>> random.randint(1, 6)
6
>>> random.randint(1, 6)
2
>>> random.randint(1, 6)
5
>>> random.randint(1, 6)
1

じゃんけん

じゃんけんはユーザーから手を選択してもらい、ランダムに選ばれた手と比較して勝敗を決めます。

ユーザーの手とコンピュータの手の組み合わせを網羅し、判定します。

入力と勝利判定まで作ります。ふたたび「random」を使用。

import random


rock_paper_scissors = ['グー', 'チョキ', 'パー']
print('じゃんけんしましょう')
print('番号を入力してね')
print('1番・グー 2番・チョキ 3番・パー')

number = input('あなたの手は? ')
if number == '1':
    user = 'グー'
elif number == '2':
    user = 'チョキ'
elif number == '3':
    user = 'パー'

cpu = random.choice(rock_paper_scissors)
print(f'あなたは{user}。向こうは{cpu}。')

if user == 'グー':
    if cpu == 'グー':
        print('あいこ!')
    elif cpu == 'チョキ':
        print('あなたの勝ち!')
    elif cpu == 'パー':
        print('あなたの負け!')
elif user == 'チョキ':
    if cpu == 'グー':
        print('あなたの負け')
    elif cpu == 'チョキ':
        print('あいこ!')
    elif cpu == 'パー':
        print('あなたの勝ち!')
elif user == 'パー':
    if cpu == 'グー':
        print('あなたの勝ち!')
    elif cpu == 'チョキ':
        print('あなたの負け!')
    elif cpu == 'パー':
        print('あいこ!')
$ python3 janken.py 
じゃんけんしましょう
番号を入力してね
1番・グー 2番・チョキ 3番・パー
あなたの手は? 3
あなたはパー。向こうはチョキ。
あなたの勝ち!

上手く行っているように見えますが、問題があって、入力の際、ユーザーが番号を押し間違えると、エラーが出てしまいます。

$ python3 janken.py
じゃんけんしましょう
番号を入力してね
1番・グー 2番・チョキ 3番・パー
あなたの手は? g   
Traceback (most recent call last):
  File "/home/fujino/janken.py", line 18, in <module>
    print(f'あなたは{user}。向こうは{cpu}。')
NameError: name 'user' is not defined. Did you mean: 'super'?

入力で'1'、'2'、'3'のどれにも引っかからず、userが定義されなかったためです。

これを回避するために、while文のなかに入力と判定処理を入れ、有効な番号が押されるまでは、ループし続けるように変更します。

以下のように変えました。

while True:
    number = input('あなたの手は? ')
    if number == '1':
        user = 'グー'
        break
    elif number == '2':
        user = 'チョキ'
        break
    elif number == '3':
        user = 'パー'
        break
$ python3 janken.py 
じゃんけんしましょう
番号を入力してね
1番・グー 2番・チョキ 3番・パー
あなたの手は? 4
あなたの手は? 5
あなたの手は? f
あなたの手は? 2 
あなたはチョキ。向こうはパー。
あなたの勝ち!

実行すると、有効な数字が入るまでループを続けています。

次に気になるのは、あいこであっても処理が終わってしまうことです。

あいこだったら処理を続けたい……。

勝ち、負け、あいこ、に対応する変数をそれぞれ用意し(win・lose・draw)、あいこには「True」を入れ、他を「False」とします。

ユーザーの入力からコードの末尾までをまるごとwhileのなかに入れ、あいこが続く限り(draw == Trueのあいだ)ループを回してじゃんけんを続けさせます。

また、判定時にprintするのを止め、ユーザーの勝ちなら「win = True」、負けなら「lose = True」に設定し、どちらの場合でも「draw = False」に設定します。

import random


rock_paper_scissors = ['グー', 'チョキ', 'パー']
print('じゃんけんしましょう')
print('番号を入力してね')
print('1番・グー 2番・チョキ 3番・パー')

win = False
lose = False
draw = True

while draw:
    while True:
        number = input('あなたの手は? ')
        if number == '1':
            user = 'グー'
            break
        elif number == '2':
            user = 'チョキ'
            break
        elif number == '3':
            user = 'パー'
            break

    cpu = random.choice(rock_paper_scissors)
    print(f'あなたは{user}。向こうは{cpu}。')

    if user == 'グー':
        if cpu == 'チョキ':
            win = True
            draw = False
        elif cpu == 'パー':
            lose = True
            draw = False
    elif user == 'チョキ':
        if cpu == 'グー':
            lose = True
            draw = False
        elif cpu == 'パー':
            win = True
            draw = False
    elif user == 'パー':
        if cpu == 'グー':
            win = True
            draw = False
        elif cpu == 'チョキ':
            lose = True
            draw = False

    if win:
        print('あなたの勝ち!')
    elif lose:
        print('あなたの負け!')
    else:
        print('あいこ!')

ユーザーとコンピュータの手の組み合わせに、あいこだった場合の分岐が必要なくなりました。

実行します。

$ python3 janken.py
じゃんけんしましょう
番号を入力してね
1番・グー 2番・チョキ 3番・パー
あなたの手は? 2
あなたはチョキ。向こうはチョキ。
あいこ!
あなたの手は? 2
あなたはチョキ。向こうはチョキ。
あいこ!
あなたの手は? 1
あなたはグー。向こうはパー。
あなたの負け!

想定通りに動きました。

これで終わり! でもいいですが、やっぱりもうちょっと出力を整えてみます。

また「time」モジュールの「sleep」メソッドを使います。

import random
import time


rock_paper_scissors = ['グー', 'チョキ', 'パー']
print('じゃんけんしましょう')
print('1・グー 2・チョキ 3・パー')
print('数字を入力してね\n')

win = False
lose = False
draw = True

while draw:
    while True:
        number = input('あなたの手は? ')
        if number == '1':
            user = 'グー'
            break
        elif number == '2':
            user = 'チョキ'
            break
        elif number == '3':
            user = 'パー'
            break

    cpu = random.choice(rock_paper_scissors)

    print(f'{user}だね。いくよ!\n')
    time.sleep(1.5)
    print('じゃん!')
    time.sleep(0.7)
    print('けん!')
    time.sleep(0.7)
    print('ぽん!')
    print(f'【あなた】{user} vs {cpu}【CPU】')
    if user == 'グー':
        if cpu == 'チョキ':
            win = True
            draw = False
        elif cpu == 'パー':
            lose = True
            draw = False
    elif user == 'チョキ':
        if cpu == 'グー':
            lose = True
            draw = False
        elif cpu == 'パー':
            win = True
            draw = False
    elif user == 'パー':
        if cpu == 'グー':
            win = True
            draw = False
        elif cpu == 'チョキ':
            lose = True
            draw = False

    if win:
        print('あなたの勝ち!')
    elif lose:
        print('あなたの負け!')
    else:
        print('あいこ!')
$ python3 janken.py
じゃんけんしましょう
1・グー 2・チョキ 3・パー
数字を入力してね

あなたの手は? 2
チョキだね。いくよ!

じゃん!
けん!
ぽん!
【あなた】チョキ vs チョキ【CPU】
あいこ!
あなたの手は? 2
チョキだね。いくよ!

じゃん!
けん!
ぽん!
【あなた】チョキ vs パー【CPU】
あなたの勝ち!

テキストをいくつか追加して「じゃん」「けん」「ぽん」のあいだにプログラムを待機させて間を置いています。

まるばつゲーム

最後はまるばつゲームです。

プレイヤーが○と✕を交互に書くようにします。

○は大文字のオー「'O'」、✕は大文字のエックス「'X'」を使います。

まず'1'から'9'までの数字を小さい順に3つずつリストに入れます。3つのリストができるので、それをまた別のリストに収めます。
このひとつになったリストを「3×3」のマス(盤面)として扱います。

board = [['1', '2', '3'],
         ['4', '5', '6'],
         ['7', '8', '9']]

そしてこの数字に対応した辞書を定義し、リストにアクセスするためのインデックス(リストの高さ, 横幅)をタプルとして入れておきます。

height_width = {'1': (0, 0), '2': (0, 1), '3': (0,2),
                '4': (1, 0), '5': (1, 1), '6': (1, 2),
                '7': (2, 0), '8': (2, 1), '9': (2, 2)}

どういうことかというとプレイヤーが'1'を入力したとき、height_width['1']とすると(0, 0)を取り出すことができ、このタプルの数値を使ってboard[0][0]とすることで、boadの'1'の所をプレイヤーの○✕に書き換えることができるようになります。

user = '1'
h, w = height_width[user]
# 上の書き方は次のようにも書ける
# h = height_width[user][0]
# w = height_width[user][1]
board[h][w] = 'X'

また入力からゲーム終了までwhile文に収めます。

入力に関しては、プレイヤーから有効な数字を入力してもらい、対応したマスの配列がすでに'O'や'X'でなければ、マルかバツに変えます。

どちらかが3つそろうか、そろわずにすべてのマスが埋まっているかの判定をして、ゲームを終了させます。

判定は具体的に、次の4つです。

  1. 盤面の横3列がそろっているか
  2. 盤面の縦3列がそろっているか
  3. 盤面の斜め2列がそろっているか
  4. そろわずに全て埋まっているいるか

では、私なりに作ってみます。

board = [['1', '2', '3'],
         ['4', '5', '6'],
         ['7', '8', '9']]

height_width = {'1': (0, 0), '2': (0, 1), '3': (0,2),
                '4': (1, 0), '5': (1, 1), '6': (1, 2),
                '7': (2, 0), '8': (2, 1), '9': (2, 2)}

print('○ まるばつゲーム ✕')
print('1から9までの数字を入力してね!')
for lines in board:
    for line in lines:
        print(line, end=' ')
    print()

count = 0
winner = ''

while not winner:
    if count % 2 == 0:
        player = 'O'
    else:
        player = 'X'

    while True:
        print(f'{player}のターン!')
        user = input('数字を入力 → ')
        if user in ['1', '2', '3', '4', '5', '6', '7', '8', '9']:
            h, w = height_width[user]
            if board[h][w] == 'O' or board[h][w] == 'X':
                print('そこには書けないよ!')
            else:
                board[h][w] = player
                break
        else:
            print('1から9までの数字を入力してね')

    count += 1

    for lines in board:
        for line in lines:
            print(line, end=' ')
        print()

    # 横方向の判定
    for y in range(3):
       if board[y][0] == board[y][1] == board[y][2]:
            winner = board[y][0]
            break

    # 縦方向の判定
    for x in range(3):
        if board[0][x] == board[1][x] == board[2][x]:
            winner = board[0][x]
            break

    # 斜め(\)の判定
    if board[0][0] == board[1][1] == board[2][2]:
        winner = board[0][0]

    # 斜め(/)の判定
    if board[0][2] == board[1][1] == board[2][0]:
        winner = board[0][2]

    # 全てのマスが埋まっているか
    if count == 9:
        break

if winner:
    print(f'{winner}の勝ち!')
else:
    print('引き分け!')
 print(line, end=' ')

上記の「end=' '」は、通常なら改行するところを、改行の代わりにスペースをひとつ置いて次のlineをprintします。

変数「count」は0からスタートし、マス目を書いたときに1が足されます。
ユーザーの選択(countが偶数なら○、奇数なら✕)と、マス目が9個埋まっているかの判定に利用します。

winnerには最初空文字('')を入れておき、勝者が出たらそれを代入します。
whileやif文に空文字を使うと、真偽値は偽になるため、「while not winner」とし、winnerが空文字である間ループさせます。

winner = ''
# printは実行されない
while winner:
    print('Winner')

実行すると次のような出力になりました。

$ python3 marubatu.py
○ まるばつゲーム ✕
1から9までの数字を入力してね!
1 2 3 
4 5 6 
7 8 9 
Oのターン!
数字を入力 → 1
O 2 3 
4 5 6 
7 8 9 
Xのターン!
数字を入力 → 1
そこには書けないよ!
Xのターン!
数字を入力 → 53
1から9までの数字を入力してね
Xのターン!
数字を入力 → 2
O X 3 
4 5 6 
7 8 9 

# 長いので略

数字を入力 → 7
O X O 
X O X 
O 8 9 
Oの勝ち!

# ドローの場合
O X O 
O X X 
X O O 
引き分け!

まとめ

Pythonを勉強して文法を覚えてきた頃、なにか作りたいと思っても作りたいものなんてなかったなあと思い出し、このページを書いてみました。

なるべく初心者向けにして、例外処理、関数、リスト内包表記など使わないように書いたのですが、分かりにくいところはなかったでしょうか。

私がPythonを使って初めて自力で作ったものはタイマーです。

結局すぐ使わなくなりましたが、それからちょくちょく自分なりに作ってみるようになりました。

まだ私も初心者に毛の生えたようなものですが、このページが役に立ったらうれしいです。

タイトルとURLをコピーしました