日本通信 IDEOS 200日パッケージを購入

Amazon.co.jpで「IDEOS+U300の200日パッケージ」を購入しました。
日本通信(b-mobile)が提供しているIDEOSというAndroid端末とU300というモバイルデータ通信用SIMカードのセットです。送料無料で17,998円でした。

ちょっとばっかしレビュー、というか感想を書いておきます。

コストについて

200日使えるU300のSIMカードが同梱されているパッケージなのですが、日本通信の公式サイトで、そのSIMカードが365日使えるというキャンペーンをやっていました。
丸1年使えるということは、月あたりのランニングコストは約18,000円÷12ヶ月=1500円。Yahoo!オークションでのIDEOSの相場は現在、5,000円前後ですので、内訳は通信費1083円・端末代417円といったところでしょうか。日本通信が出していた旧パッケージ品だと、今でも20,000円以上するものも流通しています(計算にならない)。
通信速度は理論値300kbpsと貧弱なものの、メールとちょっとした調べもの用途では不自由しません。やはり月1000円ちょっとでモバイルデータ通信が使い放題というのは、かなり魅力的です。

U300のSIMでは、電話回線を用いた音声通話はできない為、auのガラケー(W63CA)を電話専用機として運用しています。こちらの契約もデータ通信関連のプランを全て解約している為、基本料金・月1200円程度で運用できています。私はあまり通話発信をしない為、毎月ついてくる無料通話分の範囲内に収まっているようで、今年になってから月1200円以上請求されたことがありません。

端末の2台運用となりますが、電話代1200円+データ通信費1500円(端末代込み)=月2700円にまで抑えて運用できるようになりました。年間の費用に換算すると32,400円です。
auと電話もデータ通信も契約していた頃は、月に7500円(端末のローンを入れると毎月1万円以上)ほど支払っていたので、年間だと90,000円という計算になります。
差は60,000円弱で、なかなか大きいですね…。

端末について

中国の通信機器メーカー華為技術有限公司(Huawei)製です。Android2.2、現在の他社のスマートフォンの性能に比べると低スペックな部類に入りますが、なかなかコンパクトであり、筐体も安物っぽさはありません。
コンパクトなAndroid端末というのは、手にしてみて実感したのですが、かなり使い易いです。私の場合、スマートフォンが主力のネットワーク・デバイスとはなり得ないので、IDEOSに動画の表示性能やウェブブラウジングの快適さを求めていません。もちろん、何でも快適にできるにこしたことはありませんが、スマートフォンの環境を快適にする為に大きなお金をつぎ込むくらいだったら、極端に安いコストで割り切って使う方が魅力的に感じました。「動画?それならスマホじゃなくて、パソコンでフルHDで見るわ」的な考え方ですよね。費用対効果に加え、片手で操作できるコンパクトな筐体っていうのは思いがけない嬉しさでした。

回線について

U300のSIMカードは、通信速度を最大300kbpsに制限しています。ドコモのFOMA回線を利用しています。回線自体はもっと太いから、実ハードウェアの理論値300kbpsに比べたら効率いいのかな、と素人予想。

普段のライフスタイルにも大きく影響するところですが、私の場合、自宅も職場もインターネットに接続されたWiFi環境が整っています。WiFiとWiFiの切れ間だけ、データ通信回線が利用できれば十分ですし、そのタイミングで大量の通信が発生するような利用の仕方はありません。300kbpsという貧弱な回線でもメールならば十分です。

SkypeやLINEといったデータ通信回線を使った音声通話も一般化して久しいですが、果たして月1200円で維持しているauの電話回線と比べていかがなものか、と考えてしまいました。同じ値段を支払ってデータ通信回線速度を増強しても、つながりやすさとか品質、万が一の時に使えるかどうか、などいろいろ疑問点が残ります。
こういう書き方をすると疑っているように見えますが、単に知識がないだけですので、機会があれば検証してみたいなあ、と思うところです。

その他、メリット

IDEOSはSIMロックフリー、テザリングが一般化する前から公式サポートしていた数少ない機種の一つでもありました。これで、出先でラップトップや他のモバイル端末からインターネットに接続したり、自宅サーバにログインすることができます。

OpenCASCADEで曲線同士の交点計算

