1

たとえば、画面の端に沿って時計回りにボタンを移動するなど、友達に簡単なコード例を示す必要がありました。確かにこれは非常に単純なことです。いいえ、これが最も単純です。しかし、私はそれに約30分を費やしていることに気づきました. 私は 20 年以上のプロのプログラマーであり、ボタンが正しい方向に飛ぶ前に何度もプログラムを開始する必要さえあったので、私は恥ずかしかったです。そして、私は考えていました、なぜですか?したがって、この種のコードはすぐに正しく理解するのは難しいと推測しました。これは非常に古いスタイルであり、ケースごとに個別に入力し、各チェックを手動で入力する必要があり、各反復を実行して、すべての数字とチェックは正確に正確ですが、コード スタイルの性質上、これを行うのは困難です。

だから私は、ケースの代わりにループを使用する、テンプレートや他のメタプログラミングを使用する、機能的アプローチを使用する、または少なくとも配列を使用するなど、「現代的な」方法に変換する方法はありますか? そして、これには良い方法が見つからないようです。

var mx = screen.width - b.w, my = screen.height - b.h

setInterval(function() {
    var step = 3
    if (state == 1) {
        b.x += step
        if (b.x >= mx) b.x = mx, state++
    } else if (state == 2) {
        b.y += step
        if (b.y >= my) b.y = my, state++
    } else if (state == 3) {
        b.x -= step
        if (b.x <= 0) b.x = 0, state++
    } else if (state == 4) {
        b.y -= step
        if (b.y <= 0) b.y = 0, state = 1
    }
    b.apply()
}, 1)

これは JavaScript です。C では、型について考える必要があるため、すぐに理解するのはさらに困難です。

これが私が自分で思いついたものです...これはおそらく私が達成しようとしていることを示しています。別のアルゴリズムを選択することについて話しているのではありません。むしろ、言語の機能やプログラミング手法を探求することは避けてください。

var D = 3, name = ['x','y'], delta = [D,D,-D,-D], 
    limit = [screen.width - b.w, screen.height - b.h,0,0]

setInterval(function() {
    b[name[0]] += delta[0]
    if (delta[0] > 0 && b[name[0]] > limit[0] || b[name[0]] <= 0)
        b[name[0]] = limit[0],
        [name,delta,limit].some(function(x){ x.push(x.shift()) })
    b.apply()
},1)

これにより、少なくともデータがコードから分離され、より簡単に正しく処理できるようになります。最初の試みからうまくいきました。しかし、私はまだ完全に満足していません)

4

1 に答える 1

3

平均的なアメリカの新聞記事は、6 年生程度の読解レベルで書かれています。これは、それを書いている人が 6 年生を超えたことがないからではありません。むしろ、誰もが理解できる方法で書く方がよいことを彼らは学びました。あなたは自分のコードを子供じみている、または洗練されていないと呼んでいるので、これを取り上げますが、それはあなたが持っていたタスクのための最も明確で簡潔なコードであり、したがって最高です.

正方形を一周したい場合は、実際に行ったこと以外に選択肢はありません.4つの異なる方向に進み、現在地を追跡します. コードは、ステート マシンの基本を示しています。これは、4 つの異なる直線を一周する必要があるためです。

わずかに異なる動きでそれを偽造したい場合は、すべての状態を削除して、三角法を使用して楕円を一周することができます。(実際には円のはずですが、画面が長方形なので、画面の長辺と短辺で速度が異なる楕円になります。)

これが基本です。エッジが正しい場所に当たるように、微調整が必​​要になる場合があります。正直なところ、このバージョンの特殊なケースを解決する頃には、ソリューションがより洗練されていることがわかると思います。

// find the center x and y
var centerX = screen.width / 2;
var centerY = screen.height / 2;
// first, find the radius.  If you want to cover everything, you need half the diagonal
var radius = Math.sqrt(centerX * centerX + centerY * centerY);
var increment = 0.01; // higher values, of course, will move you faster
var theta = 0;
setInterval(function() {
    b.x = Math.min(Math.max(centerX + radius * Math.cos(x), screen.width), 0);
    b.y = Math.min(Math.max(centerY + radius * Math.sin(y), screen.height), 0);
    theta -= increment;
    b.apply();
}, 1);

前述したように、作成したコードと同じくらい見栄えがよくなるようにするには、ほぼ確実に微調整が必​​要です。私のコードは幼稚ではないかもしれませんが、理解するのは簡単ではありません.

あなたのコードがどれほど派手であったかについて心配する必要はありません。それはうまく機能し、理解するのが明確であり、それが本当に重要なことです.

編集

後で気がついたのですが、すべてを中心からベースにするのを忘れており、投稿したコードは左上から円を描いていました。上記の中央のものを追加しました。見る?複雑さを加えることは、コードがより良くなることを意味するものではありません... :-)

また、元のアルゴリズムに推奨する変更を 1 つ見つけました。状態に名前を付けてください。それらを文字列にし、状態を「上」、「右」、「下」、「左」にして、state ++を使用するのではなく積極的に設定します。これにより、コードがさらに読みやすくなります。

于 2013-05-21T07:42:01.310 に答える