オルトプラスエンジニアの日常をお伝えします!

2016年 有馬記念の予想

※この記事は「AltPlus Advent Calendar 2016」の23日目の記事です。

こんにちはこんにちは、shohojiです。

今週末は競馬ファンお馴染みのG1レース「有馬記念」が開催されますね。
有馬記念は、今年活躍した馬たちが一堂に会し、今年最後の活躍馬を決めるグランプリレースとも呼ばれる大きなレースです。

ダービーズキングの伝説やダービーゲート、ダービーロードなど、数々の競馬ゲームのを企画や開発をしてきたこの私が、そんなビッグレースがあるのに無視できるはずはありませんので・・・
今回は有馬記念の予想記事を書いてみようかと思います。

とはいえ、この記事は、QiitaのAltPlus Advent Calendar 2016の23日目の記事
ここでは技術的な話を書く必要があるとのことなので
今回は私が予想するのではなく、プログラムで有馬記念を予想してみようと思います。

なにで予想する?

競馬予想をする上で、様々なアプローチはあるとは思うのですが
今回は出走馬の過去のレースの走破タイムから予想してみようと思います。

とりあえず、実際の競馬ではレース展開、相手関係との駆け引きなどもあるので単純にタイムが早ければ強いというわけでもないのですが 競馬の専門誌などでも、ベストタイムが掲載されていたりするぐらいには重要な要素です。
普通に考えて、平均的にタイムが速い馬の方がポテンシャルは高いはず。
今回は出走馬の過去のレースから、それぞれの平均タイムを算出して、順位付けしてみます。

とはいえ、例えば距離が違う、斤量が軽ければ速くなるなど、いろんな条件で結果が変化するのが競馬。
単純に平均タイムを出しても全く意味のない数字になります。
なので今回は、タイムの比較ができるように、過去のレースが、全て今回の有馬記念と同じく、3歳以上の重賞、2500m、良馬場の条件で開催されていたとしたらどんなタイムだったのか?
というタイムの置き換えを行った上で、平均タイムを算出してみます。

どうやってタイムの置き換えをするか?

  1. タイムが変動する大きな要素でグループ化
    • 距離

    • 馬場状態(良、稍重、重、不良)

    • レースのクラス

    • レースの年齢条件(2歳、3歳、それ以外)

    • 競馬場

    で過去5年のログをグルーピングし、それぞれの条件の平均勝ちタイムを算出します。
    その中から「有馬記念」の中山、2500m、重賞、良馬場を「基準タイム」とします。

  2. 各馬の出走ログから、走ったレースと同じ条件の平均勝ちタイムと、基準タイムとの「タイム差」を算出

  3. 出走馬の実際の走破タイムに、タイム差を反映し「想定タイム」を生成

  4. 各馬の想定タイムから「平均タイム」を算出

実際には馬には距離適性とかもあるので、距離があまり違うレースや古すぎるレースを参考にしても仕方ないので
出走馬の過去2年半(2年前の秋の戦績から)の2000m〜3000mまでの芝のレースだけを対象にします。

予想タイムは?

だらだらと長くなるのもあれなので、それらを考慮して実際に平均タイム(予想タイム)を計算してみた結果がこれです。

f:id:shohojiap:20161222143434p:plain

前走、クラシック三冠最後のレース、菊花賞を制覇した「サトノダイヤモンド」がタイム1位となりました。

実際の競馬でもおそらく2番人気になりそうな馬が1位になりましたね、おそらく1番人気になるであろう、サブちゃんこと北島三郎さんの所有馬「キタサンブラック」は0.3秒差の5位、上位人気の馬はタイム的な裏付けもありそうですね

2位〜4位のタイム上位に入った、「ミッキークイーン」、「サムソンズプライド」、「アドマイヤデウス」などは穴馬ですが、タイム的には狙って見ても面白いのかもしれません。

ちなみに6位の「シュヴァルグラン」はハマの大魔神こと佐々木主浩さんの所有馬です。

さあ果たして予想タイムと実際のレース結果はどの程度リンクするのでしょうか?
有馬記念は12/25日の15時25分発走予定です。

Unity with VOCALOIDを触ってみる

※この記事は「Altplus Advent Calendar 2016」の22日目の記事です。

こんにちは。

どうせやるならと思いまして、昨年から気になっていたUnity with VOCALOIDを触ってみます。

そもそもUnity with VOCALOIDっていったい何?という話ですが、 「VOCALOIDを用いてUnityで音声の合成ができる」という、とても夢が広がる技術だそうで、発表があってからずっと気になってはいたものの、感覚的にはイマイチ盛り上がってないのかなーと感じています。(どうでしょう?)

でも、動的に歌声を生成することが出来るなんてすごいじゃないですか。もうちょっと盛り上がっても良いと思うんですよね。 ということで紹介してみます。