Open Cascadeを用いて三次元曲線同士の交点を求めるには、GeomAPIのExtremaCurveCurveを利用します。このエクストリーマクラスは、交点を求める為のクラスではなく、曲線同士の、それぞれ相手との最寄りの点を求める為のクラスです。お互いの最寄りの点が同一点であれば、そこが交点として扱うことができます。

ソースコード

[c]

include <stdio.h>

include <TopoDS_Edge.hxx>

include <BRep_Tool.hxx>

// TKBinL … 明示的にリンクしてやる

include <BRepBuilderAPI_MakeEdge.hxx>

// TKGeomAlgo

include <GeomAPI_ExtremaCurveCurve.hxx>

int main(void)
{
// カーブパラメータの受け取り用
Standard_Real _first, _last;

// エッジ(線分)からカーブを作成
TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(
gp_Pnt(0, 0, 0), gp_Pnt(10, 0, 0));
Handle(Geom_Curve) c1 = BRep_Tool::Curve(e1, _first, _last);

// もう一つ作成
TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(
gp_Pnt(4, -5, 0), gp_Pnt(6, 5, 0));
Handle(Geom_Curve) c2 = BRep_Tool::Curve(e2, _first, _last);

// エクストリーマに2つのカーブを入れる
GeomAPI_ExtremaCurveCurve ecc;
ecc.Init(c1, c2);

// 各々の最寄り点を得る
gp_Pnt p1;
gp_Pnt p2;
ecc.NearestPoints(p1, p2); // アドレス参照で受け取り

// 得た点が同一点なら、そこが交点。第2引数はトレランス値。
if (p1.IsEqual(p2, 0.001))
printf("p=(%f, %f, %f)\n", p1.X(), p1.Y(), p1.Z());

return 0;
}
[/c]

ビルド

ビルドオプションは次のとおり。これらのライブラリ以外にもリンクしますが、下記のオプション指定だけで適当に解決してくれます。

[bash]
g++ -g -o hoge -I/usr/include/opencascade \
-lTKernel -lTKMath -lTKBinL hoge.cpp
[/bash]

実行すると、次のように交点の座標を印字します。

[bash]
$ ./hoge
p=(5.000000, 0.000000, 0.000000)
[/bash]

  • 延長線上の交点について
  • 交点が複数ある場合

mumble VoIP サーバをインストール

mumbleとはBSDライセンスで提供されているVoIPクライアント・サーバアプリケーションです。VoIPクライアントとしては、米マイクロソフト社が昨年買収した『Skype』、韓国NHN社の日本法人NHN Japanが提供している『LINE』などが国内では有名ですが、mumbleはこれらサービスとは違ったアプローチのもと提供されています。

オンラインゲーム、特にリアルタイム性が求められるFPS(銃を打ち合って戦争するゲーム)使用中に利用することを想定としている為、重点を置いているところが違います。

  1. 常駐させても負荷が少なく、軽い。
  2. 音質をそこそこ維持しつつ、遅延が少なくするように設計されている。
  3. 連絡を取り合うことに特化されていて、余計な機能がない。
  4. 帯域や通信速度自体が制限されたナローバンドでも使える(らしい)。

VoIPクライアントの本質は「IPネットワーク網を利用した音声通信」ですので、正直なところ、他の機能は要りません。また、上記に挙げたVoIPクライアントとしてのメリットの他に

  1. オープンソースであり、特定企業の商売戦略上の都合に巻き込まれなくてすむ。
  2. サーバさえも自分で用意することができ、その気になれば何十年でも同じ環境が使える。
  3. クライアントはLinux、Windows、Androidなどで使用でき、サーバはLinux、Windowsで実行できる。

これらはmumbleに限らずオープンソースプロジェクト全体に言える話ですが、こういう通信手段このその利点が大きいんじゃないかなって思います。IRCもそうですが、コミュニケーションツールはライフラインの一つにも挙げられる時代ですから、自前で面倒が見られるようにしておきたいものです。また、自分だけで利用するシステムではないので、Linuxはもちろん、Windowsやスマートフォンから利用ができる点も大きなメリットです。

サーバのインストール

dpkg系のパッケージ管理システムを採用しているディストリビューションでは、例のごとく、APTにてインストールすることができます。私のDebian環境では、通常のリポジトリ内で見つけることができました。

