プログラミング

車輪の再発明

車輪の再発明という名のお勉強
車輪の再発明はお勉強になると思っています。学生にお勧めしているわけではありませんが、世の中に出ている面白い技術を自分でなぞってみるというのは技術者としては結構お勉強になると感じています。
最近のお勉強としてはスプラトゥーンみたいなことがしたいんだけどーって思ってて、
「InkPainter」
というUnityAssetを自分でやってみようと思い立ち、とりあえず自分でも実装してみました。
ありがたいことにフルソースコード提供なので、教材には事欠かないって感じで。
あと、作者さんは、自分のWebサイトで技術の説明をしてくださってるのですね。
http://esprog.hatenablog.com/entry/2016/04/28/235422
素晴らしいです。
まぁ、ソースコードを根気よく見続ければ、それだけでもう理屈は分かるのですが。
これをやってみた結果の気づきとしては、なんだろ、壁をヌリヌリっていうようなテクニックは所謂「デカール」のテクニックばかりが頭に思い浮かぶため、
直接テクスチャに書き込むという発想が欠けてました。いや、雪原の足跡やテレインの実装とかにも使用するテクニックでもあるんですが、ジジイで頭が固いからか
そっちに繋がらなかったんですよね。
まぁ、ひとまず、RaycastのHitで、UVとってきて、そこにSetPixelでお絵かき書くところまで作って見たところ、

Unko

のように、うんこと、地面に対してピクセルお絵かきができました。でも、これじゃつまらないね。

もちろんなんかしらのブラシを使って、本当にお絵かきソフトみたいに描きたいと思い、ソースコードからどうやってんのか見てみた。

ポイントは

Graphics.Blit関数

フラグメントシェーダ(ピクセルシェーダ)

でした。

なるほど、Graphics.Blit関数じたいを知らなかったのですが(普段Unity使ってるわけじゃないので、そこは勘弁な)、こいつは昔で言う所のBitBltみたいな関数で画像のコピーを行うのだな。

で、こいつの優秀なところは、Blitする際に、シェーダを適用することができるという点だ。つまり、シェーダでブラシ描画のプログラムを書いておいて、コピー処理を行い、元のテクスチャを書き換えれば、

壁などにペイントすることができるというわけだ。

で、この時に、塗りたいポイントのUV値と、ブラシテクスチャを一緒に渡してやることで、あたかもオブジェクトにに塗り絵しているように見せることができるというわけだ。

ただし注意点としては、そもそものモデルのUVを注意深く作っとかないと不自然になるという事だ。この辺はどうにかして改善できないかなと思う。

 

で、ブラシ込みの塗りもできてはいるんだけど、ソースコードを職場において来てしまったので、次回に解説込みで結果を魅せようと思います。

| | コメント (0) | トラックバック (0)

設計について

なんかねー、今日は九大病院前のインドレストラン「ヒマラヤ」で飯食ってたらさー、なんかプログラマなのか、プログラマ志望の学生か知らんが、設計の話をしてた。

うちの職場でもよく、僕に対してClientから「設計の話をしてほしい」とかの意見が出る。
正直「設計」ってのは、学生に対して教えたくないものである。いや、教えることが惜しいとかそういうんじゃなくて、プログラミングそのものが未熟な状態の人間に設計だけを教えることは害悪だと思ってるし、そもそも設計のセオリーなんざ職場のルールや状況によっても変わってくるのだ。

学生がコレを聞いてくるときは、なにげに話を逸らしているのだが・・・ここは俺のメモ帳なので、好きに書いてみる。
というか、設計ウンヌン前に開発に対する心構えが結構大事だったりする。設計はこの心構えというか、そういうのを心がけていたら自然とマシなものになるんじゃねーかと。
あと、今の職業柄、学生向けな意見になってしまっているとは思うので、そこは差っ引いて読んでいただきたい。というか基本情報技術者試験の勉強をしているような学生であれば、設計に役立つことは既に俺なんかよりも勉強しているはずなので、今一度頭のなかをほじくり返していただきたい。
ということでプログラムする際の原則を幾つか書いてみる
  • 設計に時間をかけ過ぎない(考え過ぎない)
  • いつでも自分のプログラムを捨てる(作ったものに執着しない)
  • 暇な時にSourceForgeなどで評判の高いプログラムを眺める
  • とにかく色々作る
  • 読みやすいプログラムを心がける(…1年後の自分が読んでもすぐ分かるような)
  • 無駄に難しいテクニックを使わない
  • できるだけ拡張可能、変更可能、削除可能な状態にしておく
  • シンプルさ>堅牢さ>実行速度
  • わざわざ遅いコードを書かない
  • どっかのサンプルを鵜呑みにしない
  • 日頃からいろんな言語に触れておく
