A Tetris Game for programming education

Overview

Tetris Game

プログラミング学習を目的とした、ブロックを操作してスコアを競うゲームです。
FAQはこちら。
tutorialはこちら。

実行環境準備

Mac環境

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

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

doc/files/install_mac.mdに上記手順を記載

Ubuntu/JetsonNano環境

doc/files/install_ubuntu.mdに手順を記載

windows環境

WSL(Windows Subsystem for Linux)を使う場合の手順
Docker for Windowsを使う場合の手順

docker環境

docker/README.mdに手順を記載

実行方法

本リポジトリを取得

cd $HOME
git clone https://github.com/seigot/tetris_game

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

cd tetris_game
bash start.sh

Screenshot

ファイル構成

ファイル一覧

  • game_manager/game_manager.py : ゲーム管理用プログラム
  • game_manager/board_manager.py : ボード管理用プログラム
  • block_controller.py : ブロック操作用プログラム(ブロックの操作は、このファイルを更新して下さい。)
  • start.sh : ゲーム開始用スクリプト

詳細

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

Screenshot

詳細

手動操作

実行時、以下のようにオプションを与えることで、手動操作が可能です。 操作方法は、PC操作準拠とゲーム機コントローラ準拠の2種類を選択できるようにしています。

手動操作 PC操作準拠 ゲーム機コントローラ準拠
実行コマンド bash start.sh -m y bash start.sh -m g
up key 回転 落下
left key 左に移動 左に移動
right key 右に移動 右に移動
m key 下に移動 下に移動
space key 落下 回転
P key Pause Pause

スコアアタック用サンプルコード

実行時、以下のようにオプションを与えることで、スコアアタック用サンプルコードの実行が可能です。
サンプルコードについてブロック操作用サンプルプログラムを参照下さい。

bash start.sh -s y

Play rules

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

Score

加点

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

減点

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

game level

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

level1 level2 level3
実行方法 bash start.sh bash start.sh -l2 bash start.sh -l3
制限時間 180秒 180秒 180秒
ブロックの順番 固定(1-7まで順番に繰り返し) ランダム ランダム
フィールドの初期ブロック なし なし あり
フレーム更新頻度 約1秒 約1秒 約1秒
備考 - - -

各レベルの参考スコア

コード作成のはじめかた

本リポジトリのfork

まず、Githubアカウントを取得して本リポジトリを自リポジトリにforkして下さい。

リポジトリのフォークの例

  1. GitHubアカウントを作成/ログインする。
  2. GitHub で、https://github.com/seigot/tetris_gameリポジトリに移動します
  3. ページの右上にある [Fork] をクリックします。
    参考:リポジトリをフォークする

その後、自リポジトリにforkしたtetris_gameをローカルマシンに取得して下さい。

"さん(yourname=自分のアカウント名に読みかえて下さい)のリポジトリを取得する場合 git clone https://github.com/seigot/tetris_game # このリポジトリを取得する場合 ">
cd ~
git clone https://github.com/
    
     /tetris_game   # "
     
      "さん(yourname=自分のアカウント名に読みかえて下さい)のリポジトリを取得する場合
git clone https://github.com/seigot/tetris_game       # このリポジトリを取得する場合

     
    

既にtetris_gameが存在しており、これを削除したい場合はrm -fを実行して下さい。

sudo rm -rf tetris_game

取得後はソースコード変更、変更リポジトリに反映する等してアップデートを進めて下さい。

実行

実行方法を参考に実行環境の構築をして下さい。
環境構築の完了後、ブロック操作用プログラムblock_controller.pyを更新していってください。

自リポジトリのバイナリを公式リリースする

提出時、自リポジトリのバイナリを公式リリースする場合は、Githubリリースの機能を使うと簡単なのでお勧めです。