[bash]$ sudo aptitude search mumble
p mumble – Low latency VoIP client
p mumble-11x – Low latency VoIP client (1.1.x)
p mumble-dbg – Low latency VoIP client (debugging symbols)
p mumble-django – A Mumble-Server web interface
p mumble-server – Low latency VoIP server
p mumble-server-web – Web scripts for mumble-server
p python-django-mumble – A Mumble-Server config application for Django
[/bash]

サーバにはクライアントをインストールする必要はないので、「mumble-server」だけをインストールします。

[bash]
$ sudo aptitude install mumble-server
[/bash]

何もエラーが発生しなかったら、mumbleサーバのインストールは正常に終わったということです。

サーバの実行

インストール時に自動実行されないので、手動で実行します。

[bash]$ sudo /etc/init.d/mumble-server start
$ sudo lsof -i TCP | grep murmurd[/bash]

2行目を実行してみて、murmurd(mumble-server)が出てきたら動いてます。
さて、早速クライアントから接続してみます。クライアントの設定はLinux/Windows/Androidとそれぞれちょっとずつ違うので、ここでは触れません。
mumble-serverの標準リスンポートは64738ですので、それを参考に設定してみてください。

[bash]
$ sudo tail -f /var/log/mumble-server/mumble-server.log
[/bash]

NEC LaVie LightのUbuntuをアンインストール

先日、実家に帰った際、妹がパソコンを欲しいと言ってきたので、それならばと以前メインで使っていたネットブックをお下がりすることにしました。

ネットブックは NEC LaVie Light BL330。タブレットPCが流行する前の、各社が競ってネットブックを出していた頃の機種です。当時の Microsoft の OS 提供ライセンスの関係に基づいてハードウェア仕様に制限をかけてあるらしいので、当時としてもあまり高いスペックではありません。(逆に言うと、その頃に登場した主力メーカーのネットブックはほぼ Windows XP を搭載していたので、どのメーカーのものでも軒並、似たようなスペックでしたが…)

低スペックとは言えど、ちゃんとチューニングをしてあげれば、メールやインターネットは難なく行えると思います。妹は我が家でも一番コンピュータ関連に疎いライトユーザなので、このくらいのスペックでも問題ないでしょう。

今年の5月に、マウスコンピューター製の 4 万円ほどのラップトップを購入して、3万5000円で購入した LaVie Light から移行したのですが、新しい環境は

  • 画面がちょっと広い
  • スペックがちょっと高い

以外は、ほとんど魅力を感じませんでした。LaVie Light の方が、筐体がしっかりしているし、コンパクトで持ち運びにも便利。マウスコンピューター製のラップトップは、筐体の底に手をあてがって普通に持つと、底のプラスチックが自重で歪むのか、中のファンが筐体に擦れる音がなります。どんだけ筐体薄いんだよ、と思いました。筐体が全ての箇所において安っぽいのはさておき、画面がめちゃくちゃ悪く(素人目で分かるほど発色が違い、他のディスプレイで判別できる色の差がこのラップトップで表示すると判別できない、薄い色は飛び、暗い色は潰れる…など。カラープロファイルとかソフトウェア的な調整をしてみたけれど変わらず。)、絵を描いたり、画像処理をする用途にはまったく向いていませんでした。ここは、かなり凹んだと同時に、なんだかんだ言いつつ、結局日本製が安心だなと思いました。

ともあれ、メイン環境は既にマウスコンピューターのラップトップに移行済みでしたので、LaVie Light は寝室の枕元で本と一緒に並んでいました。LaVie Light には Ubuntu を入れて使っていたので、プリインストールされていた WindowsXP に戻したいと思います。

ディスク構成

LaVie Light を購入した直後は、以下のようになっていたと思います。

基本領域1Cドライブ(NTFS) 論理領域1Dドライブ(NTFS) 基本領域2リカバリ領域(FAT32)
拡張領域

物理ディスクは内蔵のSATA一つだけ。MBRにはNTローダが鎮座しており、初期値で基本パーティション1のCドライブを起動するようにしてありました。基本パーティション2のリカバリ領域は、リカバリCD-ROMが付属していない為、ハードディスクにその領域を確保してあるようで、リカバリイメージのほか、リカバリ・ウィザード表示の為の簡易Windows(MiniNT、Windows PE みたいなものらしい)一式とシマンテックのGhostが入っていました。

