憂鬱な勇者 F# 版の再改定版です。今回は、F# の非同期構文をつかっています。パフォーマンスへの寄与は不明ですが。非同期構文を使うということが半ば自己目的化しています。非同期構文は関数の処理終了を待たずに次の処理を実行し、最終的に結果は配列という形で得られます。今回は経験値の計算の処理を非同期化し、30 レベル分すべてを非同期実行しています。
プログラム中では次のコードが非同期実行を実際にしている部分です
let computeEx current maximum =
Async.Run (Async.Parallel
[ for i in current .. maximum -> async_ex (big_int_of_int 1) 1 i ]);;
この構文によって、async_ex を非同期実行しています。async_ex は経験値を計算する関数。ex を実行するための関数です。
open System
open System.Collections.Generic
open Int32
open Big_int
open System.Collections.Generic
open Int32
open Big_int
let monsters = [|"焼きたてパン"; "強いシャチホコ"; "もんじゃ焼き一年生"; "怪人ホタテ男"; "ニセ勇者"; "逃げ足の早いアレ"; "睡魔"; "煩悩"; "愛らしい子犬の中の人"; "恋するスズメバチ"; "勇敢なクマンバチ"; "信じられない物"; "勇者の師匠"; "浮遊する鎧"; "怪盗ドボン"; "闇の招き猫"; "誘惑のカスタードクリーム"; "しょっぱすぎる籠手"; "カレー味の兜"; "光沢だけは一流の盾"; "若葉マークのモンスター"; "新緑の季節"; "梅雨時の車両のニオイ"; "暑すぎる夏"; "新宿らしき何か"; "やたら発達したドーナツ"; "育ちすぎたクマー"; "なごやかな雰囲気"; "凍り付いた気配"; "忍び寄る恐怖"|];;
let skills = [|"お豆腐の買い方"; "鉛筆の買い方"; "消しゴムの使い方"; "メモの取り方"; "攻撃に使えないこともない呪文"; "裏町の歩き方"; "森林浴"; "珈琲の味"; "しじみのみそ汁の作り方"; "回覧板の回し方"; "郵便物の投函方法"; "立ち話のコツ"; "猫の呼び方"; "犬の呼び方"; "カラスの呼び方"; "鳩専用豆鉄砲"; "秘密の趣味"; "速く走るコツ"; "剣の使い方"; "斧の使い方"; "まきわりで、まっきわりわり"; "聖なる祈り"; "孤独"; "涼しく過ごすコツ"; "お洒落のコツ"; "卵をふわっと焼く方法"; "ごはんの研ぎ方"; "油汚れの対応方法"; "大人の振るまい"; "Suicaの使い方"|];;
let skills = [|"お豆腐の買い方"; "鉛筆の買い方"; "消しゴムの使い方"; "メモの取り方"; "攻撃に使えないこともない呪文"; "裏町の歩き方"; "森林浴"; "珈琲の味"; "しじみのみそ汁の作り方"; "回覧板の回し方"; "郵便物の投函方法"; "立ち話のコツ"; "猫の呼び方"; "犬の呼び方"; "カラスの呼び方"; "鳩専用豆鉄砲"; "秘密の趣味"; "速く走るコツ"; "剣の使い方"; "斧の使い方"; "まきわりで、まっきわりわり"; "聖なる祈り"; "孤独"; "涼しく過ごすコツ"; "お洒落のコツ"; "卵をふわっと焼く方法"; "ごはんの研ぎ方"; "油汚れの対応方法"; "大人の振るまい"; "Suicaの使い方"|];;
let random = new Random();;
let rec ex (r:big_int) current maximum =
if current < maximum then
ex (r * (big_int_of_int current)) (current + 1) maximum
else r * (big_int_of_int current);;
let async_ex (r:big_int) current maximum =
async { return (ex r current maximum) }
let computeEx current maximum =
Async.Run (Async.Parallel
[ for i in current .. maximum -> async_ex (big_int_of_int 1) 1 i ]);;
let e = computeEx 1 30;;
let rec leveling current maximum =
if current <= maximum then begin
let r2 = random.Next(monsters.Length) in
end;; let r3 = random.Next(skills.Length) in
leveling (current + 1) maximum; System.Console.WriteLine("*-----");
System.Console.WriteLine("{0}を倒した!", monsters.[r2]);
System.Console.WriteLine("{0}の経験値を得た。", e.[current - 1]);
System.Console.WriteLine("勇者は{0}にレベルが上がった!", current);
System.Console.WriteLine("勇者は、{0}を覚えた。", skills.[r3]);
System.Console.WriteLine("");
System.Console.WriteLine("そして、");
System.Console.WriteLine("かくかくしかじかで、山あり谷ありの冒険が続いたが割愛。");
System.Console.WriteLine("{0}を倒した!", monsters.[r2]);
System.Console.WriteLine("{0}の経験値を得た。", e.[current - 1]);
System.Console.WriteLine("勇者は{0}にレベルが上がった!", current);
System.Console.WriteLine("勇者は、{0}を覚えた。", skills.[r3]);
System.Console.WriteLine("");
System.Console.WriteLine("そして、");
System.Console.WriteLine("かくかくしかじかで、山あり谷ありの冒険が続いたが割愛。");
let main =
leveling 1 29;
let r1 = random.Next(monsters.Length) in
let r1 = random.Next(monsters.Length) in
System.Console.WriteLine("{0}を倒した!", monsters.[r1]);
System.Console.WriteLine("{0}の経験値を得た。", e.[29]);
System.Console.WriteLine("勇者は、また、レベルが上がった!");
System.Console.WriteLine("勇者は、ふと空しさを覚えた。");;
System.Console.WriteLine("{0}の経験値を得た。", e.[29]);
System.Console.WriteLine("勇者は、また、レベルが上がった!");
System.Console.WriteLine("勇者は、ふと空しさを覚えた。");;
非同期構文のテストも兼ねてやってみました。でも、非同期構文は持っている、Foundations of F# では確か書いていなかったように思います。あとから出た、F# の開発者自身による Expert F# には出ているかな? 前回と今回のコードを置いておきます。
![]() | Foundations of F# (Expert's Voice in .Net) Robert Pickering Apress 2007-05-28 売り上げランキング : 1025 Amazonで詳しく見る by G-Tools |
![]() | Expert F# (Expert's Voice in .Net) Don Syme Apress 2007-12-03 売り上げランキング : 1007 Amazonで詳しく見る by G-Tools |




コメントする