1時間でFBDでゲーム「2048」

こんにちは。



この投稿は、FBDで最も単純なおもちゃ「2048」を作成する方法の簡単な説明に当てられています。



すぐに結果の写真を入れてください:



これがどのように行われるかに興味があるなら、猫へようこそ。



ソースデータ



ゲーム「2048」。 ルール



1.各ラウンドで、顔の値が「2」(90%の確率)または「4」(10%の確率)のタイルが表示されます。

2.矢印を押すことにより、プレーヤーは4つの側面のいずれかで競技場のすべてのタイルを破棄できます。 ドロップするときに、同じ額面の2つのタイルが互いに「飛ぶ」場合、それらは1つにくっつき、額面は接続されたタイルの合計に等しくなります。 移動するたびに、面の値が「2」または「4」の新しいタイルがフィールドの空きセクションに表示されます。 ボタンが押されたときに、タイルの位置またはそれらの額面が変更されない場合、移動は発生しません。

3.次の移動後にアクションを完了することができない場合、ゲームは敗北で終了します。



ご覧のとおり、ルールは非常に単純です。 アルゴリズムの実装を開始します。



乱数ジェネレーター



この問題を解決するために、「ランダム」マクロを作成します。 なぜなら コントローラには純粋な「ランダム」はありません。古い方法でテストしました。

セルのランダムな座標(行と列)が形成される出力でマクロを作成し、このセルに4を配置する必要があるというサインを作成します。



乱数ジェネレーター


短い説明。

アルゴリズム2、3、および4は、「のこぎり」に関して絶えず変化する値を取得するために使用されます。 「Now」アルゴリズムは、現在のコントローラー時間を出力します。 次に、これら2つの数量を互いに分割します。 残りは小数点以下4桁です。 「0.1」(10%の確率)と比較し、対応する記号(4つが選択されたという記号)を形成します。 残りは小数点以下6桁です。 16を乗算して、最も近い整数に切り捨て、残りを4で除算します。したがって、セルのランダムな座標を取得します。ここで、除算の商は行で、除算の剰余は列です。 単位が追加され、値が1〜4の範囲で「美しく」表示されるようになりました。これで乱数ジェネレーターが完成しました。


インストールマクロ



そのため、もう少し高く、新しい値(2または4)を配置するセルのランダムな座標を取得しました。 「インストール」マクロを使用して、この値を16個の論理記号に変換します。



設置


短い説明。

マクロ自体は非常にシンプルであり、メインタスクを煩雑にしないためにのみ必要です。 論理「And」に従って3つの記号が収集される16個の「And」アルゴリズムがあります。セルを設定するために信号を設定できることを示す「work」記号と、「row」および「column」座標の2つの記号です。 「I」アルゴリズムの1つにある3つの符号すべてが組み立てられるとすぐに、対応する出力に論理ユニットを発行し、空のセルに新しい値を設定しようとします。


マクロ「セル」



名前が示すように、これはセルの状態を表示するメインマクロです。 そのようなマクロは合計で16個あります。 しかし、これは、それらがすべてまったく同じであるという点です(これは、値を設定するアルゴリズムを削除し、ユーザーからのコマンドを個別に処理することで達成されました)。 したがって、プログラムはすばやく簡単にやり直します。 ロジックを変更する場合、マクロアルゴリズムを1つ変更するだけで十分であり、他のすべては自動的に変更されます。



セル
短い説明。

マクロには6つの入力と2つの出力があります。



インプット

  • 設定-前述のように、これは、このセルに新しい値を設定する必要があるという論理記号の入力です。
  • 4は、2ではなく、このセルに4を書き込む必要があることを示す論理記号です。
  • クリア-プログラム内のすべての値をリセットして、新しいゲームを開始します。
  • Go-コマンドが終了し、セルを上書きできるようになった後のすべての値の処理の兆候。
  • 入力-次のコマンドを処理した後の値。セルに書き込む必要があります。
  • 開始-ゲームが始まったばかりで、すべてのセルが空であり、最初の値を任意のセルに書き込むことができるという論理的な兆候。


出力:

  • 値は、セルの現在の値です。
  • 完了-セル処理が完了したことを示すサイン。


マクロ充填:



このマクロは、セルの現在の値を保存する「メモリ」アルゴリズムに基づいています。 このアルゴリズムで記録された値は、4つの連続した「選択」アルゴリズムによって選択されます。 最初のアルゴリズム「Choice」では、セルに書き込む値をチェックします-「2」または「4」。 secondf Choosingアルゴリズムは、これが空のセルかどうかをチェックします。 セルが空の場合、選択した2つまたは4つをそこに書き込みます。 3番目のアルゴリズム「Choice」は、これがゲームの始まりかどうかをチェックします。 これがゲームの始まりである場合、チェックなしで、以前に選択された値が書き込まれます。 4番目のアルゴリズム「選択」が最も優先順位が高くなります。 「クリア」という記号が表示されているかどうかを確認し、表示されている場合は、強制的にメモリゼロに書き込み、セルをクリアします。 「比較」アルゴリズムは、このセルが空かどうかに関係なくサインを形成します。 次に、2つのアルゴリズム「AND」と「OR」を使用して、セルに新しいランダム値を設定するコマンドを受信し、このセルが空であるか、これが通常ゲームの開始であるかどうかを確認し、セルが処理されて移動が完了したという兆候を設定します。



