2012年04月12日

昔話

プログラマは良く、「IT土方」と蔑称される。
しかし、これは、土方の皆様に大変失礼な蔑称である。

実際の土方の皆様は、概ね、9時から17時まで、昼休み1時間、15時の休み15分が与えられており、週休は1日だと聞く。
これが俺の知っている土方の皆様の労働である。

IT土方は違う。
IT土方は、営業時間は9時から深夜3時程度まで、週休0日制、昼休みは15分程度である。

「IT土方」などとは、土方の皆様に大変失礼である。プログラマの作業環境は、末端へ行けば行くほど、もっともっと腐っている。

・・・というのは、まぁごく一部(のハズ)なんだけど。


【軍曹が】携帯電話開発の現状【語る】をAA化した
http://www.geocities.jp/project_the_tower2/gikomona/desuma.html
を読んでたら、昔を思い出した。


かくいう俺も、月間労働400時間越えとか、北海道軟禁とか京都軟禁とか、瞬間最大1人で4ライン同時メインプログラマ&1ラインはディレクション兼務とか、1日に1時間半の睡眠を2回とる生活を10日ぐらい続けたりとか、まぁあとは普通に吐いたり倒れたり痛めたり踊ったり叫んだりといった程度かな。入院はまだない。ドクターストップもない。ちなみに、とある同期(※組長)は、ドクターストップを振り切って1日に2回の定時で働いていた。10時〜18時と、22時〜6時。


すまない、死ぬかもしれない
http://pc.2ch.net/test/read.cgi/prog/1016458885/
http://viva2ch.net/prog/1016458885.html
のことも思い出した。監禁先の北海道、それと、解放された直後の「プログラマ1人でRPGを作る」という地獄プロジェクト真っ直中にリアルタイムで読んでいた。俺のレスもいくつかあるハズ。物凄く共感しながら読んでいた記憶がある。(地獄プロジェクトは、1ヶ月程で(別場所に行ってた)同期が帰ってきて事なきを得た)
http://ogawa.sankinkoutai.com/0707~09.htm#070910
いつ読んでも、こう思う。



風が吹けば飛びそうな零細会社での正社員は約8年で終え、今では気ままなフリーランス。
最初の1年こそ苦しかったが、今では、ちょくちょく声をかけてもらえることができ、老舗デベロッパで新ハード触らせて貰ったり、大手パブリッシャの花形部署でプログラムさせて貰ったりと、あの頃とは比べものにならない程、労働環境は良くなった。

時々、地獄の真っ直中であったからこそ成長できたことを思い出したりすることもある。今は外注ゆえ、コアな部分に触れることはなくなり、結果、コアな知識を得る機会を失っているのは事実。どちらが良いのかは分からないけど、とりあえず今は外注で良いと思ってる。


ただ1つ、これからゲーム業界へ行く人にアドバイスすることがあるとするならば、これを伝えておく。



逃げ出しても良い。生きろ。心も体も病んではならぬ。心身共に、生きろ。
ラベル:2ch IT土方
posted by 小川 at 00:59| Comment(4) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2010年09月11日

Subversionいろいろ

ビルドはXcodeで行うんだけど、ソースの編集そのものは、Mac上のフォルダを共有設定にして、Windows側からそのフォルダ内のファイルを読み書きする形で行うつもり。

で、バージョン管理はSubversionに任せる。一応、WindowsにもMacにも、Checkoutして作業領域を確保しておくようにしたい。なんだけど、あいにく俺は、Apacheだとかサーバだとかそういうのは全く分からん。なので、Subversionのリポジトリも共有フォルダにおいてアクセスする形で管理しようと企んだ。

まずは、Windows上にリポジトリを作る方法を試してみた。この場合、当然、Windowsに作った作業領域からリポジトリへのアクセスは問題ない。しかし、Macからはリポジトリにうまくアクセスすることができない。
Can't get exclusive lock on file 'リポジトリのパス': Operation not supported
となる。解決方法らしきものは、ググれば出てくるが、俺には良く分からんかった。で、Macの、Windowsへのアクセス権限をAdministratorにしたりしてみたが、無念なことに一向に解決しないので、スパッと諦めた。

そうなると、あとはMac上にリポジトリを作るしか手はない。SCPluginもVersionsもsvnXも、リポジトリの作成やImportなどには対応していない(あるいは俺がその機能を見つけられなかった)ようだったので、諦めてターミナルから行う。以前のエントリ
それから、Chapter2、Chapter3の3.1と3.2、Chapter6の6.3と6.8以外は、俺には必要なかった、実質半分だったな、という点。
などとホザいたが、いやいや、Chapter4の「Linuxならどうよ」の項は役に立った。リポジトリの作成もImportもターミナル上からsvnadminなどを通して対応できた。Switchもできた。まぁ、当たり前っちゃあ当たり前であるが。ちなみに、svnXは、リポジトリを作ろうとしているフォルダへのフルパスを表示してくれて便利(使い方おかしい)。

そんなこんなで、Mac上にリポジトリを作る。Mac側から作業領域への各種アクセスは当然うまくいく。Windows側からはどうかなー、と思ったが、ファイルへのアクセス権さえきちんと設定すれば大丈夫なようだ。

具体的にアクセス権が狂うタイミングはいつかというと、WindowsからMacのファイルを直接いじる際にうっかりWindows側からsubversionに関する処理をしたときと、新規ファイルをWindows側で作ったときだ。もっとも、アクセス権を設定し直せば問題ないようなので、まぁ何かSubversionがエラー吐いたらアクセス権を設定し直し、それでもダメならうんうん唸ろう。何はともあれ、環境構築は問題なくできたということだ。ぶっちゃけ1日半かかった。氏にたい。
posted by 小川 at 23:47| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2010年09月08日

TortoiseSVNの本

