2017-11-06 7 views
1

私はGraphics.glossでハスケルで作られた小惑星ゲームに取り組んでいます。今、私はこのような小惑星のためのデータ型を定義している:それはポイントによって定義された位置、ベクトルおよびそれの大きさによって定義された速度を有する自分のデータ型のhaskellランダムインスタンス

data Asteroid = Asteroid { asteroidPos:: Point, 
          asteroidVel :: Vector, 
          asteroidSize :: Float } 

ように。ここでは、このデータ型のRandomのインスタンスをどのように書くことができるかを知りたいので、新しい小惑星がランダムな速度でランダムな場所にランダムに現れるようにします。私はこれをどのように達成できるのか誰にも分かりますか?

+2

[関連](http://hackage.haskell.org/package/QuickCheck-2.10.1/docs/Test-QuickCheck-Arbitrary.html#v:arbitrary)。 –

+1

インスタンスを書き込もうとしましたか?あなたは何の問題を見つけましたか? – chi

+0

[ランダム: System.Random](https://hackage.haskell.org/package/random-1.1/docs/System-Random.html#g:4)を見たことがありますか?あなたの 'Asteroid'データ型のための' Random'インタフェースを実装するあなたの努力を示すことができますか? – epsilonhalbe

答えて

0

Floatの場合、すでにRandomのインスタンスがあります。 VectorPointためRandomインスタンスを持っているあなたも、あなたがAsteroidためRandomインスタンスを定義するためにそれらを使用することができると仮定すると:

instance Random Asteroid where 
    randomR (Asteroid pl vl sl, Asteroid ph vh sh) g = 
    let (p, g1) = randomR (pl, ph) g 
     (v, g2) = randomR (vl, vh) g1 
     (s, g3) = randomR (sl, sh) g2 
    in (Asteroid p v s, g3) 
    random g = 
    let (p, g1) = random g 
     (v, g2) = random g1 
     (s, g3) = random g2 
    in (Asteroid p v s, g3) 

randomR関数が最小値(低)から最大値(高い)までの値の範囲を取り。 Asteroidのような複雑な値の意味のある範囲をどのように定義すれば、私はあなたに任せます。ここでは、私は単純にあなたが低いと高いAsteroid値を渡すことができると仮定しています。

最初の手順ではPointの基底のRandomインスタンスを使用して、randomRを呼び出します。 pは、ランダムに生成されたPointの値であり、g1は、次に使用するランダムな生成器の値です。

同様に、vは、ランダムに生成されたVectorという値で、Vectorの下位インスタンスによって生成されます。

最後に、sは、FloatrandomRによって生成されるFloatです。

戻り値は、新しいAsteroidpから成る値、v、およびs、プラス最新の発電g3です。

randomの実装は同じテンプレートに従います。

このコードは、たとえば次のようなよりきれいな形で書くことができます。 MonadRandomを使用していますが、初心者向けには、コードをそのままの形で残して、その動作を示しています。