遊びながらプログラミングを楽しめるゲーム Pixelflut

突然だがPixelflutというゲームを知っているか?

Pixelflutとは

百聞は一見にしかずだ。 最初の10秒だけでいいから、まずはこれを見てくれ。

Pixelflut at the EasterHegg 2014 in Stuttgart

vimeo.com

見終わった?

これはひとつのキャンバスにみんなで同時に絵を塗って遊ぶピクセルドローイングゲームだ。
勝ち負けはとくに用意されてないけど、線、図形、画像、そして工夫すれば動画だって表現できる。

用意されたキャンバスで「ピクセルに色を塗る」という原始的な制限のもとプログラムを書いて線や図形を描いて遊ぶものだ。
これは平等に与えられたシンプルなプロトコルを利用してみんなで表現するアートでもあるんだ。

Pixelflutは GUI の上で動かすこともできる。
つまりプロジェクタなど大画面でやれば盛り上がること間違いなしだ。

遊ぶために必要なのは、Pixelflut がインストールできるマシンのみ。

簡単だろ? 今回はRaspberry Pi上にPixelflutをインストールして遊んでみることにしたよ。

準備

遊ぶためには、Pixelflutがインストールされたマシンが必要だ。 Pixelflutの実装はたくさんあるからお好みで選ぶといい。 シンプルなプロトコルだから自分で実装してもいいね。
今回はRaspberry Pi上で動かそうと、以下のGo言語で実装されたものを使うことにした。 github.com

インストール

Raspberry Pi に Go をインストールする

$ wget https://dl.google.com/go/go1.12.7.linux-armv6l.tar.gz
$ sudo tar -C /usr/local -xzf go1.12.7.linux-armv6l.tar.gz
$ export PATH=$PATH:/usr/local/go/bin # put into ~/.profile
$ go version # 確認

pixelflut-raspi をインストールする

go get github.com/xaxes/pixelflut-raspi

これでインストールは完了した。 次のコマンドで起動してみよう。
リポジトリソースコードをみると、接続先のポートは 1234 のようだ。

$ ./go/bin/pixelflut-raspi

遊ぶための知識

Pixelflutの遊び方を説明するよ。 Pixelflutサーバとクライアントプログラムとのやりとりはソケット通信を使う。 できることは基本的に2つしかない ※。

  • キャンバスのサイズを取得すること
  • 指定したピクセルに色を塗ること

※ 実装によってはヘルプの表示や指定したピクセルの色を取得するコマンドもあるみたいだ。

それぞれ文字ベースでサーバに情報送る。 例えば、NetcatのようなTCPを扱えるコマンドが利用できればすぐに試してみることができる。

キャンバスのサイズを取得

$ echo "SIZE" | netcat [Pixelflutが動いているマシンのIPアドレス] [ポート番号]
SIZE 800 600

キャンバスの指定のピクセルに色を塗る

$ echo "PX 23 42 ff8000" | netcat [Pixelflutが動いているマシンのIPアドレス] [ポート番号]

以上が遊ぶための最低限必要な知識だ。

ルールの一部として、クライアントプログラムの作成もゲームを楽しむための1つになっている。 だから、ここでは具体的なプログラムを載せるのはやめておくことにする。

点、線、図形などを一通り楽しんだあとはきっと画像ファイルを表示させてみたくなるはずだ。

最後に少しそのヒントになることを書いて終わろうとおもう。
Pixelflutには1回の操作で1ピクセル描画することができる。
これを利用して画像ファイルをピクセル単位で画素を取得し、それをサーバに送れば実装できそうだ。
同じ要領で動画ファイルも、画像が複数集まったものと考えればPixelflut上で表現できるだろう。
最後にこれは複数人で遊ぶゲームだということを忘れてはならない。
せっかく描いたピクセルを他のプレーヤーが上書きしてしまうことだってある。
お気に入りの画像を表示したかったら、何度もしつこく描きなおしたり、描く順番を工夫したりすることが必要だ。
ここはプログラミングの腕の見せ所だ。

.....え?サンプルとしてクライアントプログラムのソースコードが欲しい?
OK。下のソースコードは、長さ100の赤い横線を引く例(bash)だ。

for i in $(seq 0 100); do
  echo "PX ${i} 42 ff0000"
done | netcat [Pixelflutが動いているマシンのIPアドレス] [ポート番号]

あとがき

日本ではあまり紹介のない、Pixelflutの説明をした。

この記事を書いている最中、大昔telnetコマンドでHTTPリクエストをサーバに送りHTTPを学んだことを思い出した。
そして同時にそれは私にとっては味気のないものだったと記憶している。
Pixelflutは簡単なプロトコルでグラフィカルな線や図形、画像を使い、クライアントプログラムとサーバ間のやり取りを体験できるものだ。
それはもしかするとLOGO言語がクライアントプログラムとサーバの夢を見ているのかもしれない。

この記事へたくさんのフレンドリーなレビューをしてくれた人たちがいた。
そしてそれによって2つ良い体験ができた。

1つ目はもちろん、レビューによってより分かりやすい記事になったこと。

そして2つ目は「レビューされることは決して怖いことじゃないのだ」と私が強く再認識できたことだ。
修正の自由を残してくれたり、良かった部分を含めてフィードバックをくれたり、そういった伝え方の工夫により常に前向きな気持ちで取り組めた。

考えてみればレビューというのは、ときに必ず修正してほしい部分、回りくどい表現では相手に伝わらないことが往々にしてある。
だから修正箇所や修正理由を淡々と書き連ねることはベーシックで安牌な方法だ。

でも事実をただ伝えるだけでは、意図せず相手にネガティブな感情を与えてしまうことがあるんだ。
とくに昔の私がそうであったように、レビューという行為に極端に恐怖心をもっていたりすると益々レビューされることが苦手になってしまうんだ。
そういう認知の歪みみたいなものがあると、次第に失敗を恐れるようになり、なにも良いことはない。

しかし今回のレビュアーは、文字通り私に対してフレンドリーだった。
そのおかげで終始、より良い記事にするということだけを考えて作業に集中にすることができた。
最後にそのような素敵なレビューイ体験をもたらしてくれた takei-yuya, youchanに感謝を伝えたい。ありがとう! :)

参考リンク

Raspberry Pi用のソースコードを紹介したけど、普通のPCで試したい場合は以下のソースコードもある。
このリポジトリには Python, Java, Cの実装が入っている。そしてどうやら冒頭で紹介した動画もこれを使用しているみたいだ。

クライアントプログラムを作成する上で参考になるサイトと、他言語での実装としてRust実装を紹介する

これで全部だ。最後まで読んでくれてありがとう。@gumuncle より