麻雀アプリを作りたい①

せっかくPythonの勉強を始めたので、なにか目標が欲しいなーと思うので
当面は麻雀のWebアプリを作っていこうと思います。
フレームワークはFlaskを使っていきます！

#配牌

**麻雀牌のクラス**
まず、麻雀牌のクラスを作りました。
インスタンス変数は以下の通りです。
　・牌の種類（萬子・筒子・索子・四風牌・三元牌）
　・その値（1~9 東南西北白発中）、
　・画像ファイル名（Webに表示したいので）

```
# 麻雀牌のクラス
class Tile:
    def __init__(self, kind, value, pic):
        self.kind = kind  # 麻雀牌の種類（萬子・筒子・索子・四風牌・三元牌）
        self.value = value  # 麻雀牌の値（1~9 東南西北白発中）
        self.pic = pic  #画像ファイル名
```
※麻雀牌は英語でTileというらしいです。

**山牌**
次に山牌を作ります。
麻雀牌オブジェクトを１３６個作ってlist型の変数(yamahai)に格納します。

```
yamahai = [
          Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '2', 'manzu_2.png')
        , Tile('manzu', '2', 'manzu_2.png')
        , Tile('manzu', '2', 'manzu_2.png')
　　　　　　　・
　　　　　　　・
　　　　　　　・
        , Tile('sangenpai', '3', 'sangenpai_3.png')
        , Tile('sangenpai', '3', 'sangenpai_3.png')
    ]
```

んで、そのyamahaiをシャッフルします。

```
random.shuffle(yamahai)
```

**配牌**
山牌ができたらそれをページを開くたびに14個取り出して画面に表示します。
popメソッドを使えばyamahaiから一個ずつオブジェクトを取り出すことができます。

```
@app.route('/')
def main():

    img_tags = ''
    for i in range(14):
        tile = yamahai.pop(0)  #山牌から一つ取り出す
        img_tags = img_tags + tile.create_img_tag()#画像出力用のHTMLタグ作成

    return img_tags
```


**HTMLタグ作成**
Tileクラスに画像出力用のHTMLタグを作成するメソッドを作ってそれを呼ぶことでHTMLタグを作りました。

```
    def create_img_tag(self):
        return f'<img src=/static/pic/{self.pic}>'
```

HTMLタグの文字列を返却するだけで簡単なWeb画面なら表示することができます。
Flaskだと簡単なものならすぐできますね。

麻雀牌の画像は、/static/picに格納しています。
cssファイルとかも/staticディレクトリに置かないと読み込めないみたいです。
<img width="1213" alt="スクリーンショット 2019-05-15 1.38.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363095/ec0ce296-d216-4c63-a349-a94e339b7d29.png">

**Web表示結果**
Web画面にはこんな感じで表示されました！
<img width="1095" alt="スクリーンショット 2019-05-15 1.49.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363095/7743c207-e7df-2eb0-b04d-f2825215a9d4.png">
HTMLソースは以下の通りです。
<img width="1120" alt="スクリーンショット 2019-05-15 1.52.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363095/f5681e14-b5cf-4b53-880b-756b98ebf265.png">
阿部寛のホームページ並のシンプルさ！


**今後の課題**
理牌できてないとか、yamahaiをクラス変数にしてるからリロードを何回かすると
サーバが落ちるとか課題はいくつかあるので
今後も時間を見つけて機能追加とかしていきたいと思います〜。




