アーサー・C・クラーク「未来のプロフィル」

f:id:nicotakuya:20210519042510j:plain

未来のプロフィル

偉大なSF作家にして科学者、アーサー・C・クラークさんの「未来のプロフィル」 。未来予想を扱ったエッセイです。原書は1958年、日本語版は1966年に出版されています。

執筆当時の1958年はスプートニクショックの翌年。アポロの月着陸の約11年前です。未来を語った本が世界中で求められていたんじゃないでしょうか。本の中では空飛ぶ車や通信衛星など様々な未来の技術が予想されています。

昔、これを読んだ時、空飛ぶ車は荒唐無稽すぎてスルーしましたが、2021年のCESにGMが空飛ぶ車のコンセプトモデルを公開しています。やっと時代が追い付いたのかも。

 

f:id:nicotakuya:20210524225748j:plain

未来の地図(アーサー・C・クラーク「未来のプロフィル」より)

本の最後には「未来の地図」という付録があり、未来の技術について簡単に書かれています。ただし、簡単に書かれすぎです。

たとえば、2000年の項目にあるのが「人工知能」「全地球図書館」。

人工知能」は2010年代からブレイクしたので、ほぼ予想どおり。ただ、クラークさんは2001年宇宙の旅」のHAL9000みたいなものを想定していたと思いますが、、、。

あと、「全地球図書館」は意味不明です。本編でこれについて言及しているページがありません。

 

手がかりを探すため、「未来のプロフィル」の原書「Profiles of the future」を読んでみました。昔だったら、原書を読むには大変な手間がかかりましたが、今だと一瞬で読むことができます。 

archive.org

Archive.orgにあるのは1958年版ではなく、1962年版とのこと。

ログインして「Borrow」ボタンを押すと、1時間だけ本を読むことができます。しかも無料。インターネットの図書館ですね。

全地球図書館」ってまさにコレでは?!

   

f:id:nicotakuya:20210525130415j:plain

原文との比較

原書によると、「人工知能」は「Artificial intelligence」。今現在の人工知能と同じつづりが使われていて驚きです。

全地球図書館」は「Global library(世界的な図書館)」でした。、、、結局、よくわからないです。クラークさんお得意の通信衛星と組み合わせた技術だったかもしれません。

 

ちなみに1970年代に登場と予想されていた「燃料電池」は原書だと「Efficient electric storage(効率的な電気貯蔵)」。翻訳の結果、的中率が上がってしまったパターンかもしれません。

あと、1980年代に登場と予想されていた「トランシーバーの普及」は原書だと「Personal radio(パーソナル無線)」です。

f:id:nicotakuya:20210525130928p:plain

簡易版年表(「Profiles of the future」)

書き方が2種類あって、原書の簡易版年表では「personal radio」じゃなくて、「personal radiophones」です。昔の電話は有線しかなかったので、わざわざ無線(radio)と書く必要があるわけですね。

本書に通信衛星を使った技術の一つとして出てくるのが「世界的通話システム」。その可能性については、次のように紹介しています。

まず考えられるのが、個人用受信機トランシーバーである。 だれもが、 腕時計同様に手がるに持ち歩きできる、 小型受信機だ。
(中略)

この装置一つだけでも、その原始的な祖先である電話がすでにやってのけたのと同じくらい大きく社会と経済形態を変貌させるかもしれない。

(中略)

 これが実現すれば、人が行方不明になるということがけしてなくなる。 現在のレーダー航路標識の原理に基づいたごく簡単位置方向探知装置が受信機と合わせ用いられ るようになるからである。そこで、危険や事故に遭遇したときは、 非常ボタンを一つ押すだけで救いを求めることができるようになるのだ。

(中略)

コミュニケーションの分野の進歩は、輸送の必要性を減少させるだろう。かつては何百万もの人間が都会の職場へ出かけるのに、毎日数時間も押し合いへし合いを演じなけ ればならなかったこと-そして職場は職場で遠隔通信の組織から疎外されると、しばしば手も足も出なくなったと聞かされても、われわれの孫たちはほとんど信じることさえできないだろう。

、、、トランシーバーというより、携帯電話ですね。1958年にこれを考えたのは凄いと思います。

通信技術の普及で交通量が減ると予想してたみたいですが、21世紀になっても渋滞もラッシュもありますし、まだ完全実現は難しいです。晩年のクラークさんはスリランカに移住したり、ワープロを導入したりと、いちはやくテレワークを実践していました。

 

なお、「未来の地図」には刺激的なフレーズが2100年まで書かれています。

