D言語2.0で憂鬱な勇者
http://d.hatena.ne.jp/hrkt0115311/20080527/1211891558
うちのクソゲーに名前が似ていたので、D言語2.0の勉強がてらに作ってみました。やたらてこずってしまいましたが、公開してみます。
- 経験値管理にクロージャを使ってみる
- Range(1..30)っぽいforeachを使ってみる
- std.bigint
困りポイント1:多倍長整数が標準で扱えない
経験値がレベルの階乗なので、ulongとかだとあっという間にあふれます。
D言語で多倍長整数を扱うっぽいライブラリstd.bigintは、まだ準備中のようです。
http://www.kmonos.net/alang/d/2.0/phobos/std_bigint.html
準備中のソースらしきものはこの辺で拾えるので、とりあえずこれをお借りする。
http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/bigint.d?rev=700
- ソース中の「module std.bigint;」はコメントアウトする
- mybigint.dとかいう名前で保存
- 自分のソースからはprivate importで使う
- public importとすると、予約?されてるstd.bigintと競合するのかなんかわからんけどエラーになる
bigintのソースコメントにもありますが、BigIntはこういうことができるようです。
BigInt a = "9588669891916142"; BigInt b = "7452469135154800"; auto c = a * b; assert(c == "71459266416693160362545788781600");
困りポイント2:文字化けする
憂鬱な勇者特有の問題では全然ないんですけど、標準出力がUTF-8でぶちまけられるのでWindows上でそのまま動かすと思いっきり文字化けします。
この現象はずいぶん前から知っていたのですが、まだすっきりとした解決はないっぽいのですね。。。
アプリ側で対応するのが面倒な場合は、
yu | iconv -f utf-8 -t shift-jis
みたいにiconv*1通すか、リダイレクトしていったんファイルに落とすか、となりますね。
しかいサクッ使い捨てツール作って配布したい場合、こういうこまごまとした制限はうっとおしいなあ。
そーす
import std.stdio; import std.random; private import mybigint; string[] m_monster = ["焼きたてパン","強いシャチホコ","もんじゃ焼き一年生","怪人ホタテ男","ニセ勇者","逃げ足の早いアレ","睡魔","煩悩","愛らしい子犬の中の人","恋するスズメバチ","勇敢なクマンバチ","信じられない物","勇者の師匠","浮遊する鎧","怪盗ドボン","闇の招き猫","誘惑のカスタードクリーム","しょっぱすぎる籠手","カレー味の兜","光沢だけは一流の盾","若葉マークのモンスター","新緑の季節","梅雨時の車両のニオイ","暑すぎる夏","新宿らしき何か","やたら発達したドーナツ","育ちすぎたクマー","なごやかな雰囲気","凍り付いた気配","忍び寄る恐怖",]; string[] m_skill = ["お豆腐の買い方","鉛筆の買い方","消しゴムの使い方","メモの取り方","攻撃に使えないこともない呪文","裏町の歩き方","森林浴","珈琲の味","しじみのみそ汁の作り方","回覧板の回し方","郵便物の投函方法","立ち話のコツ","猫の呼び方","犬の呼び方","カラスの呼び方","鳩専用豆鉄砲","秘密の趣味","速く走るコツ","剣の使い方","斧の使い方","まきわりで、まっきわりわり","聖なる祈り","孤独","涼しく過ごすコツ","お洒落のコツ","卵をふわっと焼く方法","ごはんの研ぎ方","油汚れの対応方法","大人の振るまい","Suicaの使い方",]; const int MAX_LEVEL = 30; // 経験値を管理する無名関数を作ってreturnする mybigint.BigInt delegate() exp_dlg(int l, int e) { int level = l; mybigint.BigInt bi = e; // クロージャ! return { bi = bi * level; level++; return bi; }; } // 0 - (n-1) の乱数を作る uint get_rand(uint n) { return rand() % n; } int main() { auto my_exp = exp_dlg(1, 1); foreach (i; 1..MAX_LEVEL+1) { auto m_id = get_rand(m_monster.length); auto s_id = get_rand(m_skill.length); writefln("*-----"); writefln("%sを倒した!", m_monster[m_id]); writefln("%sの経験値を得た。", my_exp()); if (i < MAX_LEVEL) { writefln("勇者は%dにレベルが上がった!勇者は、%sを覚えた。", i, m_skill[s_id]); writefln(""); writefln(""); writefln("そして、"); writefln("かくかくしかじかで、山あり谷ありの冒険が続いたが割愛。"); } else { writefln("勇者は、また、レベルが上がった!"); writefln("勇者は、ふと空しさを覚えた。"); } writefln(""); } return 0; }
追記
http://d.hatena.ne.jp/hrkt0115311/20080609/ThankYou
ありがとうございます。
いやその、わたしド素人で勉強中なもので、こんなに好意的なコメントを頂くのは恐縮です。
とりあえずD2.xの新機能をためしに使ってみたよというレベルです。