自リポジトリのコードを提出(バイナリリリース)する場合の手順参考
リポジトリのリリースを管理する
7.オプションで、コンパイルされたプログラムなどのバイナリファイルをリリースに含めるには、ドラッグアンドドロップするかバイナリボックスで手動で選択します。

本リポジトリの最新バージョン取り込み

今後、本リポジトリもバージョンアップしていく予定です。
本リポジトリのバージョンアップを取り込む場合は、forkしたリポジトリにて以下を実行して下さい。

※追記 2021/5より、Github UI上から操作可能になったようです。
GitHub新機能「Fetch upstream」使ってみた! 1クリックで親リポジトリに追従(同期)

git checkout master                                        # ローカルのmainブランチに移動
git remote add upstream https://github.com/seigot/tetris_game  # fork元のリポジトリをupstream という名前でリモートリポジトリに登録(名前はなんでもいい。登録済みならスキップ)
git fetch upstream                                         # upstream から最新のコードをfetch
git merge upstream/master                                  # upstream/main を ローカルのmaster にmerge
git push                                                   # 変更を反映

参考:github で fork したリポジトリで本家に追従する

Pull Requestを送る(Optional)

本リポジトリへ修正リクエストを送ることが可能です。詳しくは参考をご参照下さい。

※追記 Pull Request練習用リポジトリを作成しました。
test_pull_request

参考:
GitHub-プルリクエストの作成方法
[実践] はじめてのPull Requestをやってみよう
【GitHub】Pull Requestの手順

FAQ

doc/files/FAQ.mdを参照下さい。

参考

https://github.com/LoveDaisy/tetris_game
https://github.com/seigot/tetris_game(2021.12時点まで使用) http://zetcode.com/gui/pyqt5/tetris/
テトリスの歴史を「ブロックが落ちるルール」の進化から学ぶ

今後の課題

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

次のブロックのランダム性は、現在はrandom関数の出力に依存しています。
しかし、こちらの記事によると選択方式が色々ありそうです。
有識者の方からアドバイス頂けると助かります。

nextShapeIndex = np_randomShape.random.randint(1, 8)

対戦モード実装

準備中

AI実装

準備中

自動評価

準備中

LICENSE

MIT LICENSE

Finnaly

~ HAVE FUN ~

