プログラミング学習を目的とした、ブロックを操作してスコアを競うゲームをpythonで作成する試み

この辺りの先人のコードをベースにしています。
[https://github.com/LoveDaisy/tetris_game](https://github.com/LoveDaisy/tetris_game)
[http://zetcode.com/gui/pyqt5/tetris/](http://zetcode.com/gui/pyqt5/tetris/)

違いは、pythonでブロック操作できるよう改造してる点です。
将来的にはAIでブロック操作できるようにしたいです。（現在プレイヤーは私のみ。。）

# Githubのリポジトリ

本記事のコードは全て以下に記載しています
[https://github.com/seigot/tetris_game](https://github.com/seigot/tetris_game)
[https://github.com/seigot/tetris](https://github.com/seigot/tetris)

# 実行環境準備

Mac環境

Finder→Application→Utility→Terminalから、ターミナルを起動して以下コマンドを実行する。

```
# install pyqt5 and NumPy
brew install python3
pip3 install pyqt5
pip3 install numpy
# install other packages
brew install git
```

[Ubuntu環境はこちら](https://github.com/seigot/tetris_game/blob/master/doc/files/install_ubuntu.md)
[Docker環境も作成](https://github.com/seigot/tetris_game/blob/master/docker/README.md)

# 実行方法

リポジトリを取得

```
git clone https://github.com/seigot/tetris_game
```

ゲーム開始用スクリプトを実行

```
cd tetris_game
bash start.sh
```

デフォルトはランダム操作にしてあります。

![screenshot_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/1a8fc2c3-89e2-1c44-6de5-a9b0cae2c115.png)


# ファイル構成

[こちらから](https://github.com/seigot/tetris_game)ファイル一覧を抜粋

```text:ファイル一覧
game_manager/game_manager.py : ゲーム管理用プログラム
game_manager/board_model.py : ボード管理用プログラム
board_controller.py : ボード制御用プログラム（ブロックの操作は、このファイルを編集して下さい。）
start.sh : ゲーム開始用スクリプト
```

以下のような構成になっています。
ボード制御用プログラムは、管理プログラムから定期的に呼び出されるので、ボード情報から次の動作を決定するようにしています。

![20201017-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/8927ab5a-0c5c-6197-b0e9-adef31a8dcb3.png)

各プログラムの詳細は[こちら](https://github.com/seigot/tetris_game/blob/master/doc/files/board_model.md)

## サンプルコード

実行時、以下のようにオプションを与えることで、サンプルコードの実行が可能です。
サンプルコードは[こちら](https://github.com/seigot/tetris_game/blob/master/game_manager/board_controller_sample.py)を参照下さい。

```shell
bash start.sh -s y
```

## How to play manually
実行時、以下のようにオプションを与えることで、手動操作が可能です。

```shell
bash start.sh -m y
```

|  操作キー  |  動作  |
| ---- | ---- |
|  *up* key  |  回転  |
|  *left* key  |  左に移動  |
|  *right* key   |  右に移動  |
|  *m* key  |  下に移動  |
|  *space* key  |  落下  |
|  *P* key  |  Pause  |

# Play rules

制限時間内の獲得スコアを評価します。

## Score

加点

|  項目  |  得点  |  備考  |
| ---- | ---- |  ---- |
|  1ライン消し  |  + 100点  |  -  |
|  2ライン消し  |  + 300点  |  -  |
|  3ライン消し  |  + 700点  |  -  |
|  4ライン消し  |  + 1300点  |  -  |
|  落下ボーナス  |  + 落下したブロック数を得点に加算  |  -  |

減点

|  項目  |  得点  |  備考  |
| ---- | ---- |  ---- |
|  gameover  |  - 500点  | ブロック出現時にフィールドが埋まっていたらgameover


## game level

実行時、オプションを与えることで、難易度（レベル）を指定できます。

|     |  level0  |  level1  |  level2  |  level3  | 
| --- | --- | --- | --- | --- | 
|  実行方法  | bash start.sh | bash start.sh -l1 | bash start.sh -l2  | bash start.sh -l3 | 
|  制限時間  |  なし  |  300秒  |  300秒  |  300秒  | 
|  次のブロック  |  固定  |  固定  |  ランダム  |  ランダム  | 
|  フィールドの初期ブロック  |  なし  |  なし  |  なし  |  あり  | 
|  フレーム更新頻度  |  約1秒  |  約1秒  |  約1秒  |  約1秒  | 
|  備考  |  練習用  |  -  |  -  |  -  | 

## 次のブロックのランダム性

次のブロックは、現在はランダム関数を使ってランダムに選択しています。
しかし、[こちらの記事](https://gigazine.net/news/20191116-tetris-algorithm/)によると選択方式が色々ありそうです。
有識者の方からアドバイス頂けると嬉しいです。

* 参考：次のブロック選択処理 [game_manager.py](https://github.com/seigot/tetris_game/blob/master/game_manager/game_manager.py)

```
nextShapeIndex = np_randomShape.random.randint(1, 7)
```

# その他

今後、AIを実装しやすいようにルール等、変更していくかもしれません。
何か感想やアドバイス等あれば教えて頂けると幸いです。

# 参考
[https://github.com/LoveDaisy/tetris_game](https://github.com/LoveDaisy/tetris_game)
[http://zetcode.com/gui/pyqt5/tetris/](http://zetcode.com/gui/pyqt5/tetris/)
[テトリスの歴史を「ブロックが落ちるルール」の進化から学ぶ](https://gigazine.net/news/20191116-tetris-algorithm/)
[https://github.com/seigot/tetris_game](https://github.com/seigot/tetris_game)