kazasiki's blog

プログラミングとかVRゲームとか

期限が複数ある場合のバーンダウンチャートの書き方

この記事では、プロジェクトにおいて期限が近いタスク群Aと期限が遠いタスク群Bがあるときにどのようにバーンダウンチャートを運用すると良いかを書く。 あくまでも提案のようなもので、こうすると必ずうまくいくという類いのものではないので注意してほしい。

バーンダウンチャートとは?

バーンダウンチャートをご存知だろうか。驚いたことに日本語のwikipediaの記事がなかったのだが、backlogの解説記事を読むと、以下のように書いてある。

「期限までに全ての作業を消化できるのか?」ということが一目で分かるグラフです。 バーンダウンチャートでは縦軸に「作業量」、横軸に「時間」を割り当てて残りの作業量がグラフ表示されます。時間が進むと残りの作業量が減っていくので、右肩下がりのグラフになります。

私がspreadsheetで書いた雑な図がこちら。この図では幸運にも期日通りに作業が完了している。

f:id:kazasiki:20180720231451p:plain:w600

進捗が芳しくない場合は 実線が理想線よりも上にある という形でひと目で分かるようになる。作業が終わらない不幸なプロジェクトは以下のようになる。

f:id:kazasiki:20180720232238p:plain:w600

複数の期限がある場合にどうするか

さて、バーンダウンチャートの紹介はここまでにして本題に入ろう。 基本的にバーンダウンチャートはチームに対して大きなタスクが1つだけあり、それには単一の締切(もしくはマイルストーン)があるという前提で書かれるものだ。 その大きなタスクを細かいタスクに分けて、その経過を見ることで全体の進捗を推し量る手法だ。 ただ、現実にはそんなにわかりやすい状況はあまりない。チームとして複数のタスクが同時進行し、そのタスクにはそれぞれ違う締切が切られている場合も多いだろう。

最初に述べたとおり、期限が近いタスク群Aと期限が遠いタスク群Bがあるときにどのようにバーンダウンチャートを書くと良いだろう? 前提として、タスク群の優先度は考慮しない。基本的にはA群とB群のどちらも必ず終わらせる必要があるし、進捗が悪くなれば残業なり、人を増やして対応するとする。

まず、A群とB群でそれぞれバーンダウンチャートを書くというのはどうだろう?これはうまく機能しない。図を書くまでもない。 例えば、A群の締切が5日後で、残りの作業量が4日分だったとする。また、B群の締切が10日後で、残りの作業量が8日分だったとする。 どちらも単体であれば、終わりそうに見えるが、A群→B群で順序で作業した場合、総作業量は12日分であり、B群の締切には2日分間に合わない。 別々にバーンダウンチャートを書いている場合、このことには気づきにくい。

最も簡単な解決策は、A群のバーンダウンチャートの上に、B群のバーンダウンチャート積み上げることだ。要するに、期限が近い方を下に置き、遠い方を上に積み上げていくグラフにする。 例えば以下の図のようにする。この図は作業Aは間に合ってるが作業Bは間に合っていない。

f:id:kazasiki:20180721002526p:plain:w600

この図は先程の説明とほぼ同じ状態になっている。作業想定は50h/日で、A群は4日分の200hを5日で、B群は8日分の400hを10日でやろうとしている。全体として600hを10日でやろうとする。 A群をこなすだけなら速度は想定より低い40h/日でも足りる。だが、A+B群をこなそうとすると、60h/日は必要だ。(わかりすくするために50h/日の補助線を緑で引いた)

この図ではお行儀よくA群を全て終わらせてからB群に取り掛かってるが、そうでなくてもこの図は同じように機能する。 これを通常のバーンダウンチャートと同じようにチーム単位や、個人単位で見ることが出来れば、速度の遅れやキャパシティの超過は同じように追えるだろう。

察しのいい人はわかると思うが、B群単体の理想線は引いても意味がない。なぜならA群の作業をしている間、B群の作業は進捗しないからである。A群と並列で作業している間は、B実線がB理想線よりも上にくるのは当然であり、そんな図を見ても意味がない。A群とB群にどのくらい作業量を振り分けるかを計画できているなら計画線(理想線とは別に実績の計画を書く線)は引けるが、そんな芸当ができるケースは正直そんなにないと思う。

あなたが使っているバーンダウンチャート作成ツールがこういった形式の出力にうまく対応できることを祈る。

私と、競馬と、美穂という女性について

私と競馬について

私の父は競馬を愛している。私が実家を出てからは実際には見ていないが、たぶん今でも気になるレースでは馬券を買っているだろう。ギャンブルに身を滅ぼず様な賭け方ではなく、1000円程度の慎ましい賭け事を楽しんでいた(筈だ)。競馬場には行かずに、家で携帯やパソコンから馬券を注文していた。それもあって、家でスポーツ新聞の競馬の面を開いてよく唸っていたし、テレビでレースを見ては時折リビングでわーわーと騒いでいた。

