2017-11-25 34 views
0

テトリスのthisの実装を理解しようとしています。テトリスのこの実装を理解する助けが必要

私にはいくつか質問があります。 update_score機能で

if ((score > LEVEL_UP * level)) ; then   # if level should be increased 
    ((level++))         # increment level 
    pkill -SIGUSR1 -f "/bin/bash $0" 

遅延を調整するために、すべての独立したプロセスを持つの使用は何ですか?なぜSIGUSR1SIGUSR2を使用するのですか?

draw_piece関数では、なぜ8を掛けますか?私は変換がどのように行われているのか、ここでは「回転」の概念がどのように実装されているのか理解していません。

for ((i = 0; i < 8; i += 2)) { 
    # relative coordinates are retrieved based on orientation and added to absolute coordinates 
    ((x = $1 + ${piece[$3]:$((i + $4 * 8 + 1)):1} * 2)) 
    ((y = $2 + ${piece[$3]:$((i + $4 * 8)):1})) 
    xyprint $x $y "$5" 

    ... 
} 

ここでは、以下の構文について理解していません。

clear_nextでは、${filled_cell}の代わりにdraw_next ${filled_cell//?/ }が必要なのはなぜですか? //は何を表していますか?

答えて

3

私は一般的にシェルスクリプトやプログラミングの初心者だと私はどういうわけか

[シェルに]テトリスのこの実装を理解しようとしている、私はあなたが簡単に発見した可能性が疑われます開始するプログラム。

遅延を調整するために別のプロセスを使用することは何ですか?なぜ[SIGUSR1]と[SIGUSR2]を使うのですか?

私は遅延を調整するための、しかしタイマーを実装するための別のプロセスがないと思います。タイマーは、プログラムがプレイヤーが入力を待っている間でも実行しなければならず、シェル関数がreadにタイムアウトを持たない場合は、別のプロセスにエクスポートする必要があります。だから、あなたは、最後の1に行く最初の2からの出力と、タイマー、ユーザの入力ハンドラ、および実際のゲームロジックに分裂、スクリプトの最後にそこにあるものを得る:

(ticker & reader) | (controller) 

バッシュさんreadは、タイムアウトのために-tフラグを持っています。したがって、Bashで実装されていれば余分なタイマー処理は必要ありません。しかし、タイマーを外部プロセスに置くことで、ユーザーの入力に依存しないようにして、ユーザーがボタンを押すたびにreadタイムアウトがリセットされます。これを回避するには、経過時間を正確に判断する方法が必要です(または、readで実際に短いタイムアウトを使用してダニを数える)。

SIGUSR1およびSIGUSR2は、システムにとって大きな意味を持たない「純粋な」信号であるため、ここで使用できます。もちろん、あなたは他人を使うこともできますが、SIGINTまたはSIGHUPを捕まえることで、ゲームをやめたいと思った場合にはユーザーを煩わせるでしょう。

draw_piece関数では、なぜ8を掛けますか?

((x = $1 + ${piece[$3]:$((i + $4 * 8 + 1)):1} * 2)) 

pieceアレイは、異なる形状及び片の向きを含んでいます。ピースは4つの正方形で、各四角形は2つの座標を必要とするので、1ピース/方向ごとに8つの数字が得られます。それは2つの方向があるので、例えば、Sピースのための文字列は、0001111201101120です:

yx yx yx yx yx yx yx yx 
00 01 11 12 01 10 11 20 

をピースはこのようなものになります。

012  012 
0 xx. 0 .x. 
1 .xx 1 xx. 
2 ... 2 x.. 

${variable:position:length}表記が与えられたから部分文字列を取り出しますプログラムはより大きな文字列から必要な1桁の数字を取得します。それは配列を実装するやや奇妙な方法です。

clear_nextでは、なぜdraw_next ${filled_cell//?/ }が必要なのですか? //は何を表していますか?

${parameter/foo/bar}は、パターン置換えです(例:Bash's manual on parameter expansion、「置き換え」を参照)。 parameterの値のfooと一致するものは、barに置き換えられ、結果は展開されます。二重スラッシュでは、すべてのマッチが最初のスラッシュのみで置き換えられます。疑問符はファイル名のように任意の文字にマッチするので、元の文字列と同じ長さの文字列を効果的に作成できます。例えば

$ str="hallo hallo" 
$ echo "${str/a/e}" 
hello hallo 
$ echo "${str//a/e}" 
hello hello 
$ str="abc" 
$ echo "x${str//?/ }x" 
x x 
+0

ありがとう!あなたは文章の文法を説明することができますか?それはどこに座標を割り当てようとしていますか?これはプログラムの共通要素であると思われ、if-elseの点で解釈することはできません – Enne

+0

@Enne、 '$ {::}'?部分文字列。編集されました。 Bashマニュアルの同じページ。 – ilkkachu

+0

別のプロセスでタイマーを実行することはあまり役に立ちません。なぜなら、トラップハンドラは 'read'が返る前に実行されないからです。しかし、私は 'bash'以外のシェルがそれを別々に扱うかもしれないと認めます。 –

関連する問題