miniP ゲームでＹＢＧの命令語を理解しよう！
白井宏明＠横浜国立大学
ＹＢＧの新規ゲーム開発でテンプレートとなっている miniP ゲームを例にして，ＹＢＧの命令語を解説する．
横浜国立大学大学院では，学生が自分の興味のある企業や業界のビジネスプロセスを次の３ステップでモデル化して実験する授業を実施している．
(1)ステップ１：概念モデル
ビジネスプロセスの自然言語によるあいまいな表現や非構造的な表現を，ダイアグラムを利用して表記することで，ビジネスプロセス内の要素を明確にする．学生はエクセルやパワーポイントを用いてダイアグラムを描く．
(2)ステップ２：論理モデル
学生は，ステップ１の概念モデルから，ビジネスを構成する具体的な要素とその要素間の関係を．数式や論理式として定義する．
(3)ステップ３：実装モデル
ステップ２の論理モデルからコンピュータ上に実装するために，専用言語を用いてソースコードを作成すると，ＹＢＧシステムがコンピュータ言語に翻訳する．
この手順で作成した，製造業 miniP の概念モデルの例を図１に示す．部品市場から部品を調達し，製品を製造して，製品市場で販売を行うモデルである．

図１miniP ゲームの概念モデル

ＹＢＧで使用できる命令語は５０語足らずであるが，これだけでも様々なビジネスゲームの開発が可能である．以下に miniP ゲームゲームのソースコード（末尾参照）を例にとって，ＹＢＧの代表的な命令語を解説する．

# ゲームの規模
def max-team 3
def max-round 10
これはビジネスゲームのチーム数とラウンド数を定義する命令である．ここでは 3 チームで 9 ラウンドまで実行することのできるゲームが定義されている．
（ＹＢＧはラウンド進行型のゲームであり，ラウンドが進むたびに前のラウンドの実行結果を参照することができる．このため，max-round を 10 とすると，ラウンド１０になったときに，ラウンド９の結果が参照できるので，実際に実行できるラウンド数は９となる．）# シリーズ定数
scon 商品需要 300 300 300 300 300 300 300 300 300 300 300
scon は各ラウンドに一つの定数を設定する命令である．この例では，商品需要が各ラウンドで 300 と設定される．miniP ゲームでは，この商品需要を３チームが取り合う構造となっている．
（経済状況の変化などに応じて，商品需要を変化させたい場合は，scon ではなく svar という変数として定義すれば，各ラウンドの商品需要を計算で作り出すこともできる．）# 広域定数gcon 所要量 50
gcon は全チームと全ラウンドを通して値が固定された定数を設定する命令である．ここでは１個の製品を製造するのに必要な部品の所要量を５０個と設定している．
（研究開発によって部品の所要量を削減したいような場合は，後述の tvar という変数で定義することもできる．）# 入力変数と入力ページ
ipage price 意思決定の入力<P>販売価格を入力してください．</P><P>生産指示(個数)を入力してください．</P><P>部品調達(個数)を入力してください．</P>
ivar 販売価格 range 0 100000 20000
ivar 生産指示 range 0 1000 100
ivar 部品調達 range 0 100000 5000
ipage は，ビジネスゲームでプレーヤがキーボードから入力する意思決定のための画面を作成する命令である．
<P>と</P>の間に書かれた文字は，入力画面上に説明文として表示される．
ivar は，入力変数を定義する命令である．range は数値を入力する変数を指定するもの
で，最小値，最大値，初期値を規定する．
（range 以外に，プルダウンメニューから項目を選択するための，select 指定も可能である．）
これらの命令によって生成された入力画面は図２のようになる．

図２

入力画面