あまり深読みすると、MMRノストラダムスみたいなことになるので危険です。クラークさん自身も「本気で受け取られると困る」と最初に断りを入れてます。

興味のある方は読んでみてはいかがでしょうか。

日経ソフトウエア2021年7月号

f:id:nicotakuya:20210523191607j:plain

日経ソフトウエア2021年7月号

次の記事を書かせて頂きました。

・特集「ゲームボーイで動くゲームを作る」第1回目。

・連載「ゲームプログラミング質問箱」第3回目。

f:id:nicotakuya:20210524000943p:plain

ゲームボーイ用のプログラムのイメージ

今回はボタン操作を紹介したところで終わりです。次回に続きます。

ゲームプログラミング質問箱は今回で最終回です。すごい不完全燃焼ですが、まあ仕方なし。

 

nicotakuya.hatenablog.com

WonderSwanのソフトをどう自作するか

こちらの続きです。

nicotakuya.hatenablog.com

WonderSwan用ソフトを自作する方法を検討します。希望する条件は以下の通りです。

・開発環境がフリーであること。

・対応OSがWindows10であること。

WonderWitchを使わないこと。

f:id:nicotakuya:20210522120707j:plain

WonderWitchは使いません

、、、さすがに都合良すぎかな、と思って検索したら、すぐに見つかりました。

 Sebastian Mihaiさんという方が、WonderSwan Color用のプログラム「Swan Driving」を自作されていました。車をボタンで操作するソフトです。

 

sebastianmihai.com

公開しているROMイメージをダウンロードして、エミュレータで実行するとソフトが動きます。ソースコードも公開しています。素晴らしいです。

これを参考にさせて頂こうと思います。

「Dev Kit」のリンク先から開発ツールもダウンロードすることができますが、今回はbatファイルやexeファイルは使わず、ソースファイルと画像データだけを使わせて頂きます。

 

続いて、開発環境を入手します。

アセンブラは「NASM(Netwide Assembler)」を使います。x86系のアセンブラです。

f:id:nicotakuya:20210524111503j:plain

NASMをWindows10で動かした場合

NASMはDOSプログラムなのでWindows10では動きません。そこで、エミュレータで動かすために16bit版を入手します。自分は以下のサイトから2005年公開のVersion 0.98.39をダウンロードしました。 ファイルは「NASM.EXE」だけ使います。もう、サポートが終了しているので、行儀の良くない使い方です。

sourceforge.net

 

「Swan Driving」をビルドします。

適当なフォルダを作って、ソースファイルを置きます。  

f:id:nicotakuya:20210522200813p:plain

