週に一回は書きますよ 月に4つ記事を書けばノルマは満たされます。
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
C++で関数オブジェクトを作ってそれを渡して云々というコードを書いていると、
> tritest.cpp(89) : error C2064: 1 引数を取り込む関数には評価されません。
>    tritest.cpp(87): クラス テンプレートのメンバ関数 'void hogehoge'のコンパイル中
何故、何故unary_functionが関数に評価されないんだ。おかしいだろう。

と30分くらい悩みました。

そういえば継承による部分型多相(<-で良いんでしょうか呼び方は。全く勉強していないんですが) はC++ではポインタとかを使わないとやってくれなかったことを思い出しました。しかし関数オブジェクトは普通コピー渡しに実装していた覚えもあります。理由は忘れました。

とりあえずalgorithmファイルを見て、どう書いたらよいかを復習。

[人ハスケル脳症]の続きを読む
スポンサーサイト
Haskellの型クラスは便利です。超便利。詳しくはまた後日。
しかしこれはたとえばオブジェクト指向の継承法のようには利用できず、たとえばNum aからなるリストを作ることは出来ません。
うまくやれば出来るのかしら。
前の話と関係なくメモ。以下の二つのデータ型を書きます。
data GameNode =
  GameNode {
    update :: ShootSystem ss => ss -> [Key] -> [GameNode],
    render :: ShootSystem ss => ss -> IO (),
    entity :: Maybe GameEntity
    }

data GameEntity =
  GameEntity {
    move :: ShootSystem ss => ss -> [Key] -> [GameNode],
    draw :: ShootSystem ss => ss -> IO (),
    isValid :: Bool,
    receive :: GameEntity -> GameEntity,
    coord :: XY, velocity :: XY, energy :: Int, team :: Team,
    collisionType :: CollisionType
    }
これをコンパイルすると以下のエラーが出ます。
Illegal polymorphic or qualified type: forall ss.
                                       (ShootSystem ss) =>
                                       ss -> [Key] -> [GameNode]
In the definition of data constructor `GameEntity'
In the data type declaration for `GameEntity'
ここで注目は、GameNodeのところではなくその後のGameEntityでエラーが起きていること。なぜ上は許されて下は許されないのでしょう。

それとも上のもコンパイルが進むとエラーになるのでしょうか。

追記:どうもソースファイルで後のほうに定義されているものについてのエラーが先に出て、それだけでコンパイルがとまることは日常茶飯事のようです。うえのデータ型が可能かどうかは確かめていませんが。
Monadiusを参考にHaskellでゲームを製作しています。なれない言語を扱う中で、気になったことがありました。

Monadius中では、ビックバイパー、オプション、弾、敵、地形などすべての要素は、GameObjectという型を持っています。
data GameObject = -- objects that are actually rendered and moved.
  VicViper{ -- player's fighter.
    tag::Maybe Int,position::Complex Double,hitDisp::Shape,hp::Int,
    trail::[Complex Double],
    speed::Double,
    powerUpPointer::Int,
    powerUpLevels::Array Int Int,
    reloadTime::Int,weaponEnergy::Int,
    ageAfterDeath::Int
    } |
  Option{ -- trailing support device. 中略
    } |
  StandardMissile{
    } | -- missile 以下略
