ホット・ビイから発売されていたメガドライブ用ソフト「キングサーモン」の攻略メモです。
攻略と言っても、ポイントに糸を垂らして大物が来るのをひたすら待つばかりなので、攻略することはほとんどありません。そこで本ページではパスワード解析なんてことをやっています。
ハック技
パスワードの3文字目〜8文字目をでたらめに入れ替えても認識される(2文字目も入れ替え可能だが、法則がある)。これによってレベルが大幅に上がったり、世界記録がとんでもなく大きくなったりする。
ゲームを楽しみたい人にはオススメできない。
説明書を読んでも良く分からないのでポイントをまとめてみました。
広域マップとポイントマップ
ルアーの表示のないのが広域マップで、ルアーが表示されているのがポイントマップ。トローリングできるのはポイントマップのみ。
ポイントマップのみつけ方
広域マップでAボタンを押すとメッセージが表示されてポイントマップに移動する。
「なかなか良いポイントだ」といったメッセージがでるポイントを攻めればまず間違いない。
海でのトローリングスポット
海にいるキングサーモンは、餌になるニシンを追いかけているので、ニシンの群れの魚影の後ろにルアーを落とし、魚影に合わせて舟を走らせる。
サーモンの群れの魚影に合わせるのもありだ。
ルアーの色が赤色になるのでポイントは分かると思う。
河でのトローリングスポット
河でのキングサーモンは、産卵のために上流へ遡上(そじょう)しているので、舟を上流に向かってゆっくりと走らせ、ルアーを河の流れに任せるようにする。
舟の速度が合うとルアーの色が赤色になるはず。
固定ポイント
魚影を追いかける以外にも、ルアーの色が変わるポイントが存在する。それが固定ポイント。
海の場合は、棚の深さが変わる所、入り江になっている所、小島の近くなどにある。
河の場合は、キングサーモンが跳ねている場所の近くにある。
あわせかた
説明書には、竿が大きくしなった時に上キーを押すと書いてあるが、押しっぱなしではダメ。押した後に離さないといけない。なので押すというよりも叩く感じでやった方が成功しやすい。
連打しているだけでも合わせられることもある。
ファイト
説明書のヒント集には書いてないが、ポイントはサーモンをいかに疲れさせるか。
サーモンが勢いよく引いている時は、ロッドを立ててラインが流出するのを抑える。そのうちサーモンが引かなくなる瞬間があるので、隙を見てラインを巻き取れば良い。
逆にこちらもスタミナが切れてくるが、そのときはAボタンを押して手をブラブラさせることでスタミナを回復できる。
ポンピング
ファイト時にリールを巻いているだけでは釣り上げるのは難しい。そこでポンピングというテクニックを使う。
やりかたは、まずロッドを立て、ロッドが立ったらロッドをニュートラルに戻してロッドを立てた分のラインを素早く巻き取る。これを繰り返すと比較的早く巻き取ることができる。
それでもプレイヤーのレベルが低いうちはこのテクニックを使ってもなかなか釣り上げられなかったりはする。
1.最初にやったこと
とりあえず、何もしない状態でのパスワードを採取。同じ状態になるパスワードは最低でも16種類は存在するようだ。
これらを良く見ると、1文字目〜8文字目は"PQRFWVTXLDSYCZNGHJKBM"が循環していることが分かる。
予想するに、1文字目はマジックナンバー(特別な意味をもった数値、ここでは乱数の初期値)で、9文字目と10文字目はチェックサム(誤りを検出する符号)になっていると思われる。それと、パスワードに使う文字は、アルファベット26文字から母音になる5種類の文字(A,E,I,O,U)を除いた21種類だけらしい。
2.サンプルは多い方が良い
総釣果量 6ptの状態でパスワードを採取。14種類しか採取できなかったが、これも16種類存在すると思われる。
総釣果量 0ptの状態と比べると、6文字目に違いがある(9、10文字目も違うが、無視)。それぞれ、例の文字列("PQRFWVTXLDSYCZNGHJKBM")のインデクスを 6だけ進めたものになっている。
おそらく下の表の様に値が決まっていて、差分を取るようになっているのだろう。
文字 | P | Q | R | F | W | V | T | X | L | D | S | Y | C | Z | N | G | H | J | K | B | M | …以下循環 |
数値 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21… |
3.さらにサンプル採取
総釣果量 18ptの状態でパスワードを採取。これも14種類しか採取できなかった。
− | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 |
0 pt | R | F | W | V | T | X | L | D | K | C |
18 pt | R | F | W | V | X | D | L | D | J | C |
差分 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | 0 | -1 | 0 |
5文字目と6文字目に注目すると、5文字目の差分が1、6文字目の差分が2になっている。もしかしたら一文字が4ビット分の情報量を持っているのかもしれない。5文字目の値を16倍したものに6文字目の値を加算すると、ちょうど 18になる。
各文字の対応は、下の表のようになっていると推測。
1文字目 | 乱数列の最初になる文字 |
2文字目 | ステージ? |
3文字目 | 総釣果量、0〜3bit |
4文字目 | 総釣果量、4〜7bit |
5文字目 | 総釣果量、8〜11bit |
6文字目 | 総釣果量、12〜15bit |
7文字目 | 最大キングサーモン、0〜3bit |
8文字目 | 最大キングサーモン、4〜7bit |
9文字目 | チェックサム |
10文字目 | チェックサム |
4.チェックサムの解析
残りはチェックサム(誤りを検出するための符号)を解析するだけだが、一体全体どうなっているのか分からない。
しかし、何気なく、既存のパスワードの1文字目〜8文字目の文字を入れ替えたら、すんなり認識された。と言うことは、1文字目から8文字目を加算もしくは排他的論理和(xor)しただけかもしれない。
試しに、6ptのパスワード"PQRF WYTX JN"の"WY"の部分を入れ替えると、5文字目の値は 1、6文字目の値は 20(4bitの値を取るのならオーバーフロー)になる。実際にこのパスワードを入力してみると、ちゃんと認識され、総釣果量は 20ptになっていた。6文字目の値が 4として認識されたという事は、数値が16以上になると循環するということだろう(普通ならエラーにするものだが…)。
ついでに各文字の対応を調べたら、表3の通りになっていた。
5.チェックサム解明
連立方程式のようにしてチビチビ計算(例えば、表2の場合だとT=D+16だと分かる)していったら、チェックサムの法則を解明できた。
まず、アルファベット順にA=1, b=2, …, y=25, z=26としておく。そんでもってパスワード1文字目から8文字目までを加算合計する。それをチェックサムとして法則通りに9文字目と10文字目に収める。それだけでいいらしい。
6.まとめ
1文字目は乱数の最初の文字とし、2文字目以降は、乱数列(表1)を一文字ずつ進めたものに数値を加算したものとして扱う。
総釣果量は他のゲームで言うところの経験値に価する。経験値からはレベルや体力の値を求める事が出来る。値の最大値は65000になっており、それ以上だとエラーになる。
1文字目 | マジックナンバー(乱数の最初の文字) |
2文字目 | ステージ(0〜3以外の値だとエラー) |
3文字目 | 総釣果量、上位0〜3bit |
4文字目 | 総釣果量、上位4〜7bit |
5文字目 | 総釣果量、上位8〜11bit |
6文字目 | 総釣果量、上位12〜15bit |
7文字目 | 最大キングサーモン、上位0〜3bit |
8文字目 | 最大キングサーモン、上位4〜7bit |
9文字目 | チェックサム、上位0〜3bit |
10文字目 | チェックサム、上位4〜7bit |
パスワードの生成プログラムをC言語で書いてみた。人によってはプログラムソースを見た方が理解し易いかもしれない。
C言語のプログラムソース |
/* メガドライブ用ゲームソフト「キングサーモン」のパスワードを生成する */ #include <stdio.h> char rand_table[] = "pqrfwvtxldsycznghjkbmpqrfwvtxldsycznghjkbm"; void main(void) { int i, stage, pound, record, idx, chacksum; char pass_str[16]; printf("乱数初期値[0-15] => "); scanf("%d", &idx); printf("ステージ[0-3] => "); scanf("%d", &stage); printf("総釣果量[0-65000] => "); scanf("%d", £); printf("キングサーモン記録[0-255] => "); scanf("%d", &record); /* パスワード生成 */ idx &= 0x0f; pass_str[0] = rand_table[idx]; pass_str[1] = rand_table[++idx + (stage & 0x3)]; pass_str[2] = rand_table[++idx + ((pound >> 12) & 0xf)]; pass_str[3] = rand_table[++idx + ((pound >> 8) & 0xf)]; pass_str[4] = rand_table[++idx + ((pound >> 4) & 0xf)]; pass_str[5] = rand_table[++idx + ( pound & 0xf)]; pass_str[6] = rand_table[++idx + ((record >> 4) & 0xf)]; pass_str[7] = rand_table[++idx + ( record & 0xf)]; /* チェックサム計算 */ chacksum = 0; for (i = 0; i < 8; i++) { chacksum += pass_str[i] - 'a' + 1; } pass_str[8] = rand_table[++idx + ((chacksum >> 4) & 0xf)]; pass_str[9] = rand_table[++idx + ( chacksum & 0xf)]; pass_str[10] = '\0'; printf("%s\n", pass_str); } |
実行結果 |
乱数初期値[0-15] => 15 ステージ[0-3] => 3 総釣果量[0-65000] => 0 キングサーモン記録[0-255] => 0 GBJKBMPQTJ |