Comments
  • 179手目に時間が掛かると180手目が落ちない(179手目の時点で0.5sec遅れになっていたら180個目が落ちない)

    179手目に時間が掛かると180手目が落ちない(179手目の時点で0.5sec遅れになっていたら180個目が落ちない)

    179手目に時間が掛かると180手目が落ちない (179手目の時点で0.5sec遅れになっていたら180個目が落ちない)

    理想  179手目を処理した時点で180sec以内であれば最後の手を置いてから終了させたい。

    現状  コールバック処理を終えた時点で179.5secを超えていたら終了する(最後の処理が179.5未満に始まっていたらOK)  179手目を処理した時点で0.5sec遅れになっていたら180個目が落ちなくなる(少し厳し目設定になっていそう)

    対策案  案1.) 現状のまま  案2.) 時間を調整する  案3.) 何かしら代案を検討する

    以下を確認する必要がある

    • level1,2,3で期待通り動作すること(python start.py -l1、python start.py -l2、python start.py -l3)
    • level3+αで期待通り動作すること(python start.py -l3 -d1)
    • AIの学習処期が期待通り動作すること(python start.py -l2 -m train -d1 -t -1 )-

    影響範囲

    • ルール
    • fork先のコード
    • 自動実行環境(スコア、大会)
    opened by seigot 5
  • board_manager.py L.200 で nextShape の minY を取得しているのにもかかわらず、L.204 で tryMoveCurrent を実行しているのは正しくないかもしれない

    board_manager.py L.200 で nextShape の minY を取得しているのにもかかわらず、L.204 で tryMoveCurrent を実行しているのは正しくないかもしれない

    board_manager.py L.200 で nextShape の minY を取得しているのにもかかわらず、L.204 で tryMoveCurrent を実行しているのは正しいでしょうか? https://github.com/seigot/tetris/blob/8514ce133d30c3dc7e44a97be6dcdaee33865843/game_manager/board_manager.py#L200

    opened by seigot 5
  • train_sampleでなるべくcpコマンドを使わない検討(powershellでエラーになる)

    train_sampleでなるべくcpコマンドを使わない検討(powershellでエラーになる)

    train_sampleでなるべくcpコマンドを使わない検討(powershellでエラーになる)

    いまさらですが、train_sample を動かしてみました。 win11 + python3.9 + VSCode (PowerShell) 環境ですが、  pip install torch torchvision torchaudio  pip install omegaconf  pip install hydra-core --upgrade  pip install tensorboardX あたりが必要でした。 また、cp コマンドが組み込まれており、エラーになります。 結果保存用でしょうか。 おそらく alias が効かなくて、 DOS プロンプト想定で、copy コマンドにせねばならないのだろうと思われます。 また、train_sampleは、赤ちゃんのようですね。 もう少し強いサンプルがあればなと思いました。 自分で教育せよということですよね。 というわけで、上記情報を共有しておきます。

    opened by seigot 3
  • Dev

    Dev

    機械学習用チュートリアルのノートブックを追加しました。 追加したファイルは以下です.

    • game_manager/machine_learning/model/tutorial/tutorial1.ipynb #DQN実行用のチュートリアル
    • game_manager/machine_learning/model/tutorial/tutorial2.ipynb #MLP実行用のチュートリアル
    • game_manager/machine_learning/model/tutorial/tutorial3.ipynb #強化学習の推論用チュートリアル

    よろしくお願いします。

    opened by bushio 2
  • block_controller_train_sample.pyにてゲームオーバー時の学習処理を実装したい

    block_controller_train_sample.pyにてゲームオーバー時の学習処理を実装したい

    ・block_controller_train_sample.pyに強化学習のサンプルコードを実装する予定 ・強化学習はゲームオーバー時にモデルを更新する必要があるが、ゲームオーバー判定はgame_manager.py側で行っている ・block_controller_train_sample.py側でモデルの更新処理をするための処理を追加したい

    opened by seigot 2
  • `python start.py`実行時に`TypeError: arguments did not match any overloaded call:`エラーが出る

    `python start.py`実行時に`TypeError: arguments did not match any overloaded call:`エラーが出る

    TypeError: arguments did not match any overloaded call:エラーが出る

    Desktop\work\tetris> python start.py
    game_level: 1
    game_time: 180
    RANDOM_SEED: 0
    IS_MODE :default
    OBSTACLE_HEIGHT: 0
    OBSTACLE_PROBABILITY: 0
    USER_NAME: window_sample
    RESULT_LOG_JSON: result.json
    Python 3.10.0
    CompletedProcess(args='python --version', returncode=0, stderr='')
    Traceback (most recent call last):
      File "C:\Users\staka\Desktop\work\tetris\game_manager\game_manager.py", line 621, in paintEvent
        drawSquare(painter, x * self.gridSize + dx, y * self.gridSize + dy, val, self.gridSize)
      File "C:\Users\staka\Desktop\work\tetris\game_manager\game_manager.py", line 591, in drawSquare
        painter.fillRect(x + 1, y + 1, s - 2, s - 2, color)
    TypeError: arguments did not match any overloaded call:
      fillRect(self, QRectF, Union[QBrush, QColor, Qt.GlobalColor, QGradient]): argument 1 has unexpected type 'float'
      fillRect(self, QRect, Union[QBrush, QColor, Qt.GlobalColor, QGradient]): argument 1 has unexpected type 'float'
      fillRect(self, int, int, int, int, Union[QBrush, QColor, Qt.GlobalColor, QGradient]): argument 1 has unexpected type 'float'
      fillRect(self, QRectF, Union[QColor, Qt.GlobalColor, QGradient]): argument 1 has unexpected type 'float'
      fillRect(self, QRect, Union[QColor, Qt.GlobalColor, QGradient]): argument 1 has unexpected type 'float'
      fillRect(self, int, int, int, int, Union[QColor, Qt.GlobalColor, QGradient]): argument 1 has unexpected type 'float'
      fillRect(self, int, int, int, int, Qt.GlobalColor): argument 1 has unexpected type 'float'
      fillRect(self, QRect, Qt.GlobalColor): argument 1 has unexpected type 'float'
      fillRect(self, QRectF, Qt.GlobalColor): argument 1 has unexpected type 'float'
      fillRect(self, int, int, int, int, Qt.BrushStyle): argument 1 has unexpected type 'float'
      fillRect(self, QRect, Qt.BrushStyle): argument 1 has unexpected type 'float'
      fillRect(self, QRectF, Qt.BrushStyle): argument 1 has unexpected type 'float'
      fillRect(self, int, int, int, int, QGradient.Preset): argument 1 has unexpected type 'float'
      fillRect(self, QRect, QGradient.Preset): argument 1 has unexpected type 'float'
      fillRect(self, QRectF, QGradient.Preset): argument 1 has unexpected type 'float'
    error: subprocess failed.
    
    opened by seigot 2
  • `dropdownscore`を`result.json`に出力するパッチ

    `dropdownscore`を`result.json`に出力するパッチ

    dropdownscoreresult.jsonに出力するパッチ

    diff --git a/game_manager/board_manager.py b/game_manager/board_manager.py
    index fc4f493..1f53bdf 100644
    diff --git a/game_manager/game_manager.py b/game_manager/game_manager.py
    index 76f3c8f..2189a36 100644
    --- a/game_manager/game_manager.py
    +++ b/game_manager/game_manager.py
    @@ -496,6 +496,7 @@ class Game_Manager(QMainWindow):
                             },
                             "line_score_stat":"none",
                             "shape_info_stat":"none",
    +                        "dropdownscore":"none",
                           },
                       "judge_info":
                           {
    @@ -532,6 +533,7 @@ class Game_Manager(QMainWindow):
             status["debug_info"]["shape_info"]["shapeS"]["color"] = "blue"
             status["debug_info"]["shape_info"]["shapeZ"]["index"] = Shape.shapeZ
             status["debug_info"]["shape_info"]["shapeZ"]["color"] = "yellow"
    +        status["debug_info"]["dropdownscore"] = self.tboard.dropdownscore
             ## judge_info
             status["judge_info"]["elapsed_time"] = round(time.time() - self.tboard.start_time, 3)
             status["judge_info"]["game_time"] = self.game_time
    
    opened by seigot 1
  • `board_manager.py`の`line_obstacle_cnt`は削除可能と思われる。次回のリファクタリングタイミングで削除する予定、のパッチ

    `board_manager.py`の`line_obstacle_cnt`は削除可能と思われる。次回のリファクタリングタイミングで削除する予定、のパッチ

    board_manager.pyline_obstacle_cntは削除可能と思われる。次回のリファクタリングタイミングで削除する予定

    diff --git a/game_manager/board_manager.py b/game_manager/board_manager.py
    index fc4f493..ebaaa92 100644
    --- a/game_manager/board_manager.py
    +++ b/game_manager/board_manager.py
    @@ -292,18 +292,14 @@ class BoardData(object):
             obstacle_probability = self.obstacle_probability
     
             for y in range(BoardData.height):
    -            line_obstacle_cnt = 0
                 for x in range(BoardData.width):
     
                     if y < (BoardData.height - obstacle_height):
                         continue
    -                if line_obstacle_cnt >= (BoardData.width - 1):
    -                    continue
     
                     # create obstacle
                     tmp_num = np_randomObstacle.random.randint(1, 100)
                     if tmp_num <= obstacle_probability:
                         self.backBoard[x + y * BoardData.width] = np_randomObstaclePiece.random.randint(1, 8)
    -                    line_obstacle_cnt += 1
     
     BOARD_DATA = BoardData()
    
    opened by seigot 1
  • Kickoff 2022 q1

    Kickoff 2022 q1

    ・変更点  ・モデル名をDQNとMLPに変更  ・block_controller_train_sample.py をDQN使った推論に変更  ・block_controller_train_sample2.py をMLP使った推論に変更  ・sample_weightをDQN用とMLP用に変更  ・ai.mdにコマンドを記載

    opened by bushio 0
  • `python start.py -l2`実行時に、`python start.py -l2 -m predict`と同じオプションを与えるためのパッチ

    `python start.py -l2`実行時に、`python start.py -l2 -m predict`と同じオプションを与えるためのパッチ

    python start.py -l2実行時に、python start.py -l2 -m predictと同じオプションを与えるためのパッチ

    具体的には、以下のパッチを当てるとpython start.py -l2 -m predictを実行している事と同じ動作になる。

    diff --git a/start.py b/start.py
    index b6f4f93..176c2c3 100644
    --- a/start.py
    +++ b/start.py
    @@ -48,7 +48,7 @@ def start():
         ## default value
         GAME_LEVEL = 1
         GAME_TIME = 180
    -    IS_MODE = "default"
    +    IS_MODE = "predict"
         IS_SAMPLE_CONTROLL = "n"
         INPUT_RANDOM_SEED = -1
         DROP_INTERVAL = 1000          # drop interval
    
    opened by seigot 0
  • python3.10をインストールする手順にアップデートしたい

    python3.10をインストールする手順にアップデートしたい

    python3.10をインストールする手順にアップデートしたい https://github.com/seigot/tetris/blob/master/doc/files/install_windows_powershell.md

    現状  インストール手順にはpython3.9を使う手順を記載している  (間違いではないがちょっと古い)

    改善案  python3.10を使う手順にアップデートしたい  (できるだけ最新バージョンを使うようにアップデートしたい)

    opened by seigot 0
  • docker imageの軽量化

    docker imageの軽量化

    ・サーバ側で評価用途メインで使いたいかも ・imageサイズを減らしたい  ・editorやVNC環境などは不要  ・bullseye-slim(python:3.10-slim-bullseyeなどpythonいりでも良いかも)が候補  ・サイズはせめて1GB未満に抑えたい(今3GBほどでは。。)

    opened by EndoNrak 0
  • 1回のコールバック関数実行時に1秒制約のルールはあったほうがいいのかどうか

    1回のコールバック関数実行時に1秒制約のルールはあったほうがいいのかどうか

    1回のコールバック関数実行時に1秒制約のルールはあったほうがいいのかどうか

    課題  xxx

    対策案  xxx  案0) 1秒以上掛かることがあっても別に問題ない(次の探索が高速であり最終的につじつまが合えば問題なし)  案1) 1秒以上掛かることがあれば何かしらのペナルティ(例えばスコアにマイナス補正を加えるなど)  案2) 1秒以上掛かることがあればゲームオーバー

    opened by seigot 1
  • docstringの利用検討

    docstringの利用検討

    opened by seigot 0