Ubuntuをインストールした際、リカバリCD-ROMもないと言うことで、リカバリ領域だけは残して、次の構成でインストールしました。

基本領域1swap 基本領域2/boot (ext2) 基本領域3/ (ext3) 基本領域4リカバリ領域(FAT32)

余談ですが、最初はUSB CDドライブを接続してDebian GNU/Linuxをインストールしたのですが、カーネルモジュール(ドライバ)周りを整えるのに心が折れてしまったので、オールインワンなUbuntuにしてしまいました。MBRにはgrub2、ブートエントリには/bootに入ってるカーネルと、自動認識されて追加されたリカバリ領域の2種類がありました。

さあ、この状態からWindows XPに戻します。

修復ウィザードを実行

LaVie Lightの電源を入れ、grubが起動したらリカバリ領域から起動させます。すると、MiniNTが起動して、GUIな修復ウィザードが起動します。ウィザードに従ってハードディスクをフォーマット後、リカバリするようにしました。元通りにしたいので、以下のような構成ですね。(ドライブを細分化する必要もないので、Dドライブは基本パーティションに格上げしました)

基本領域1Cドライブ(NTFS) 基本領域2Dドライブ(NTFS) 基本領域3リカバリ領域(FAT32)

ハードディスクのフォーマットを終えると、一旦再起動するように促されます。手順に従い、再起動させました。

すると、BIOS画面を過ぎた後、ブートローダが起動すべき場所で

[bash]Grub Error (22)[/bash]

と出てOSを起動することができません。半ば予想はしていたのですが、それでも淡い期待をしつつ修復ウィザードに任せた自分がバカでした。

リカバリ領域の修復ウィザードは、MBRまで修復(fixmbr)してくれないみたいです。

grubよ、そりゃあ/boot/grub/grub.cfgが消えてるんだからエラー吐くよね。お前は悪くない。自分のようにカスタマイズして使わない場合でも、マイクロソフトの回復コンソール(とfixmbr/fixbootなど)が起動するCD-ROMはないのだから、MBRが壊れたらマズいんじゃないの…。リカバリ領域を起動できた→つまり、MBRは修復しなくても大丈夫なんだろ?という発想なのかもしれません。

Trisquel GNU/Linuxで起動

さて、どうしたものかと思ったものの、とにかく起動できないのでは手の施しようもないので、ちょうど手元にあったフリーソフトウェア財団のカード型USB KeyをLaVie Lightに差して起動しました。中にはTrisquel GNU/Linuxがプリインストールされています。手元にこういうツールがあったら本当に便利ですね。コイツには何度も助けられています。

USBブートしたTrisquel上で、

[bash]sudo grub-install /dev/sda[/bash]

しても、まあナンセンスだろうと思い、マニュアルで色々するよりは、Trisquelをハードディスクにインストールして、その際に他のパーティションにあるWindows領域のブートエントリまで拵えてくれるくれる方が確実だろう、と、インストールを実行することにしました。

基本領域1Cドライブ(NTFS) 基本領域2Cドライブ(NTFS) 論理領域1/ (ext3) 論理領域2swap 基本領域3リカバリ領域(FAT32)
拡張領域

基本パーティション2を縮めて、空いた領域に論理パーティションを作成、その中に / と swap を確保しました。インストール後、再起動すると見事にgrubが復活してくれました。

基本パーティション1のCドライブのブートエントリも入ってるかなーと、またも淡い期待をしていましたが、論理パーティション1のTrisquelと基本パーティション3のリカバリ領域のエントリしかありませんでした。

というのも、Trisquel側から基本パーティション1をマウントして分かったのですが、Cドライブの中には設定ファイルが一つ入っているだけで、ほぼ空の状態でした。修復ウィザードがMBRを修復することなくハードディスクをフォーマットして再起動した時点では、まだリカバリイメージの展開が行われていなかったことをここで知りました。

リカバリ処理の続きを再開

それならブートエントリが自動的に追加されていなくて然り、この続きの手順が分からないままでしたが、とりあえずgrubが復活してリカバリ領域を起動できるようになったので、起動してみました。すると、今度は修復ウィザードではなくシマンテックのGhostが起動し、ユーザの入力を待たずしてインジケータバーを動かし始めました。あ、ようやくリカバリイメージの展開を始めたな。10分ほど待つとCドライブへの書き込みが終わったようで、自動的に再起動しました。