多くのプログラマには笑われるんだろうけど、入門Subversion Windows/Linux対応/上平哲/秀和システムという本を買っちゃった。こないだ新宿で打ち合わせた帰り、小田急百貨店の本屋で色々な本を手にとっては立ち読みしていて、ビビッと来た(古)。そのまま他2冊と共に連れて帰ってきた。1時間半も本屋にいた自分に驚き。他にも良い本がたくさんあったが、我が家の大蔵省の顔がチラチラ浮かんで、すべてを連れて帰る勇気は出なかった(笑

俺はいわゆる「初心者本」が大好きなのよね。一から十ぐらいまで事細かに説明してある本。そういうのが大好き。仕事でなかったら、初めて触れるモノに触れるのはとても怖いのよ。なぜと言われても困るけど、そういう性格なのよね。だから手取り足取り教えてくれる「初心者本」が好き。我ながら、とてもプログラマとは思えないねwww


さて。この本では、Windows用のSubversionクライアントとして、TortoiseSVNを使って紹介してるのね。まぁWindowsかつVisual Studioでないならば、これ使ってるトコ多いだろうね。7月までやってた職場でも使ってた。CVSが分かれば大体分かるし、どうせ使うのはCVS同様、Update, Commit, diff, Show Logあたりが9割だしね。俺の場合、たまにCheckout, Add, Delete、ごくまれにRename, Update to Revision, Revert to this revisionぐらいだったかねぇ。

だから、本書で説明してある、Edit conflictやResolved, Revert, Check for modifications, Repo-browser, Branch, Switch, Merge, Create patch, Apply patch, Blameなどの使い方は全然知らなかった。が、この本できっちり解説してあり、あっさりと把握。Branch, patch関連は、ちょっとめんどくさそうで、使いたくないなと思ったし、Revertはちょっと怖い。うっかり何かやらかしそう。そして、知らなかったコマンドの中でも、特にBlameは知っておきたかった!

基本的に、日本語化パッチ適用後のコマンド名で説明してあるので、「Update」は「更新」、「Blame」は「注釈履歴」などといった日本語表記で統一してある。(英語表記にしたのは俺の趣味。)日本語化パッチはTortoiseSVN公式ページで配布されているので、入手もインストールも問題ないよね。本当に初心者向けなので、プログラマではない人にもオススメ。そんな本でした。

欠点は、4年前の本である点。それから、Chapter2、Chapter3の3.1と3.2、Chapter6の6.3と6.8以外は、俺には必要なかった、実質半分だったな、という点。もう1つ、表現のセンスが合わないので、時々イラッとする点。ま、そんなこたぁ些細なことと思えるぐらい、俺には良書だった。プログラマじゃない人にオススメの一冊。星5つ。
posted by 小川 at 03:10| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2010年09月07日

TortoiseSVNでインポートできない?

TortoiseSVNのバージョンは、1.6.10の32bit版で、日本語言語ファイルをあててある。

TortoiseSVNで、自分マシンのテキトウなところへリポジトリを作り、管理したいファイルをインポートしようと思ったら
svn.gif
んんー? なんか大事な部分は灰色になって選択できねぇ。なんだこりゃ。


・・・とりあえず、自分のマシンの中で完結する作業フォルダなので
file///C:/Hoge/Fuga/Piyo
と指定することで、インポート自体はできた。何だったんだろう?

「URLの履歴」や「ログメッセージ(入力ダイアログ)」を消し、日本語フォルダを介していたので、取り除いてみたが、現象変わらず。しかし、一度「URLの履歴」が残ると、以降は選択できるようになっている。ググってみたけどワカラン。


・・・ま、いっか。
ラベル:subversion TortoiseSVN
posted by 小川 at 13:15| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2010年09月02日

Mac上のファイルをWindowsから読み書きする

さて、俺は秀丸エディタを心から愛しているので、Mac標準のテキストエディタやXcodeで開発するなんていう意識はハナっから無い。Windows側のマシンにドライブを割り当てて、そのドライブがMacの特定のプロジェクトを指していれば、事実上、秀丸エディタで開発ができる訳だ。

Google先生を頼りに、そのようなバッチファイルを書く。
system_error.gif

うん、全然ダメねー。

まず、システム エラー 1222 は、どうやらWindowsマシンがファイル共有できない類の問題っぽい(このあたりは詳しくないので良く分からない)。ちなみに「マイネットワーク」→「ネットワーク全体」→「Microsoft Windows Network」も利用できない。で、こういうエラーが出るときは大抵、俺の止めたサービスが悪さしてることがあるケースが多いので、サービスを調べ回る。最後に調べ回ったのがいつだったがトンと記憶にないが、「無効」で良かったモノが「手動」や「自動」にすべきケースが多々あった。そのうちの1つ「Workstation」と「Computer Browser」の開始条件を「自動」にして、マシンを再起動することで、この「システムエラー 1222」は出なくなった。ちなみに、「Computer Browser」は「Workstation」に依存している。どうでもいいか。

次。システム エラー 67。
ココにある図8のようにも試してみたが、案の定失敗する。
IPC$共有へのアクセスも失敗する場合は,クライアントの設定不備,もしくはファイアウォールの設定不備やルーティング設定不備により,ネットワークもしくはクライアントに問題があるということが確認できます。
ということだそうだ。まーた何かのサービス止めてあるのが問題か? んで色々調べた結果、「WebClient」サービスを起動させたところ、このエラーは消えた。(「WebClient」サービスを本当に起動させて大丈夫なのかどうかは疑問が残る。)

新たに出たエラーは、システム エラー 53。解消法は「WebClientサービスを止める」と出てきた。無限ループ。これは違うようだ。とどのつまり、「システム エラー 67解消」のために「WebClientサービスを本当に起動」させるのがそもそもの間違いだろう。

ココでふと気付く。Macでファイル共有をONにしているだろうな?
mac_common.png

ちょwww 案の定じゃねーか!!

以下、Mac側に施した設定。

1.「システム環境設定」→「アカウント」→「鍵」アイコン→パスワード入力→「+」ボタン→「新規アカウント」は「共有のみ」とし、アカウント名などを決定。
2.「システム環境設定」→「共有」→「ファイル共有」にチェックを入れる→「オプション」→「SMB(Windows)を使用してファイルやフォルダを共有」にチェックを入れる→先ほど作ったアカウントにチェックを入れる→「完了」→「共有フォルダ」の下にある「+」を選択し、共有したいフォルダを選択→選択状態にしたまま、「ユーザ」の「+」を選択→1で作ったアカウントを指定→必要に応じて、「読み出しのみ」を「読み/書き」に変更→「共有フォルダ」の該当フォルダを右クリック→「内包している項目にアクセス権を適用」

以上だ。


次。
ネットワークドライブの指定を行いたいが、別に、常にアクセスしておく必要はない。起動したりするたびにいちいち警告が出るのもうざったい。かといって、アクセスしてない状態からアクセスするようにするのは、ワンクリックで終わらせたい。そんなものぐさな俺の要求を叶えるのがbatファイル。
@echo off
net use Z: /delete /yes
pause
net use Z: \\マシン名\共有フォルダ /user:接続したいマシンで作ったアカウント
net use /PERSISTENT:NO
pause

net use Z: /delete /yes
は、Zドライブに割り当てられているネットワークドライブを消す。「Z:」を「*」にすると、無条件にすべてのネットワークドライブを全部消す。

net use Z: \\マシン名\共有フォルダ /user:接続したいマシンで作ったアカウント
は、メイン部分。ネットワークドライブの指定が可能。共有フォルダ名と/userの間にパスワードを埋め込むこともできるが、それはどうかと思った。パスワードをここに書かない場合、入力を求められる。

net use /PERSISTENT:NO
は、次回起動時に、勝手にネットワークドライブ接続を行うかどうかの指定。NOなので、それを拒否している。必要なときに俺が自分でやる。

pause
が2箇所入っている。上のは、ネットワークドライブ接続を消すコマンド成功直後に、以降のコマンドを実行させたくないときのために入っている。この一時停止時にCtrl+Cでムリヤリ止めてしまえば、以降のネットワークドライブ接続は行われない。なんとなく入れてみたが、今後の使い勝手次第で変更するだろう。末尾のpauseは、成否確認用。一応残しておかないと、エラーを出しながらポッと消えられても困るので。


と、こんなカンジで、秀丸エディタからMac上のファイルをアレコレ編集できるようになった。実に喜ばしいことだ。
posted by 小川 at 17:53| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

Apple ID

先週の金曜日から、iPhone SDKをダウンロードしようとしているのだが、AppleIDは取得できたが登録がうまく行かない。何度やっても
We are experiencing technical difficulties.

Please try again later.
と出る。訳すと、
アップルのXCODEをダウンロードしたいのですが、パーソナルプロファイルとい... - Yahoo!知恵袋

技術的な問題が発生しました。しばらくたってから再度やり直して下さい。
ということだ。27日(金)に発生して30日(月)にまだ直ってないっておかしいだろ! と思って、Google先生により詳しく聞いてみた。そしたら・・・
hmylab.com - Dev Centerへ登録できない|iPhoneアプリ開発

SDKをダウンロードする為に、Developer Centerへ登録しないといけません。
が、最初の一歩でつまづく人が結構います。

以下の点を確認してください。
  • Apple IDの登録情報に日本語を使っている
  • 日本語サイトから登録したApple IDを使っている
上記にあてはまる方は、
We are experiencing technical difficulties. Please try again later.
Please return to the Member Center and try again.
というエラーが出てきて登録できません。

英語サイトで新しくApple IDを作成して挑んでください。


Ω ΩΩ<な、なんだってー!?

てなわけで、英語サイトからやり直したらあっさり行けた。ナンダソレ(゚∀゚)アヒャッヒャッヒャッヒャッヒャーーー!!!!11
ラベル:Apple ID tips
posted by 小川 at 12:44| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2009年10月05日

フリーズ対策

ソフトウェア開発に幸せな未来はあるのか: 第15話 コーディング規約は必要か?


本文とはさほど関係ないのだが、
if(flag == true)
{
  // 処理1
}
else if(flag == false)
{
  // 処理2
}
else
{
  // 処理3
}
を見て思ったことをつらつらと書く。

あ、その前に、↑のはアホすぎだな(筆者が、ではなく、こんなことを本当に書くヤツが)。flagがbool型である以上、trueとfalseの2つしか取りえない。筆者は、
どう考えても「処理3」は通りません。
(中略)
true/falseしか条件がないのに3つ処理が用意されている事の方が不自然です。
と書いているが、俺的に不要なのは1か2のどっちかだと思うけどなぁ。


さて、昔のファミコンのゲームって、本体を蹴飛ばすとかコントローラを激しく引っ張る(結果、本体が動く)とかでもしない限り、フリーズはしなかったように思う。しかし、現代のゲームは、実によくフリーズする。これはなぜなのだろう。

あくまで、俺のプログラマとしての経験だが、大型のプロジェクトに初めて関わったとき、以下のようなコーディング規約があった。
 Debug_Assert (System/debug.h) を使う.

 「この変数は...だから,...だよな」というような「前提」がある場合には積極的にアサートを使ってください.前提が崩れた状態で処理を続行すると,問題の発生地点から根本原因にたどり着くのに余分な時間を取られます.リリースビルド時にはなくなりますので最終的な実行速度には影響しません.

 ただし,あくまでも「絶対にありえない」条件に対して記述すべきものです,「例外」とは違います.リリースビルド時にはなくなります.
で、俺がコレを勘違いして使っていたのが、以下のような時だ。
switch( theFlag )
{
 case 1:  // Menu
  inWork->mDivide  = eMatrix_Divide_Menu;
  STATE_CHANGE( ( u8 )eMatrix_Divide_Menu_State_Init );
  break;

 case 2:  // Transform_Start
  inWork->mDivide  = eMatrix_Divide_TransformStart;
  STATE_CHANGE( ( u8 )eMatrix_Divide_TransformStart_State_Init );
  break;

 case 0:  // Transform_End
  inWork->mDivide  = eMatrix_Divide_TransformEnd;
  STATE_CHANGE( ( u8 )eMatrix_Divide_TransformEnd_State_Init );
  break;

 default:
  DEBUG_ASSERT( false );
  break;
}
STATE_CHANGEマクロは、場面を次へ進めるマクロだ。もし、このままこの状態でリリースされてしまい、かつ、何らかのバグないしは暴走などによって、theFlag の値が3以上になったとき、おそらく、この関数を何度も通り、結果、無限ループ≒フリーズする。

とりあえず何とかするならば、
 default:
  DEBUG_ASSERT( false );
  STATE_CHANGE( ( u8 )eMatrix_Divide_Menu_State_Init ); // case1 と同じように進める。
  break;
とでもしておくのが無難だろう。

Assertは、
あくまでも「絶対にありえない」条件に対して記述すべきもの
だ。開発中にバグの原因を突き止めるための便利な命令に過ぎない。しかしながら、条件式の中で、起こりうる値を無視するってのもどうか。理論上、起こらないハズだが、自分の担当箇所以外の何らかの要因があれば、起こりうる。他人が参照する関数ならば尚更だ。対策を置いておけば、少なくともフリーズという憂き目は防げるのではないか、などと思った。


有名だが、こんな話がある。
ファミリーコンピュータ版 ドラゴンクエスト3
普通にプレイすると、HP自動回復の恩恵でどうやっても死なないキングヒドラだが、万が一、億が一にもオルテガが勝ってしまった場合の処理が実装されていた。RPGにおいて、負けることによって話が進むケースはしばしばあるが、もしも勝ってしまったらどうなるのか・・・・・・そんなときの処理まで組んでいたFC版ドラクエ3のプログラマを、俺は尊敬する。起こりうるケースを想定して、一応組んでおく。この考え方は、大切な事だと思う。


洗濯物を干すとき、なんとなく「やきゅあそ」のCPUvsCPUを流しっぱなしにしている。「やきゅあそ」のCPUvsCPUは、両チームに介入することができる。アホなCPUの粗末な選手起用に異を挟みたいときに、勝手に代打や代走、守備固めを送りつけたりできるわけだ。

昨日、ロッテvs中日(DH制あり)でプレイしていた。7回ウラ、ロッテの攻撃。6番の大村巌が塁に出たので、介入して代走に諸積を出した。すると何故か「代打ボーリック」の画面になる。「んんん?」と思いながら放置していたら、ボーリックは左打席の後ろにいて、打席にはそのまま次打者7番佐藤幸彦が入った。画面にはボーリックのバットが微妙に映ってること以外問題なし。なんじゃこりゃ。よくよく考えたら、ボーリックは3番DHでスタメンじゃないか。意味わからん。

その後ボーリックは、左打席の後ろに位置取ったまま、ロッテの攻撃中ならバットを持ち、ロッテの守備中ならバットを持たず、イニングをまたいでも居座り続けた。んで、打順が回って次は3番DHボーリックというところで、フリーズした。


ま、こんなこともあるさ。とりあえず、俺が開発に携わる際には、Assert関数と、その後の念のため対処プログラムを組み込もうと思った。
posted by 小川 at 12:44| Comment(3) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2009年09月09日

BCB5だもんなぁ

未定義の関数 'ForceDirectories' を呼び出した

別に何も変更しなくても、C++Builder5では上記エラーが出ることがある。さかもつ備忘録のsakamotzさんによると、
DirectoryExists() 等、FileCtrl.hpp を使用していて「実行時パッケージを使って構築」しない場合、何故かリンクエラーになることがある。
らしい。解決方法には、
<SPARELIBS value="…"/>に空白で区切って VCLX50.lib を追加する。 「リンカ」の「共有 RTL DLL を使う」のチェックも外す。
とあるが、後者は常にチェックを外しているし、前者はbprファイルを開いたら既に記述されていた。自分で書いた記憶はない。手元の環境(WindowsXP)では、2009/4/17の段階では問題なかったが、それ以降のMicrosoftUpdateで、問題が発生するようになってしまったのではないかと思われる。

色々探しつつ、ダメモトで、
#include <FileCtrl.hpp>
を明示的に宣言したところ、エラーは出ず、問題なくなった。

               /|:::::::::::::::::::::ヽ.:.:.:.:、:.:.:.:、:.:.:.、.:.、.:.:.:.:.:.::`゛>
           /{::|:\:::::::\.:.:.:\.:.:.ヽ::.::.ヽ:.:.ヽ::::::::::.:.`゛ー- ..,__
: 何 :    /:|::',:ト、::::::ヽ、:.\:.:.:.\:.:.ヽ:.:.:\.:.:.:.:.:::.:.:.:.:::.::::_;:-'´   : : :
: が :   //:/:::|::',|::'、:::::::::\:.:\.:.:.ヽ:.:.:\:.:..\::::::::::::\、::::\    : : :
: 何 :  /!::|::l::::/|:::l:ヽ:\::ヽ:.:\:.:\.:::ヽ:.:.:ヽ:.:.:.:\::::::::::::\ ̄   : : :
: だ :   |/l::|::|::|:ト、:::::::::、、:ヽ、:.:.:.:::::::::::::::ヽ::::.:ヽ:.:.:.:.\:.:.:.ヽ:::\.   : : :
: か :   |::|::/l::|::|r‐ヽ:::::ヽ(ヽー,―\::::::、::::::::::ヽ::.:.::::::.:::::::ヾ. ̄   : : :
:    :   }//l::|:::|{(:::)ヾ、:::ヽ \!(:::) ヽ,:::ヽ:::::::::::::::::::::::::::::::::::ヾ、   : : :
: わ :.  |/l::|::|:::|ヽ==''" \:ヽ、ヽ=='" |:::::::::::::::::::::::::::::::::::ヽ、::::\
  か     / ',|::|:::|   /   `゛       |!::::::::::::::::::::::::::::ト、::ト、_` ゛`
  ら      l::!::::ト、  '、 _         ||::::::::::::::::::::::::ト:ヽヾ| | ̄ ̄ ̄`ヽ、
  な     r'"´||',::::',                 |:::::/l:::::|\:::ト、ヾ | |     / / \
  い   /   ll ',::', 、 ーこニ=-       /!::/ ヽ:::|  ヾ、  ノ ノ  /  ,イ   ヽ、
       ,'    |  '、:, \ --       ,. '´ |;'  l ヾ、.   //     / |    l: l
      |   |!  ヽ;  ヽ       /.:    i!  /   ゛// |l      / |      | |
ラベル:tips C++ Builder
posted by 小川 at 21:58| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2009年08月11日

gotoの例

プログラマの宗教の話で、gotoの話が軽く盛り上がったので、別エントリにしてみた。miracleさんからリクエストのあった『goto使ったほうがきれいに書けるというシチュエーションってどんなの?』について、俺の作った自作アプリのソースの一部を見ながら、俺自身も検証してみようかと思う。画像が見にくかったらゴメンナサイ。保存して見てくだしあ。ちなみに、『Drag&Drop Delete Exif』で1つ、『コナミワイワイワールド エッチ005 アナライザ』で2つ使ってた。意外と使ってるなぁ。



1.例外(まぁエラーだ)が起こった際、以降の処理をかっ飛ばす。

goto.gif

すべて見えてはいないが、forループの中で、AssignメソッドやSaveToFileメソッドで例外処理が起きなければ、ProgressBar_StepIt関数で、プログレスバーを進める処理である。(全部で6個のtry〜catchがある。)AssignメソッドやSaveToFileメソッドが例外処理を吐き出したら、gotoで、かっ飛ばす。かっ飛ばす前に「エラーメッセージボックス処理(BcbMessage_Error関数とそれより上の行)」と「現在の進行度(theMessagePosへ代入してる行)」を格納する処理を経ている。かっ飛ばされた先では、例外処理の中で格納された「現在の進行度(theMessagePos)」をもとに、かっ飛ばされた分のプログレスバーを進める。(breakなしのswitch〜case文が見えるでしょ。)

if( 関数1() == 0 )  // 戻り値は0(正常)か10(例外)
{
  if( 関数2() == 0 )  // 戻り値は0(正常)か20(例外)
  {
    if( 関数3() == 0 )  // 戻り値は0(正常)か30(例外)
    {
      if( 関数4() == 0 )  // 戻り値は0(正常)か40(例外)
      {
        if( 関数5() == 0 )  // 戻り値は0(正常)か50(例外)
        {
          if( 関数6() == 0 )  // 戻り値は0(正常)か60(例外)
          {
          }
        }
      }
    }
  }
}
と、tryからProgressBar_StepItまで(例えば330行目から342行目まで)を関数にして、戻り値が0だったら次の関数へ・・・ともできるが、ネストがムダに深くなるのでやめた。戻り値が0以外だったらcontinueするという手もあるが、これまた個人的には美しさを感じない。上で強調したが、あくまで「forループの中でプログレスバーを進める処理」なので、プログレスバーを進める関数(ProgressBar_StepIt)が見えないというのは、ナシと判断した。また、「どのルートを辿っても、必ずProgressBar_StepItを6回通る」ことが一望できることを望んだその結果がgotoとも言える。なお、犠牲にしたのは、関数の長さ。一般的には長くても100行ぐらいに抑えるのが良いとされているが、この関数は200行ある。



2.同じ制御文が連続するのを嫌った。

goto_1.gif

先に答えを言ってしまうと、上記をgoto無しにすると、以下のようになる。

goto_2.gif

前者で言うところの468行目のif文、後者で言うところの481行目のif文は、ともに下のほうでelse文が待っている。ともかくtheIsErrorが真の際は、そのelse文へ飛ばしたい。後者のように、まったく同じif文が続くのはなんだか美しくないし、最適化されてくっつけられても困る。(どうなるかは分からない。)もし、後者が最適化されて2つのif文が合体してしまったとき、つまり前者の「goto IS_ERROR」の行だけが消えてしまうような状態に最適化されてしまうと、当然、意図する動作にならない。

過去に、後者のような書き方をした結果、最適化されてくっついてしまって意図しない動作となったことがあった。最適化されたバグを探し出すのは非常に面倒なので、それならばとgotoを使って戻すことにした。



3.forループの中のif文を完全に満たしたらエラー。

goto_3.gif

ワイワイワールドのパスワードが、基準パスワードかどうかを調べるくだり。14個のすべての値が基準パスワードと一致したらエラー。エラーの場合、2079行目にて、theReturnに-2をブチ込む。1つでも一致しなければ、theReturnの値は変わらない。これをgotoなしで書くと、

goto_4.gif

となる。もう個人的には、後者の2078行目のif( i == 13 ) ていう条件式を書くのがイヤでしょうがない(マジックナンバーのくだりは置いておく)。かといって、forの中に複数の条件を書くのもイヤだ。また、while文でも書けそうだが、先述のとおり条件式を2つ書くのは趣味じゃないし、そうすると
if( i == 13 )
{
  break;
}
となるが、これまた美しくない。その結果がgotoとなった。



あれー。アレックスさんの言うように
C言語なら、2重・3重ループから一気に抜ける場合
ぐらいでしか使ってないつもりだったけど、普通に使ってるなーwww

一応、自己フォローしておくと、
・gotoとラベルの距離が近い位置でしか使っていないこと
・複文の中へ入り込む位置にラベルを置いていないこと
・goto使った方がまだ美しいソース(主観)になること
は踏まえて使っているようです。

濫用するようなものではないけど、美しさや見やすさを犠牲にしてまで拒否するほどのものでもない、そんなカンジです。「miracleさんお分かりになりましたでしょうか〜。お分かりになりましたら今後の参考にして頂ければと思いま〜す(仁鶴師匠の声で)」



もっとイカす書き方があったら、ぜひ教えてください(他人任せ
posted by 小川 at 23:04| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2009年08月07日

宗教戦争なんざどうでも良い

カッコをつけたコードはカッコわるいのか論争

ワロタ

俺も同じ理由でカッコをつける。更に言えば、
if (buffer == null) {return;}
よりも、
if (buffer == null)
{
  return;
}
とすることを好む。1行単文とでもいうか。ちなみに更に言うと
if (buffer != null)
{
  // 本文
}
とすることを好む。好むというか俺が作る場合90%こうする。関数の途中やif文の中からreturnで返るのは好きじゃない。可能な限り関数の最後まで行かせるように書く。 上で『1行単文』と言ったが、当然例外があって、例えはつくあそ新人・外国人選手リストを作ったときのソースの一部にある。
switch( theReadData_1 )
{
  case 6635:  fputs( "ギャラード,"   , theCsv );  break;
  case 6926:  fputs( "ラドウィック,"  , theCsv );  break;
  case 6927:  fputs( "シュールストロム,", theCsv );  break;
  case 6928:  fputs( "ヘイニー,"    , theCsv );  break;
  default:
    fwrite( theReadData, 2, 6, theCsv );
    fputc( ',', theCsv );
    break;
}
(いうまでもないが、当然一部抜粋だ。)
縦に同じ内容の構文が長く続くとき、このように1行に複文を書くことがある。


俺は、俺の書き方のルール(それは宗教と言っても過言ではないほど狂信的に)に従ってプログラムを書いている。そして、俺は前の会社で「時間はかかるがバグが少ない」という評価を受けていた。バグが少ないのは、俺があらゆるケースを事前に想定してプログラムを組むからであって、俺の書き方のルールとは直接関係がない。しかし、自分のソースに一定のルールを設けておけば、少なくともバグ発見時に、著者のような
if (buffer == null) pos++; return;
などというミスで時間を潰す心配は減る訳だ。このようなコーディングスタイルの積み重ねは、「バグが少ない」という俺への評価にまったく貢献していない訳ではない。

俺の書き方の方式は、2003年ごろにはもう確立されていて、あれから変わったのは「必要に応じてgotoを使うようになったこと」「つくあそ新人・外国人選手リストのようなときの、fputs関数の1つ目の『,』の位置を揃えること」「##で連結する目的以外でdefineマクロを使わないようになったこと」などまぁ数えられる程度だ。

以前はコーディングスタイルの統一を図るべく色々文書を書いたりしていたが、とあるベテランプログラマと出会い、それをやめた。彼は、プログラマとしては俺よりも非常に優れた人物であった。新しい技術はすぐに触って実験して理解してしまうという、彼がSFC時代から生き残ってきた理由が垣間見える凄い人だ。ところが彼のソースは、尋常じゃなく汚い。関数はおろか、ファイルすら分けない。コメントもほぼゼロ。100KBを越えるソースファイルなんてお手の物だ。しばらく一緒に仕事をして分かったことは、彼の頭の中にすべて入っている、ということだった。いやらしい言い方をすると、彼の担当箇所はすべて彼に押しつけてしまえば、難しい仕様でも仕様変更でもバグ修正でも文句言わずやってくれる。もちろん、彼が倒れてしまえばとんでもない事態になりかねないが、そこは流石のベテランプログラマ、彼のソースは汚いが、決してスパゲティではない。上から追っていけば何をしようとしているか、何を目的としてそのようなコードにしたかは、手に取るように分かる。

俺はこの方を見て、コーディングスタイルを統一することをやめた。外注に頼っているようなプロジェクトでは、その外注のコードや性格等が分からない以上、コーディングスタイルの統一はやむを得ないだろうが、社員+頼れる外注でやるのであれば、個々人のコーディングスタイルなど好きにすれば良いと思っている。俺は自分のスタイルを布教することはやめたし、他の人にも特に布教はしない。もちろん、議論する中で「それ頂き!」と思うことはあるが、それもまた個々の自由だ。


さて、最後に関係ない話を1つ。Cの分かるプログラマ諸氏に尋ねたい。

ある出向先の会社のソースで、***_main.cというファイルがあり、その文末で、
// 取得・設定関数
#include "***_etc.c"
// キー操作
#include "***_key.c"
// メッセージ関連
#include "***_message.c"
// サウンド関連
#include "***_sound.c"
// セーブ・ロード関連
#include "***_save_load.c"
として締めくくっているものがあった。当然、俺は疑問に思う。「cファイルをincludeするのって、(コンパイルはもちろん通るけど)やっちゃいけないことじゃなかったっけ」と。ところが、肝心の「なぜcファイルをincludeしちゃダメ」なのかが思い出せなかった。検索しても「それはダメだ」という意見は出てくるが「なぜダメなのか」が出てこない。出向先から本社へ帰ってきて、何人かのプログラマに訊いて回ったが、皆「俺はやらない」けど「なぜダメなんだっけ?」という状態だった。結局、1人の若い職人系プログラマが、「『畳の上では正座する』みたいなマナーの問題なんじゃないですかね」みたいなことを言い、面白かったのでそれをオチとして採用したのだが、当然、腑に落ちない(笑

どなたか、お分かりになる方はいらっしゃるだろうか。いらっしゃれば是非、ご教示願いたい。
posted by 小川 at 17:10| Comment(7) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2009年06月07日

恩師のことを考えてみた

俺には4人の恩師がいる。いると言っても、直接その人達に「あなたは俺の恩師です」と言ったわけではないが。まぁ、いわゆる『心の恩師』というヤツである。

1人目は、北海道の極寒地獄で出会ったメインプログラマ。この方のスタイルは後の俺に大きな影響を及ぼした。

当時駆け出しで見た目からして若手であろう俺に対しても、常に穏やかな丁寧語で話し、指示は口頭であっても必ずメールし、いわゆる『忘れていた』が起こらないように全員に指示していた。そして、メールの振り分けルール(件名に【プロジェクト名】)、コメントのルール、プロジェクト全体の設定方法、VSSの手引き等、すべてドキュメントを用意し、自身のメインプログラマとしての雑用を軽減させ、かつ、若手の質問を最小限に抑えていた。それから、誰がなすべき作業なのかを常に明確にしていた。ご自身の作業であれば「××までに私が作ります」と言い、他者の作業であれば「それは○○の作業なので、いつまでに完成するか確認して、メールか口頭で伝えます」と、自分の作業を明確にされていた。ここまで指示された上で、情報を聞き漏らしたのであれば、それは確実にこちらの責任となるので、当然、こちらも集中する必要がある。10人を超えるプロジェクトのメインをされていたので、こちらから疑問があって直接確認した後、ご自身が忘れないように必ず「今の件、メールでも送っておいてください」と伝えるのが常だった。俺は、10人規模のメインプログラマを勤めたことはないので、氏の苦労がどれほどのものだったか、想像でしか分からない。とかく、『メインプログラマとしての仕事の仕方』は、この方の影響を大きく受けた。

2人目は、お亡くなりになったと聞いた、酒とタバコで生きていたプログラマ氏。この方の考え方は、大いに影響を受けた。

この方の作られたシステム、個人的には今ひとつ受け入れがたいカンジであったが、その設計理念は大いに同意できた。残念ながらそのシステム、いわゆる『スクリプタ』には非常に敷居が高く、プログラマでないと理解しづらい設計だったであろうな、と思っている。特に、俺の前いた会社のシステムと比べると、その使い勝手は雲泥の差だ。自由度が非常に高い反面、決して使いやすいものではなく、変数の概念やその使用可能範囲、他者と被らないようにしなければならない命名規則等々、色々と複雑で使った人の評判は今ひとつ高くない。俺個人は本格運用になる前に離脱することになったので詳しく触っていないが、あの設計思想を元に、前の会社で使っていたシステムを混ぜると、もう少し『スクリプタ』に優しく、かつ高機能なエディタになりそうな気がしていた。その設計思想は、忘れずに心の中に留めてある。

3人目は、前いた会社の上司だ。人当たりの良さと問題解決能力の高さは、その会社の中でも群を抜いて高い方だ。この先1人で生きていく以上、この2点は常に意識しておかねばならないと感じている。

『経理をやっていたらいつの間にかプログラマになっていた。何を言っているかわかr(AA略』という異色の経歴ながら、C/C++、Z80アセンブラだけでなく、HTML、Perl、PHP、サーバ関連、ネットワーク関連、マシンセットアップやマシンの不調、果てはプリンタの異常まで、何かあれば頼られる存在であった。北海道から帰ってきた俺は、「あの人は凄いプログラマだから、あの人から雑用を奪わねば」と、マシンセットアップやマシン・プリンタ不調、ファイルサーバ関連など、あらゆる仕事を奪い取っていったつもりだ。特に、マシン関連のトラブルはとにかく場数がモノを言うので、分からないときでも後ろから一緒に覗き込んで知識を溜めていった。仕事の内容上、俺が対応できるのはそれら雑用とC/C++程度なので完全に頼られる存在にはなれなかったが、目標として常に頭に入れておきたい存在であった。

4人目は、これまた前いた会社に方だ。ある意味、俺が目標とする最終形態に近い状態におられる方だと思う。

話によると、SFC時代からプログラムをされていたとのこと。以前、「メジャーなゲーム開発に携わったことありますか?」と聞いたが、「ほとんどない」ということだった。確かに、聞いても知らないゲームばっかりで困った(苦笑)。とにかくプログラムに対して貪欲で、新しい技術は黙っていても気がついたら触れている。そしてそれを俺に的確に教えてくれる方だ。ソースコードは汚く、コメントはほとんどないが、上からきちんと読んでいけば何をしようとしているかは理解できる。職人プログラマの究極形だ。少なくともフリーで生きていく以上、この方並の知識欲と理解力、実践力は持たねばならないと、常々思っている。


アメリカAAAで審判をされている平林岳氏のブログのエントリを見て、ふと、俺の恩師のことを思い出してみた。プログラマの恩師への恩返しとは何だろうか。ちょっと見当つかないが、いつか、再会した折には、成長した姿を見て頂きたいと願っている。そのために、今はとにかく地盤を固めること。1歩ずつでも1足飛びでも猛ダッシュでもいいから、前を向いて進もうと思う。
ラベル:恩師
posted by 小川 at 23:03| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2009年03月05日

最前面に表示するが、フォーカスは奪わない方法

『時報時計』を作る際に一番苦労したのは、画像表示の部分である。具体的に言うと、『フォーカスを奪わない』という仕様である。


 プログラム話の続きを読む
posted by 小川 at 16:35| Comment(4) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2008年11月12日

今更100質

今更だが、プログラマさんに100の質問をやってみた。

別に面白いコメントのひとつも残していないので、リアル知人プログラマ(3人ぐらい)しか楽しめないだろうなぁ。

 100質を見る
posted by 小川 at 02:56| Comment(4) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2008年10月31日

ランダム

1ヶ月半ぐらい前、仕事がヒマだったので、ずっと擬似乱数について調べていた。

発端はもちろんあの(といってもだいぶ古い)Xbox360のカルドセプトだ。偶数奇数が順番に出るという、おそらくイケてないrand関数をそのまま使ったのであろうアレだ。俺もゲームを作る上で乱数を利用することはあるので、調べておいて損は無いどうせヒマだしー、ということで調べていた。

まず、カルドセプトで使われたどうしようもないrandをどうしても使わなければならないならば、下位ビットの剰余
a = rand() % 10;
で求めるのではなく、
a = ( int )( ( rand() / ( ( double )RAND_MAX + 1.0f ) ) * 10 );
ぐらいのことはしたほうが良いらしい。この場合、0〜9までの値を返す。赤字部分を適宜変更する。なお、コンパイラによってrandの中身は微妙に違うらしいが、どれもイケてないことに変わりはない。

次に、最近の流行りは『メルセンヌ・ツイスタ』。某後輩がメインプログラマをやったプロジェクトでは、これが使われていた。現時点では最強らしい。これの改造版の『SFMT』というものもある。倍精度浮動小数点擬似乱数が必要ならば『dSFMT』という姉妹版もある。現在最強という点で非常に惹かれるものがあるが、また別のものを見つけた。

『XorShift』。精度は『メルセンヌ・ツイスタ』に及ばないもの、計算にxorとビットシフトしか使わないということで、非常に高速との触れ込み。今回、自分のためにBorland C++ Builderで作ったソフト『ランダム値作成』の_lrand関数を、この『XorShift』に変えてみた。

改造するに当たって必要なのは、ぶっちゃけコピペで済むソース
unsigned long
xor128( void )
{
    unsigned long x = 123456789;
    unsigned long y = 362436069;
    unsigned long z = 521288629;
    unsigned long w = 88675123;
    unsigned long t;
    t = ( x ^ ( x << 11 ) );
    x = y;
    y = z;
    z = w;
    return( w= ( w ^ ( w >> 19 ) ) ^ ( t ^ ( t >> 8 ) ) );
}
なのだが、どうも初期化処理が書かれているページが見当たらない。初期化がないと常に同じ値になるのはソースを見なくても想像つく。探した。全力で探した。スタッフが全力で探しました。そして、初期化処理、見つかりました。(紳助)(徳光すすり泣き)

Klabo-Wiki
えーと、東北大河田研、かな。よくワカランけど。んで、内容はごくシンプル。
void
init_xorshift(
    unsigned int    s )
{
    for( int i = 1; i <= 4; i++ )
    {
        seed128[ i - 1 ] = s = 1812433253U * ( s ^ ( s >> 30 ) ) + i;
    }
}
と。変数seed128ってのは、unsigned int型の配列。上記の、x, y, z, wに相当する。x, y, z, w の初期値を固定で書くのはマズいので、seed128[ 4 ]の値を初期値として用いる。もちろん、s には、time( NULL ); を入れておけば良い。ということらしい。

ところで、上記東北大河田研では、s に入れる値を
time( NULL ) * getpid()
としている。うーん、これはちょっと冗長じゃないかなぁ・・・と思いつつも、明確に否定できる知識を持っている訳じゃない。気が向いたら調べてみよう。

さて、ゴチャゴチャしすぎたので整理。( u32 は、unsigned int 型 )
// 配列用意。
u32 gSeed128[ 4 ];

// 初期化
u32 s = time( NULL );
for( int i = 1; i <= 4; i++ )
{
    gSeed128[ i - 1 ] = s = 1812433253U *( s ^ ( s >> 30 ) ) + i;
}

// 実行部
u32 t = ( gSeed128[ 0 ] ^ ( gSeed128[ 0 ] << 11 ) );
gSeed128[ 0 ] = gSeed128[ 1 ];
gSeed128[ 1 ] = gSeed128[ 2 ];
gSeed128[ 2 ] = gSeed128[ 3 ];
return( gSeed128[ 3 ] = ( gSeed128[ 3 ] ^ ( gSeed128[ 3 ] >> 19 ) ) ^ ( t ^ ( t >> 8 ) ) );

終わり。

ちなみに、今回引用するにあたり全て俺式に書き直したが、上記東北大河田研のソースはムダに横長で美しくない。まぁ、このようなライブラリ部分は(完成しているならば)汚くても構わないっちゃあ構わない。

だが、あんまり横詰めにすると、1週間ぐらい経って見直したとき、に最初から解析しないと理解できないソースになったりすることがある。ゆえに控えたほうが良いと思う。

とはいえ、こういうの(プログラムの記述)は宗教戦争みたいなモンなんで、各々の信じる宗派に従って書けば良いとも思う。最悪なコーディングってのは、『知識が乏しいこと』『一貫性が無いこと』の2点であるから、ごく一部のソースを見て全てを否定するのは良くない。

しかしながら、横長はどうだろうか。それを信ずる宗派はかなり少ないのではないか、という思いはある(横長が有効な場合ももちろんあるが、今回はそれに該当しないと思う)。まぁ、他所様のことなんでどっちでも良いんですがね。
ラベル:XorShift 擬似乱数
posted by 小川 at 00:47| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2008年09月22日

『働く』の対義語

俺にそれを教えてくれたのは、どこのサイトだったかな・・・


それでも明日はやってくる。

1、2ヶ月ぐらい前からだろうか、素晴らしきこの世界で有名(だよね?)なFujiharaさんが、スランプ陥ってるみたいです。まぁ、俺のような若造がゴチャゴチャ言うのはアレですが、最近気づいた言葉を1つ、ここに書き記しておきます。


『働く』の対義語は『休む』ではない。『働く』の対義語は『遊ぶ』だ。


『遊ぶ』気力も湧かない状態ならば、早急に『働く』を止めるべきではないでしょうか。肉体的に、あるいは精神的に死んでしまうよりは、半年間、金欠でギリギリの生活しかできない、というほうがまだマシだと思いますよ。生に未練があるなら。まぁ、とりあえず、い`。
ラベル:藤原宏樹
posted by 小川 at 22:07| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする

2008年08月21日

紹介してみました

ウチの会社の仕事の進め方は、ほぼ100%、ウォーターフォール型です。ですから、仕様変更が入ると、開発陣のテンションが大きく下がります。私自身も、幾度と無く煮え湯を飲まされてきました。

XP開発部屋の一例
計画ゲーム紹介をこんな形で

以上2つのURLを、副社長兼凄腕プログラマの上司に伝えてきました。その上司は、「なかなか面白い」という反応でした。ただ、同僚たちやクライアント様がどう反応するかは、まだ分かりません。ゲーム開発に向いているのかどうかも未知数です。俺自身、なんとなく名前を知っていただけで、行動は起こしませんでした。

課題は色々あるし、やってみないと見えてこない問題点もあるとは思うのですが、置き土産としては面白いのではないかと思っています。

これで開発陣の作業効率やモチベーションが上がると良いな。
posted by 小川 at 01:33| Comment(0) | TrackBack(0) | プログラム/マ | このブログの読者になる | 更新情報をチェックする