Owner
null
TetrisAI - Tetris AI Bot using computer vision to play game automatically

Tetris AI Tetris AI Bot using computer vision to play game automatically bot.py

null 11 Aug 29, 2022
A Tetris game made using PyGame as renderer only, for a school project.

Tetris_Python A Tetris game made using PyGame as renderer only, for a school project. Twist in the Game Blocks can pentrate through right and left bou

Ravi Arora 2 Jan 31, 2022
Creating Tetris with Pygame

Tetris ?? Contributing Contributions, issues and feature requests are welcome! Feel free to check issues page. Show your support Give a ⭐️ if this pro

Gavin Capriola 0 Mar 1, 2022
Mastermind-Game - A game to test programming and logical skills

Bem vindo ao jogo Mastermind! O jogo consiste em adivinhar uma senha que será ge

Marcelo Daros 0 Jan 27, 2022
Blender Game Engine Game Type Templates Logic Bricks (and Python script) based Game Templates for Blender

Blender-Game-Engine-Templates Blender Game Engine Game Type Templates Logic Bric

null 3 Oct 25, 2022
Mandaw 2 Mar 1, 2022
Snake game mixed with Conway's Game of Life

SnakeOfLife Snake game mixed with Conway's Game of Life The rules are the same than a normal snake game but you have to avoid cells created by Conway'