VicViperだけは詳細を載せました。位置やらパワーアップ状態やらがレコードの要素になっています。
updateObjectという関数にこの要素を渡すと、少し未来のこの要素が帰ってきます。
  updateGameObject::GameObject->[GameObject]
  updateGameObject vicViper@VicViper{} = sounds ++ newShields ++
  (略)
  updateGameObject option@Option{} = makeMetalionShots option{
    position = trail vicViper !! (10*optionTag option),
    reloadTime = max 0 $ reloadTime option - 1
  }
  updateGameObject miso@StandardMissile{} = if hp miso <=0 then
  (略)
  updateGameObject shot@StandardRailgun{} = if hp shot <=0 then [] else
    [shot{position=position shot + velocity shot}]  
  updateGameObject laser@StandardLaser{} = if hp laser <=0 then [] else
  (略)
  updateGameObject shield@Shield{} = if(hp shield<=0) then [] else [
  (略)
こんなのがすべての要素について書いてあります。そのほか、要素を描画するrenderGameObjectという関数もあり、こちらもすべての要素について描画方法を書いてあります。

すべての要素について、更新処理や描画処理を一箇所にまとめて書かなければいけないのでしょうか。私はそういう風に書くことが少ないので、ちょっと当惑しました。

たとえばJavaだったら、私はこんな風に書きます。
public interface GameObject {
    void update(Game s);
    void draw(java.awt.Graphics g);
    void isValid();
}
public class VicViper implements GameObject {
    public void update(Game s) {
        以下略
いろいろな要素の更新・描画関数が一箇所に集まっていると、コードが見にくくなりがちなような気がします。慣れたら平気になるのでしょうか。

以下数回にわたって、上のMonadius的書式を下のJava式書式に変える方法について書きます。
なれない言語を使うと、エラーメッセージに苦労します。中学の頃はC言語のコンパイルエラーメッセージの意味が全くわからず、実行ファイルの生成までにだいぶ苦労しました。その後エラーメッセージ集を部活で作ったりとか。「実行時にミスがわかるよりはコンパイル時にミスを検出すべき」のためには、もう少し親切なエラーメッセージが出る必要があるのかもしれません。あるいはコンパイルエラーメッセージに頼らない何かとか。これについてはまた後で。

今日はGHCのエラーメッセージで苦労しました。
  Couldn't match `a -> [b]' against `[Quark]'
   Expected type: a -> [b]
   Inferred type: [Quark]
  Probable cause: `move' is applied to too many arguments in the call
    (move q scene keys)
  In a lambda abstraction: \ q -> move q scene keys
なんじゃこりゃ。とりあえずmoveに割り当てられている型を勘違いしている可能性があります。しかしプログラム内の特定の式の型はどうやって出すのでしょう。マニュアル見ても良くわからなかったのでまたHaskell入門とふつけるを立ち読みしてしまいました。結局判りませんでしたが。
ちなみに、上のエラーはconcatMapと関数の間に間違えてドットを打ってしまったのが原因です。忠告違うし。
Haskell記述中。

GLUTで、スクリーンの大きさからアスペクト比を取ろうとします。サイズはGLsizeiで与えられて、こいつはInt32であってIntではありません。そのためfromIntが適用できず、Doubleに変換出来ません。やり方がわからずライブラリを右往左往。Ratioとか探したりとか。

結局書籍部に走ってふつけるを立ち読み。答えはfromIntegralでした。日本語の本は便利です。買いませんが。

ところで今気がつきましたが、Hoogleはこういうときに使えばよかったんですね。Int32->Doubleで検索したらfromIntegralがトップに出てきました。OpenGL系の関数がぜんぜん出てこなくて使えないと思っていたんですが、こう使えると便利です。
http://cence.hp.infoseek.co.jp/eqtest.htm

状況判断力
[54点] 客観的な立場での情報判断力はピカイチ

あなたはまずまず人並以上の状況判断力をもっています。特にあなたの場合、客観的な立場であるほど、正しい判断ができるようです。これまでも友人から恋愛や就職問題などについて相談を持ちかけられたときに、相手が驚くような的を射たアドバイスをして、感謝された経験があるのでは?
ただしその反面、せっかくの状況判断力も自分に直接利害が及ぶような場面ではやや鈍ってしまいがち。「失敗したらどうしよう」とリスクを実際以上に大きなものと考えたり、逆に本来なら危機を感じなければいけないような局面でも楽天的にのんびり構えたりしやすいのです。そのためあなたは、アドバイス上手ではあるけれど、実際に自分に関することでは読みがはずれるケースが少なくないよいうです。
ある程度、優れた状況判断力を持っているのですから、欲に目がくらんだり悲観的になりすぎたりせず、自分自身に対して客観的な立場から結論を下す姿勢が大切といえます。


感情制御力
[38点] 表面はクールでも内面はすぐに動揺しがち

あなたはまずまずの感情制御力をもっています。特にあなたの場合、少なくとも表面的には怒り、悲しみ、喜びなどあらゆる感情を上手にコントロールすることができるでしょう。どんな難題にも冷静に対処するように見えるあなたの姿は、周囲の人から尊敬を集めているかも知れません。
ただしそれは、あくまでも他人から見ての場合。一見クールに見えるあなたですが心の中は人一倍ナイーブで、悲しみや怒りといった感情にとらわれやすいのです。だから悲しい出来事があったりすると、表面はふだんとかわらなくても仕事の能率がガックリ落ちたり、つまらないミスや勘違いが増えたり・・・・・ということになりがち。
どんなにつらいときも自分を見失わないだけの「精神的なタフさ」を身につけるlことが、あなたのこれからの課題といえるでしょう。


意志実行力
[53点] チャレンジ精神は旺盛だけれどすぐに飽きてしまうことも

あなたは意志実行力という点では、まずまず平均値をクリアしています。チャレンジ精神も旺盛なので、興味が向いた分野があればすかさず自分なりにトライしたりもしそう。それだけにあなたのスケジュール帳は、様々な予定でいつも真っ黒なのではありませんか?
ただしあなたの場合、行動力はあるものの、持続力にうやや欠けている部分があります。道具をそろえてせっかく始めた趣味に途中で飽きてしまったり。気になる異性ともう少しで両思いになれるというところでほかの異性に心変わりをしたり・・・・・。ひとつのことをずっと続けるのが、とくいではないのです。
それでは、いつまでたっても何もマスターできないままです。様々なことに興味を持つことは大切ですか、ひとつのことをずっと継続することのほうが、あなたにとっては重要。一度は飽きても投げ出さずにがんばれば、再び「楽しいい」とおもえるようになるかもしれません。


対人共感力
[71点] 思いやりはあるけれどおせっかい癖には気をつけて

あなたは、かなりハイレベルな対人共感力の持ち主。特にあなたの場合、思いやりの気持ちが他の人と比べてものすごく強いようです。ですから少し浮かない顔をしている人がいれば、「どうしたの?」と相談に乗ってあげようとするし、雑用なども自分から手伝ってあげます。
周囲の人気もそこそこに高いあなたですが、唯一の問題点はそうしたあなたの優しさがときとしておしつけがましいものになってしまうこと。みんなに親切にするのは決して悪いことではありませんが「おせっかい」という評判が広まることにもなりかねません。
あなたの場合、あまり見境なく対人共感力を発揮するのは考え物。相手に本当に感謝されると思える時にだけ周囲の人に親切に振舞ったほうが、あなたのおもいやりの価値も高まるはずです。


総合診断

[タイプC] 他人の失敗を許すことができずに人望を失いがち

感情制御力をのぞいて、状況判断力・意志実行力・対人共感力の3つの能力について比較的高い得点をマークしたあなたは、周囲の人たちと協力し合って大きな夢を実現させる力を持った人といえます。
しっかりと周囲の状況を判断して、あなたは何をするときも無理のないプランをたてることができるでしょう。そのうえ友人の数も多いので、あなたが何かをしようとすれば、必ず「自分も一緒に・・・・・」と名乗りをあげる人が何人か現れるはず。その結果、ほとんどの場面で比較的少ない努力で目標を達成できるのです。
ただしあなたの場合、感情制御力が残念ながら今ひとつ。それだけに思いがけないピンチにはややもろい側面があります。自分のせいでミスをまねくようなことは少ないだけに、一緒に行動している人のせいでトラブルに巻き込まれたりすると、その人を激しく責めたててしまいそう。
そのためせっかく協力しあってやってきた人と、仲違いをしてしまうことが少なくないのです。またあなたがリーダーの場合は、メンバーの失敗を激しく責めるため、みんなの心がいつしか離れていってしまう怖れが。
恋愛でも、片思いの間はかなりがんはるのでどんな相手でもふりむかせることができますが、両思いになってからは相手の遅刻などを許すことができずケンカはかり・・・・・という可能性があります。
周囲の人の失敗に対して感情的にならず、あくまでも許す気持ちを持つことが、成功へのカギといえるでしょう。本来は統率力に優れ、将来を見通すことができる「大物」としての才覚を備えているあなただからこそ、感情のこじれで人望を失ってしまうのは本当にもったいない話といえます。いつも冷静さを忘れずにいてください。

うーん。客観性、客観性と。
久しぶりにゲームを作成しています。難しいことを考えなくてすむように、簡単なシューティングで、とりあえず完成させることを目標にしています。
はじめはJavaで書いていました。シューティングは多くのオブジェクトを生成、廃棄するので、ガベージコレクタがあると楽です。また、グラフィックとかキーボード入力とかが簡単に扱えるのも利点です。

ある程度作ったところで問題が二つ生じます。まずはインターフェス。Javaのグラフィックとキーボード入力を私が書くと、ちょっともっさりします。腕のいい人が書くと違うのかもしれませんが。もうひとつは言語の記述力の問題で、ステージを記述する際に、coroutineかクロージャがあると便利かと思いました。知識がありませんが、本当はJavaのスレッドでも何とかなるでしょう。イベント処理スレッドと交錯すると怖いですが。

ここ数日解決策を模索していました。順当なのはC++&boost::shared_ptr&Lua&SDL。SWIGを使うとLuaの面倒なインターフェス書きが楽になるかな、とか。他にはOcamlという案もありました。Ocamlのグラフィカル&キー入力ライブラリが良く判りませんでしたが。OcamlSDLとかを使うのかな。

結局ひとつ解決策を見つけて、適当に移植を開始しています。とりあえず言語自体に慣れていないので、Neheのサンプルを(Monadiusのソースを参考に)書いて慣れようとしています。

OpenGLとGLUTが初期ライブラリに入っているというのが、Haskellを選ぶ動機になってしまいました。
以前インターネットの巨大掲示板で、Luaで特定の行にジャンプできないかという書き込みがあった覚えがあります。ノベルゲームのスクリプトだとジャンプできるのが基本とか。

解決策としては、たとえば
  • Luaを使わない、きりきりとかでよい。
  • 何をしたいかによって別の書き方があるはず
  • Luaのバイトコードにはジャンプ命令がある。改造して組み込む
があがります。この場合はどうも最後の形で解決したようです。RPGゲームのノベル部分に組み込むのではじめのはだめで、さらに中途セーブして途中から始めたい、とのことでした。

この場合はどうするのが良いでしょうか。もしあなたの開発した言語にGotoを組み込んで欲しいという人がいたらどうしましょうか。あるいはGotoを使わないでノベルゲームスクリプトを作るにはどうするんでしょうか。

ちなみに私はGotoは嫌いです。さらにこの類のゲームは作ったことが無いので、以下の話は机上の空論です。

普通のジャンプの代わりは末尾再帰でよいでしょう。構造化も出来て一石二鳥かも知れません。問題はLuaが末尾再帰を最適化してくれるかどうかですが。実際使うときに調べましょう。あるいはSchemeを使いましょうか。冗談ですが。

ステートのセーブ、ロードはまったく別の問題ですね。実行コードを含めた永続化でしょうか。あるいはfiber/microthread/coroutine/concurrencyの永続化。違ったらごめんなさい。こういう話はあまり知りませんが、簡単に出来るのでしょうか。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。