マクロ処理



このマクロは、ゲームに実装されているすべてのロジックの基礎です。



マクロには2つの入力と3つの出力があります。 「コマンド」入力は、マクロが4つの入力要素を処理して出力値を生成する必要があることを示す論理記号です。 このマクロはユニバーサルであり、4つのコマンドすべてを処理するために使用されます。 「右へ」コマンドの下で作成されますが、「左へ」コマンドを処理するには、行要素を逆の順序で入力し、同じ逆の順序で出力から取得すれば十分です。 「up」および「down」コマンドを処理するために、列を形成する異なる行からの対応する値が入力に送られます。

一般的な考え方と動作原理
マクロの内容の一般的なビュー:



動作原理:

4つの要素と処理を開始するコマンドが入力に渡されます(コマンドは、要素を1番目から4番目、つまりコマンドを右にシフトするために機能します)。

コマンドのリーディングエッジで、要素がメモリに書き込まれます。 さらに、4つの要素の行に翻訳の方向に空のセルが含まれていないことを確認します。 このチェックが実行されない場合、空のセルが1つ下のセルで検出される前にすべての要素の循環シフトがあります。 結果のシーケンスは、シフト方向の空のセルについて再度チェックされ、チェックが完了するまで要素の循環シフトが継続されます。



これがアルゴリズムの最も弱い点です。 文字列を処理するには、プログラムを3回(制限内で)実行する必要があります。 チェックはプログラムの最初のパスまたは3番目のパスでのみ実行でき、16個のセルすべてが同時に機能する必要があるため、プログラムに多数のメモリ要素とトリガーを配置する必要があります。 しかし、これまでのところ、1回のパスで並べ替えを実装するためのシンプルで美しい方法を思いつきませんでした。 しかし、まだ夕方ではありません。 時間があれば、私はそれをより厳しくし、2回ごとにプログラム全体が単純化されるでしょう。



検証が最終的に完了し、すべての要素が隙間なく順番に配置されると、インパルスが形成され、それによって要素のペアワイズ比較が下から開始されます。 4番目と3番目の要素を比較します。 それらが等しい場合、4番目のセルで合計を書き留め、他のすべての要素を1セル下にシフトします。 次に、2番目と1番目の要素を互いに比較し、同じことを行います。 4番目と3番目の要素が互いに比較されない場合、3番目と2番目の要素などを比較します。 ここでは、すべての非ゼロセルを既に並べ替えており、塗りつぶされたセルの間に空のセルがないことを確実に知っているため、アルゴリズムは単純です。 このソートは1つのパスで実行されます。 最後に、結果の要素値が出力に書き込まれ、「完了」出力信号が生成されます。



同時に、コマンドを発行するときに、少なくとも1つの要素セットが変更されたことを確認する必要があります。 それ以外の場合、このコマンドは移動ではなく、送信するときに何もする必要はありません。 このチェックには、マクロの下部に要素があります。元のシーケンスでは、少なくとも1つの順列が必要であり、少なくとも1つのセルのペアが「折りたたまれている」ことをチェックします。 この場合、出力信号「worked」が形成されます。



一般的な言葉



実際、それがすべてです。 プログラムの主要な要素が準備できました。 それらを接続するだけです。 残りの補助要素に関するいくつかの言葉。

制御ユニット


これらはメインのゲームコントロールです。

「one of n」スキームに従って出力を生成するアルゴリズムである手動セレクターは、6つのコマンドすべてを提供します。 1-「上へ移動」コマンド、2-「右へ」、3-「下へ」、4-「左へ」、5-「新しいゲームの開始」、6-「リセット」。

ブロックは、ユーザーコマンドをブロックするのに役立ちます(前述したように、1サイクルでコマンドを処理することはできませんでした。つまり、コマンドの処理中は、新しいコマンドのフローをブロックする必要があります)。 経験上、サイクル時間が5ミリ秒のコマンドの最大処理時間は約150ミリ秒でした。 また、すべての処理は最大5サイクルで実行されますが(フィードバックにより「予備」に2サイクル追加されます)、わずか25ミリ秒ですが、残りの時間はセルに新しい値を設定するために費やされます。 実際、フィールドに入力すると、空のセルに入る機会が減ります。 制限では、待機時間は無限にすることができます。 マット 80ミリ秒待機します。 最大150ミリ秒を修正。 ランダムな値を排出するアルゴリズムを微調整して、移動の完全な処理にかかる時間を短縮できます。 なぜなら セルは16個しかないので、1から16までの値が保存された16個の要素を作成できます。次に、プレイフィールドのセルから値を読み取り、非ゼロのセルを戻し、行の先頭にある要素の数をすべてゼロのままにします。 ゼロセルの数をカウントし、この範囲の乱数をスローします。 しかし、これにより多くのアルゴリズムが追加され、すでに複雑なプログラムを複雑にしたくありませんでした。



