ゲームAdventureをスマホに移植する1週目: データ解析

# はじめに

個人的に長めの夏休みをとったのですが、
異常気象でなかなか遠出のよいタイミングがないので、自由研究をかねて
ゲームAdventureをUnityを使用してスマホに移植してみようと思います。

現時点で成功するかわからないし作業途中です。
この記事はその過程を書いたいわゆる製作日記です。

なんとなく4週間のうちにできたらいいなと思っているので全4回予定..


# 概要編

## Adventureって？

ゲームジャンルとしてアドベンチャーゲームという言葉がありますが、
その語源となったゲームがAdventureです(別名: Colossal Cave Adventure, Advent)

Will Crowther氏が1976年にFORTRANでオリジナル版を開発し、
Don Woods氏がFORTRANで1977年に改良版を開発しました。
Jim Gillogly氏がFORTRANをCに移植しています。

(以下, bsdgames版の冒頭メッセージ)

> This program was originally developed by Will Crowther.  Most of the
> features of the current program were added by Don Woods. Address
> complaints about the UNIX version to Jim Gillogly

ゲームは文字を打って進める方式で、コマンド選択式ではありません。
現在でいうとコンピュータと対話するChatbotに近いです。
アイテムを取ったり謎を解きつつ洞窟を探検します。

<img width="701" alt="スクリーンショット 2018-08-09 7.41.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/6a919a2b-6aba-a849-ed17-8bffb07a16e2.png">

https://ja.wikipedia.org/wiki/コロッサル・ケーブ・アドベンチャー

### 様々なバージョン

AdventureはタイトルにAdventure 350やAdventure 550など末尾に数字がついています。
スコアを競うゲームなのですがその最大得点でバージョンを区別しています。

現在最も有名なのは350ptバージョンでDebian packageのbsdgamesに収録されています。

以下DebianのサイトからCのソースコードをダウンロードできます。
https://packages.debian.org/stable/games/bsdgames

まるひろ氏のVersion 0というサイトで日本語パッチを配布しており、
日本語版について、自分はこのパッチをあててプレイしました。
http://ver0.sakura.ne.jp/pc/index.html#advent

Adventure 430など後のバージョンについてはRick Adam氏の以下サイトにて
攻略情報含め一通りまとまっています。

http://rickadams.org/adventure/

## 追記: Adventure 2.5のオープンソース化

350pt版はBSDライセンスですが以降のバージョンのライセンスについては長らく整理されていない状態でした。Eric S. Raymond氏が2017年にAdventure 2.5に限りなく近いopen-adventureプロジェクトをgitlabで公開しています。こちらはBSD 2-clause licenseとなっています。

> Recently, Eric S. Raymond, author of The Cathedral and the Bazaar, with the approval and encouragement of Crowther and Woods, released the official version of Adventure under a BSD 2-clause license. Raymond calls this release Open Adventure to avoid conflict with the various unofficial releases of Adventure that have version numbers higher than 2.5.

> The earliest port to C was by Jim Gillogly under an early Unix running
at the Rand Corporation in 1977; this version was later, and still is,
included in the BSD Games collection.  I have it from Don Woods directly
that "[Jim Gillogly] was one of the first to request and receive a copy
of the source" but that Woods did not actually know of the BSD port
until I briefed him on it in 2017.  (This contradicts some implications
in third-party histories.)

https://gitlab.com/esr/open-adventure

https://opensource.com/article/17/6/revisit-colossal-cave-adventure-open-adventure

# 調査編

※ ここからゲームのネタバレを一部含む場合があります。


## 移植に使用するバージョン

3つのバージョンを一通り読んで、
Cで書かれているのでbsdgames版を元に移植することにしました。
ただしbsdgames版はコメントが少ないのでDon Woods1977版のコメントから仕様を照らし合わせます。
補助的にAdventure 2.5のコードも参考にします。

### 1. Don Woods1977版 (Adventure 350)

  - コメントがしっかり書かれていて仕様がわかりやすい。
  - 使用言語がFORTRANで構造型とは書き方が異なる
  - ソースは1ファイルのみ(約3000行)
  - GOTO文が多用してある

### 2. bsdgames版 (Adventure 350)
  - コメントがまるっと消失していて仕様がわかりずらい..
  - マジックナンバーが多い..
  - データファイルは1と同じ
  - ヘッダファイル: 2 ソースファイル: 10
  - Cで書かれているが変数はほぼグローバル定義
  - GOTO文の多用は残っている

### 3. Adventure 2.5版 (Adventure 430)
  - コメントは1を継承しておりしっかり書かれていて仕様がわかりやすい。
  - ゲーム自体は350から変化しており一部処理が異なる
  - ヘッダファイル:4 ソースファイル:7
  - 一つ一つの処理は2よりわかりやすくなっている
  - コンパイラがC99だと動作しない箇所がある(C90を設定)  
  - GOTO文の多用は残っている