# チーム毎モデル変数と初期値
tvar 部品発注数 5000
tvar 部品納入数(途中省略)
tvar 売上高
tvar 売上原価
tvar 売上総利益
tvar はチーム毎に異なる値を持つ変数を定義する命令である，変数名の後には初期値を設定することができる．
# 計算モデルtlet 部品発注数 = 部品調達
tlet は計算式を定義する命令である．注意すべきは，計算式の右辺の計算結果が左辺に代入されるという点である．単に左辺＝右辺という意味ではない．計算は上の行から順に実行されるので，ある変数の値を計算式の中で使用したい場合は，それ以前の行でその変数の計算を実行しておく必要がある．
tlet 部品納入数 = 部品発注数@1
tlet 部品在庫数 = 部品在庫数@1 + 部品納入数@1 は，1 ラウンド前を指定するための記述方法である．ビジネスモデルにおけるリードタイム（時間遅れ）を表現するものである．ｎラウンド前は，@n と書く．
tlet 生産可能数 = int(部品在庫数 / 所要量)
tlet 生産待ち数 = min2(生産可能数, 生産指示)
計算式の加減乗除は，+ - * / で指定する．int は小数点以下を切り捨てるための関数であり，min2 は２つの変数の値の小さな方を選択するための関数である．
pinv 受注数 = 商品需要 by 販売価格
pinv は，ある値を各チームに分配するための関数である．ここでは商品需要を各チームの販売価格に逆比例して分配したものを，各チームの受注数としている．
（他に正比例して分配するための prop などの関数もあるが，必要に応じて tlet の計算式を定義して分配数を決定することも可能である．
）
tlet 受注数 = rint(受注数)
rint は小数点以下を四捨五入するための関数である．
# 出力指定以下は計算結果を表として画面に表示するための命令である．
ooption fmt %1.0lf
ooption は，表示する数値の小数点以下の桁数を指定するための命令である．
opage sales 販売状況 public<H1>販売状況</H1><P>第${ラウンド}期: 需要: ${商品需要}</P>begintable
out teamsout teams-vars 販売価格 出荷数 売上高
endtable
opage は画面の形式を指定するための命令である．opage の後には,画面の名前を英文字と日本語で指定する．次に，public を指定すると，その画面は全チームが見られる画面になる．
（teamspec を指定すると，その画面は自チームの値だけが見られる画面になる．また，control を指定するとゲーム開発者だけが見られる画面となる．）<H1>と</H1>の間に書かれた文字は，表のタイトルとして表示される．
<P>と</P>の間に書かれた文字は表の説明文として表示される．${}を指定すると文字ではなく，変数の値が表示される．
begintable は表の始まりを，endtable は表の終わりを示す．out teams を指定すると全チームのチーム番号が表示される．out teams-vars の後に変数名を指定すると，その変数名と値が表示される．これらのソースコードにより作成された出力画面を図３に示す．

図３

出力画面

付録 miniP モデルのソースコード# ｍｉｎｉ－Ｐ# ゲームの規模
def max-team 3
def max-round 10# シリーズ定数
scon 商品需要 300 300 300 300 300 300 300 300 300 300 300# 広域定数gcon 部品価格 90
gcon 所要量 50
gcon 製造単価 5000
# 入力変数と入力ページ
ipage price 意思決定の入力<P>販売価格を入力してください．</P><P>生産指示(個数)を入力してください．</P><P>部品調達(個数)を入力してください．</P>
ivar 販売価格 range 0 100000 20000
ivar 生産指示 range 0 1000 100
ivar 部品調達 range 0 100000 5000
# チーム変数と初期値
tvar 部品発注数 5000
tvar 部品納入数
tvar 生産可能数
tvar 生産指示数
tvar 生産待ち数 100
tvar 部品消費量
tvar 部品在庫数 5000
tvar 生産数
tvar 販売可能数
tvar 受注数
tvar 出荷数
tvar 製品在庫数 100
tvar 売上高
tvar 売上原価
tvar 売上総利益
tvar 一般管理費 350000

tvar 広告費 50000
tvar 営業利益
tvar 累積営業利益# 計算モデルtlet 部品発注数 = 部品調達
tlet 部品納入数 = 部品発注数@1
tlet 部品在庫数 = 部品在庫数@1 + 部品納入数
tlet 生産可能数 = int(部品在庫数 / 所要量)
tlet 生産待ち数 = min2(生産可能数, 生産指示)
tlet 部品消費量 = 生産待ち数 * 所要量
tlet 部品在庫数 = 部品在庫数 - 部品消費量
tlet 生産数 = 生産待ち数@1
tlet 販売可能数=製品在庫数@1 + 生産数
pinv 受注数 = 商品需要 by 販売価格
tlet 受注数 = rint(受注数)
tlet 出荷数=min2(受注数, 販売可能数)
tlet 製品在庫数 = 販売可能数 - 出荷数# 損益計算tlet 売上高 = 出荷数 * 販売価格
tlet 売上原価 = 出荷数 * (製造単価 + 所要量 * 部品価格)
tlet 売上総利益 = 売上高 - 売上原価
tlet 一般管理費 = 一般管理費@1
tlet 広告費 = 広告費@1
tlet 営業利益 = 売上総利益 - 一般管理費 - 広告費
tlet 累積営業利益 = 累積営業利益@1 + 営業利益
# 出力指定ooption fmt %1.0lf
opage sales 販売状況 public<H1>販売状況</H1><P>第${ラウンド}期: 需要: ${商品需要}</P>begintable
out teamsout teams-vars 販売価格 出荷数 売上高
endtable#
opage accounting 会計情報 teamspec

<H1>損益計算書</H1><P>第${ラウンド}日，チーム: ${チーム}</P>begintable
out rounds
out rounds-vars 売上高 売上原価 売上総利益 一般管理費 広告費 営業利益 累積営業利益
endtable#
opage allvteam 全変数チーム横断 control<H1>第${ラウンド}ラウンド: 全変数チーム横断</H1>
begintable
out teamsout teams-allvars
endtable#
opage allvround 全変数ラウンド横断 control<H1>チーム${チーム}: 全変数ラウンド横断</H1>begintable
out rounds
out rounds-allvars
endtable