aokomoriuta's blog

青子守歌のブログ

株式会社はてなに入社しました

株式会社はてなに入社しました

株式会社はてなに入社しました - hitode909の日記

ボードゲーム「六次化農村」

この記事は、ボドゲ紹介Advent Calender 2017の5日目の記事です。遅刻して申し訳ありません・・・。

私が紹介するのは「六次化農村」というボドゲです。

ニューゲームズオーダー 六次化農村 ボードゲーム

ニューゲームズオーダー 六次化農村 ボードゲーム

なお、私はゲームのフレーバーテキストとかを知ってからプレイするのが大好きな人間なので(ともすると少しロールプレイもしたい)、先にその辺を中心にお話します。ルールや遊び方をすぐに教えてほしい!という方はちょっと飛ばしてください。

みなさん、農業の六次化って聞いたことありますか?
私は専門分野の関係上、まちづくりや国土計画の講義があって、そこで聞いたことがありました。
六次化聞いたことない方でも、第一次産業第二次産業第三次産業の区別は聞いたことある方多いかと思います。ざっくりいうと、生産業・加工業・商業のような区別です。
農業の六次化とは、大雑把に言うと「農家の人も、この第一次産業の生産だけではなく、加工して売る、第二次や第三次まで統合してやりましょうよ!」ということです。そうすると、ただ作物を作って売るだけより付加価値を付けられてより儲かるよ、という話です。

この「六次化農村」というゲームは、その農業の六次化がテーマです。つまり、やることを簡単に言うと

  • プレイヤーみんなで同じ村の農家です
  • 農業を六次化して、自分たちの村を発展させていきましょう
  • やったことに応じて、貢献度が貯まっていきます。
  • 6ターンやります。最終的に貢献度が高い人が優勝です!

ということです。盤面はこんな感じになります(と思ったら、プレイ途中の良い写真がありませんでした、すみません。これは終局後です)
f:id:aokomoriuta:20170909205541j:plain

この右側の大きなのが自分たちの村です。周囲にある数字が貢献度レーンで、ここの最終得点を目指します。

では、この最終的な勝ち負けを決める「村への貢献度」をどうやって手に入れるか?ですが、途中で、村の方向性を決める議会というのがあります。議会で何をするかは後述しますが、とりあえずこの議会で、たくさんの票を使って投票したら、その投票した票の数と同じ数だけの貢献度がもらえます。

では、使える票数はどうやって手に入れるのか。答えは、金で買います

大事なことなのでもう一度言いますね。

議会への票は金で買います

なんてリアルな津軽政治でしょう!?

はい、そんなわけで、このゲームは

  1. 農作物や加工品を作って売ってお金を儲けて
  2. そのお金で議会の票を買い
  3. 投票した票が多いほど村に貢献したとみなされるので、最終的に勝てる

という素晴らしいゲームです!!

その農作物はどうするかというと、自分の畑で作ります。ターンの一番最初に生産フェーズというのがありますので、そこで、自分の持ってる畑で

  • タマネギを作る
  • キャベツを作る
  • ナスを作る
  • (休耕=何も生産しない)

が選べます。同じ作物は連作できず、かつ、この順番に制約があります。例えば、キャベツを作った次のターンは、タマネギを作れず、ナスを作るか休耕するかしか選べません。ナスを作るともう休耕しかないですね。なので、最低でも4ターンに1回は休耕が必要です(が、そもそも6ターンしかないので、そんなに頻繁に休耕しないはず)。
なお、牧場もあって、その場合は牛乳が生産できます。

そして、その農作物を売る方法は2通りあります

  • 直売所で売る
  • 農協に卸す

直売所というのは、先の写真の左の方にある緑の黒板みたいなやつです。上町・中町・下町というのが見えると思いますが、最初は上町の直売所しかありません。また、直売所は地図上にあり、その直売所に3マス以内にある畑しか、その直売所に出荷できません。

まず農作物のランクごとに売れる値段が変わります。B, A, Sの3ランクあるんですが、ランクが良いものほど高く売れます。ランクは、生産する畑をアップグレードするか、最初からランクの高い畑を作ることで生産できます。
そして、同じランクの中でも右の方に陳列するほど高く売れます。出荷順に並べていくので、高いところは早い者勝ちです。

しかし、直売所で売れるのは、同じ種類の生産品につき一つ限り。しかも一番ランクが高く、ランクが同じ場合や安いもの、となります。つまり、

  • Bランクの3金のナス
  • Bランクの4金のタマネギ
  • Aランクの4金のキャベツ
  • Sランクの6金のタマネギ
  • Sランクの8金のタマネギ