こんな感じ。最初に赤字の太字で書いてあるアレは、数々の未熟者が設計という名の甘い罠のもとに数々の学生たちが設計のダークサイドに堕ちてしまい、使い物にならなくなったのを見てきたから、これって結構大事だと思うのねん。だからデザインパターンとかも迂闊に教えられないのねん。
とにかく「設計」と称して1行もプログラムを書かない時間が1日以上あるような自体になってるのなら、ある意味病気や逃避に近いのだ。ちょっと自覚した方がいい。もちろん、そうしなければいけない時がある。実際の仕事では確かにある。しかしプログラミングに熟達していない人間が設計に悩むのは時間の無駄。さっさとコード書けってこった。
次に設計で悩む人間は大抵この性質も持っているんだけど、「いらんコードを捨てられない」もしくは「一度作ったコードに執着し、他の部分がそれによって歪められてしまう」なんてことが多い。
そもそもある程度書いて行って、規模がある程度大きくなってきたら「あ、こりゃ…アカン」と思う時が来る。その時は、例えばVisualStudioとかなら、プロジェクトから作り直す。コードも初期化のところとか以外は1から作り直すべきだ。
それができないのは単なる執着心だったり、そもそも自分が書いたコードを理解している自信が無かったり、ただ単に面倒臭がってるわけなのだ。
それは…そんなものはコードに対する「」ではないッ!!!
そんな執着心は捨ててしまえ。
さっさとクオリティ高いものを作る奴は、本能の赴くままに作るから最初はm9(^Д^)プギャーってなコード書くんだけど、しょーもないと感じたら何の躊躇いもなく捨てる。びっくりするくらい捨てる。
そして数時間後には前以上のものが前以上のコードの綺麗さで出来ている。
そう…まるで、イモムシが蝶になるようにな!!!

とまあ、そんなことがいきなり出来るのは天才的なやつだとは思うので、我ら凡人がなんとなくそういうセンスを獲得するためには、天才的なコードを眺めることだ。
どうせ理解できないんだから、眺める。たまにすごい「気づき」がある。それがなんとはなしに自分を成長させることもある(行っておくけど眺めるだけでは「天才」は身につかない、それはあまりに都合がよすぎるだろ)
で、他人のコードをみたければLinux界隈にはいくらでもあるだろうし、SourceForgeとかでもいくらでもみれるであろう。
その中で自分のセンスに合ったものを見つけることができたのなら真似して作ってみてもいいとは思う。
で、自分で気になるテクニックがあったら、とにかく自分でなんかそれを利用して作ってみることだ。
実際に作ってみないとそのメリットデメリットはわからない。

ここでも注意点なんだけど、「執着してはいけない」ってこと。
確かに「ModernC++Design」のテクニックは面白いしすごいんだが、それに執着してしまうとテンプレだらけで収拾がつかなくなる。デザインパターン系についても同様。
次に読みやすいコードを心がけるってことなんだけど、とにかくシンプルに考えましょう。なんか難しいコードに見えるように書けばカッコいい・・・とか思うのは中二病です。エンジニアではございません。

あと、当たり前な話なんですけどね、変数名、関数名は適切なものをつけましょう。あと、ソレにともなって英語は勉強しておきましょう。間違ったスペリングはトラブルのもとになります。今どきネットで英語はすぐに分かるんだから、恥ずかしい間違いはやめておきましょう。
で、「どうせ他人に見せないんだから」って思う人も、「1か月後の自分は他人」くらいに思っておいたほうがいいです。「男子三日会わざれば刮目して見よ」とか言うでしょ?
というわけで「無駄に難しいテクニックを使わない」ね。これ結構いるんですよ。まさに中二病!!m9(^Д^)プギャー。そしてそのテクニックがローカルルールに基づくものだったり、実は自分の勉強不足によるものだったりすればもう周りの人は苦笑。m9(^Д^)プギャーm9(^Д^)プギャーですよ。