f:id:kazasiki:20090307115000j:plain:w400

私が小学生くらいの頃は父がよくゲームセンターに連れていってくれて、競馬のメダルゲームを遊んでいた。父いわく「あれが一番1円あたり長く遊べる」らしい。小さいバケツのようなメダル入れ一杯分くらいのメダルを買って、私と父で半分に分けてゲームを始める。私は(幼かったのもあって)馬券の種類すらよくわからないまま遊んでいたが、なんとなく楽しかった記憶がある。おそらくミニチュアの馬たちが競馬場を模した盤面を走っているのが良かったのだろう。実際はモーターで動いていたわけだが、子供の私にはそれで十分だった。

ルールもよくわかってないからすぐに私の分のメダルが尽きてしまうのだが、そういったときは父から少しメダル分けて貰って延命を施した。それを繰り返し、二人ともメダルが尽きたら、その日はもう家に帰るという具合だった。

美穂という女性について

小学生の頃の私の友人に、美穂という名前の年上の女性がいた。姉の同級生であり、また美穂の妹も私の同級生だったので偶然接点があったのだ。子供同士が仲良くしてたのもあって、授業参観か運動会かなんかで父親同士も話す機会があったらしく、そこで彼女の父親も競馬好きであることを知った。今考えると大した偶然だと思うが、当時の私は大人の男性はみんな競馬が好きなものだと思っていたのでそんなものかと思っていた。

ある日、父が晩酌しながら「ちょっと面白い話があって」と話をしてくれた、曰く「美穂という名前は実は競走馬であるミホシンザンにちなんでつけた」と美穂の父親が言っていたらしい。競馬に詳しくない読者に伝えておくと、ミホシンザンというのは大体1985〜1987年に活躍した競走馬で、1985年の皐月賞菊花賞に優勝し、中央競馬クラシック二冠を達成している。私にもこの凄さはよくわからないがとにかく凄い馬だそうだ。確かに、美穂は1987年生まれなので時期的には一致している。私の姉も同じ年度の生まれだが、私の父はミホシンザンがそこまで好きではなかったようだ。

もともと日本人の女性に美穂という名前は多い。日本の女性の名前ランキング(生まれ年別) を参照すると、1973~1984年でも7~10位にはたまに入っている。ただ、やはりミホシンザンの効果なのか1986年は2位、続く1987年は5位、さらに翌年の1988年は3位、1989年も3位である。その年代のタレントに中山美穂氏もいるので、その影響もあるかもしれないが、どちらにしても子供につける名前とはそういうものということだろう。

私の元同僚にも1987年生まれの美穂という名前の女性がいる。流石にあなたの名前は競走馬が由来ですかとは聞いてない。

f:id:kazasiki:20150321151246j:plain:w400

私の名前にも馬編が入っている。父は自身が競馬が好きだからお前の名前に馬編の漢字を入れたと豪語していた。私はまだ独身だが、もし今女の子を授かれば鈴香(すずか)と名付けるのだろうか。

貴女の魂が未だ此処にあるうちに【cuphead】

「あ、死んだ。」

私たちはまた唐突に死を迎えた。私と彼女は休日に『Cuphead』をプレイしていた。

f:id:kazasiki:20180519202756j:plain:w400

このゲームはいわゆる2Dのアクションゲームであるが、画面が横や縦にスクロールせず、基本的に1ステージは1つの固定された画面で展開される、ボス戦のみのゲームである。その所為もあってとても難しい。

「また死んだ!」

と彼女は叫んだ。

このゲームはキャラクターが死んでから魂が天に召される(画面の上の方にフェードアウトする)までの間に、味方から魂を触ってもらうと生き返ることができる。なので、「死んだ」と宣言することは「助けて」とお願いすることと同義になる。 魂は天に向かっていくので、上の方で死ぬと助けてもらえる猶予時間が短くなる。また、味方に触ってもらう都合上、離れたところで死ぬと助けられなかったりする。そういった時は

「死んだ!助からない!」

と言う事になる。もしくは生きてる方が

「無理(助けられない)!ごめん!」

と言うことも多い。

味方を助けられなかった場合は、以降の戦いを1人で行う事になり、勝てる見込みが薄くなる。敵にはHPがあり、こちらの攻撃によって少しづつ減るので、手数が多いことはシンプルに火力につながる。また、ボスは相殺可能な攻撃をしてくることが多く、片方が相殺に専念しつつ、もう片方が攻撃に専念するなどのプレイングもある。