Aidan 5 May 26, 2022
Lint game data metafiles against GTA5.xsd for Rockstar's game engine (RAGE)

rage-lint Lint RAGE (only GTA5 at the moment) meta/XML files for validity based off of the GTA5.xsd generated from game code. This script accepts a se

GoatGeek 11 Sep 18, 2022
HTTP API for FGO game data. Transform the raw game data into something a bit more manageable.

FGO game data API HTTP API for FGO game data. Transform the raw game data into something a bit more manageable. View the API documentation here: https

Atlas Academy 51 Dec 26, 2022
A near-exact clone of google chrome's no internet game, or the "google dinosaur game", with some additions and extras.

dinoGame A near-exact clone of google chrome's no internet game, or the "google dinosaur game", with some additions and extras. Installation Download

null 1 Oct 26, 2021
Quantum version of the classical Nim game. An automatic opponent allows to game to not be as easy as it seems.

Nim game Running the game To run the program just launch : python3 game.py Rules This game is inspiring from the Nim game. You are 2 players face to f

Michaël 1 Jan 8, 2022
Average Clicker Game (AVG) is a Python made game using tkinter

Average-Clicker-Game Average Clicker Game (AVG) is a Python clicker game not made with pygame but with tkinter, it has worker, worker upgrades, times

Zacky2613 1 Dec 21, 2021
Ice-Walker-Game - This repository is about the Ice Walker game made in Python.