が出荷されている場合、売れるのは、1, 3, 4番めだけになり、出荷した人に3, 4, 6金それぞれ手に入りますが、2番めと5番めのタマネギを出荷した人は廃棄されて0金になります(後述する「レストラン」があれば敗者復活があります)。

こういう時のために、地図上には加工場という特殊な建物が建てられます(建て方は後述)。畑と直売所の通り道に加工場があると、

  • タマネギ→タマネギの瓶詰め
  • キャベツ→キャベツの瓶詰め
  • ナス→ナスの瓶詰め
  • 牛乳→チーズ

に加工することができます。加工しただけでは高く売れるわけではありませんが、生産品としては別扱いになるので、例えばさっきの例で言うと、5番目のSランク8金に置くタマネギを、タマネギ加工場を通して加工できれば、8金でちゃんと売れるということになります。
一方、その出荷を見た後に、4番めのSランク6金の人が、同じく加工してタマネギ瓶詰めとして置くと、重複するのでやっぱり売れなくなります。このあたりもあるので、出荷順と誰がその直売所に売るかというのは読み合いが発生してなかなか面白いゲーム展開になります。

特に、直売所にはレベルというのがあって、たくさん利用されている(正確に言うと、あるランクの行が全部埋まった)場合に、レベルが上って、更に高い列に置くことができるようになります。なので、基本的には、みんなで直売所に出荷して、直売所のレベルを上げて、より高く売る、ということになります。

さて、では直売所から遠かったり、直売所に出しても廃棄されそう・・・という場合が出てきます。その場合は、直売所に出荷せずに畑に置いたままにしておきます。そうすると、その野菜・牛乳は、農協が一律1金で買い取ってくれます。ランクは関係なく全部1金です。ですが廃棄されて0金よりマシです。

ただし、農協には裏技(?)があって、議会で補助金というのが採択されると、特定の農作物を3金で買い取ってくれるようになります。

これが曲者です。なぜなら、先述の通り、最初は上町直売所しかありません。しかも、初期レベル(レベル1)の場合、Bランクの場合、2金・3金・3金という列しか使えません。

となると、どうなるか。みんな直売所に売らずに農協に売り続けます。だってそっちのほうが高いし。
結果、その村はいつまで経っても直売所も発展せず、補助金頼りのズブズブ農村になります

なんて素晴らしいニホンテキノーソンでしょうか!!

これ、初回プレイでよくありがちな風景です。が、正解は、多少無理してでも2金のところに置いて、直売所を発展させたほうが、後々のためにも良いです。


あと、補助金には、そのような農協が高く売れる以外に、土地が半額になったり、生産しただけでお金がもらえたりする仕組みがあります。これは、毎ターン議会で新しい補助金がランダムで提案されるので、それを賛成・反対に投票して過半数になったら可決&採択となります。場には常時2種類の補助金が発動していて、新しいものが採択されると、古い補助金から廃止されるという仕組みです。なので、古い補助金を目一杯利用している人はこの投票でかなりの反対票を積んできたりします。

ついでに議会には、補助金を決める以外にもうひとつ、先ほどの加工場や、新しい直売所のような特殊な建物を決める投票があります。毎ターン、今回建てられる建物が4つランダムに提案されてくるので、それぞれ「どの建物を、どこに建てたいか」をプレイヤーが1つずつ提案します。4人プレイだと4案集まるので、提案が終わったら誰か一つの提案に何票か投票します。最終的に得票数の多かった2案が採用され、建物が作られます。
みんな基本的には我田引水しますが、加工場などは同じ通り道にあると共同で使えるので、隣の人と結託して、票を合計したりすることもあります。その辺の相談はルール上制約はありません。

ということで、議会では建物と補助金の2種類に票を使います。先述のお金で買った票を、どちらに何票使うかというのも考えどころです。
また、票は先述の通りこの議会で使うと貢献度が得られますが、使わずとっておくと、最後に残った票数に応じて、プレイ順が変えられます。プレイ順は、農地の購入順や、出荷の順番です。ですので、どうしてもあそこの土地がほしい!とか、先に出荷したい!とかの場合は、(貢献度になりませんが)票を残しておくというのも手です。
特に、畑の種類には限りがあって、Sランクの畑などは枚数が3枚とかしかありませんので、早い者勝ちです。

そして、これが重要なのですが、持っている貢献度は、畑を作るorアップグレードするのに消費します。
貢献度で点数が決まるのに消費したら意味ないやん、ってなるかもしれませんが、そんなことはありません。
実は畑にはそれぞれのランクや種類に応じて「最終得点計算時に得られる貢献度」がついています。例えば、Sランクの畑などは、建てるのに18貢献度必要ですが、最終計算時には、40貢献度になります。ボードが1周80貢献度になっているのが分かる通り、40貢献度はとても大きいです。