f:id:kazasiki:20180519141730j:plain:w400

味方の失敗の予知とその対処こそがこのゲームの本質

ずっと2人で同じボスと戦っていると、ふと気付くことがある。彼女には当たりやすい攻撃とそうでない攻撃があるということだ。ということは即ち、ボスの行動パターンを把握するのと同時に、彼女の行動パターンも把握できてくるということである。いや、この場合は死亡パターンといったほうが正しい。死亡パターンが把握できてくると、彼女の死を予知できるようになる。不思議な表現だが「死ぬ前に助けに行く」ことが可能になる。彼女の生存率が上がれば、ゲームを有利に進められる。味方の失敗の予知とその対処こそがこのゲームの本質であると私は思う。

私達は何度も死に、その度に「死んだ」と「ありがとう」を繰り返した。

このゲームを1人でやる場合、プレイヤーが行うのは回避と射撃のみである。射撃は基本的にひたすら連射してるので、もっと言えば回避だけしてれば良いゲームでもある。だが、2人でやっていると話は別である。彼女の死は、私に助けるか助けないかの選択肢を生む。助けに行くには、ボスの攻撃を避ける以外の行動をすることになり、被弾のリスクを上げる。仲良く一緒に死ぬ、いわゆる「仲よ死」となる可能性もある。その中で一瞬で助けることを選択し、巧みな操作で猛攻をかいくぐり、実際に彼女を助けられればさぞ格好よかろうというものである。実際、こういったシーンは数多くあった。私達は何度も死に、その度に「死んだ」と「ありがとう」を繰り返した。

f:id:kazasiki:20180519142606j:plain:w400

長い戦いの末、私と彼女は遂に悪魔を打ち滅ぼし、インク壺島に安息を取り戻した。
皆から英雄として讃えられ、私たちは清々しい気持ちで紅茶で一服しながら感想を言いあった。

私は愛らしい卵のキャラが描かれたカップを使い、彼女は艶かしい唇が縁に掘られたカップを使った。私達はそれぞれ違うお気に入りのカップがあるのだ。

f:id:kazasiki:20180519202032j:plain:w400

RS-WFIREX3を買ってGoogle Home miniで家電を操作してみた!

GWにスマート家電コントローラ RS-WFIREX3 を買いました。それでいろいろいじってみたのでレビューしてみます。

www.ratocsystems.com

概要

スマート家電コントローラ RS-WFIREX3 とは、Wifi経由で命令を受け取り、赤外線として発信する装置です。
Nature Remoをご存知の方は似たようなものだと思って頂ければ大丈夫です。RS-WFIREX3は実売が7000円程度と安く、Nature Remoが現在14,000円くらいするのと比較すれば実に半額程度で手に入ります。
また、RS-WFIREX3には温度計の機能もついており、特に自宅外からエアコンなどを操作する場合、温度計で部屋の室温を把握してからエアコンの電源のON/OFFが出来ます。
スマホアプリを仮想リモコンのようにして使うことができますが、Google Home miniでも使えるとのことで今回購入してみました。

セットアップ

Wifiなどのセットアップは特に特筆すべき部分がなかったので割愛します。 リモコンの設定はかなり便利です。大体の家電であればプリセットで対応できますし、プリセットにないものでも自分で登録できます。自分で登録する場合は、スマホ上の仮想リモコンのボタンを押して、それに対応する実物のリモコンのボタンを押す感じです。ボタンも自分で名前をつけることが出来るので、独自機能のあるリモコンでも問題なく使用することが出来ます。 RS-WFIREX3は360度、20mの範囲であれば赤外線が届きます。私の家は3部屋あるのですが、真ん中の部屋に置いて全部屋の照明を操作することが出来ました。

右下の黒いちっこいやつが本体です。本当にちっこいです。

f:id:kazasiki:20180513181042j:plain:w300

Google Home miniとの連携

ここのセットアップも簡単なので割愛します。音声での命令は例えば『家電リモコンを使って照明1の電気をつけて』などになります。家電リモコンの部分は、RS-WFIREX3のgoogle assistantアプリの名前(ピカチュウトークみたいなもの)で、頭に付ける必要があります。google assistantの機能でショートカットを作れば省略できますが、逆にややこしくなる気がするので使ってません。
照明1のところは照明2、エアコン、テレビなどのバリエーションがあります。あとは電気をつける以外にも「消して」、「明るくして」、「暗くして」などは使えます。テレビは試してないですが、チャンネルを指定したり、音声を大きく/小さくなどは出来るようです。

スマホの(仮想)リモコンの機能

スマホで様々な家電のリモコン操作ができるだけでかなり嬉しいのですが、さらに嬉しいのがタイマーでの動作です。私は朝起きるくらいの時間に寝室の電気が自動で点くようにしました。これが一番重宝してる機能かもしれません。