それでは早速やっていきたいと思いますが、 といっても、正直順を追って説明できるレベルのものではなかったので、ヤマハ公式サイトに置いてある、「サンプルプロジェクト3種類同梱パック」の「CreateSequence demo」を元に改変して今回のネタとしました。 とりあえず軽くポイントとなる箇所だけ説明します。

エンジンの起動とモードの設定

まずはエンジンを起動します。staticなYVFクラスを取り回す感じです。プラットフォーム毎にnamespaceが違うので、クラスのインポートの部分がこんな感じに。。。

#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
using Yamaha.VOCALOID.Windows;
#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
using Yamaha.VOCALOID.OSX;
#elif UNITY_IOS
using Yamaha.VOCALOID.iOS;
#endif
using UnityEngine;

public class Hoge : MonoBehaviour {
    void Start () {
        YVF.YVFStartup("personal", Application.streamingAssetsPath + "/VOCALOID/DB_ini");
    }    
}

起動後、モードの設定をします。 大きく分けて

  • Playback合成モード
  • Realtime合成モード

の2つのモードがあるようです。

ざっくり言うと、Playbackの方が、事前に用意したデータで発声、Realtimeの方が、その瞬間に合成して発声するものの様です。 Playback合成モードは最初に出来た曲があって、それをいじったりするという時に使う。(VSQXファイルを再生できる模様) Realtime合成モードは、たとえばボタンを押すなどした時にリアルタイムで音声を発声させたい時に使う。という感じでしょうか?

// PlayBack合成モードの場合。引数はエンジンのインスタンス数で、並列で歌声合成処理を実行する必要がない場合は1を設定する。
YVF.YVFResult result = YVF.YVFSetStaticSetting(engineCount);
// Realtime合成モードの場合。512はバッファサイズ。
YVF.YVFResult result = YVF.YVFRealtimeSetStaticSetting(YVF.YVFRealtimeMode.Mode512);

今回改変したサンプルはシーケンスを作って再生するというものなので、PlayBackモードになっています。

ノートの編集

実はこの間に色々あるのですが、ごめんなさい。省略します。 今回肝となる、ノートの編集部分です。ノートを編集し、シーケンスを作成→再生する。という流れになります。 ノートに音階や長さ、発生する単語などを設定します。

// ノートの編集.
List<VocaloidNote> melody = new List<VocaloidNote>();
VocaloidNote nt = new VocaloidNote();

string jsonData = "{\"noteArray\" : [{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"じ\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"ん\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"ぐ\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"る\"},";
jsonData += "{\"noteLength\" : 720,\"noteNumber\" : 76,\"lyricStr\" : \"べ\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"る\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"じ\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"ん\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"ぐ\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"る\"},";
jsonData += "{\"noteLength\" : 720,\"noteNumber\" : 76,\"lyricStr\" : \"べ\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 76,\"lyricStr\" : \"る\"},";
jsonData += "{\"noteLength\" : 480,\"noteNumber\" : 76,\"lyricStr\" : \"す\"},";
jsonData += "{\"noteLength\" : 480,\"noteNumber\" : 79,\"lyricStr\" : \"ず\"},";
jsonData += "{\"noteLength\" : 720,\"noteNumber\" : 72,\"lyricStr\" : \"が\"},";
jsonData += "{\"noteLength\" : 240,\"noteNumber\" : 74,\"lyricStr\" : \"な\"},";
jsonData += "{\"noteLength\" : 720,\"noteNumber\" : 76,\"lyricStr\" : \"る\"}";
jsonData += "]}";

NoteArrayModel noteArrayData = JsonUtility.FromJson<NoteArrayModel>(jsonData);

int StartTime = preTick;
for ( int i = 0; i < noteArrayData.noteArray.Count; i++ ) {
    nt.ClearNote();
    nt.Note.noteTime = StartTime;
    nt.Note.noteLength = noteArrayData.noteArray[i].noteLength;
    nt.Note.noteNumber = noteArrayData.noteArray[i].noteNumber;
    nt.Note.lyricStr = noteArrayData.noteArray[i].lyricStr;
    StartTime += nt.Note.noteLength;
    melody.Add( new VocaloidNote(nt) );
}

今回、最低限で音階と長さと言葉のみ設定しています。ノートの登録は楽してjsonにしちゃいました。 こういうとき、unityのJsonUtilityは便利ですね。 NoteArrayModelというモデルクラスを作って、jsonデータをデシリアライズして、ぐるぐる回してます。 リファレンスにC4=72とありましたので、音階はそれに合わせて設定しました。 ド=72 レ=74 ミ=76 ファ=77 ソ=78 ラ=80 シ=81 ド=82 こんな感じかと思います。

歌声合成の実行