```main.py
from flask import Flask
import random

app = Flask(__name__)


# 麻雀牌のクラス
class Tile:
    def __init__(self, kind, value, pic):
        self.kind = kind  # 麻雀牌の種類（萬子・筒子・索子・四風牌・三元牌）
        self.value = value  # 麻雀牌の値（1~9 東南西北白発中）
        self.pic = pic  #画像ファイル名

    def create_img_tag(self):
        return f'<img src=/static/pic/{self.pic}>'

#山牌
yamahai = [
          Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '1', 'manzu_1.png')
        , Tile('manzu', '2', 'manzu_2.png')
        , Tile('manzu', '2', 'manzu_2.png')
        , Tile('manzu', '2', 'manzu_2.png')
        , Tile('manzu', '2', 'manzu_2.png')
        , Tile('manzu', '3', 'manzu_3.png')
        , Tile('manzu', '3', 'manzu_3.png')
        , Tile('manzu', '3', 'manzu_3.png')
        , Tile('manzu', '3', 'manzu_3.png')
        , Tile('manzu', '4', 'manzu_4.png')
        , Tile('manzu', '4', 'manzu_4.png')
        , Tile('manzu', '4', 'manzu_4.png')
        , Tile('manzu', '4', 'manzu_4.png')
        , Tile('manzu', '5', 'manzu_5.png')
        , Tile('manzu', '5', 'manzu_5.png')
        , Tile('manzu', '5', 'manzu_5.png')
        , Tile('manzu', '5', 'manzu_5.png')
        , Tile('manzu', '6', 'manzu_6.png')
        , Tile('manzu', '6', 'manzu_6.png')
        , Tile('manzu', '6', 'manzu_6.png')
        , Tile('manzu', '6', 'manzu_6.png')
        , Tile('manzu', '7', 'manzu_7.png')
        , Tile('manzu', '7', 'manzu_7.png')
        , Tile('manzu', '7', 'manzu_7.png')
        , Tile('manzu', '7', 'manzu_7.png')
        , Tile('manzu', '8', 'manzu_8.png')
        , Tile('manzu', '8', 'manzu_8.png')
        , Tile('manzu', '8', 'manzu_8.png')
        , Tile('manzu', '8', 'manzu_8.png')
        , Tile('manzu', '9', 'manzu_9.png')
        , Tile('manzu', '9', 'manzu_9.png')
        , Tile('manzu', '9', 'manzu_9.png')
        , Tile('manzu', '9', 'manzu_9.png')
        , Tile('pinzu', '1', 'pinzu_1.png')
        , Tile('pinzu', '1', 'pinzu_1.png')
        , Tile('pinzu', '1', 'pinzu_1.png')
        , Tile('pinzu', '1', 'pinzu_1.png')
        , Tile('pinzu', '2', 'pinzu_2.png')
        , Tile('pinzu', '2', 'pinzu_2.png')
        , Tile('pinzu', '2', 'pinzu_2.png')
        , Tile('pinzu', '2', 'pinzu_2.png')
        , Tile('pinzu', '3', 'pinzu_3.png')
        , Tile('pinzu', '3', 'pinzu_3.png')
        , Tile('pinzu', '3', 'pinzu_3.png')
        , Tile('pinzu', '3', 'pinzu_3.png')
        , Tile('pinzu', '4', 'pinzu_4.png')
        , Tile('pinzu', '4', 'pinzu_4.png')
        , Tile('pinzu', '4', 'pinzu_4.png')
        , Tile('pinzu', '4', 'pinzu_4.png')
        , Tile('pinzu', '5', 'pinzu_5.png')
        , Tile('pinzu', '5', 'pinzu_5.png')
        , Tile('pinzu', '5', 'pinzu_5.png')
        , Tile('pinzu', '5', 'pinzu_5.png')
        , Tile('pinzu', '6', 'pinzu_6.png')
        , Tile('pinzu', '6', 'pinzu_6.png')
        , Tile('pinzu', '6', 'pinzu_6.png')
        , Tile('pinzu', '6', 'pinzu_6.png')
        , Tile('pinzu', '7', 'pinzu_7.png')
        , Tile('pinzu', '7', 'pinzu_7.png')
        , Tile('pinzu', '7', 'pinzu_7.png')
        , Tile('pinzu', '7', 'pinzu_7.png')
        , Tile('pinzu', '8', 'pinzu_8.png')
        , Tile('pinzu', '8', 'pinzu_8.png')
        , Tile('pinzu', '8', 'pinzu_8.png')
        , Tile('pinzu', '8', 'pinzu_8.png')
        , Tile('pinzu', '9', 'pinzu_9.png')
        , Tile('pinzu', '9', 'pinzu_9.png')
        , Tile('pinzu', '9', 'pinzu_9.png')
        , Tile('pinzu', '9', 'pinzu_9.png')
        , Tile('souzu', '1', 'souzu_1.png')
        , Tile('souzu', '1', 'souzu_1.png')
        , Tile('souzu', '1', 'souzu_1.png')
        , Tile('souzu', '1', 'souzu_1.png')
        , Tile('souzu', '2', 'souzu_2.png')
        , Tile('souzu', '2', 'souzu_2.png')
        , Tile('souzu', '2', 'souzu_2.png')
        , Tile('souzu', '2', 'souzu_2.png')
        , Tile('souzu', '3', 'souzu_3.png')
        , Tile('souzu', '3', 'souzu_3.png')
        , Tile('souzu', '3', 'souzu_3.png')
        , Tile('souzu', '3', 'souzu_3.png')
        , Tile('souzu', '4', 'souzu_4.png')
        , Tile('souzu', '4', 'souzu_4.png')
        , Tile('souzu', '4', 'souzu_4.png')
        , Tile('souzu', '4', 'souzu_4.png')
        , Tile('souzu', '5', 'souzu_5.png')
        , Tile('souzu', '5', 'souzu_5.png')
        , Tile('souzu', '5', 'souzu_5.png')
        , Tile('souzu', '5', 'souzu_5.png')
        , Tile('souzu', '6', 'souzu_6.png')
        , Tile('souzu', '6', 'souzu_6.png')
        , Tile('souzu', '6', 'souzu_6.png')
        , Tile('souzu', '6', 'souzu_6.png')
        , Tile('souzu', '7', 'souzu_7.png')
        , Tile('souzu', '7', 'souzu_7.png')
        , Tile('souzu', '7', 'souzu_7.png')
        , Tile('souzu', '7', 'souzu_7.png')
        , Tile('souzu', '8', 'souzu_8.png')
        , Tile('souzu', '8', 'souzu_8.png')
        , Tile('souzu', '8', 'souzu_8.png')
        , Tile('souzu', '8', 'souzu_8.png')
        , Tile('souzu', '9', 'souzu_9.png')
        , Tile('souzu', '9', 'souzu_9.png')
        , Tile('souzu', '9', 'souzu_9.png')
        , Tile('souzu', '9', 'souzu_9.png')
        , Tile('sufonpai', '1', 'sufonpai_1.png')
        , Tile('sufonpai', '1', 'sufonpai_1.png')
        , Tile('sufonpai', '1', 'sufonpai_1.png')
        , Tile('sufonpai', '1', 'sufonpai_1.png')
        , Tile('sufonpai', '2', 'sufonpai_2.png')
        , Tile('sufonpai', '2', 'sufonpai_2.png')
        , Tile('sufonpai', '2', 'sufonpai_2.png')
        , Tile('sufonpai', '2', 'sufonpai_2.png')
        , Tile('sufonpai', '3', 'sufonpai_3.png')
        , Tile('sufonpai', '3', 'sufonpai_3.png')
        , Tile('sufonpai', '3', 'sufonpai_3.png')
        , Tile('sufonpai', '3', 'sufonpai_3.png')
        , Tile('sufonpai', '4', 'sufonpai_4.png')
        , Tile('sufonpai', '4', 'sufonpai_4.png')
        , Tile('sufonpai', '4', 'sufonpai_4.png')
        , Tile('sufonpai', '4', 'sufonpai_4.png')
        , Tile('sangenpai', '1', 'sangenpai_1.png')
        , Tile('sangenpai', '1', 'sangenpai_1.png')
        , Tile('sangenpai', '1', 'sangenpai_1.png')
        , Tile('sangenpai', '1', 'sangenpai_1.png')
        , Tile('sangenpai', '2', 'sangenpai_2.png')
        , Tile('sangenpai', '2', 'sangenpai_2.png')
        , Tile('sangenpai', '2', 'sangenpai_2.png')
        , Tile('sangenpai', '2', 'sangenpai_2.png')
        , Tile('sangenpai', '3', 'sangenpai_3.png')
        , Tile('sangenpai', '3', 'sangenpai_3.png')
        , Tile('sangenpai', '3', 'sangenpai_3.png')
        , Tile('sangenpai', '3', 'sangenpai_3.png')
    ]
random.shuffle(yamahai)

@app.route('/')
def main():

    img_tags = ''
    for i in range(14):
        tile = yamahai.pop(0)  #山牌から一つ取り出す
        img_tags = img_tags + tile.create_img_tag()#画像出力用のHTMLタグ作成

    return img_tags


if __name__ == '__main__':
    app.run(port=8080)

```