ここで、MBRも書き換えてくれたかなあ、と半ば諦め気味に起動画面を見ていたのですが、やはりgrubのままでした。ブートエントリはもちろん変わらず。Cドライブのリカバリイメージだけだから、ブートレコードはリカバリイメージに含まれていても、マスターブートレコードまではリカバリの対象外なんでしょうね。

さて、確実にリカバリイメージの転送は終わっているので、Cドライブは起動可能な状態になっているはずです。残るはMBRを戻したいのですが、まずはCドライブから起動できないと話しにならないので、起動してみることにしました。

Grubの設定

Trisquelでインストールされるgrubは、初期設定でパスワードが設定されていました。grubのブートエントリ選択画面でeキーを押しても、起動コマンドの編集の前にユーザ名とパスワードを求められ、編集することができません。

一旦、Trisquelを起動して

[bash]sudo less /boot/grub/grub.cfg[/bash]

してみると、ユーザ名「grub」、パスワード「12953」と設定されていることが分かりました。再起動して、grub画面でこれらの情報を入力すると、コマンドの編集画面に辿りつきました。Windowsのブートコマンドの書き方は知らないので、リカバリ領域に入ったMiniNTのものを変更して用いることにしました。

[bash]insmod fat
set root='(hd0,3)’
search –no-floppy –fs-uuid –set d8fe-92a4
drivemap -s (hd0) ${root}
chainloader +1
[/bash]

1行目はFATじゃなくてNTFSに変更、(hd0,3)はマスターに接続されたディスクの3つめのパーションってことだろうから、(hd0,1)に変更。searchの行は、ディスクを探されるとかえって面倒なので削除して、次のようにしました。

[bash]insmod ntfs
set root='(hd0,1)’
drivemap -s (hd0) ${root}
chainloader +1
[/bash]

C-xを押して起動してみると、ようやくCドライブを起動することができました。WindowsXPの初期設定画面が出てきます。その後、Windowsの初期設定→NECのプリインストールされているソフトの本当にどうでもいい初期設定で4回ほど再起動しやがりました。その度にgrub起動時のパスワード入力からエントリの書き換えまでやりました。Cドライブの起動コマンドをブートエントリに登録しとけばよかったんですが、「1回再起動したらWindowsの初期設定も終わるし、すぐにfixmbrできるだろう」と思ったのが間違いでした。ハードは最高なのにソフトがダメっていう典型的な日本企業のアレですね。本当にどうでもいい初期設定を繰替えしました。

fixmbrはどこ?

WindowsXPに戻せたとは言え、MBRがgrubのままなのでNTローダに差し替える必要があります。回復コンソールが起動できるようなリカバリCD-ROMはないし、リカバリされたWindowsXPにも、もちろんfixmbr.exeは入っていません。Microsoftの公式配布も起動用フロッピーやCDイメージばかりで、あまりこのご時世に合ったサポートは得られそうにありませんでした。そもそもこんな基本的なツールも同梱してないとは…と閉口しつつも、太陽が昇り始めていたので本日の作業はここまでということにしました。

NTローダを諦めれば、Trisquelをもう一度立ち上げて、grubのブートエントリにCドライブのみにして、自動起動までの時間を短くしておけばいいかなあ、と思っています。

新しいサイトを作ってみた。

月曜日の早朝からナニやっているんだ、と自分でも思う。

さくらインターネットのVPSサービスを眺めていると、ふと知人がロリポップでサイトを作っていたことを思い出し、どんなプランなんだろうと詳細ページを見ていると、なかなかバカにできない環境&コストだったので、新しいサイトを作りたくなってきた。

というのも、仕事の関係でちょっと触ってみたWordPressがなかなかイイ感じだったことと、今、メインにしているホームページのサーバが遠い(ワシントンにあるらしい。シェルログインができるのは嬉しいんだけど、契約しているプランではDBが使えない上に、たまにつながらない。重い。)という理由があって、国内に一つはまともな情報発信源でも持っておきたいなあ、と思っていたから。

調子に乗ってドメインまで取得してしまった始末。

さて、これから寝て、仕事が終わったらデータの引っ越しでもするかなあ。

OpenCASCADEの最低限のサンプル

OpenCASCADE を用いた最低限のサンプルを書いてみます。下記は、2つのベクトルが平行か否かを検証するコードです。Standard_Macro.hxx は不要かも。