## マスターデータを調査

まずゲームの全体像を把握するためマスターデータを調査しました。

マスターデータはどのバージョンも共通形式でした。
1ファイルでタブ区切りのテキストファイル(tsvファイル)で管理されています。
1ファイル内に12のセクションに分かれており、`-1` の行になるまでを同一セクションとする仕様です。
細かい特殊イベントなどはハードコードで管理されていますが、
マスターデータ(特にSECTION 1)を読めばゲームの概要がつかめる状態でした。

<img width="649" alt="スクリーンショット 2018-08-13 13.27.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/1e426b1b-4f00-5b90-e55b-bc457a90b650.png">

マスターデータを今回Google SpreadSheetで整形したものが下記となります。
ゲータ形式はint, stringのみです。

https://docs.google.com/spreadsheets/d/e/2PACX-1vTha5-nOwg6foRNPFzpNfYFY-wLkKQT8-2dSgJ4bmhiaZ_D2CUl2hveYlbebGf30wG7huhSP5fk5OBQ/pubhtml

マスターデータ一覧

|SECTION|概要|備考|
|:--|:--|:--|
|SECTION 1|LONG FORM DESCRIPTIONS|状況(ロケーション)の説明(長文)|
|SECTION 2|SHORT FORM DESCRIPTIONS|状況(ロケーション)の説明(短文)|
|SECTION 3|TRAVEL TABLE|分岐条件など(1,4に関連)|
|SECTION 4|VOCABULARY|入力文字(モノ, アクション)の照合|
|SECTION 5|OBJECT DESCRIPTIONS|モノの説明|
|SECTION 6|ARBITRARY MESSAGES|付属説明|
|SECTION 7|OBJECT LOCATIONS|モノのある場所|
|SECTION 8|ACTION DEFAULTS|4のアクションのデフォルト結果|
|SECTION 9|LIQUID ASSETS, ETC|ロケーション属性|
|SECTION 10|CLASS MESSAGES|最終結果|
|SECTION 11|HINTS|ヒント|
|SECTION 12|MAGIC MESSAGES|現時点で不明..|

上記でSECTION: 1,2,5,6,10,12は `Key-Value` 形式のデータなので、
読み込み処理を共通で使用していました。

ゲームのコアとなっているのがSECTION 1,2,3,4,6 あたりでゲームは主に以下のように進行されます。

1. (条件によって)SECTION 6のメッセージ表示
2. SECTION 1または2のメッセージ表示
3. ユーザ入力受付
4. ユーザ入力とSECTION 4照合
5. SECTION 3を元にアクション実行(移動, モノを使うなど..)
6. 1に戻る

### SECTION 3: TRAVEL TABLEの仕様

SECTION 1,2のロケーションデータをつなぐアクションと条件を表すセクションです。
コード内コメントを一部整形したものが以下となります。

```
EACH LINE CONTAINS A LOCATION NUMBER (X),
A SECOND LOCATION NUMBER (Y),
AND A LIST OF MOTION NUMBERS (SEE SECTION 4).

EACH MOTION REPRESENTS A VERB WHICH WILL GO TO Y IF CURRENTLY AT X.
Y, IN TURN, IS INTERPRETED AS FOLLOWS.
LET M=Y/1000, N=Y MOD 1000.
	IF N<=300	IT IS THE LOCATION TO GO TO.
	IF 300<N<=500	N-300 IS USED IN A COMPUTED GOTO TO A SECTION OF SPECIAL CODE.
	IF N>500	MESSAGE N-500 FROM SECTION 6 IS PRINTED, AND HE STAYS WHEREVER HE IS.

MEANWHILE, M SPECIFIES THE CONDITIONS ON THE MOTION.
	IF M=0		IT'S UNCONDITIONAL.
	IF 0<M<100	IT IS DONE WITH M% PROBABILITY.
	IF M=100	UNCONDITIONAL, BUT FORBIDDEN TO DWARVES.
	IF 100<M<=200	HE MUST BE CARRYING OBJECT M-100.
	IF 200<M<=300	MUST BE CARRYING OR IN SAME ROOM AS M-200.
	IF 300<M<=400	PROP(M MOD 100) MUST *NOT* BE 0.
	IF 400<M<=500	PROP(M MOD 100) MUST *NOT* BE 1.
	IF 500<M<=600	PROP(M MOD 100) MUST *NOT* BE 2, ETC.
IF THE CONDITION (IF ANY) IS NOT MET, THEN THE NEXT *DIFFERENT*
"DESTINATION" VALUE IS USED (UNLESS IT FAILS TO MEET *ITS* CONDITIONS,
IN WHICH CASE THE NEXT IS FOUND, ETC.).
TYPICALLY, THE NEXT DEST WILL BE FOR ONE OF THE SAME VERBS,
SO THAT ITS ONLY USE IS AS THE ALTERNATE DESTINATION FOR THOSE VERBS.

FOR INSTANCE:
	15	110022	29	31	34	35	23	43
	15	14	29
THIS SAYS THAT, FROM LOC 15, ANY OF THE VERBS 29, 31, ETC., WILL TAKE
HIM TO 22 IF HE'S CARRYING OBJECT 10, AND OTHERWISE WILL GO TO 14.
	11	303008	49
	11	9	50
THIS SAYS THAT, FROM 11, 49 TAKES HIM TO 8 UNLESS PROP(3)=0, 
CASE HE GOES TO 9.
VERB 50 TAKES HIM TO 9 REGARDLESS OF PROP(3).
```

