現在は、情報IでもPythonを使うことになrマスが、PythonはAI関連の処理を得意としているので、Anacondaをインストールしておくと、色々なライブラリが使用できるので殆どのことができます。
Pythonはコンパイルが不要なインタプリタ型言語ですから、
■ コンソールアプリ
■ デスクトップアプリ
の双方をファイルの実行だけで行えるようになっています。
コンソールアプリを使う場合、キー入力が1文字入力ではなく、バッファを使った状態でエンターキーの入力で動くようなものになりますから、組み込み関数の機能だとこれを使用することになります。
標準ライブラリを使うと、
■ コンソールアプリ : curases
■ デスクトップアプリ : tinter、turtle(*)
(*)これらはTkが必要になります。
を使用できるので、コンソールでもウインドウの管理やイベントハンドラ(マウスも使えるようになります。)が使えるようなアプリケーションを作ることが出来るのですが、標準ライブラリを使うだけでも決行色々できるようになっています。
Pythonでは、外部ライブラリを使うと便利なのでそう言った利用方法をしますが、これは、パフォーマンスが高く、アプリケーションを作成した時に処理がもたつかなくなるためです。
基本的な考え方は標準ライブラリと組み込み関数だけでも学習できますが、同じことを行う際のパフォーマンスを考えた場合には外部ライブラリを使ったほうがいいので、そうした利用が行われています。
仕組みを考える場合だと、組み込み関数と標準ライブラリから基礎を学んで、組み方がわかった後に、同じ処理をする場合にパフォーマンスが上がる処理を模索することになりますが、この時に外部ライブラリを探すことになります。
この辺りは、
■ ゲームの仕組みを考えて作リながら学習する
■ 完成品を作る
後外になります。前者は、仕組みを学習するので、無駄に間引かれたものが存在すると知識が断片的になるので弊害品発生しないのですが、既に、知識がある状態で、実装するだけという条件だと、効率的な制作を行う必要がでてきます。
そうなると、前者で行うことと後者で行うことでは全く異なるので使用する環境や作業の手順もことなります。
つまり、ゲームの仕組みを考えながら理解を深める場合だと処理の内容を理解しながら作ることになりま菅、同じものを作る作業だと学習で必要になる工程の大半が発生しなくなります。その為、 【 学習するためのカリキュラム 】 と 【 効率的な製造をするためのワークフロー 】 では行っていることが全く違うので、前者の場合だと、あれこれと知識が欠如しそうな学び方は避けたほうがいいです。
学校でPythonを学ぶ場合、組み込み関数は間違いなく学ぶと思いますし、データサイエンスだと
■ 配列
■ 乱数
は使用しますが、PandasやNunPyなどを使用して作業を行うと思います。この時に字に現配列を使用することになりま菅、Rなども使用してデータの扱い方を学習すると思いますが、速度が出ませんが、組み込み関数でもリストは使用できるので、インストール直後から配列を使用できるようになっていますから、そう言ったデータの集まりを扱うことは出来ます。
また、乱数は標準ライブラリで精度の高いものを使用できるようになっていますから、極当たり前に使用できるようになっていますから、Pythonをインストールしただけでもいろいろなことができるようになっています。
LinuxだとPythonは標準実装ですから、コンソールアプリを作るだけだと最初から行えるようになっているので、pipで機能を追加しなくても、
■ 組み込み関数
■ 標準ライブラリ
を使用することができます。こうした元からある機能を使ってアプリケーションを作ることもできるので、簡単なミニゲームの・ようなものを作ることも出来ます。
コンソールアプリの注意点
C言語やC++などだとコンソールをclear(WINDOWSの場合だとDOSの機能を使ってclsを使用します。)を使用すると画面が消えるのですが、PythonでIDLEを使うとそうなりません。
その為、 【 表示が上に積み上がっていく 】 ような状態になります。外部ライブラリを入れるとゲームエンジンもあるので、条件が違ってきますし、cursesを使うとコンソールでも出来ることが違ってきますが、そう行ったライブラリを使わない条件だと表示が積み上がっていくような挙動になります。
入力もキーボードのみで、文字列をバッファしてエンターキーで確定させるような仕組みなので、この仕組みを使った物を作ることになります。これも標準ライブラリのcursesを使うとコンソールでも出来ることが全く違ってくるのですが、input()関数を使ったものだと簡単に作ることが出来るので、この処理を基準に考えると、作りやすくなります。
ゲームの場合だと乱数を使うので、標準ライブラリを使用するので、inportでライブラリを読み込むことになります。その為、必要なライブラリの内容は学習してく必要があります。この標準ライブラリも結構な量があるので、思った以上に何でも出来るような仕様になっています。(これはプログラミング言語全般に言えることですが、結構多機能な仕様になっています。)
今回作ったもの
とりあえず、ミニゲームだと簡単に作れそうだったので、今回は、
のようにスコアが最初に表示されていて、数値を指定して確定すると、
のように数値の並びで指定した数値が増減し、スコアが変化する物を作ってみました。
今回は元のスコアが決まっていて、そこから任意の数値を指定して変化を与えて元のスコアに加算できる数合わせゲームを作ってみたのですが、ミニゲームのスロットマシンがこれと同じ考え方になります。
のように終了処理で判定を行い、任意のキーを押すと
のようにスコアが変化して最初の表示に戻ると言う仕組みになっています。スコアの横におかしな数字がでていますが、これはただの文字列の間違いなので、実際には、指定した数値分だけ減少します。
今回のアプリケーションのコード
今回の処理のコードは、
になりますが、62行程度の短いコードでこの処理が出来ます。
今回は乱数を用いた数値の抽選が存在するので、
のようにrandomモジュールを読み込んでいます。そして、clsを行うのでosモジュールも読み込んでいます。これ以外だと、osではなくシェル(Linuxの場合だとbash)を実行するsubprocessを使う方法もあります。
プログラミング言語も現実世界と同様に 【 存在しないものは使用できない 】 ので、必要なものは事前に揃えておくことになります。その為、使用する変数やライブラリは実行前に用意しておくことになります。Pythoの変数は初期化をする形で使用するので、
のように先に変数を指定しておきます。
このようにブロック外に配置された変数のことをグロバール変数と呼びますが、この状態の変数はどこからでも呼び出すことが出来ます。また、関数内で呼び出すと再代入しない限りは変化しない特性があります。
アプリケーションは連続して処理が実行される必要があるので、メインループ内にコードを実装する子とになります。
その為、 【 無限ループ 】 を実装することになります。今回は簡素な処理なので、速度低下が発生するような条件は存在sませんから、
のようにwhile True:を使用しています。そして、画面の初期化をするので、
のようにclearを実行しています。これを行うと通常はコンソールがクリアされるので、
のようになるのですが、IDLEではそうならないので注意が必要です。Python環境だと基本的に表示が積み上がっていくことになりますから、IDLEと同じ状態になると思います。
コンソールで表示がしっかりと消えてくれる条件だと、表示が残ると問題があるので、最初に 【 表示の初期化 】 を行うことになります。
次に、今回の処理の主役の乱数を用意します。今回は整数を使うので、random.randint()を使用しています。
コードを見てもらうと、while True: 以降は、処理の間に空白が空いていますが、これをインデントといいます。これはタブで指定できますが、半角スペースの文字数を複数用意して指定することになります。この数の指定は、テキストエディタでも行えるので、エディタ側で指定をしておけば、TABキーだけでインデントを追加できます。現在の統合開発環境やテキストエディタでは自動入力機能が実装されているので、こうしたインデントはブロックの指定がアレば自動で追加されるようになっています。
ちなみに、ターミナルで使用できるviでもそう言った処理が行えるようになっています。
ここで変数に対して乱数を格納していますが、これはループ内に包含された変数になりますから、グローバル変数とは異なります。その為、ループ内で指定した乱数はループの度に違う値を取得することが出来ます。
このようにブロック内に配置された変数のことを 【 ローカル変数 】 と呼びます。ちなみに、関数内で変数の宣言をして使用した場合、ブロックスコープがかかるので、外部参照が出来ない(出来るようにする方法もあります。)のですが、目的に応じて
■ グローバル変数
■ ローカル変数
を使い分けることになります。次に、必要な情報を記述するのでprint()関数で表示を行い、初期値で指定したスコアの値を表示します。
ここでは、変数の参照をしていますが、str(変数名)にすると 【 + 】 で結合できるようになりますが、型が異なる場合には、間隔が空きますが、 【 , 】 で区切るとint型とsrt型を組み合わせて表示をすることが出来ます。
次に指定する数値を決めるので、input()関数を使って変数に値を格納します。
これが、数値の並びの結果で変化する値の基準になります。次に、抽選された乱数を表示するので、print()関数で数値を表示します。
そして、この後に、判定を行うことになります。
判定は、
のようになっていますが、最初に複雑な組み合わせから判定をしていくことになります。というのも、
A==B ⊂ A==B==C
と言う条件が成立するので、先にA==Bを行うとそのまま判定が終わるので、A==B==Cの判定ができなくなります。その為、判定を行う際にはA==B==Cのように複雑な判定から順番に行うことになります。
その為、
のような処理を行い、
のような処理を行っています。input()関数で取得した変数はstr型なので、計算には使用できませんから、int型に変換しています。ここでは、定数を使っていますが、倍率は変数で指定しているので、本来だとここは変数になります。
そして、スコアの値を変更することになるので、
のように変数aに対し変化分の値を加算します。そして、print()関数で追加された後のスコアの表示を行うようにしています。
そして、このまますぐに切り替わるのではなく、
のようにinput()関数で入力待ちを入れることで、表示を見ることが出来るようにしています。次に判定は2つ揃った状態なので、
のような判定にになりますが、ifで別の条件で分岐をする際には、elifを使います。ここでも
のように倍率の指定をして、
のようにスコアに加算するようにしてあります。後の流れは同じなので割愛します。そして、それ以外ははずれなので、elseで先程の2対外の条件の判定を行います
ここでは、指定した値を減算することになるのですが、表示をする際の値は
のように値はそのままで、表記の部分に 【 − 】 を追加しています。そして、
のようにすることで、スコアから指定した値を減算しています。
そして、この処理の後に終了処理を実装しています。
ここでは、
のような判定にすることで、
■ 半角
■ 全角
■ かな
■ 大文字(CUPS LOCK)
のすべての状態に対応しているので、どの状態でもNキーであれば終了します。そして、その判定が行われた後に
が実行され、ループが終了する仕組みになっています。
IDLEで実行する
先程のコードをIDLEで実行すると
のような表示になり、入力待ちになるので、
のように数値を入力して実行すると、
のように数値が表示されてその状態で判定が行われます。今回は揃っていないので、没収となり、スコアが減っています。
この状態で、
のような入力待ちを入れているので、ここでEnterキーを押す前にこの状態が維持されるのですが、Enterキーが押されると
のように終了処理の表示が発生します。ここで、任意のキーを押すと
のように最初に戻るのですが、
のようにスコアが変化した状態で再度数値の指定が行えるようになっています。数値を指定して実行すると
のようになりますが、試した感じからすると、 【 嘘のように当たらない 】 ので、数値を大きくすると、瞬く間にマイナスになります。ちなみに終了処理で
のように大文字のNを入力しても判定側でNキーの状態をカバーしているので、
のように終了させることが出来ます。コンソールアプリの場合だと、
のように一番最初に 【 exit() 】 を追加すると、breakでメインループから出た後にコンソールを閉じるのか否かを確認するダイアログが表示されるようになります。
今回のアプリでは、
今回は、スロットマシンを簡素にしたような物を作ってみたのですが、投入する値の上限の判定などを入れいていないので、実装スべき機能は多く存在しますが、
■ 数値を指定する
■ 数値の状態が変化する
■ 状態によって数値が増減する
■ 元の数値が変化する
の実装をしてみました。今回のアプリケーションは 【 終了するまで実装された処理がループする 】 仕組みになっていますが、アプリケーションを考える際には、この構造にする必要があります。これが、 【 メインループ 】 になりますが、そのメインループの中にどのように処理を実装するのかを考えていくことになります。