まとめ

買った当初は音声操作でのレスポンスが悪く、言い終わってから実際に家電が操作されるまでに5秒程度かかっていたのですが、いつの間にかほぼノータイムで操作できるようになりました。(アップデートがあった?)
家を出るときなどに偶に消し忘れた照明を消すのに使ってますし、寝るときもリモコンがぱっと見つからないときは音声で照明を消してます。 エアコンが本格的に活躍する季節になればエアコンの操作にも活躍してくれるでしょう。アプリ機能も音声機能も頻繁にアップデートされているので、今後もより便利になっていくものと思われます。
この記事が皆様の参考になれば幸いです。

ソシャゲのガチャを擁護する

まずは以下の記事を読んでほしい。結論から言うと「ガチャは賭博だ、規制が必要だ」という記事であり、その理由がつらつらと書いてある。私も概ね同意する。

togetter.com

ただ、私はカードゲーム、特に遊戯王のようなトレーディングカードゲーム(以下、TGC)にはやはりランダム性が必要だと思う。おそらくソーシャルゲームにも同じ理由でランダム性は必要だと思う。その理由をこの記事では述べる。

飽きが発生しにくいようにする

そもそも、ゲームにおけるランダム性というのは基本的にプレイ内容の多様性を実現するための装置だ。例えば、1パック10枚で販売されるTGCであれば、3パック(30枚)買ったA君と同様のB君では持っているカードに違いが出る。運良く1枚もかぶらなければ、2人併せて60種類のカードになるだろう。 そこでA君とB君が対戦をする。そうすれば、お互い持っているカードが違うので当然全く違う戦い方をするようになる。この、『一人ひとりが違う戦い方をすることを強制される』というのがTGCの面白いところだ。飽きが発生しにくいようになる。色んな人と対戦すれば、ずっと楽しいし、もし世界に2人しかいなくてもカードの交換などをすれば長く楽しめるだろう。

組み合わせを見つける

次に、カードを組み合わせる楽しさがある。カードには単純な優劣があるわけではなく、いろんな種類が存在する。攻撃力は低いがコストが低いカードや、特定の属性にだけ機能が発動するカードなどだ。であれば、1枚では弱いが他のカードと組み合わせることで強力な効果を発揮することもある。そういった組み合わせを探すのもカードゲームの良さであり、各々のプレイヤーが違うカードを持っていた方がそういった組み合わせを発見する機会が増える。(他プレイヤーと交流するきっかけにもなる)

カードを交換する

次に、カードを交換する楽しさがある。自分のカードと相手のカードで強力な組み合わせを作れるならそこでカードを交換することになるだろう。そういった交流もTCGの醍醐味である。だからこそ トレーディング なのだ。 突っ込まれると思うので書いておくと、殆どのソーシャルゲームではアイテムのトレードは禁止されている。これはリアルマネートレードに関連する問題によって運営としてそうせざるを得なくなったのだろうと邪推している。

まとめ

まとめると、カードゲームには入手するカードをランダムにした方がよい理由はちゃんとある。私は現在のガチャを巡る状況は、運営が想定するよりもプレイヤーが愚かであったことに起因しており、そこから『儲かる』という絶対的な正しさから各ゲームメーカーが便乗しはじめたと思っている。最後に自分のツイートを貼っておく。

eachメソッド(for文)は嫌い

eachメソッド(for文)は嫌いで、極力(Rubyで言うところの)mapやselectやreduceを使う。
理由は引数で与える集合と演算結果の関係性を不透明にしないためである。

文章を簡単にするため、引数の集合をxsで戻り値の集合をysとする。

mapの場合、ysはxsと同数の集合である。
ysの一要素はxsの一要素によって決定され、他の要素は関連しないことが期待される。
xsに順序がある場合、ysでもその順序が保持されることが期待される。

selectの場合、ysの1つ1つはxsのいずれかと同値であり、ysの要素数はxsと同じか、より少なくなる。
ysの一要素はxsの一要素によって決定され、他の要素は関連しないことが期待される。 (mapと同じように)
引数に順序がある場合、戻り値でもその順序が保持されることが期待される。

reduceの戻り値は1つの値である。
基本的にxsの順序に戻り値は依存する。演算が交換法則を満たす場合は、引数の順序に戻り値は依存しない。

for文やeach文は以上のことが明示的でない。よって嫌いである。
逆に言えば、特に戻り値が期待されない場合はfor文やeach文を使う。
集合を条件で絞りながら変換させたいなら、selectをしてからmapをするべきだ。

maxやsumはreduceの仲間である。findはselectにもreduceにも近い。