[c]

include <stdio.h>

include <Standard_Macro.hxx>

include <gp_Pnt.hxx>

include <gp_Vec.hxx>

int main()
{
gp_Pnt p1(0, 0, 0);
gp_Pnt p2(1, 0, 0);
gp_Vec v1(p1, p2);

gp_Pnt p3(1, 2, 0);
gp_Pnt p4(2, 3, 0);
gp_Vec v2(p3, p4);

if (v1.IsParallel(v2, 0) == Standard_True)
puts("parallel!");
else
puts("not parallel!");

return 0;
}
[/c]

ビルドします。

[bash]g++ -g -o hoge -I/usr/include/opencascade -lTKernel -lTKMath hoge.cpp[/bash]

実行します。

[bash]
$ ./hoge
not parallel
[/bash]

上手く動作している模様。次に、依存関係を調べてみます。

[bash]
$ ldd hoge
linux-gate.so.1 => (0xb77a0000)
libTKernel-6.3.0.so => /usr/lib/libTKernel-6.3.0.so (0xb7549000)
libTKMath-6.3.0.so => /usr/lib/libTKMath-6.3.0.so (0xb73f2000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb72fc000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb72d6000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb72b8000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7171000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb716d000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7153000)
/lib/ld-linux.so.2 (0xb77a1000)
[/bash]

使っていない直接参照を調べます。

[bash]
$ ldd -u hoge
Unused direct dependencies:

    /usr/lib/libTKMath-6.3.0.so
    /usr/lib/libstdc++.so.6
    /lib/i686/cmov/libm.so.6
    /lib/libgcc_s.so.1

[/bash]

あれ、TKMath は使われてないな。っと思ってビルド時に -lTKMath を外すと