Ice-Walker-Game Ce dépot contient le jeu Ice Walker programmé en Python. Les différentes grilles du jeu sont contenues dans le sous-dossier datas. Vou

Mohamed Amine SABIL 1 Jan 2, 2022
Deal Or No Deal was a very popular game show. Even now, for a family party, it's a fun game to pass time

Deal Or No Deal was a very popular game show. Even now, for a family party, it's a fun game to pass time. I made a code to play the game right in your terminal/console. This isn't made to be a game which can be installed by everyone and played, I just made it as a fun project as I just started out with python. So if you have python installed and wanna have some fun, or just curious to see how I did this, feel free to check the code out!

null 1 Feb 15, 2022
Quiz Game: answering questions naturally with a friendly UI to enjoy the game

About Quiz Game : The Game is about answering questions naturally with a friendl

null 4 Jan 19, 2022
This is a simple telegram bot for the game Pyal, a word guessing game inspired by Wordle

Pyal Telegram Bot This is a simple telegram bot for the game Pyal, a word guessing game inspired by Wordle. How does it work? Differently from the ori

Rafael Omiya 4 Oct 6, 2022
Adventure-Game - Adventure Game which is created using Python

Adventure Game ?? This is a Adventure Game which is created using Python. Featur

ArinjoyTheDev 1 Mar 19, 2022
Game-of-life - A simple python program to simulate and visualise the Conway's Game of life

Conway's game of life A simple python program to simulate and visualise the Conw

Dhravya Shah 3 Feb 20, 2022
This repository has the lessons of the gamming programming course

learning-python-game-programming This repository has the lessons of the gamming programming course Na faculdade, estou fazendo a disciplina de program

Mateus Faustino 1 Nov 16, 2021