六次化農村での勝敗は、建てた畑から得られる貢献度の数で決まると言っても過言ではありません。その他にも、持っている土地と同じだけの貢献度がもらえたりしますが、土地はどれだけ高くても17金なので、17貢献度にしかなりません。良い畑を建てて村に貢献するのが勝者への近道かな、と何回かプレイしていると感じました。

以上がゲームの簡単なルール紹介です。写真が手元になくて文章だけになってしまい分かりづらいところあるかもしれません・・・すみません。とりあえずまとめると、六次化農村というボドゲ

  • みんなで農業を六次化して、我らが村を発展させよう!
  • たくさん発展に貢献して、貢献度が一番高かった人が優勝だよ!
  • 議会でたくさん投票しよう!投票した票数に応じて貢献度がもらえるよ!
  • 票は金で買います
  • 金は作物を直売所に出荷して手に入れよう!みんなで直売所をたくさん利用してレベルを上げれば、より高く売れるようになるよ!
  • 直売所を使わず補助金頼りで農協に売り続けるといつまでも発展しません
  • 金と貢献度を使って、畑を増やそう!より高いランクの畑は、最終的な貢献度がとても高くなるよ!

という感じです。


と、まぁどんなボドゲでもそうだと思いますが、文章で読んだり耳で聞いただけではよく分かんないと思います。ぜひプレイしてみてください!
なお、6ターンしかありませんが、だいたい2時間ぐらいかかります。また、3人プレイも可になってますが(ルールがちょっと変わる)、何度か遊んでみた感じ、3人だとちょっと物足りない感じです。原則4人で遊ぶことをオススメします。

特に、6ターンは少ないように感じますが、最後の方のターンになると、急に得られる金も貢献度も増えるので、一気に色んなものを建てたり票をたくさん買えたりできるようになって、面白さが爆発します。でもそれは最初の数ターンでちまちまと改善したやつの結果なので、割と最初の方にどうするかが重要そうなゲームです。

以上、ボードゲーム「六次化農村」の紹介でした!もし「買うまでもないけどプレイしてみたい」という人は、持っていくので一緒にプレイしましょう!
基本的に、社内か研究室内でボドゲ会を主催しているものの、外部のボドゲ会は既に先駆者の方もいっぱいいらっしゃるので、誘ってくれたら喜んで行きますスタイルです。東京か名古屋あたりだとたぶんすぐに行きますので、六次化農村興味ある方はぜひお声がけください・・・!

株式会社はてなに入社しました

株式会社はてなに入社しました

株式会社はてなに入社しました - hitode909の日記

C#はunsafeの方が速いという幻想

数日前に話題になったこの辺の話。

espresso3389.hatenablog.com
qiita.com

C++よりC#が速いかどうかというのはとりあえず置いておきましょう。
しかし、大元ネタが「unsafe使うと1.2倍速くなります!」と言ってますね。