最終的に歌声を合成して実行します。 ソースコードについては説明できるだけの知見を得ることが出来なかったので割愛します。 サンプルソースコードやセミナーの資料にかなり詳しく書いてありますので、そちらを参照しましょう。

できたもの

windows版実行ファイル

Mac版実行ファイル

リポジトリはこちら

*Unityのバージョンは5.5です

*VOCALOID SDKのバージョンは1.3.0.0です

*動作には別途VOCALOID SDKをダウンロードし、インポートしてください。

http://business.vocaloid.com/unitysdk/download/

所感

サンプルの改変とはいえ、結構簡単に音声合成が出来るのは魅力です。 今回触りませんでしたが、音色などもかなり細く設定できるようになっています。 ゆっくりしていってね!でおなじみのSoftTalkの上位版みたいなものはサクッと作れそうな感じでした。

そして、以下感じた問題点です。

  • なにをやっているのかを読み解くコストが結構高い
  • モバイルでのパフォーマンスが少し心配
  • 現状、利用できる音声ライブラリがユニティちゃんのみ

これらが解消されていくと、より広がっていける。かもしれないですね。

以上です。ではまたどこかで。

ゲームジャムに参加しましょうー!

※この記事は「AltPlus Advent Calendar 2016」の21日目の記事です。

※日本語で記事を書くのは初めてですので、分からない部分があれば、教えてもらえればとの事です!

はじめに

皆さん、こんにちは!今年の8月に入社した Unity エンジニアーのバイロンです!この記事では、ゲームジャムのお話しをします!多分ゲーム業界で働いてる人はご存知だと思うのですが、「まだゲーム業界に入ったばかりの人」、「ゲーム業界で働いてみたい人」、「自分のゲームを作ってみたい人」ー そんな人向けに書いてみました。ゲーム作りにパッションがある方で、まだゲームジャムに参加した事が無い方はぜひ読んでもらいたいです!

ゲームジャムとは何か

「ジャム」と言う言葉は音楽家がよく使うフレーズで、「集まって曲を作る」と言う意味があります。それを元に、ゲームジャムとは色々な人が集まってゲームを短時間で作るイベントです。制限時間はゲームジャムによりますが、平均で言うと、24〜48時間です。ゲームジャムのイベントではいつもゲームのテーマがありまして、それをベースにしてゲームを作ると言うイメージですね。

そこで今一番有名なゲームジャムが (GGJ) Global Game Jam です。GGJ 毎年開かれるイベントで、今年の一月に93国から、3万6千人以上の参加者が同時にゲームを作りました。GGJでは、各場所にイベント会場がありまして、そこで参加者の皆さんが集まり、自己紹介、チームを組み、テーマの公開を待ち、48時間の短い時間でゲームを作ります。来年の2017年1月にまたゲームジャムが開かれるので、こちらのリンク でイベント会場を探してみましょう!

「参加者に何のメリットがあるんですか?」

そうですねー。ゲームジャムは基本コンクールとは違うので、賞品・賞金とかはもらえません。イメージとしては、「自分が一生懸命作ったゲームが一番の賞品」っと言うロマンチックな感じかなー?

多分人によって参加する目的が違ってくると思うんですが、良く有るのが「自分のアイデアを試したい」、「自分の限界を超えてみたい」、「ゲームを作ってみたい」、「ゲームを作る仲間が欲しい」、とかですかね。そんな感じな人がゲームジャムに集まります。

そう言う事なので、メリットは自分の成長・野望・パッション(?)ってところかなー。でもそんなに真剣に考えなくても、少しでも「なんかゲーム作りたいなー」って気持ちがあれば、それで十分だと思います。

「でも自分はゲームを作った事が無い」。。

または「ゲームを作れる自信が無い」、「足手まといになる」、と言う風に思ってる人には、怖がらず、参加してもらいたいです。自分も来年のゲームジャムで5年目になるのですが、毎回「足手まといになりたくない」、「ダメなゲームは作りたくない。。」と言う気持ちでいっぱいです。多分ゲーム業界で働いてる人はそう言う「怖い」と言う感情と向き合って仕事をしているのでしょう。(デザイナー・プランナーさんは特に)

ゲームジャムに参加する人は、そう言う怖さを知ってるので、皆さんは怖がらず、自信がなくても参加しましょう! あと、一人でゲームは作れないのは当たり前なので、「分からない部分」または「これ自分は出来ない事わ。。」って事がある場合は、チームメイトに任せましょう。

まとめ

次のGGJは1月20〜22日になりますので、ぜひ参加してください!その日にちに来れ無い人は、Ludum Dareをお勧めします。Ludum Dareのゲームジャムはネット上で行われるので、自分の家・カフェからゲームを作るっと言う感じですね!

最後まで読んで下さってありがとうございます!

Global Game Jam
Ludum Dare