[bash]
/tmp/ccSaJdhZ?.o: In function gp_Vec::Angle(gp_Vec const&amp;amp;) const':
/usr/include/opencascade/gp_Vec.lxx:111: undefined reference to
gp_VectorWithNullMagnitude?::Raise(char const*)’
/usr/include/opencascade/gp_Vec.lxx:114: undefined reference to `gp_Dir::Angle(gp_Dir const&amp;) const’
collect2: ld returned 1 exit status
[/bash]

gp_Vec クラスの依存関係の解決に失敗して ld から怒られます。

間接参照で、TKMath も使ってるってことかな。

んー、どいつとリンクさせればいいのか、いまいちちゃんと分かっていない感じです。

Numer0n数当てゲーム

フジテレビの深夜枠で放送されていたヌメロンという数当てゲームの動きを書いてみました。このゲームは、プレイヤー二人が向かいあって対戦するもので、基本的なルールは次のとおりになります。

基本ルール

  1. それぞれのプレイヤーが0~9までの数字が書かれたカードのうち3つを使って3ケタの番号を作成する。ただし、「112」「121」といった同じ数字を2つ以上使用した番号は作れない。
  2. 先攻のプレイヤーは相手が作成したと思われる番号をコールする。相手はコールされた番号と自分の番号を見比べ、コールされた番号がどの程度合って いるかを発表する。数字と位置が合っていた場合は「EAT」、数字は合っているが位置は合っていない場合は「BITE」となる。例として相手の番号が 「765」、コールされた番号が「746」であった場合「1EAT-1BITE」となる。
  3. これを先攻・後攻が繰り返して行い、先に相手の番号を完全に当てきったプレイヤーの勝利となる。

海戦ゲームを数字に置きかえてシンプルにし、艦船の位置による限定要因(推測の手掛かり)を、数字の有無であったり数字の位置情報に置きかえたようなゲームです。

ソースコード

このソースコードでは、プログラムが乱数で決定した3桁の数字をユーザが当てる形式をとっています。プログラムはユーザの入力値に基づいて、「イート」「バイト」「ヒット」の情報を正確に答えます。

#include <stdio.h>
#include <stdlib.h> // rand
#include <time.h>

int main()
{
    char x, y, z;
    int a, b, c;
    int n, m;

    /* 3桁の乱数値を生成 */
    srand((unsigned int)time(NULL));
    x = (char)(rand()%10);
    do {
        y = (char)(rand()%10);
    } while(y == x);
    do {
        z = (char)(rand()%10);
    } while(z == x||z == y);

    for (;;) {

        /* ユーザ入力を受け、1の位、10の位、100の位に分ける */
        scanf("%3d", &n);
        a = n/100;
        b = n%100/10;
        c = n%10;

        /* 不正な入力値をはじく */
        if (n < 12||n > 987||a == b||a == c||b == c)
            continue;

        /* 「イート」の数 */
        n = 0;
        if (a == x) n++;
        if (b == y) n++;
        if (c == z) n++;

        /* 「バイト」の数 */
        m = 0;
        if (a == y || a == z) m++;
        if (b == x || b == y) m++;
        if (c == x || c == y) m++;

        if (n != 3)
            printf("%d-%d\n", n, m);
        else {
            puts("Hit!\n");
            break;
        }
    }
    return 0;
}

アイテムなどの特別ルールはありません。基本システムだけです。

コムソート

先日、知人の大学生にソートプログラムの課題についての相談を受けました。ASCIIテキストのみのワードリストファイルを入力し、ソートして出力するという簡単なものだったので、そこそこ早くてかつコードがシンプルなコムソート(comb sort)でコーディングしてみました。

大学の課題ということで、ひょっとしてstring.hすら使えないんじゃないかな、と思い strlen()、strcpy()、strcmp()も自前で準備してみました。これらの文字列用の関数は ASCII 文字列に対しては動いてはいるものの、変なものを食わせたらすぐにお腹を壊すと思います。 使い方は、標準入力にワードリストを食わせてやるか、オプションにリストのパスを指定します。

gcc -o csort csort.c
./csort < wordlist.dic
abc
bbb
dcc
# もしくは ./csort wordlist.dic

PyGame で遊ぶ

PyGameとは、Python用のSDLラッパで「Pythonを使って比較的簡単にゲームが作れるよー」といったライブラリです。自前のIRCモジュールと組み合わせて、キャラクターの操作が可能なアバターチャット的な偽オンラインゲームなど、ガリガリ書いてみました。

今日はとりあえず、メモ代わりにPyGameを用いたスクリプトの基本形を貼っつけておきます。

[python]

!/usr/bin/env python

– coding: utf-8 –

import pygame
from pygame.locals import *

if name == "main":

pygame.init()
pygame.mouse.set_visible( True )
scr = pygame.display.set_mode( (640, 480) )
pygame.display.set_caption( 'test' )
c = pygame.time.Clock()

while True:
    c.tick( 60 )

    scr.fill( [ 63, 127, 127 ] )
    pygame.display.update()

    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                sys.exit()

[/python]

特に解説するところもないですね。読んだままの意味です。

参考リンク

C による Brainfuck インタプリタ

難解プログラミング言語のひとつ、Brainfuckのインタプリタを書いてみました。命令は8つしかありませんが、立派にチューリング完全です。

言語仕様

処理系の構成要素

  • インストラクションポインタ – プログラム中のある文字を指す。
  • 少なくとも30000個の要素を持つバイトの配列 – 各要素はゼロで初期化される。
  • データポインタ – 前述の配列のどれかの要素を指す。最も左の要素を指すよう初期化される。
  • 入力と出力の2つのバイトストリーム

命令

  1. > ポインタをインクリメントする。ポインタをptrとすると、C言語の「ptr++;」に相当する。
  2. < ポインタをデクリメントする。C言語の「ptr--;」に相当。
  3. + ポインタが指す値をインクリメントする。C言語の「(*ptr)++;」に相当。
  4. - ポインタが指す値をデクリメントする。C言語の「(*ptr)--;」に相当。
  5. . ポインタが指す値を出力に書き出す。C言語の「putchar(*ptr);」に相当。
  6. , 入力から1バイト読み込んで、ポインタが指す先に代入する。C言語の「*ptr=getchar();」に相当。
  7. [ ポインタが指す値が0なら、対応する ] の直後までジャンプする。C言語の「while(*ptr){」に相当。
  8. ] ポインタが指す値が0でないなら、対応する [ にジャンプする。C言語の「}」に相当。

コード

hello.bf を食わせてやると、”Hello, world!” と表示されます。

ビルド

gcc -o bfi bfi.c

実行

./bfi hello.bf
# または
./bfi < hello.bf

注意

実行するスクリプトによっては、危険な振舞いをする可能性があります。十分に注意してください。