よく聞きますよ、「C#で速度出したかったらunsafeにしなさい」って。
しかし本当にそうなのでしょうか?その謎を解明するため、我々探検隊はジャングルの奥地へ(ry

なおこの記事のタイトルは以前の『OpenCLやる前にSIMD使い切れっていう幻想』と合わせています。興味がある方はそちらもどうぞ。

結論

unsafeにしなくても速くできる!!

f:id:aokomoriuta:20160505130347j:plain

コードと環境は以下の通り。

連休中で出先でやってるのでマシンスペックが低いのはご容赦ください(誰かまともなやつでやってみた結果ください・・・)

ご覧のとおり、unsafeを使ったアンマネージドなtest2より、マネージドの世界のまま書いたtestManagedBitmapの方が1.5倍ぐらい速いです。
もちろん、速いコードを書くにはそれなりの知識と技術が必要で、誰でもどんな風に書いてもマネージドで速くなるわけではありません(だから仕事になるんですが)。
「誰でもぱっと乗せたらぱっと速い」というのはとても大事です(だからGPGPUが流行りました)。でもunsafeは「ぱっと速くする」とお手軽さを出すにはリスクが大きすぎます。せっかく安全で手軽なマネージドの世界で閉じていた部分に無理やりアンマネージドを許可するというのは、とても危険ですし(だからunsafeって名前なんです)、気にすべきことが増えすぎます。
それなら、同じ高速化したいのなら、マネージドの世界で閉じたまま、どうやったら速くできるのかを追求するほうが安全だし健全だし貴重な技術になります。
今回みたいにマネージドで書いたほうが実は速くなるならなおさらです。

「とてつもなく速くなる」とか「どうしても互換性のために仕方なく」という特殊な事情がないなら、やはりunsafeは使う必要はないし使うべきではないですね。

続きを読む

株式会社はてなに入社しました

株式会社はてなに入社しました

株式会社はてなに入社しました - hitode909の日記

(ご報告遅くなって申し訳ありませんでした・・・)

MPS法における圧力ポアソン方程式の境界条件

MPS法やISPH法では圧力のポアソン方程式
\displaystyle \nabla^2 p = S(ここでSは生成項)
が出てくるのですが、色々なところの「MPS法実装してみました!」記事を見てみるとこのポアソン方程式の特に境界条件の扱い方が間違っているのが散見される(&よく「なんか上手く動かないんだけどどうしたらいい?」と聞かれる)ので、まとめておきます(別に新規性のあることじゃないし)。

続きを読む

Re: Re: OpenCLやる前にSIMD使い切れっていう幻想

d.hatena.ne.jp

なんだか知らない間にぜんっぜん関係ないtweetを拾われて勝手に憤られてた上に、全然まともに計算していないもの*1を出されてたので、ちゃんと動くようにして測りなおしました。

計算機は前回と同じものを使いますが、手元からVS2013がなくなってVS2015になってしまったので、Visual Studioのバージョンだけ違います(System.Numerics.Vectorsが必要ですが、4.1.0を使ってます)。
結果は以下の通り。

  • C#(なにもしない)
    • 5.5秒ぐらい
  • C#(System.Numerics.Vector<double>)
    • 4.5秒ぐらい

ということで、1秒ぐらい縮まりました。

FX-8350だとSIMD幅が128bitと判定されてSystem.Numerics.Vector<double>.Countが2になっていました(※先の記事の通りAVX2を使えば256bitできます)。
なので、2倍弱ぐらいは期待したのですが、結果は1.2倍で、ちょっと微妙な感じです。
関数呼び出しのコストがこんなに取られてるのか・・・よく分かりません。

私は最近まともなC#を書けてないので、まともなC#erさんに解明を期待します。

追記 (09/21 11:30)

すいません、昨日眠い状態でコード書いてたので、最後にコミットせずにpushして安心して寝てしまってました・・・。多分昨日の時点ではSystem.Numerics.Vector<double>を使っても全然速くないどころか遅かったと思います。
正しいのはさっきコミットしました。これで、4.5秒ぐらい(x1.2ぐらい)です。

追記 (09/21 12:30)

構造体もちゃんとサイズを切り分けたら、速くなりました。

  • C#(なにもしない)
    • 5.5秒ぐらい
  • C#(System.Numerics.Vector<double>)
    • 2.5秒ぐらい

なぜか2倍以上出ている・・・?まぁとりあえず速くなったので良しとします。
多分これが一番早いと思います(フラグ)。

追記 (09/21 23:00)

という話を聞いて、確かに手元のSurface Pro 3(OS:Win10、CPU:i3 4020Y)で試したところ、256bit SIMDになってくれました。

  • C#(なにもしない)
    • 5.5秒ぐらい
  • C#(System.Numerics.Vector<double>)
    • 2.2秒ぐらい

CPUが違うので単純比較できませんが・・・。
実行可能ファイルも置いておくので、もしお時間のある方は、OSとCPUの情報を添えて、実行時間とSIMD長を教えてくれると嬉しいです。

追記 (10/17 15:00)

↓のコメントにある通りAkio Takahashiさんからpull requestもらってました。
全部は取り込みませんでしたが、一部を取り込んだところ、以下のようになりました。

  • C#(なにもしない)
    • 5.5秒ぐらい
  • C#(System.Numerics.Vector<double>)
    • 2.5秒ぐらい
  • C#(今回)
    • 1.3秒ぐらい

以前の記事C++SIMD(AVX2)が1.3秒ぐらいだったので、同等ぐらいには速くなったようです。
ちょっと使い方に工夫が要るのかもしれませんが、C++と同じぐらいの性能がでるのであれば、C#には

  • アライン考えなくていい
  • CPUに合わせて勝手にSIMD長変えてくれる(逆にこれは欠点でもある?)
  • 最初から演算子オーバーロードされてるのでintrinsic書かなくていい

という長所が3点あります。

積極的に使えるタイミングでは使っていきたいところですね。

*1:4倍近く加速されたとのことでしたが、System.Numerics.Vector<T>が何かをちゃんと理解できておらず、System.Numerics.Vector.Countを一切考慮できていない、結果的に半分しか計算できていない粗末なものだった(例えばxSimd[0][2]とかアクセスしたら、SIMD長が足りなくて例外吐いて死ぬ)