ファイルの一覧
  • 「swandriving.asm」はアセンブラのソースファイルです。
  • WonderSwan.inc」はOrion_さん(http://onorisoft.free.fr/)という方が作られたインクルードファイルです。アドレス等が記述されています。
  • 「gfx」フォルダの中身は画像/パレットデータのバイナリファイルです。

さらに「NASM.EXE」と「MSDOS Player(msdos.exe)」をソースファイルと同じ階層に置きます。MSDOS Playerは16bit版DOSプログラムを動かすエミュレータです。DOSBoxでも実行可能だと思います。ここではexeファイルを同じ階層に置きましたが、パスを設定して、別のフォルダに置いたほうがスマートだと思います。

それから、テキストエディタでビルド用のバッチファイル(_build.bat)を作ります。内容は以下の通りです。

echo off

set SRCFILE=swandriving.asm
set ROMFILE=swandriving.wsc

msdos nasm -f bin -o %ROMFILE% %SRCFILE%

pause

 

アセンブラを呼び出してバイナリを生成します。

「_build.bat」を実行すると、コマンドプロンプトが立ち上がって、ビルドを行います。

ビルドに成功すると、「swandriving.wsc」というROMイメージが出来上がります。

f:id:nicotakuya:20210522195858p:plain

ROM情報

参考までに生成したROM情報です。ROMイメージの最後の16バイトにROM情報が記録されています。Sumが0x0000だったり、ROMのサイズが間違っていますが、問題なく動くようです。 

 

f:id:nicotakuya:20210522024756p:plain

WonderSwanエミュレータでの実行結果

 WonderSwanエミュレータで実行すると、上のような画面が動きます。

この技術を応用すれば、WonderSwan用ソフトを自作できるようになります。

ROMイメージをフラッシュメモリに書き込めば、実機でも動くのでは?、、、と期待しています。

 

f:id:nicotakuya:20210522200249p:plain

画像データの例1

f:id:nicotakuya:20210522202339p:plain

画像データの例2

ちなみに「gfx」フォルダには画像データと、パレットデータのバイナリファイルが格納されています。16色モードを使っています。

タイル1枚あたり8x8pixel x4bit=32Byte。

パレット1つあたり2Byte x16色=32Byteです。

将来的には変換ツールを自作したいです。

 

(2021/05/23追記)

以下のページにモノクロ版「Swan Driving」が公開されていましたので、こちらも動かしてみました。初代WonderSwan用プログラムです。

sebastianmihai.com

先ほどと同じく、ソースコードをダウンロードします。

次のようにビルド用のバッチファイルを作ります。ファイル名を変更するだけです。

 

echo off

set SRCFILE=swandrivingBW.asm
set ROMFILE=swandrivingBW.ws

msdos nasm -f bin -o %ROMFILE% %SRCFILE%

pause 

 

ただし、このままビルドして実行すると、画面が灰色のまま固まってしまいます

そこで、次のようにソースを修正してみました。

 

f:id:nicotakuya:20210523001050p:plain

機種のチェックを外す

機種のチェック処理を丸ごとコメントアウトしました。

カラー機の場合、ここで無限ループに落ちてしまうので、それを防ぎます。

 

f:id:nicotakuya:20210523001122p:plain

色の設定を修正

画面モード設定の処理で「VMODE_16C_CHK」を削除しました。あてずっぽで対応したので、間違っているかもしれません。

 

f:id:nicotakuya:20210523001013p:plain

モノクロ版Swan Driving

ビルドし直すと、このように動きました。タイル1枚あたり4階調の表現ができます。

WonderSwanのプログラムを作る場合、初代専用カラー専用両対応のうちどれかを選択しないといけません。

 

f:id:nicotakuya:20210523000931p:plain

画像データの例3

f:id:nicotakuya:20210523001221p:plain

画像データの例4

モノクロの場合、タイルは8x8pixel x2bit=16Byte。パレットは4bit(実質3bit) x4色 =2Byteです。

スターフリート/Bの話

f:id:nicotakuya:20210515201529j:plain

スターフリート/B

昔、遊んだパソコンゲームの中で特に衝撃的だった作品がこちら。

テクノソフトの「スターフリート/B」です。自分はPC−6001mkII版を遊びました。

スターフリート/Bはスタートレック系のゲームです。ここでいうスタートレック」はゲームのジャンルのことです。全盛期には数多くのソフトハウスからスタートレックが発売されました。著作権の意識が低かったころの時代です。

スターフリート/Bは他のスタートレックとは違って、とにかく斬新でした。

表示は「本物の3D」。「オリオン」みたいな単一方向じゃなくて、プレイヤーがあらゆる方向に移動が可能です。しかもリアルタイムで進行します。これは実際の宇宙空間を飛び回っているかのような衝撃的なプレイ体験でした。とにかく3Dが珍しかったので、今、遊んだら全く感動しないかもしれません。

 

f:id:nicotakuya:20210516032829j:plain

マイコンソフトの広告(ベーマガ1984年1月号より)

ほぼ同時期にマイコンソフトでもスタートレックを販売していました。

題名は「リアルタイム SUPER STAR TREK」。この作品はFORESIGHTというマイコンサークルで沼田裕さんが開発されています。アスキーの「トレードトレック」もこの方です。

 

f:id:nicotakuya:20210516161438j:plain

当時の広告(ベーマガ84年10月号)

1984年当時のテクノソフトの広告。

ページの上半分を「プラズマライン」が占めていて、残ったスペースに小さく載ってます。本作は最初にMZ-80B版がリリースされて、移植を繰り返すうちに表現力がパワーアップしていったという経緯があります。この時点でもうMZ-80B版がありません。

あと、スターフリート/Bの「/B」の意味がいまだにわからないです。パッケージを見ると、/Bがないのが正しいみたいですが、個人的に違和感があるので/Bを付けて書きます。

 

f:id:nicotakuya:20210517013016j:plain

スターラスター(ナムコアンソロジー1より)

数年後、1985年にナムコが「スターラスター」を発売。

当時は「スターフリート/Bをパクった!!」と思ったのですが、実際は1979年にAtariが発売した「Star Raiders」のリメイクでした。そして、Star Raidersはスタートレックの影響を大きく受けています。元ネタがすべて同じです。

 

f:id:nicotakuya:20210515200547j:plain

Atari Vaultにも収録

f:id:nicotakuya:20210515200724j:plain

Star Raiders(Atari 2600)

Star Raidersは「Atari Vault」にも収録されています。これは1979年発売のAtari 400/800版じゃなくて、1982年発売のAtari 2600版でした。Atari 2600版は力作ですが、性能が追い付いていないです。

これを見て、スターラスターを連想するのは難しいかも。

追加コンテンツのAtari 5200版のほうがグラフィックは綺麗です。

 

f:id:nicotakuya:20210516204056p:plain

Stellar Track(Atari 2600)

f:id:nicotakuya:20210516204007p:plain

Stellar Track

この他、1980年にAtari 2600用として発売した「Stellar Track」というゲームもあります。表示はテキストのみ。まぎれもないスタートレックです。

 

f:id:nicotakuya:20210516230252p:plain

Tinyスタートレック  ver.1.0

話が前後しますが、オリジナルのスタートレックについて紹介します。検索したところでは、スタートレックは1971年から存在していたようです。コンピュータが全くパーソナルじゃなかった時代です。

さらに元ネタをたどるとウォーゲームがあって、さらにボードゲームの「海戦ゲーム(Battle ship)」に行きつくと思います。wikipedia情報だとBattle ship風のボードゲームは1930年代から商品化されていたそうです。Battle shipは軍人将棋の「ストラテゴ」の影響があるとも書かれてますが、これ以上、元をたどるとキリがありません。

上の写真はVectorで公開されている「Tinyスタートレック」。1993年公開。これは、1977年に石田晴久先生の「マイクロコンピュータの活かし方」に掲載していた「Tiny Trek」をeyesさんという方が移植したものです。自分は石田先生の翻訳した本でC言語を学びました。

 

www.atariarchives.org

1978年には「BASIC COMPUTER GAMES(Microcomputer Edition)」という本で「Super Star Trek」が掲載されています(日本語版は1979年)。現在、本の内容は合法的にアーカイブ化されていますツクモ電機の「スーパースタートレック」よりも、こっちが先です。この本によると、作者さんが1967~68年ごろに大学でスタートレックを遊んだと書かれてて、wikipedia情報と食い違う。コンピュータじゃなくてウォーゲーム版という意味?

1978年にはApple II用に「Apple II trek」が登場。プログラムがBASICなので、容易に移植が可能でした。

 

f:id:nicotakuya:20210517221805j:plain

ハドソンの広告(月刊マイコン1979年7月号より)

1979年に「月刊マイコン」に掲載されたハドソンコスモス札幌/ハドソン丸井今井店の広告。「おなじみの」と書かれているので、この時点でスタートレック知名度は相当なものだったと思います。

他にも、TK-80やプログラム電卓で動くスタートレックがあるのですが、よく知りません。

 

f:id:nicotakuya:20210516230153p:plain

敵戦艦に攻撃が命中!!(この熱さが伝わるでしょうか?)

MSDOS Player(msdos.exe)を使って「Tinyスタートレック」を遊んでみました。コマンドプロンプトを起動して、「msdos strek.exe」を実行します。

ゲームの進め方ですが、大ざっぱにいうと

  • 敵を探す。
  • 敵に近づく。
  • 敵を撃つ。

、、、の繰り返しです。「それで面白いの?」と思われるかもしれませんが、プレイヤーが得られる情報が限られているので、頭を使って敵の位置を予想する必要があり、それが面白いところです。残り時間が減ったり、センサーが故障したり、残弾が減ったり、トラブルが発生して緊張感を高めてくれます。狙いどおりに敵を見つけて、攻撃が当たることの気持ち良さ。

情報が限られてるというコンセプトはテキスト画面とマッチしています。

 

遊んでみて思ったのですが、「情報が限られている」「敵の位置を予想する」というのが、スタートレックの特に重要な要素だと感じます。

そう考えると、スターラスタースタートレック要素が抜け落ちてしまってます。敵の位置がゲーム開始時からバレバレです。その代わり、ゲームがスピーディーに進むので、一長一短なのかなという気がします。

一方、スターフリート/Bはスタートレック要素がかなり残っています。センサーで探索しないと敵の位置がわかりません。ただし、メッセージ表示が遅いし、座標入力はキーボードだし、進行が遅いのが難点です。今、プレイすると、イライラするかもしれません。

スターフリート/Bみたいなゲームを今、快適な状態で遊んでみたいです。

ぷよぷよの連鎖プログラム(pygame zero)

ぷよぷよの連鎖を再現するプログラムです。pygame zeroで動きます。
2020年にセガが公式でぷよぷよのプログラミング学習用のキットを公開していますが、このプログラムはそれを使っていません。

f:id:nicotakuya:20210514135848j:plain

ぷよぷよの連鎖

 

実行画面です。消えていくプロセスを一気に表示します。
ぷよの接続数は再帰処理で検出しています。プログラムの特徴はそれだけです。

# 落ち物の連鎖
import pgzrun # Pygame Zeroをインポート
WIDTH = 800   # 画面の幅(ピクセル)
HEIGHT = 600  # 画面の高さ(ピクセル)
CELLW = 6     # 舞台の幅(セル数)
CELLH = 8     # 舞台の高さ(セル数)
CELLSIZE = 20 # 1セルのピクセル数
DISPW = int(WIDTH/CELLSIZE)
DISPH = int(HEIGHT/CELLSIZE)

cell = [[0 for j in range(DISPW)] for i in range(DISPH)]

initialdata = [
    [0,0,0,0,0,0],
    [0,2,0,0,0,0],
    [0,2,3,0,0,0],
    [0,2,3,4,0,0],
    [0,1,3,4,0,0],
    [0,1,2,3,3,0],
    [0,1,2,4,3,4],
    [2,1,3,3,4,4]
]

# カラーテーブル
colortable = ['black','blue','red','purple','green']

# セルの書き込み(X座標,Y座標,カラー番号)
def setcell(x,y,data):
    cell[y][x] = data

# セルの読み込み(X座標,Y座標)。戻り値=カラー番号
def getcell(x,y):
    ret = 0
    if x>=0 and x<CELLW and y>=0 and y<CELLH: ret = cell[y][x]
    return ret

# セルを塗りつぶす(X座標,Y座標,変更前の色,変更後の色,連結セル数)
def fill(x,y,before,after,cnt):
    if (before<=0) or (after<0):return 0
    if getcell(x,y)==before:
        setcell(x,y,after)  # 色を変更する
        cnt = cnt+1         # 連結セル数を加算する

    if getcell(x,y-1)==before: cnt = fill(x,y-1,before,after,cnt)
    if getcell(x,y+1)==before: cnt = fill(x,y+1,before,after,cnt)
    if getcell(x-1,y)==before: cnt = fill(x-1,y,before,after,cnt)
    if getcell(x+1,y)==before: cnt = fill(x+1,y,before,after,cnt)
    return cnt  # 戻り値=連結セル数

# セルの落下
def movecell():
    for i in range(CELLH-1):
        for y in range(CELLH-1,0,-1):
            for x in range(CELLW):
                num = getcell(x,y-1)
                if (getcell(x,y)==0) and (num!=0):
                    setcell(x,y-1,0)
                    setcell(x,y  ,num)

# セルの消去。戻り値=消去した回数
def checkcell():
    clearcnt = 0
    for y in range(CELLH):
        for x in range(CELLW):
            num = getcell(x,y)
            if num>=10:continue  # 調査済みのセルはスキップする
            cnt = fill(x,y,num,num+10,0)  # 連結セル数を算出
            if cnt>=4:             # 4個以上連結した場合
                cnt = fill(x,y,num+10,0,0)  # セル消去
                clearcnt = clearcnt+1

    for y in range(CELLH):
        for x in range(CELLW):
            num = getcell(x,y)
            if num<10:continue  # 復元済みのセルはスキップする
            cnt = fill(x,y,num,num-10,0)    # セルの復元

    return clearcnt  # 消去した回数を返す

#セルの状態をバックアップ(X座標,Y座標)
def backup(ofsx,ofsy):
    for y in range(CELLH):
        for x in range(CELLW):
            setcell(ofsx+x,ofsy+y,getcell(x,y))

# 画面の描画
def draw():
    screen.fill('BLACK')
    for y in range(DISPH):
        for x in range(DISPW):
            color = colortable[cell[y][x]]
            r = int(CELLSIZE / 2)
            pos =(x*CELLSIZE+r,y*CELLSIZE+r)
            screen.draw.filled_circle(pos, r, color)

    for i in range(4):
         screen.draw.text(str(i+1)+' COMBO',
              left=CELLSIZE*8*i,top=CELLSIZE*27,fontsize=30)

# セルの初期化と連鎖処理
for y in range(CELLH):
    for x in range(CELLW):
        setcell(x,y,initialdata[y][x])

for combo in range(100):  # 連鎖のループ
    movecell()               # セルの落下
    backup(combo*8,8)        # 消去前のセルをバックアップ
    if checkcell()==0:break  # セルの消去。不可能な場合は終了
    backup(combo*8,18)       # 消去後のセルをバックアップ

pgzrun.go()