で、実際の仕事とかやり始めるとですね、特にゲーム開発だと、プログラマがある程度完成させてくると狙ったかのように、今までにない仕様が追加されたり、かなりの仕様変更が行われたりします。
こういう時は「潔く捨てる」と行きたいところですが、プロジェクトがある程度…中盤以降くらいになってるとそうもイカない時があります。そりゃね、1~2個のソースファイルを削除するくらいならそれはやるべきなんでしょうけど。
そういうのにもなるべく対応できるようにしておきましょう。
例えば、「仕様が変わったから引数の数を増やす」なんて思想を貫くと最終的には引数が10個以上なんていう悲しい自体に陥ります。こうなると呼び出し側の対応も大変です。ある程度は予想をたてた上で、例えば「これから引数がやたら増えるかもしれん」と思うのなら、渡すものを構造体のconst参照にするとかいくらでもやりようはあると思います。
あと、これも結構いるんですが、「どこぞで見た高速化コード」を書くためにプログラム全体が複雑になってしまうってやつ。こういうのはたいてい失敗します。何故かと言うと、その高速化コードのために他が複雑になると、たいていは全体としてより遅くなるからですし、その高速化が逆にコンパイラ最適化を阻害することもあるからです。

ソレよりも何よりも、複雑化したことでバグは発生しやすくなるし、何より読みにくいのでメンテしにくくなる。
このリスクを考えた上で組み込むべきコードかどうかを十分に考えて組み込みましょうと言いたいが、「組み込みたいと思っている人」は、何が何でも組み込もうとするでしょう。だって全体のバランス考えるほうがめんどくさいですから。
だから、もう、妙な最適化コードは使わないようにしましょう。逆に同僚のそういうコードを見つけたら「くせぇくせぇ…このコードは中二病の匂いがプンプンするぜェーー!!」って思っておきましょう。
はい、わざわざ遅いコードを書かない。もうこれは前回のにも関連していますが、自分の勉強不足からわざわざ遅いコードを書く場合があります。コレに対処する対処法は勉強するしかないですね。もしくは既存の使い古されたアルゴリズムをきちんと用法を守って使う。これしかない。車輪の再発明をしていいのは時間に余裕がある時、趣味の時、学生の間だけですね。
どっかのサンプルを鵜呑みにしない。これ、前にアンチパターン的なところでも紹介しましたが、「どっかのサンプル」はあなたのプロジェクトを保証しません。
「サンプルにこう書いてあったから正しいはず」と思考停止するなど愚の骨頂です。
もっとひどいのになると「○○というHPに書いてあったコード」をそのまま使用して、それがバグってることもあります。というかHPからパクって理解もせずそのまま使うとか、開発者として大丈夫ですか?ヘタしたら利用したソースコード全公開する必要があったりするんですよ。

日頃からいろんな言語にふれておく。これ、結構大事ですね。例えば同じC++を扱う人でも、C言語から来た人とJavaから来た人はスタイルが違うものです。違ってていいんですが、その違いがどこからくるものなのか理解してないとトラブルのもとになります。
また、いろんな言語を知っていれば、C++だけだったら「この書き方」の発想しか出てきませんが、いろいろな言語にちょびっと触れておくことによって、いい発想も出てくると思います。
こういう事すべてが「良い設計」に結びつくのではないでしょうか?
最初にも言いましたが、直面している「解決すべき問題」によって設計ってのは変わってくるし、センス的なものもあるので、設計に正解はないと思っています。
ある程度の基礎知識はあるにせよ、基本情報技術者的な資格持ってる人なら知識としては十分でしょう。

僕自身、今まですごいプログラム書いてる人であんまり「設計ウンヌン」を語る人を見たことないんだよね…

↓初心者は読んだらダメ!ゼッタイ!!

| | コメント (0) | トラックバック (0)

挿入ソート

こう言うわかりきっている基礎的なところを復習し固めるのが、無職時代にすることですな。

とりあえず、簡単に言うとやね、

  1. 整列済み区間と非整列済み区間を区別する
  2. 最初は整列済み区間の数は0
  3. 非整列済み区間から一つ取り出し整列済み区間へ挿入
  4. 挿入の際に先客がいれば、先客と比較して先客より小さければ先客の位置に挿入、先客は一つ後ろにずれる
  5. 先客と比較して先客より大きければ、先客の後ろにつける、このとき別の先客がいれば比較を行い、4または5と同じ事をする
  6. 非整列済み区間がなくなるまで3~5を繰り返す

カッコ内が整列区間だとすると

[]|3|4|1|5|2|

[|3|]|4|1|5|2|

[|3|4|]|1|5|2|

[|1|3|4|]|5|2|

[|1|3|4|5|]|2|

[|1|2|3|4|5|]

てな順番でソートされる。簡単でしょ?

整列済み区間は整列済みなので、挿入する奴は左側から順に比較して、自分より大きな数が見つかった時点でその手前に挿入してやりゃいい。

以下に擬似コードを書いたよ…もはや何言語だかわかりゃあしねぇ

