SyntaxHighlighter

StackEdit CSS

2013年4月15日月曜日

C++で遠隔操作

釣り。

授業を聞いててふと思いついた。
その授業では、モジュールの隠ぺい(オブジェクトのprivateとか)について説明していたんだけど、C++ではprivateにしても外からいじれるという話をどこかで聞いたので試したくなった。

そのオブジェクト自身が漏らす場合

class Player {
    int money;
public:
    Player(int m) : money(m) { }

    int getMoney() { return money; }

    int* wrongMethod() { return &money; }
};

int main(){
    Player player(10);

    cout << player.getMoney() << endl; //=> 10

    int* money = player.wrongMethod();
    *money *= 100;
    cout << player.getMoney() << endl; //=> 1000

    return 0;
}
何かのミスで、privateのメンバ変数のアドレスを漏らしてしまった場合。これはほかの言語でもありうるだろう

外から位置を特定して触る方法

class Player {
public:
    int power;
private:
    int HP;
    int MP;
    int money;
public:
    Player(int m) : money(m) {
        cout << &power << endl;
        cout << &HP << endl;
        cout << &MP << endl;
        cout << &money << endl;
    }

    int getMoney() { return money; }
};

int main(){
    Player player(10);
    cout << &player << endl;

    cout << player.getMoney() << endl; //=> 10

    int* money = (int*)&player + 3;
    *money *= 100;
    cout << player.getMoney() << endl; //=> 1000

    return 0;
}
Playerのコンストラクタでメンバのアドレスを調べたら、playerのアドレスがpowerと一致していて、また、power、HP、MP、moneyの順でアドレスが4(=sizeof(int))ずつ増えていったのでもしやと思い、playerのアドレスに+3したら見事にアクセスできたw
C++のポインタが理解しにくいといわれてるのは、クラスなどの先進的な機能とポインタなどのプリミティブな機能が同居しているところにあるってどっかで見たけど、まさにその通りだとこれで実感した。こういうキケンなことができることは、速度とのトレードオフだろうけど。

おまけ

privateメソッドは内部から漏れることぐらいしか思いつかなかった
class Player {
    void privateMethod(){
        cout << "@privateMethod" << endl;
    }
public:
    void (Player::*wrongMethod())() { return &Player::privateMethod; }
};

int main(){
    Player player;
    (player.*(player.wrongMethod()))();

    return 0;
}
関数ポインタの書き方わからんwww

2013年4月11日木曜日

CoffeeScript + enchant.jsでパズドラもどきを作ってみた感想

動機

パズドラ面白そうだなぁ → ソシャゲーはちょっとなぁ。。。 → じゃあつくってみるか

スクショ


どう見てもパズル&ドラゴンズです。本当にありがとうございました。

感想

CoffeeScriptとenchant.js、どちらも初めてだったが、意外とすんなりできた。バグを直す時間のほうが長かったんじゃないかってくらい。CoffeeScriptはRubyがまぁまぁ使えるので、直ぐに書けるようになったし、enchant.jsは情報が多かったのでそれほど詰まるってことはなかった。
 JavaScriptはよくわからないので比べられないが、少なくともCoffeeScriptで実装中のストレスはほとんどなかった。0引数の関数を呼ぶときのかっこをRubyのノリで付け忘れてすこし悩んだり、インデントを間違えて数時間悩んだりしたぐらい。豊富なシンタックスシュガーのおかげでサクサクかけた気がする。->が結構かっこいい。
isInField = (x, y) ->
    #...
とか。
lines.forEach (line) ->
    #...
はRubyでいうブロックみたいに見える
 enchant.jsはSpriteで画像を表現するのに少し慣れなかった。勝手にカウントしてくれるラベルがあったのは少し驚いた。こうしたもののおかげで実装の負担が軽くなるのはいいことだと思う。何より好感が持てたのは、ゲームに使える画像がいくらか付属していることだ。ゲームを作っても絵が描けないので、見た目が残念だったりして、結構萎える。クオリティの高い画像が付属していると、作る側のモチベーションも上がるよなぁと思った。自分もドラゴンの画像を使わせてもらった。
 最初は充実感があったが、だんだん完成に近づくにつれ、充実感が無くなってきた。どれだけ頑張っても、本家には勝てない気がしてきたからだ(あたりまえ)。つまり劣化コピーだ。やはり模倣は面白くないなと身に染みてわかった。コピーしようと思ったらそれを超えるものを作らないと成長しないしね。
 ちなみに動機は実装している間に消えてしまったwww