最終プログラム:



プログラムのすべての要素を調べました。 これで、それらを組み合わせるだけで十分に機能します。

最終プログラムを含む大きな図面
プログラムの一般的なビュー。 写真が非常に大きいため、別のホスティングへのリンク。



この図は、プログラムが4つのメインブロックに分割されていることを明確に示しています。

左上はコントロールユニットです。 コマンド、乱数ジェネレーター、ロックなどを形成するセレクターがあります。

左下はセルのブロックです。 16個のセルがあり、その値はグラフィックパーツに表示されます。

右上部分はコマンド処理ブロックです。 以降4つの部分で構成されます 各コマンド(「右」、「左」、「上」、「下」)は個別に処理されます。 私たちのマクロは普遍的です。

右下部分は、要素の順序を変換し、ゲームオーバーの兆候を形成するための補助要素です(ただし、すべてのフィールドが占有されており、同じ値を持つ2つの隣接セルがない場合)。



グラフィックパーツを添付します



まあ、すべてが簡単で、5分で完了します。

1つの正方形を描きます。 対応するセルの値に等しい値を与えます。 セルの値に応じて背景色を変更します。 次に、ボックスを15回コピーして、完成したフィールドを取得します。 いくつかの署名を作成し、「開始」ボタンと「リセット」ボタン、および「ゲームオーバー」フィールドの上に大きな碑文を追加します。



「描画」モードでのウィンドウの表示。



すべて完了しました。 始めてプレイできます。



UPD.1



昼食時にコーヒーを飲みながら、「一体どうしたの?」と思って、処理マクロをやり直すことにしました。 ライン処理は数サイクルで行われ、これがプログラム全体の最も弱い点だと言ったのを思い出してください。 これを取り除き、すべてのチェックを1つのシーケンスに入れることにしました。 一方で、最初から条件を満たしていれば、追加のチェックが行われます。 しかし、一方で、このソリューション(かさばり、ugい見た目ですが)により、大量のトリガー、大量のメモリセル、およびこの全体を同期する必要があるポルノを取り除くことができます。 次に、猫の下で、新しい処理マクロとプログラムの一般的なビュー。 処理マクロが単純化され(単一のフィードバックはありません)、要素のヒンジ付き松葉杖が冗長になり、プログラムの異なるサイクルで発生する兆候を同期する方法に注意を払うことができます。

新しいマクロ処理


上半分は、「額」の列をソートしています。 すべてのオプションは単純に連続してチェックされ、条件が満たされると、適切な置換が行われます。 下半分は変更されませんでした。 以前のバージョンと比較して、すべてのメモリ要素とフィードバックが削除されていることに注意してください。 最後のブロック「Memory 54-57」は、プログラムには実際には必要ありません。 処理は1サイクルで行われます。 マクロの出力に値を表示するためだけにそれらを残しました。 なぜなら サイクルタイムは5ミリ秒なので、これらのブロックがないと、マクロ出力の実際の値は1サイクルだけスキップし(5ミリ秒、ほとんど認識できません)、出力の残りの時間は「-1」でハングします。



プログラムの新しい概観
写真が非常に大きいため、別のホスティングへのリンク。



ここでは、「Processing」マクロのバインディング(またはその欠如)に注意を払う必要があります。 プログラムの以前のバージョンを見ると、各レディ信号のトリガー、共通トリガー信号のトリガー、これらのトリガーのエッジ検出およびフィードバックリセットがあることがわかります。 今、このすべての恐怖は不要になり、プログラムの一般的な見方はきれいであり、あらゆる種類の松葉杖で散らかっていませんでした。 プログラムの他のすべての要素は変更されていません。





まとめ



ここでも、役に立たないものの、アルゴリズムの実装の観点から非常に興味深いおもちゃを作成しました。 さらに、私は特に、ポストの書き換えを開始せず、古いマクロを新しいマクロに置き換えて、プログラムの残りに影響を与えることなく、プログラムを根本的に書き換える方法を示しました。 FBD言語でプログラムを書くことの単純さに関して、ここで最も雄弁なのは、プログラムを書くよりも2〜3倍多くこの時間を費やしたという事実だと思います。



未実現のまま。

1.スコアリング。 私はこのゲームで特別ではありません。 さらに、彼は彼のプログラムでこの投稿を書いたときにのみそれを演奏し、今のところ彼は256の記録に達することに成功していません。 したがって、スコアリングは簡単です。 「Processing」マクロでは、同じ公称値を持つセルの値を合計するときに、この量をマクロ出力に追加して、外部からこれらの値の合計量を計算する必要があります。 しかし、これには何の意味もありません。 ゲームの目標は、最大額面のタイルを取得することです。

2.ランダムな値を選択して空のセルに2つまたは4つを設定するための「スマート」アルゴリズム。 これをどのように行うことができるかについては、上に書いた。 しかし、以来 そこに面白いものは何もないので、みんなに任せてください。



以上です。 面白かったと思います。



All Articles