for j=1 to Array.length
--keyは挿入する対象
key=Array[j]
i=j-1
while i>0 and Array[i]>key
Array[i+1]=Array[i]--ずらす
i=i-1
Array[i+1]=key--挿入

アルゴリズムは簡単だけど、速くない。ただし、ある特定の場合には最強になる。

それは、最初からほぼソート済みに近い状態であれば、特に何もすることなく、ずらす必要もないため、高速になる。

また、配列でなく、リスト構造を使用していれば、ずらす必要がないため高速にはなる。

| | コメント (0) | トラックバック (0)

寝る前だというのに面白い記事を…(プログラミング言語Go)

くそー、寝ようと思ったら

http://codezine.jp/article/detail/4594

の記事が目に留まってしまった。なんでも、Googleが新しい言語"Go"を公開したのだそうだ。オープンソースで。相変わらずあそこはフリーだとかオープンだとかで…それで儲けているというのがいまいちピンとこないが、僕の感覚が遅れているのでしょう。

で、

http://golang.org/doc/gccgo_install.html

までいって、とりあえず、SVNチェックアウトだけした。残りは後日…もう寝る。

2009/11/13 01:48 追記

やっとチェックアウトが終了したが、本家HP(http://golang.org/)のインストールマニュアルを見てみると…linuxとmax osしか対応していないんだって…な、なんだってー!!

Cygwinでコンパイルいけるかなぁ…さすがは、Unixの作者Ken Thompson氏…Windowsユーザに喧嘩売ってんな。

まぁ、一ヶ月たたないうちに、Windowsバイナリ出るだろうけど…。まぁ、こっちも興味本位でCygwinでコンパイルしてみるか。

| | コメント (0) | トラックバック (0)

ぷろぐらテクニック

ログ見たらK2の人が見に来てるね

http://www.kei-two.co.jp/

前もスクエニの人神に来てたけど、結構ゲームプログラマ多いんだね。
最近プログラミングページ更新してなくて、ごめんね。

スキルは確実に蓄積してるんで、まとまった時間ができたら、学んだこと、惜しげもなく公開しちゃうから。

まぁ、会社はもう辞めて、福岡帰っちゃうつもりなんだけどね。しんどいとかそういうことじゃなくて、会社の方針が気に入らないのと、もう先行き不安だしさ、ここで過労死するまで働いたって、なんかもう潰れかねない勢いだし、過労死したら関係ないけどさ。

どうせ過労で死ぬなら、福岡で死にたいじゃん?生まれた街でさ。

まぁ、別に職業プログラマやんなくても勉強できるしさ。

そうだ!

いいことを思いついた。そこのプログラマー、俺のブログにリクエストしろ。

男は度胸、プログラムのネタをリクエストしてみるのさ。きっといい情報が手に入るぜ。

俺がすばらしいテクニックで教えてやるからよ。

あんまり難しいネタだと、頭ん中がパンパンだぜ。になるけどな

| | コメント (0) | トラックバック (0)

DirectShow①

苦しめられました…。マジで、ホントに…(ρ_;)

フィルタとかピンとか、グラフとか…。うわべだけわかった気になるのと、きっちり使いこなせるのとでは、大きな差がありました…。

サンプルが動いて「ヒャッホウ」とか言って、そのまま自分のプログラムに組み込むのはプロのやることじゃない…てか自分の首を締める行為ですな。

正しく理解していないから、きちんと動かないときに対処の仕様がない、ここかな?あそこかな?

とかやってたらいつまで経っても的外れの個所を捜索している…。

まずヘルプをしつこいくらい読む。インターネットや書籍などの方がわかりやすく解説してくれていますが、コレにも落とし穴があるのです。

なぜならば、著者の主観や先入観でフィルタがかかるからです。そりゃ、教えられるとおりにやればうまく動くだろうよ、でもそれはきちんと理解していないのです。サンプル動いてよろこんでるのと変わらんのです。

更に不味いことには、そのやり方が絶対だとか思ったりすることもあるわけで、「実はヘルプ見てきちんと理解したら、もっと効率のいい方法があった」なんてことは多々あるわけです。勿論本を出すくらいの人はかなり理解しているでしょうし、間違ったことも教えないでしょうが、それでも参考程度にして、きちんとヘルプを読んで、更に読んで、関係なさそうなところも読み飛ばさずに読んで、サンプルに飛びつかないで、とにかく理解すべきです。期間のプレッシャーに負けずに、遠回りに見えますが、理解が先です。

勿論初心者ならば学習のモチベーションもあるので、さっさと動かすことを否定しませんが…てか初心者はあのDirectShowヘルプを正しく理解できるのか?

ま、言わずともわかると思いますが、僕はプロのくせにやっちまいました。おかげで3週間の工数を無駄にしました…。

プロプログラマの皆様、DirectShowに限らず、全てのプログラミングにおいて、マニュアル、仕様を熟読しておきましょう。

プログラマは理系のイメージ強いけど、こりゃ読解力のほうが重要ですよ。マジで…。

| | コメント (0) | トラックバック (0)

現在DirectShowに苦戦中

そのうちまとめて書きます。

| | コメント (0) | トラックバック (0)

そろそろ

プログラミングネタをマジで始めようかと思う。ボクシングネタばかりじゃ「こいつ本当にプログラマか?」と思われるし、いい機会かな?但しプログラミングネタがあまり続くと、ただでさえ少ない読者が限定されてしまうから3連くらいでやっとこかな。

まず、僕は一応未熟ながらプログラミングでお金を貰っています。言わばプロです。なので当然知っておかなければいけない知識がいくつかあります。現在の開発言語がC++なため、オブジェクト指向についてわかっていなければなりません。で、とりあえず、

①デザインパターンその他イディオム
②事前条件事後条件
③メモリとか、スタック、デック、キューとか

を、さらっと、浅く書いてみることにします。以下は序文ってな感じで

最近デザインパターンに関する理解が少し変わりました。少し前まではプログラミングを助けるためのもの(この理解も正しいとは思うけど)だと思っていましたが、今は少し違っていて、ライブラリ(別にlibじゃなくても普通のソースでもいい)開発者がクライアント(利用者)に楽させるものだと思っています。つまり、クライアントが楽にならなければ、デザインパターンを使用する意味が薄いと認識しています。だからライブラリ側のプログラミングは必ずしも楽にはならないと言うこと、むしろクライアントのために頭を使わなければならないわけです。あたりまえなんですけどね。

事前条件事後条件については、恥ずかしながらつい最近までその存在すらあんまり知りませんでした。逆にいえば知らなくてもプログラマにはなれますが、知らないと恥ずかしいものですし、事前条件事後条件を考えずにクラス、関数を作りまくっているとワケワカランことになります。はい、現状ワケワカリマセン。とりあえず最初は小難しく考えずに、doxygenのpre,post,invariantを書いて遊んでればいいのではないかと思います。ボクシングでもそうだけど、仕事も楽しまないと持たないっす。仕事だからって小難しくやってたらつぶれますって。楽しくプログラミングしてればセンスは後からついてくると思う。考えが甘いかな?でもそういう感覚で仕事できない人は絶対つぶれると思う。

まぁ、話が脱線しちゃったけど。

最後にメモリの話。苦手ッす。正直言って。ただ自前プログラミング言語を作るときには、ガベコレとか考えなきゃいけないし、もちろんC++であってもOSがどのようにメモリを管理しているのかを知っておけば、確保の順番や、クラスの定義などについてのアイディアがいろいろ出てくると思います。とにかく基本からいこうと思います。

ふぅ…。じゃあまずはデザインパターンからか…次までにネタを考えておきます。

| | コメント (0) | トラックバック (0)

仕事がもうちょっと暇になったら

わんくま同盟とかで活動してみたいなぁ…とか思っている今日この頃。

最近、仕事の効率が非常に悪いため、本気で勉強しています…マルチスレッドだの、テンプレートだのSTLだの。

あとまぁ、言語全般…特にスクリプトを利用する機会が多いため、ゆる言語をどう活用しようか…などなど。

まぁー、忙しさを言い訳にしている状態ではまずダメだなぁ。

情熱に火をつけないと…だな。

| | コメント (0) | トラックバック (0)

関数プログラミング

関数プログラミングに興味を持ってしまいました。
そこで、haskell,scheme,ocamlで遊んでいます。

もともと、Luaやjavascript,actionscriptなどのまた~りゆる~い言語が好きなのですが、

たまにはそうゆー言語もいじってみたくなった。

しかしocaml流行ってるんだな。図書館でも最近貸し出し中だったり
予約が入りまくりだったりする。

ついでにいうとF#にも手を出している。まぁ、名前みてわかるが
.net framework的なものだ。pythonやら、rubyやらが.net frameworkで
動くようになってきているので、これも当然の流れかな…なんて思う。

余談だけれど、うちのパソコンはmsiをダブルクリックすると桜エディタで開いてしまう…関連付けしてないのになあ…。

あと、F#の日本語情報が少なすぎ…まぁ、英語の勉強だと思って頑張るか…。

| | コメント (0) | トラックバック (0)

より以前の記事一覧