タブ区切りの1番目は移動元、2番目は移動先(条件含む), 3番目以降はアクションを表します。
2番目の値は下位３桁(N)と上位3桁(M)に分けて認識します。

下3桁(N)の仕様

|NUMBER||
|:--|:--|
|N<=300|Nの行き先 (SECTION 1, 2)に移動|
|300<N<=500|N-300 をコード内のGOTOで使用|
|N>500|N-500 をSECTION 6メッセージ表示。場所移動はしない。|

上3桁(M)の仕様


|NUMBER||
|:--|:--|
|M=0|無条件|
|0<M<100|M%の確率で行われる|
|M=100|無条件だがドワーフに禁じられている|
|100<M<=200|M-100 のモノを持っている|
|200<M<=300|M-200 のモノを持っているか同じ場所にいる|
|300<M<=400|PROP(M MOD 100)が0でない|
|400<M<=500|PROP(M MOD 100)が1でない|
|500<M<=600|PROP(M MOD 100)が2でない|

下記テーブル行は、以下を表しています。

```
15  110022  29  31  34  35  23  43
15	14	29
```

- a. 場所 `15` の時、`29 or 31 or 34 or 35 or 23 or 43` のアクション入力で、 `10`のオブジェクトを持っていると `22` に移動
- b. 場所 `15` の時、aに該当せず `29` のアクション入力で `14` に移動

### SECTION 4: VOCABULARYの仕様

主に入力データした単語を認識させるためのテーブルです。

コード内コメントを一部整形したものが以下となります。

```
SECTION 4: VOCABULARY. 
EACH LINE CONTAINS A NUMBER (N), A TAB, AND A FIVE-LETTER WORD. 
CALL M=N/1000.
IF M=0, THEN THE WORD IS A MOTION VERB FOR USE IN TRAVELLING (SEE SECTION 3).
ELSE, IF M=1, THE WORD IS AN OBJECT.
ELSE, IF M=2, THE WORD IS AN ACTION VERB (SUCH AS "CARRY" OR "ATTACK").
ELSE, IF M=3, THE WORD IS A SPECIAL CASE VERB (SUCH AS "DIG")
    AND N MOD 1000 IS AN INDEX INTO SECTION 6. 

OBJECTS FROM 50 TO (CURRENTLY, ANYWAY) 79 ARE CONSIDERED TREASURES (FOR PIRATE, CLOSEOUT).
```

まとめると以下の仕様です。
ゲーム開始時の説明でありますが、単語は先頭5文字で認識しています。

> Magic is said to work in the cave. 
> I will be your eyes and hands.
> Direct me with commands of 1 or 2 words.
> I should warn you that I look at only the first five letters of each word,
> so you'll have to enter "northeast" as "ne" to distinguish it from "north".

日本語

> 洞窟では言葉が魔法の力を持つ。
> それはあなたの目や手になり、1つか2つの単語で命令できる。
> 注意すべきことは、最初の5文字しか識別しないこと。
> 例えば北東のつもりで "northeast" と入力した場合でも "north" と
> 解釈される。

|NUMBER||
|:--|:--|
|   0 ~ 999|SECTION 3で使用する、主に移動に使用する単語です|
|1000 ~ 1999|モノを表す単語です。特に1050 ~ 1079は宝を表します(実際の宝データは15個)|
|2000 ~ 2999|アクションを表す単語です (Verb=動詞)|
|3000 ~ 3999|特別なアクションを表す単語です 


# つづく

Adventureは40年前のゲームとは思えないほど、
現在のアドベンチャー/RPGの原型が殆どできていて感動します。

条件分岐なども自身のアイテムやステータスを参照して、
また、マスターデータを別ファイルにして汎用的に追加できるシステムとなっています。
現在のゲーム以上に作り込まれている印象でした。

bsdgames版はコメントも消失して、コードも自動変換(?)で難解な状態ですが
オリジナル版はコメントに仕様がきちんと書いてあってとてもわかり易いです。
ゲームとしてもコードとしても名作でした。

==

1週目はゲームAdventureのざっくり概要とマスターデータの調査を行いました。
今週(2週目)はCのコードを読んでUnityでのC#に落とし込む予定..