2010年7月~12月
2010-12-19(SUN)
よいではないか、よいではないか(操作性的な意味で)
PC版のMHFで使って以来、僕はXbox360コントローラに惚れ込んでいるわけですが、そんな僕がPS3でも360コントローラを使いたいと思うのは、当然の欲求なのです。そんなわけで、XCM Cross Battle Adapter 2.0と動作確認用にコール オブ デューティ ブラックオプスを買いました。難易度ノーマルで1週目をクリアした後、オンラインデビュー。
前は、スナイパーライフル+ACOGスコープで走り回っていましたが、クロスヘアタイプのACOGスコープがどうも眼に馴染まないので、サブマシンガンを持って走り回っています。AK74使いやすい。
XNAる。
もしかして、XNAって普通のアプリケーションプログラムにも使えるんじゃないのか、と思いついたので、やってみました。アプリケーションをXboxコントローラで操作できたら面白そうです。以下、実験手順。
XNAをインストールすると、VC#の「新しいプロジェクト」の選択画面で「XNA Game Studio 4.0」っていうのが選択できるようになります。が、今回はこれを使わず、「コンソールアプリケーション」を選択します。
「参照設定」に以下の2つを追加します。
- Microsoft.Xna.Framework
- System.Windows.Forms
コードを書きます。以下のとおり。
using System.Threading; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; namespace ControllerTest { class Program { static void Main(string[] args) { while (GamePad.GetState(PlayerIndex.One).Buttons.A != ButtonState.Pressed) { Thread.Sleep(1); } System.Windows.Forms.MessageBox.Show("おけー"); } } }
処理内容は、コントローラのAボタンが押されるまで待機して、押されたらメッセージボックスを表示。というとてもシンプルなプログラムです。
プロジェクトのプロパティの「出力の種類」を「コンソールアプリケーション」から「Windowsアプリケーション」に変更して、コンパイルして、実行。おけー。
実行環境にもXNAがインストールされている必要があるので、面倒といえば面倒ですが、アイデア次第で面白いものが作れそうですねぇ。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001219
2010-11-24(WED)
XNAはじめました。
今度こそはじめました。いつのまにやら、バージョン4.0になってたようです。App Hubというところに、役立ちそうなサンプルコードがごろごろしてるので、その辺を参考にグリグリいじってみようかと思います。特に作りたいものがあるわけでもないので、いつまで続くかわかりませんが。
とりあえず、今日のところは、サンプルコードを適当にいじって、PCに360コントローラを挿して、動くことを確認したところで終了。バージョン3.0からの変更点が多いみたいで、3.0のサンプルがすぐ動かせないのはやや不便です。あと、360コントローラのドライバはMicrosoft純正のものじゃないと反応しないようです。
また、HiDefでコンパイルしたものを動かしたい欲望に駆られたので、勢いにまかせてDirectX 10に対応したグラボをAmazonで注文中。色々考慮した結果、GeForce GT 240のDDR5版を搭載したものにしました。価格もスペックも微妙だけど、電源が心もとないので、この辺が妥当なんじゃないかと思います。CUDAにも対応しているから、これでも遊べそうです。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001124
2010-11-04(THU)
すうがく!
Project Eulerという、面白そうなものを見つけました。これは、プログラムで解く数学の問題集です。
まずは、Problem 1。とても簡単そうです。普通に解いても面白くないので、練習を兼ねて、テンプレートメタプログラミングでやってみました。が、VC++2010では、テンプレートの再帰は500未満までしかダメなようです。fatal error C1202: 再帰的な型の指定または関数の依存関係が複雑すぎます。というエラーが出て、コンパイルできませんでした。コンパイラオプションの設定で何とかできそうな気もしますが、どこを探しても見つからないので、eclipseとMinGWをサクッとインストールして、コンパイル!。これなら特に設定せずとも、OKのようです。
// Problem1.h #pragma once template<int i> struct Problem1 { enum { value = ((i%3) && (i%5)) ? Problem1<i-1>::value : i + Problem1<i-1>::value }; }; template<> struct Problem1<1> { enum { value = 0 }; };
#include <iostream> #include "Problem1.h" int main() { std::cout << "Problem1 : " << Problem1<999>::value << std::endl; return 0; }
このコードの見所はなんと言っても、コンパイルが完了した時点で、Problem1<999>::value
が答えの数値になるところです。実行時の処理は、文字列と定数の出力だけ。これは楽しい。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001104
2010-10-27(WED)
カリカリ
オライリーの『プログラミング言語Ruby』を読んでるときに気になった、カリー化の話。まだ良くわかってないですが、Rubyコードでは、以下のようになるらしいです。
multiplication = ->(x, y){ x * y } # 掛け算を行うラムダ式 triple = multiplication.curry[3] # tripleは、第1引数が3のmultiplication puts triple[10] #=> 30
これって、C++のbindで同じことできるんじゃないのか?ってことで、やってみました。以下の9~11行目が上のRubyコードと同じ処理をしている部分です。行数はC++の方が多いですが、書くのはC++のほうが早いです。Rubyはまだ指になじんでないなぁ。っていうか、functionって標準ライブラリ入りしてたのか!
#include "stdafx.h" #include <iostream> #include <functional> int _tmain(int argc, _TCHAR* argv[]) { using namespace std::placeholders; std::function<int(int,int)> multiplication = [](int x, int y){ return x * y; }; auto triple = std::bind(multiplication, 3, _1); std::cout << triple(10); return 0; }
……えーと、カリー化について調べてみると、新たに「部分適用」という言葉が出てきました。これとカリー化の違いがさらによくわからんです。カリー化について、Wikipediaを信用するならば、複数の引数をとる関数を、(中略)であるような関数にすること
と書いてあるから、「std::bindがやっているのは厳密に言うと部分適用なんだけど、カリー化って呼んでも良いんじゃねーの?」ってことなのかな?そうなると、Rubyのcurryメソッドも、もしかして部分適用なのか?
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001027
2010-10-26(TUE)
数年ぶりの試験期間。
更新頻度が上がってますが、単純に現実逃避がしたいだけです。会社の昇級(昇給?)試験が近くてですね……。あと、SyntaxHighlighterと昨日作った変換プログラムの使い心地が意外と良くて、これだけ簡単にコードをアップできるなら、何か書こうか!という気持ちになっているのです。
というわけで(現実から目をそらしつつ)、今日はラムダ式の練習。100個の数字が偶数か奇数かを表示する、よくあるプログラムです。
#include "stdafx.h" #include <iostream> #include <array> #include <algorithm> #include <numeric> #include <boost/lambda/lambda.hpp> #include <boost/lambda/if.hpp> int _tmain(int argc, _TCHAR* argv[]) { std::array<int, 100> values; std::iota(values.begin(), values.end(), 1); // 1 ~ values.size()までの値を設定 // ふつうのラムダ式 std::cout << "C++0x lambda\n"; std::for_each(values.begin(), values.end(), [](int value) { std::cout << value << "は"; if (value % 2) { std::cout << "奇数"; } else { std::cout << "偶数"; } std::cout << "です。\n"; }); // Boostのラムダ式 std::cout << "\nboost::lambda\n"; using namespace boost::lambda; std::for_each(values.begin(), values.end(), ( std::cout << _1 << "は", // プレースホルダーがあると自動的にラムダ式として認識される。式はカンマで区切る。 if_(_1 % 2) // ifキーワードではなく、boost::lambda::if_という関数。 [ // operator[](添え字演算子)をオーバーロードして、{}に見立てるというワザ。 std::cout << constant("奇数") // プレースホルダーがないと、ラムダ式として認識されないので、定数にconstantを付ける。 ]. // コロンに注目。if_()[]の戻り値から、boost::lambda::else_を呼び出している。 else_ [ std::cout << constant("偶数") ], std::cout << constant("です。\n") )); return 0; }
boost::lambdaが意外と読みやすいことに驚きました。慣れの問題なのだろうか?ちなみに、この例では、C++0xのラムダ式とboost::lambdaが同じ表記になるように、わざと括弧の位置とかを合わせています。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001026
2010-10-25(MON)
今日はC#。
コードを貼り付けるときに、「<」やら「>」を「<」やら「>」に変換するのが手間なので、変換ツールをザクッと作成。
変換処理は、別にC++でもよかったんですけど、クリップボードの操作は.NETを使ったほうが楽なので、C#です。
using System; using System.Text; using System.Windows.Forms; namespace CodeToHtml { class Program { [STAThread] static void Main(string[] args) { // クリップボードにデータがあれば if (Clipboard.ContainsText()) { // クリップボードからデータを読み出して、変換して、クリップボードにコピー Clipboard.SetText(Convert(Clipboard.GetText())); MessageBox.Show("できたよ。"); } } // へんかん!! static string Convert(string code) { // メモリの再配置がいやなので、元の2倍の容量を確保しておく StringBuilder htmlCode = new StringBuilder((code.Length * 2)); foreach (char c in code) { switch (c) { case '<': htmlCode.Append("<"); break; case '>': htmlCode.Append(">"); break; case '"': htmlCode.Append("""); break; case '&': htmlCode.Append("&"); break; default: htmlCode.Append(c); break; } } return htmlCode.ToString(); } } }
ちなみに、変換処理部分をC++で書くと以下のような感じ。このくらいシンプルだとほとんどC#と同じですね。std::for_each
をBOOST_FOREACH
やVC++の独自拡張のfor each
に変えて、文字列の追加を+=
から.append()
に変えるとより、C#みたいなコードになります。
#include <string> #include <algorithm> std::string Convert(const std::string& code) { std::string htmlCode; htmlCode.reserve((code.length() * 2)); std::for_each(code.begin(), code.end(), [&htmlCode](char c) { switch (c) { case '<': htmlCode += "<"; break; case '>': htmlCode += ">"; break; case '"': htmlCode += """; break; case '&': htmlCode += "&"; break; default: htmlCode += c; break; } }); return htmlCode; }
関数の戻り値でstd::stringオブジェクトを返しているため、受け取り側での効率が悪そうに見えますが、VC++2010は、C++0xの右辺値参照に対応しているため、それほどでもありません。ムーブセマンティクスは偉大なり。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001025
2010-10-24(SUN)
すごいよ!!ラムダさん
プログラミングの話が多くなりそうなので、SyntaxHighlighterというのを導入してみました。これは、JavaScriptとCSSを使って、プログラムコードを下記のような感で、綺麗に表示してくれるものです。対応している言語が多いのが良いところ。
今後、このサイトで扱いそうな、C++、C#、Ruby、XML、CSSのjsファイルを読み込むようにしてみました。
以下、C++のお遊びソース。開発環境は、VC++ 2010 Express。boost::fusion::for_each
へ、C++0xのラムダ式を与える方法がわからなかったので、boost::lambda
を使用してます。boost::lambda
は、初めて使ったけど、19行目が関数オブジェクトに化ける仕組みが良くわからんです……。どんな魔法を使っているのだろう。
#include "stdafx.h" #include <iostream> #include <string> #include <memory> #include <boost/fusion/container/vector.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/algorithm.hpp> #include <boost/lambda/lambda.hpp> int _tmain(int argc, _TCHAR* argv[]) { using namespace boost::lambda; // 7タプルを生成 auto septuple = boost::fusion::make_vector(1, 2U, 3.0, '4', "5", std::string("6"), std::shared_ptr<int>(new int(7))); // タプルの中身を表示 boost::fusion::for_each(septuple, std::cout << _1 << ", " ); // タプルの6番目の要素(std::shared_ptr<int>)が指している値を表示 std::cout << *boost::fusion::at_c<6>(septuple) << std::endl; return 0; }
実行結果 → 1, 2, 3, 4, 5, 6, 007673A8, 7
個人的には、数値リテラルにも色が欲しいところですが、CSSを書く気力もないので、しばらくはこの状態で。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201001024
2010-09-19(SUN)
部屋(一部)晒し。
テレビ周辺と配線状況の図。配線状況の図にUML(クラス図)使ってますが深い意味はないです。
最近仲間入りしたのは、AT-PMX5P。こいつはオーディオミキサーで、PCとゲーム機から出た音を混ぜるために使います。ゲームをしながらSkypeでボイスチャットをする、という構想です。各CHはモノラル入力なので、ステレオ音声を左右に分けて入れています。CH1とCH2にDR.DAC2経由でPCの音声、DCH3とCH4にSU-DH1から出たバーチャル5.1ch音声という感じです。HEADPHONE OUTから音を出すとノイズが気になるので、LINE OUTからケーブルを出して、それをヘッドホンに直結させてます。
ヘッドホン(イヤホン)は、K702とATH-AD900と10Proの3つ。10proのケーブルはLANケーブルを使った手作り品。
ついでに、本棚。一番上がコンピュータ関連書籍。これの2倍くらいの量を会社に持ち込んでいます。会社には、実用的なものだけ置いておきたいので、この間書いていた『C++の設計と進化』は持ち帰ってきました。2段目3段目は、漫画・CD・BD・ゲーム・その他をまとめて置いています。漫画用の本棚が欲しいけど、置き場所がないんだよなぁ。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201000919
2010-09-14(TUE)
ょしくど
去年の夏あたりから、会社が始まる前と昼休みの合わせて20~40分くらいの時間を読書の時間に当てています。読んでるのは、ひたすらソフト関係の本ばかりです。200~300ページくらいの本がほとんどなので、だいたい2、3週間で1冊というペースですね。そんな今日、先月から読んでいた『C++の設計と進化』をやっとこさ読了しました。500ページ超えの本は久しぶり。この本は、C++の設計者(ビャーネ・ストラウストラップさん)が書いた「C++が何でこんな言語になったのか」というC++の歴史書(?)です。近頃、C++が好きで好きでたまらなくなっている僕にはとても面白い本でした。
以下、印象に残った項目をざっくりと。
- ストラウストラップさんはデンマーク人でベル研究所の人。
- coutは、character outの略。(console outの略かと思ってた。)
- C++の目標。
C++は本格的なプログラマにとってプログラミングをもっと楽しいものにする
- C++とCとの関係。
1については、名前の印象から、ソ連の怪しげな研究所の研究者だと勝手に想像していた(失礼)ので、ベル研でカーニハンさん(C言語の設計者)とかと一緒に仕事をしていたとかいう話を読んで申し訳ない気持ちになりました。あと、Wikiってみると、C#のアンダース・ヘルスバーグさんもデンマーク人らしいですね。デンマークには何かあるんだろうか……?
2は、CプログラマがC++の入門書の最初のページで面食らう、これ→std::cout << "Hello, world!" << std::endl;
の話。この1文の中に「ねーむすぺーす」とか「ひょうじゅんらいぶらりー」とか「えんざんしおーばーろーど」とかいうキーワードが隠れています。
3については、C++の意外な一面を見た気がしました。C++は、強い静的型付けという性格上、もっと学者的に凝り固まった言語だと思っていたので、楽しいものにする
という言葉が印象的でした。ただ、本書を読み終わってみると、ストラウストラップさん自身がジョーク好きな人という印象を持ったので、言語も設計者に似るんだなぁ、と妙に納得。
4は、本書の中で度々出てくる話題で嫌でも印象に残りました。よく「C++は、Cを含んでいる」って言うけれど、実際には「C++は、Cに非常に良く似た言語を含んでいる」というのが正しいみたいですね。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date201000914
2010-08-09(MON)
なつやす
実家に帰省してます。ヒマだから本格的にRubyの勉強でもしようかと思っていたんですが、猫が「かまって」と言うので仕方なく、一日中だらだらとした生活をしています。猫怖い。とりあえず、猫の監視の目をぬって、Rubyの本を読んでますが、言語の自由度が高くて、静的言語に慣れた自分にはすごく新鮮。「すべてが実行文」っていう考え方が気に入りました。クラスの継承関係すら動的に決定できるってすごいなぁ。
最近はMicrosoftさんががんばってくれたおかげで、IronRubyなんていうものもでてきているので、.NET言語からRubyスクリプトを呼び出したり、Rubyのクラスを使うなんてこともできるようになってます。覚えてよかったC#。
とまぁ、こんな感じで、仕事でまったく使わないRubyに興味津々なのですが、やっぱりC++が楽しいんですよねぇ。特にSTLが、楽しくて楽しくて。Visual Studio 2010から、新規格C++0xの一部がサポートされて、ラムダ式が使えるようになったおかげで、STLのアルゴリズムに喰わせる関数オブジェクトを定義する手間がずいぶん減りました。BoostのMPLにも手を出したいけど、仕事で使うにはやりすぎ感があってまだ手を出せないでいます……。
……昔はプログラミングが好きだったけど、最近はプログラミング言語そのものが好きなのかもしれないと思い始めました。世の中には、プログラミング言語オタクなる生き物もいるらしいし、まぁいいや。
- http://hrdr.nobody.jp/log/2010/2010_08-12.html#date20100809