三角法に精通しているが、Robocode には精通していない人への注意事項: Robocode の角度値は、三角法の慣例のようにゼロ中心で反時計回りに増加するのではなく、非負であり、時計回りに増加します。
聖なる牛、それは毛玉です。static
変数を割り当ててから同じ式内で使用し、さまざまな目的で変数をランダムに再利用するという面倒なスタイルも同様です。(編集:私は robocode から離れすぎています。難読化されたように見える混乱は、コード サイズを手作業で最適化した結果である可能性があります。) ここから始めて、その厄介な行を 1 つ取り出してみましょう。
setTurnGunRightRadians(Math.sin((Guppy.var = e.getBearingRadians() + getHeadingRadians()) - getGunHeadingRadians() + Math.asin((vel * 0.4D + e.getVelocity() * 0.6D) / 14.0D * Math.sin(e.getHeadingRadians() - var))));
var
が部分式の結果を保持するために使用されているようですe.getBearingRadians() + getHeadingRadians()
。あなたのヘディングに対するe.getBearingRadians()
ターゲットの方位を返すので、は絶対的なターゲットの方位です。リファクタリング:var
double targetBearing = e.getBearingRadians() + getHeadingRadians();
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + Math.asin((vel * 0.4D + e.getVelocity() * 0.6D) / 14.0D * Math.sin(e.getHeadingRadians() - targetBearing))));
うーん、まだ混乱しています。説明されていない変数もありますvel
が、コードの残りの部分に基づいて、最後にスキャンされたときのターゲットの速度のようです(そして、1 対 1 の試合のみが行われるという軽率な仮定の下で)。現在の速度と加重平均を組み合わせて、大まかな予測速度を提供するため、おそらくターゲットを導くロジックがここで進行しています。
double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + Math.asin(predictedVelocity / 14.0D * Math.sin(e.getHeadingRadians() - targetBearing))));
ロボコードはコースとヘディングの違いを無視しているように見えるため、最も内側の正弦は、ターゲットの速度のどのコンポーネントがその方位に垂直であるかを示す符号付き係数をMath.sin(e.getHeadingRadians() - targetBearing)
与え、したがって発射角度の調整が必要です。
double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
double perpendicularMotionCoefficient = Math.sin(e.getHeadingRadians() - targetBearing);
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + Math.asin(predictedVelocity / 14.0D * perpendicularMotionCoefficient)));
逆正弦表現は、ターゲットの動きの垂直成分を角度調整に戻すことを意図しているようです。アークサインはそのようには機能しないため、この数学のビットは完全に間違っています。区間 [-1, 1] の係数を区間 [-pi/2, pi/2] の角度に戻し、予測された速度を 14 で除算することは、おそらく、引数を逆正弦にその領域内に限定しようとする試みにすぎません。繰り返しますが、ターゲットまでの距離も発射体の速度も計算に入らないため、この調整について私が言える最善のことは、漠然と正しい方向にあるということです.
double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
double perpendicularMotionCoefficient = Math.sin(e.getHeadingRadians() - targetBearing);
double firingAngleAdjustment = Math.asin(predictedVelocity / 14.0D * perpendicularMotionCoefficient);
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + firingAngleAdjustment));
その最後の正弦は、私にはまったく意味がありません。引数はすでに、銃を動かす必要のあるラジアン単位の角度です:ターゲットの絶対方位から現在の銃の向き (これは、銃がターゲットを正確に指すためにどれだけ回転する必要があるか) を差し引いたものと、ターゲットの動き。そこにある正弦関数を完全に削除します。
double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
double perpendicularMotionCoefficient = Math.sin(e.getHeadingRadians() - targetBearing);
double firingAngleAdjustment = Math.asin(predictedVelocity / 14.0D * perpendicularMotionCoefficient);
setTurnGunRightRadians(targetBearing - getGunHeadingRadians() + firingAngleAdjustment);
もちろん、これは銃を半回転 (pi ラジアン) 以上回転するように設定することが、代わりに半回転未満で反対方向に回転させると自動的に理解されるかどうかにも依存します...あなたは多くの無意味なことをすることになるかもしれませんそれ以外の場合は銃を回転させます。