はてなキーワード: VC++とは
[自社開発メガベンチャーをわずか半年で鬱退職した雑魚エンジニアの話|JoanOfArc](https://note.com/joan_of_arc/n/ned510ca913c7)
1. 今はなき鉄鋼メーカー、研究所で新規シミュレーションコード立ち上げ
メンターが米国自動車メーカーへ転職して途方にくれた。電磁気学の教科書を読み漁って掲載されているサンプルコードを理解して、コード手打ちして3ヶ月で動く様にした。社内で誰も見たことが無い結果に驚かれた。
2. 鉄鋼メーカーの人員削減が若手にも迫ってきたので、電子部品メーカーへ転職。コードは書かず開発現場で製品試作品の制作をモクモクと行う。
3. 色々あってプログラマー派遣会社へ転職。ドコモ向けのアプリのテストデータを作成するだけの仕事をアサインされた。楽勝の仕事だったが、拘束時間が長く半年で10kg太る。
4. 派遣で今はなきシャープ常駐でデジカメファームウェアの開発現場に放り込まれる。C言語の未知のコードとLSIの仕様書に戸惑ったが、親切な若手社員に助けてもらって独り立ち出来た。2年程やったが、雇い止めに合った。
VC++製の画像処理アプリもメンテした。VBの画像処理アプリも自作した。
5. 現NTT、当時住友銀行子会社で常駐で電磁界シミュレーションアプリの新機能開発を担当。分散処理による計算時間短縮を狙う部分を担当。分散処理はMPI(現OpenMPI)を使用。まずはパソコン2台で分散処理を行うもNIC(LAN Card)がボトルネックで計算は出来るが1台で計算するよりパフォーマンスが出なかった。職場にジョインしたあとは、しばらくは訳がわからず、戸惑った。通勤時間が長く体が消耗した。
派遣プログラマーは嫌で正社員で働きたかったので、プログラマーにこだわらず職場を探した。知財の職に採用されたので、常駐先と派遣会社に退職を願いでると引き止められて困った。退職を強行して転職できた。離職票の入手に苦労した。暑い夏だった。
6. 中小製造メーカーの知財の職場では要領よく仕事をこなしていると時間があまる。余った時間で社内WEBサイトを作ったりした。使ったのはASP(ASP.NETの前身、VB.NETでコーディング)。フレームワークに従ってコードを埋めるとそれなりに動いた。DBMSはAccessを使った。要するにmdbファイルにデータを保存した。更新処理は管理者のみ、データの閲覧が主な機能であるWEBサイトだった。
7. 知財の仕事は楽勝なのだが、やはり開発の仕事に未練が出てきた。iOSアプリの開発もやってみたくなった。10年以上知財の仕事を行ったが思い切って無職へ転向した。親父も無くなり、遺産の整理もサラリーマンを行いながら難しかったのだ。(つづく)
16歳 はじめてのエロサイト このときPCの壁紙が金髪お姉さんのオ○ンコ画像になって戻せなくなり、情報セキュリティに興味をもつ
16歳 はじめてのCプログラミング 学割でVC++を買うがまったくわからず挫折
16歳 はじめてのVBプログラミング 学割でVBを買い、メモ帳をつくったところで、それ以上のことができなくなり飽きた
18歳 HSPという言語を知り、ゲームをつくったり、エロ画像をEXEのバイナリに含めて隠したりした
20歳 Javaを触っているうちにポリモーフィズムの概念がわかってきた、ここからプログラミングが急速に伸びた
21歳 IE6があまりにもアレなので、Javaでタブブラウザを作り、エロサイト巡りをはかどらせる
〜24歳 なんやかんやで Java, PHP, C++, Python, VB6, VB.NET, C#, Oracle, MySQL, PosgreSQLを覚える (このあたりでOracle Silver,応用情報をとる)
〜30歳 なんやかんやで Go, Obj-C, Swiftを覚える 機械学習に興味を持つ
31歳 エロ画像収集AIが完成したが、風俗にはまったため活用されず
32歳 Reactで爆速エロサイトをつくったところ、なぜか東南アジアで人気になる。AWS教では月間1200万PVを月4000円でさばける。
上司の命令でグラフィック制作チームからプログラマーのチームに配属された
グラフィックデザイナーとして就職したのに何でプログラミングしないといけないの?
Rubyとか知らねえよ
Windowsあんまり使ったことないし・・・まあ仕事なら覚えますけど・・・
「このチームではエディタはVimとEmacsしか使えないから。どっちか選んで。」
出来れば長年愛用してきたmiが使いたいんですけど・・・やっぱりMacがいいな・・・
「ここ、午後までに修正してプルリクしてね」
「ここ壊れてるらしいから午後までに潰して」
はあ?????????????????????????????????????????????
マジクソだろこの会社
CとかVC++とかRubyとかPHPとかJAVAScriptとか採用情報にいろいろ書いてあるけどそんなの1つも出来ねえよカス
プログラマーを雇えばいいだろ
そもそもプログラマーにも同じ事させてみろや
何でグラフィックデザイナーの俺にプログラミングの即戦力を期待してるの?
俺はグラフィックがやりたいの!
Windows 7 64bit 版上で winpcap を使ったサービスプロセスを制作。
こちらのページを参考にさせてもらった。
「WinPcapを使用したパケットモニターの作成」CodeZine 古谷誠進さん
http://codezine.jp/article/detail/126?p=2
・アダプタ一覧(アダプタ名およびIPアドレス)を取得する
の箇所
処理は、while(d)ループの外でやらなくちゃいけない。
デバッグきつかったっす、サービスだとデバッグできないこともあって。
・俺のマシンが64bitだから、winpcap.dllやlibと合わない?
(PCAPSDKのLibにx64というサブフォルダがあって、こっちのものを指定しなきゃだめ?)
・WIDECHARとMULTIBYTE の扱いの問題?
と、いろいろ迂回してしまった。
解消したら、無事動き出した。
これは弊社だけの事かもしれないけど、どうも「人材の育成」ってのに全く関心が無いように見える。なんでもかんでも「即戦力」ばかり求めていて、自分個人的にはお話にならない。
密室会議でプロジェクトの体制が決まるのだが、だいたい自分の担当範囲は「その他」と書かれている事が多い。
基幹部分はVisualStudioで、だいたい、VB.netで書かれたプログラムで目立つところばかり。でも別に基幹部分とはいえ、クリティカルな部分は無くて、万が一止まってしまったら、リブートすればいいだけ。この部分は、たいてい他の人に取られている。
で、自分に割り振られる「その他」ってのは、VisualStudioで、VB.netとVC++で、主にネットワークとミドルウェア、ドライバの部分、他のマシンでUNIXのX-Windowだったり、Webサーバ、Webアプリ、Oracleデータベースだったり、組み込みマイコンのOS、ドライバ、アプリの担当となる場合がある。
ちょっと待ってよ。なんでVBの部分は数人で作っているのに、その他のクリティカルで多様な部分は俺独りなのか?
聞いてみた。
「誰も出来ないから」
は?
俺だって生また時から出来るようになったわけじゃねーよ。誰も出来ないなら育てろよ、と言ってみた。
意味わかんねーし。
でも、最初から担当出来るならまだまし。たいていは、「出来ない部分」は外注に発注する。
そして、外注が失敗する。
その尻ぬぐいが俺になるパターンが9割を占める。
勘弁してくれ……。
自分の課の人員動向を見ていても気になる部分がある。課長や係長の様子を見ていると「使えない」と判断したら他の課に回してしまう、けど、教育はしない、みたいに見える(でも、部から外へは出ない)。
なんかおかしくないだろうか?
先述の外注の件も、「社内で遊んでいる人員がいるけど、技術が無いから、外注に出す」パターンで、結果、外注に踊らされて「動かないコンピュータ」が出来上がってくるパターン。
外注と話をすれば、(まぁ、だいたい15分も話をすれば)、相手がどのくらい出来るかどうかなんて判断出来る。たいていの場合「無理じゃね?」「これじゃ出来ないのあたりまえじゃね?」という結果が俺の脳裏をよぎる。でも、何故か、外注に発注する事になる。
おかしいよな。だって「社内に遊んでいる人員」がいるのに「外注に出す」ってなんなのさ?
「即戦力」
しか頭にないんだろうな。
外注も頭良くてね。業界つながりで他の会社の人達と話す事もそれなりにあるんだが、出来る会社、出来る人員(個人事業主も含む)は、口をそろえてこう言うんだ「悪いけど、君の会社の、特に君の部からの仕事は受けないようにしてるんだ」とね。表向きには言わないけど、複数の会社に相見積もりをとると、そう言っている会社は、弊社に出してくる見積書がめちゃくちゃ見積金額が高い。当然、弊社からはその会社に発注しないわけ。そう、残っているのは「実情を知らない会社とその社員」だけ。だから「動かないコンピュータ」が出来上がってくる。上の連中がどれだけ、この事を知っているのか。
の、割には「職人」に対する扱いがひどいのもある。
どうも、経営者、管理者どもは、自分の力で物理法則が変えられる、他人の脳をオーバークロック出来るかと勘違いしているようだが。どこかの国の政治家やDQN連中と同じように見える。
IT業界だけの話じゃ無いと思うんだけど、例えば……そうだなぁ、漫画・アニメ・小説とかのコンテンツ業界も(外から見てる限り)そんな感じを受ける。こっちの業界も、「即戦力」と「職人に対する扱い」に関しては、IT業界と同じに見える。
漫画・小説も、「既に売れている作品」に勝るとも劣らない作品をクリエイト出来る人間だけが採用されているような気がしてならない。いや、同人誌界を見てるとそう思うわけなんだが。
商品なんだから、それは当たり前の話なのも分かる。
だがよ。「育てる」事してないだろ?(という風に見える)
ある機会があって、就活生と話す事があった。やはりかなり焦っていて「もう仕事は何でもいいし、どこでもいいから内定とらないと」と言っていた。「うちの会社にだけは来るな」とだけ言って、俺は言わなかったけど、確かに「新卒」というカードを使えるのは1度きりだけど、「意に沿わない仕事、職場の雰囲気、自分の技術力、これらが合わないと、早々に精神を病むぞ」と言いたかった。現に、弊社やその周りの会社では早ければ入社後1週間、2~3年後までに辞めてしまう、またはメンタル疾患にかかる人が急増している。
なにしろ、育てないで、新人といえども「即戦力」を求めるからな。付いてこられない、精神的疲労は大変だろう。
今年の新人君と話をしてみたが、情報系の院卒のれっきとした修士でありながら、16進数とバイナリとテキストの区別が分からなかった、という驚愕の事実。これで「即戦力」?
「ゆとり」世代、の一言で方つけてしまうのは、少々酷かとは思うのだが、採用判定する方も「ゆとりジジィ」としか思えない。
まぁ、うちの部は、会社の中では「墓場」と言われていて、この部から出て行くには「自殺」「精神疾患による退職」の2択しかないのだが。
こうやって脱線した時の、リトライのすべが無いのも事実だよなぁ。
「そりゃ、実力が無いだけ」「努力が足りないだけ」
と一刀両断にするのは、いかがなものかと。まぁ、分からなくもないけどね。
前述のような事を書けば、ほとんどの人は
「辞めればいいじゃん」
と言う。まぁ、それも分かるわ。実際その通りだし。別に社畜じゃないし、会社に未練も無いから。少なくとも今の会社、出来れば「職人」を蔑ろにする風潮のIT業界からは離脱したい。
サービス業なんていけない。ぶっちゃけてしまえば、サービス業(例えば接客業等)って、いわゆる「感情職業」じゃないですか。一度鬱病やって休職した経験のある自分にとって、感情職業は無理。
転職エージェントとか見ていても、やはり「キャリア」。「即戦力」だよねぇ。
最近のmixiの(少なくとも自分にとっては改悪だった)状況に対する、mixi使っている人達の反応や、Twitterの非公式RTに関するページを読んでいて、「そんなに嫌なら、使わなきゃいいじゃん。自分に合ったものを自分で作れよ。」と思う。無料サービス・アプリなんだから文句たれてないで、使うの辞めればいいのに。
なんか、弊社のある課長を思い出したわ。ある有名なフリーソフトを使っていて「これ、使いにくいから、作者にクレームのメール入れるわ」とか……。おいおい。使いにくいなら使わなきゃいいだろう、フリーソフトなんだし。相手(課長)の常識より、自分の常識を疑ったわ。フリーとはいえ、クレームをつけるという常識が、昨今の風潮なのか、と。
と、思うのは、前述した「(会社を)辞めればいいじゃん」と同じなんだろうか?
少なくとも、金銭や契約が関わっている以上(他、労使契約、労働基準法等)、違うと思うんだよね。
と、書いても、例えば、喫煙者(愛煙家と言うか?)にたまにいる「金と税金払って吸ってるんだから、どこで吸おうと勝手だろ」というのと同じなんだろうか?
いったんレールから外れると、ほとんど復帰のすべが無いってのは、なんだかなー、と思う。
するとこう言う。
これも「(会社を)辞めればいいじゃん」「使わなきゃいいじゃん」と同じなのかな?
自殺する気は無いから、会社は辞めるけどね、耐えられなくなったら。自殺するくらいだったら、引きこもり→生活保護の方がいいわ。
1900年以来、第4位の大地震であれだけの災害だったにも関わらず、死者・行方不明者数が、スマトラ島沖地震、チリ地震よりも少なく、かつ、「年間の総自殺者数」の方が多いってのは、どうかと思うわけだが。
ちょっと、最近、閉塞感を感じるので、つらつらと書いてみただけ。
fooのintへのキャストがtrue/falseを返すというように、fooのクラス仕様が決められてるんなら、
そしてboolへのキャストが未定義だったり、また違う意味なのなら
if (foo) {
ではなく
if (foo == true) {
って書かざるをえないだろう。嫌いとか好きとかの問題ではないと思う。
class { public: operator bool() { std::cout << "xxx\n"; return true; } //*1 operator int() { std::cout << "yyy\n"; return true; } //*2 } foo;
があったときに、「if (!foo)」だったら*1が、「if (foo == false)」だったら*2が実行されるような処理系がある。
最新のVC++だと後者は曖昧だってエラー出るね(たぶんC++だと「trueは1でfalseは0」なんかではなくあくまでもtrueとfalseなんだ)。
なんにせよ演算子や条件式などに関連する暗黙のキャストはわかりづらく、そしてそんなのを利用したコードはきっとバグる。
だから
というのが本当なら、==trueがどうこうなんて些細な問題はおいておいて、fooを暗黙のうちにintにキャストしたりboolにキャストしたりして使っているという危険な部分をまずなんとかすべきだろう。
古いC言語風に書けばこんな感じ。
#define FALSE 0 #define TRUE (!FALSE)確かに、実際に値を表示させてみると、昔のVC6だと「1」という結果が出てくるし、VB6だと「-1」という結果が出てくる。これ、当時混乱の元だったんだよね。
VC6とか関係なくてC言語の仕様でそうなんだが、それをわかってないとすればやばい。
個人的には
if( foo != FALSE ){
も十分きもちわるいので
if (foo) { ... } if (!foo) { ... }
にしてほしい。
いろいろ引き伸ばしていたけど、とうとう明日から無職。
俺は、無理に就職しないのが得策だと考えた。
つまり、今は「景気回復まで我慢する」という方針。
景気回復まで何とか食いつないで、景気回復したら何とかなるだろう、と考えている。
だけど、冷静に考えてみる。
ひょっとしたら、このまま景気回復まで我慢っていう選択肢、ダメなんじゃないだろうか。
この年齢になるまでプログラマだけやってきた。プログラマっていうのはアレもコレもコンピュータに関わる事は大体全部出来ないといけない。
ネットワークの知識は社内LANでパケットキャプチャしたら大体全部の信号の意味が判る程度、サーバの設定も試験内容にあわせて変えなきゃいけないから大体やってる。Apache、HTTP-proxy、sendmailという一般的なところから、RADIUS、ITStage、SIPサーバもやった。ドキュメントを素早く大量に正確に作らないといけないのでワードエクセルパワーポイントVISIOも使いこなしてる、事務のお姉ちゃんより断然詳しい。Oracleだってやった。パズルみたいなSQLを読み解いて、問題解析して、またパズルみたいにSQLを組み立てて、みたいな日常を何ヶ月も過ごした。Linuxも必要があってカーネル改造した経験があるというかカーネル改造だけでここ数年食ってた。Windowsだってやった。VBもVC++もやった。インストーラをVisualStudioデベロッパで作って、InstallSheildで作って、でも仕様を満たさない&顧客が納得しないのでVC++でスクラッチした。SIP電話開発した。SIPなら大概わかる。UNIXもミドルウェア作りまくったのでシステムコールはかなり深くやった。ちなみにvi派。UNIXなら絶対viが使えるから。シェルだってABCTやった。Aシェルやったのは1回きりだけど。
ここまでやってても、でも、仕事は無いんだよ。
ウチのHPへN×T××がアクセスしてきて、何だろうと思ったらインストーラの記事を昔Blogで書いた事があって、それへのアクセスだった。
ちなみにウチのページはモロおたくな同人作家のページだが、1年に1度ぐらい、プログラマとしてのグチを書く。
VisualStudioについてるヤツとか、フリーソフトのとか、ああいうので日本企業が出すソフトのインストーラを何とかしようったって、無理なんだよ。うん。
PCが判らない人が仕様書作るんだから、PC判ってる方々が作ったインストーラと仕様が一致するはずがない。
日本のソフト上流工程の方は「途中で電源断」とか異常に拘る。インストールしなおしでいいだろ?でも連中は電源再び入れたら再びインストール再開とか仕様書に書く。
電源断した時と電源再開した時のユーザが違ったらどうなるか?当然そんなの「想定外」とか言って「あとまわし」とか言って、結局「ごめんなさいこの仕様マズかったね」となる。
日本でインストーラに拘る現場で必ず通るパターンだ。ざけんな糞。
インストーラ開発したいんだったら、雇ってくれりゃすぐ作ってあげられるよ。VC++スクラッチでね。ものすごい細かい挙動まで全部制御する。明らかにPCの中身を知らない人の仕様でも、ある程度までは実現してあげられる。
でもN×T××じゃ仕事したくない。実は昔揉めたから。72時間耐久デバッグに1人で挑まされた事は忘れない。マジで忘れない。
っていうかそもそもN×T系列って開発全部止めてるはずなのに、どうしてアクセスあったんだろう?
N×T、開発復活したのかなぁ。
個人情報配慮Ver
岡○氏(IPA職員=准公務員)、Shareをつこうてハメ撮り.scrを踏む。個人情報流出。
↓
同時にAtok、SoftEther?(IPAプロジェクトによるソフト)、エロゲー、
エロ動画(児童ポルノの関西援交など含む)をダウンロードしていたことも発覚。
↓
勤務先のIPA(独立行政法人)、ありきたりの謝罪文をHPに載せる。
しかしShareでの流出なのにwinnyと書いてあったり、ファイル共有ソフトとファイル交換ソフトの区別が付いてなかったりして失笑を買う。
↓
嫁の石鹸サイト非公開に。石鹸転売に薬事法違反の疑いが浮上し話題になる。
参考:http://www.tanteifile.com/newswatch/2009/01/06_01/index.html
↓
NHKはじめ一部マスコミで「IPA職員の情報流出」報道が始まる。
↓
岡○氏の素敵な言い訳 「古い無料ソフトウエアを探すためにつこうた」
しかしどう見ても違法ファイルも落としてます。本当にありがとうございました。
↓
↓
IPA、1月6日18時より記者会見「やっぱりAtokや児童ポルノ落としてました」
岡○氏の民間時代の顧客情報が大量に流出、ファイル数16000件以上。
↓
↓
政党政治家や早稲田大学への振込リストなど、きな臭いファイルが出てくる。
個人の振込先リストも。(振込Xといういかにも怪しい名のファイル)
ソニーやマイクロソフトなど大手企業勤務者等の大量の個人情報流出!
自民党とか衆議院とか年金基金とかも。岡ちゃんマネーロンダリング疑惑。
↓
特許庁の庁内ファイルが岡ちゃんのPCから見つかる。父親のものか?
特許庁の内部資料がダダ漏れ状態。2001年(平成13年)公表済みの特許データベースが
何故か最終更新日時1999年11月の状態で発見される。インサイダー取引疑惑も。
↓
01/08(木)00時37分02秒、IPA、再度おまんちんにひっかかる。
岡ちゃんのソフトウェア不正利用の証拠発見(秀丸・VC++・Becky)。
↓
↓
めざましテレビで一瞬取り上げられる。
↓
↓
13日、196氏の分散型解析ツール、通称「ダミアン」(196氏が666レス目に登場し、しかも書き込んだ時間の下3桁が666と「オーメン」の呪いの番号と一緒だった為に住人により名前が付けられた。)のうp待ち最中にキンタマウィルスのURLが貼られた。
↓
同日、突如現れたUSAがパスを解読(パスがかかっていたファイルは全て同一パスワード。IPA職員だとは到底思えない)。
これで全部のファイルは解かれた。あとはν速住人のつたない解析能力のみが頼りになる。
↓
同じ金をだすなら1つ2つ上のスペックのデスクトップとかミドルタワーとか、もしくは2つ買ってしまうとか出来る。ディスプレイもいらないし。
別に高いスペックは要らないのでノートでも5万くらいのでいいのです。
サーバならGUIなんてお飾りだし、無駄に容量食うし、わざわざお金出してXP homeにする意味がわからない。ミドルタワーに2003の方がまだわかる。
2003serverでもいいんだけど、それがセットで売ってないんです。
バラで買うと高いし。
ミドルタワーとか寝てる横で稼動させたくないのです。たぶんうるさくて眠れない気がする。
gccでもいいような気もするけど、サーバ管理用にGUIとか書きたくなったときに困るかなと。
家にVC++があるってのもあるし、慣れてるから。
つか、取っ掛かりはLAMP的なレン鯖が安いし楽だと思う。
レンタルサーバーってexeとか動かせるもの?
しかし、将来的に茨の道になりそうな気がするんだよな。
それはそうかもとは思う。2年先とか3年先にはいろいろ問題発生するかもだけれども。
一つは、なんでノートなの?と思う。
あまってるノートを自分用サーバってのはわかる。静かだし消費電力少ないし。
しかし、新規に買うとなると、何を言っても高い。同じ金をだすなら1つ2つ上のスペックのデスクトップとかミドルタワーとか、もしくは2つ買ってしまうとか出来る。ディスプレイもいらないし。
サーバならGUIなんてお飾りだし、無駄に容量食うし、わざわざお金出してXP homeにする意味がわからない。ミドルタワーに2003の方がまだわかる。あと、VC++は外せないのかな?LAMP的にPHPのかわりにGCCじゃ駄目なのかな。つか、取っ掛かりはLAMP的なレン鯖が安いし楽だと思う。WinでVC++でやりたいなら仕方ないけど。
しかし、将来的に茨の道になりそうな気がするんだよな。
とかとか気になる。
逆に、ここ数年MS万歳な環境でやってます、とか、前はそんなんでした、なんていう個人の方とか、いたりしませんかね。LAMPの話は良く聞くけど、MSなのは商業しか聞かない。
VC++2005使ってます。
構造体内に構造体を持たせて、その構造体が親の構造体を継承するコードを書いたんだけど
template<typename T> struct foo{ typedef T type; template<typename T_> struct bar : foo<T_>{}; }; int main(){ foo<int>; { foo<int>::type a; } // 変数を定義すれば良いのかよ!? foo<int>::type; // error C2059: 構文エラー : '空の宣言' foo<int>::bar<short>; { foo<int>::bar<short>::type a; } foo<int>::bar<short>::type; // error C2059: 構文エラー : '空の宣言' // error C2039: 'bar<long>' : 'foo<T>::bar<T_>' のメンバではありません。 foo<int>::bar<short>::bar<long>; return 0; }
何故か先の二例では空の宣言というコンパイルエラーで蹴られるし、最後の例に至っては継承を使って本来の目的である“入れ子構造体を必要であれば事実上無限に定義する”をしようとしているのに、これがまるでできないかの如くエラー。
どういうことなんだよおおおおお 後、前は増田にcppコード書くと何故か文字化けしたんだけど、今は直ってる!中の人ありがとう!GJ!
http://anond.hatelabo.jp/20070711013155 こちらの宿題を作ってみました。
http://anond.hatelabo.jp/20070711080519 で参加を宣言した者です。
#include "stdafx.h" #include <time.h> #include <conio.h> #include <list> using namespace std; enum MMError { MME_None = 0, MME_SizeError, MME_MemoryAllocError, MME_NotInitialized, }; enum MMKind { MMK_None = 0, MMK_Space, // 通路 MMK_Filled, // 埋まってるところ。掘れる。 MMK_Wall, // 壁。掘れないところ。 }; // // 迷路実体管理用クラス定義 // class CMazeMatrix { public: CMazeMatrix(); virtual ~CMazeMatrix(); public: virtual bool Initialize(int nXSize, int nYSize); // 初期化すると同時に、外壁まで作ってしまう。 virtual MMKind GetAt(int nXPos, int nYPos); virtual bool SetAt(int nXPos, int nYPos, MMKind kind); MMError GetLastError() {return m_lastError;} protected: inline int calcIndex(int nXPos, int nYPos) {return nYPos * m_nXSize + nXPos;} bool finalize(); protected: MMKind *m_pMaze; int m_nXSize; int m_nYSize; MMError m_lastError; }; // // 実体管理用クラス実体 // CMazeMatrix::CMazeMatrix() { m_pMaze = NULL; m_nXSize = 0; m_nYSize = 0; m_lastError = MME_None; } CMazeMatrix::~CMazeMatrix() { finalize(); } bool CMazeMatrix::Initialize(int nXSize, int nYSize) { finalize(); int nSize = nXSize * nYSize; if ((__int64)nSize != (__int64)nXSize * (__int64)nYSize) { m_lastError = MME_SizeError; return false; } m_pMaze = new MMKind[nSize]; if (m_pMaze == NULL) { m_lastError = MME_MemoryAllocError; return false; } m_nXSize = nXSize; m_nYSize = nYSize; int nCnt; for (nCnt = 0; nCnt < nSize; nCnt++) m_pMaze[nCnt] = MMK_Filled; for (nCnt = 0; nCnt < m_nXSize; nCnt++) { m_pMaze[calcIndex(nCnt, 0)] = MMK_Wall; m_pMaze[calcIndex(nCnt, m_nYSize - 1)] = MMK_Wall; } for (nCnt = 0; nCnt < m_nYSize; nCnt++) { m_pMaze[calcIndex(0, nCnt)] = MMK_Wall; m_pMaze[calcIndex(m_nXSize - 1, nCnt)] = MMK_Wall; } return true; } MMKind CMazeMatrix::GetAt(int nXPos, int nYPos) { #ifdef _DEBUG if (nXPos < 0 || nXPos >= m_nXSize || nYPos < 0 || nYPos >= m_nYSize) { m_lastError = MME_SizeError; return MMK_None; } #endif return m_pMaze[calcIndex(nXPos, nYPos)]; } bool CMazeMatrix::SetAt(int nXPos, int nYPos, MMKind kind) { #ifdef _DEBUG if (nXPos < 0 || nXPos >= m_nXSize || nYPos < 0 || nYPos >= m_nYSize) { m_lastError = MME_SizeError; return false; } #endif m_pMaze[calcIndex(nXPos, nYPos)] = kind; return true; } bool CMazeMatrix::finalize() { if (m_pMaze != NULL) { delete [] m_pMaze; m_pMaze = NULL; } return true; } // // 迷路作成用クラス定義 // class CMazeMaker { public: CMazeMaker(); virtual ~CMazeMaker(); public: bool Initialize(int nXSize, int nYSize); // 力業。ループで回す。メモリは食わない。 // 美しくない。 bool Generate1(); // 掘った箇所をスタックに積んで、掘れなくなったらスタックを戻す。 // 綺麗だけれど、迷路のサイズを増やすとスタックオーバーフローが起こる。 bool Generate2(); // Generate2をlistに置き換えたもの。 // stdを使ってしまったのが心残り。 bool Generate3(); MMError GetLastError() {return m_lastError;} protected: bool finalize(); bool checkPos(int nXPos, int nYPos, int nXAdd, int nYAdd); int process(int nXPos, int nYPos); void dig(int nXPos, int nYPos); bool makeStartGoal(); virtual CMazeMatrix* matrixAllocate(); protected: int m_nXSize; int m_nYSize; CMazeMatrix *m_pMatrix; MMError m_lastError; }; CMazeMaker::CMazeMaker() { m_nXSize = 0; m_nYSize = 0; m_pMatrix = NULL; m_lastError = MME_None; } CMazeMaker::~CMazeMaker() { finalize(); } bool CMazeMaker::Initialize(int nXSize, int nYSize) { finalize(); m_pMatrix = matrixAllocate(); if (m_pMatrix == NULL) { m_lastError = MME_MemoryAllocError; return false; } if (m_pMatrix->Initialize(nXSize, nYSize) == false) { m_lastError = m_pMatrix->GetLastError(); return false; } m_nXSize = nXSize; m_nYSize = nYSize; return true; } CMazeMatrix* CMazeMaker::matrixAllocate() { return new CMazeMatrix; } bool CMazeMaker::finalize() { if (m_pMatrix != NULL) { delete m_pMatrix; m_pMatrix = NULL; } return true; } // スタート位置と、ゴールの位置を作成。外壁部分に穴を開ける。 // 今回のアルゴリズムでは、外壁のすぐ内側が通路になっていないことがあるので // その場合には箇所を移動させる。 // どこをとっても通路が見あたらない場合には、エラーとする。 // (乱数の発生具合がとても意地悪な場合を考えると、可能性は少なくとも0ではない。) // bool CMazeMaker::makeStartGoal() { // スタート地点を左の壁の上の方に int nCnt = 0; for (nCnt = 1; nCnt < m_nYSize - 1; nCnt++) { if (m_pMatrix->GetAt(1, nCnt) == MMK_Space) { m_pMatrix->SetAt(0, nCnt, MMK_Space); break; } } if (nCnt == m_nXSize - 1) { return false; } // ゴール地点を右の壁の下の方に for (nCnt = m_nYSize; nCnt > 0; nCnt--) { if (m_pMatrix->GetAt(m_nXSize - 2, nCnt) == MMK_Space) { m_pMatrix->SetAt(m_nXSize - 1, nCnt, MMK_Space); break; } } if (nCnt == 0) { return false; } return true; } // 現在位置nXPos, nYPosからみて、nXAdd、nYAddを足した位置に移動できるかをチェック // 移動先が埋まっている状態で、さらに三方が通路以外に覆われているなら、OKとする bool CMazeMaker::checkPos(int nXPos, int nYPos, int nXAdd, int nYAdd) { if (m_pMatrix->GetAt(nXPos + nXAdd, nYPos + nYAdd) != MMK_Filled) return false; if (nXAdd == 0) { if (m_pMatrix->GetAt(nXPos - 1, nYPos + nYAdd * 2) != MMK_Space && m_pMatrix->GetAt(nXPos , nYPos + nYAdd * 2) != MMK_Space && m_pMatrix->GetAt(nXPos + 1, nYPos + nYAdd * 2) != MMK_Space && m_pMatrix->GetAt(nXPos - 1, nYPos + nYAdd ) != MMK_Space && m_pMatrix->GetAt(nXPos + 1, nYPos + nYAdd ) != MMK_Space) { return true; } } else { if (m_pMatrix->GetAt(nXPos + nXAdd * 2, nYPos - 1) != MMK_Space && m_pMatrix->GetAt(nXPos + nXAdd * 2, nYPos ) != MMK_Space && m_pMatrix->GetAt(nXPos + nXAdd * 2, nYPos + 1) != MMK_Space && m_pMatrix->GetAt(nXPos + nXAdd , nYPos - 1) != MMK_Space && m_pMatrix->GetAt(nXPos + nXAdd , nYPos + 1) != MMK_Space) { return true; } } return false; } static const int moveInfo[4][2] = { {-1, 0}, {0, -1}, {1, 0}, {0, 1}, }; int CMazeMaker::process(int nXPos, int nYPos) { int digCount=0; int aryMove[4] = {0}; if (m_pMatrix->GetAt(nXPos, nYPos) != MMK_Space) { return 0; } while (1) { int nMoveCount = 0; for (int nCnt = 0; nCnt < 4; nCnt++) { if (checkPos(nXPos, nYPos, moveInfo[nCnt][0], moveInfo[nCnt][1]) == true) { aryMove[nMoveCount] = nCnt; nMoveCount++; } } if (nMoveCount == 0) { break; } int nMove = ((rand() >> 1) % nMoveCount); nXPos = nXPos + moveInfo[aryMove[nMove]][0]; nYPos = nYPos + moveInfo[aryMove[nMove]][1]; m_pMatrix->SetAt(nXPos, nYPos, MMK_Space); digCount++; } return digCount; } bool CMazeMaker::Generate1() { // 開始点は1, 1から。(ループの先頭 m_pMatrix->SetAt(1, 1, MMK_Space); ::srand((unsigned int)time(NULL)); int nXCnt; int nYCnt; for (nXCnt = 1; nXCnt < m_nXSize - 1; nXCnt++) { for (nYCnt = 1; nYCnt < m_nYSize - 1; nYCnt++) { while (process(nXCnt, nYCnt) != 0) {} } } return makeStartGoal(); } void CMazeMaker::dig(int nXPos, int nYPos) { m_pMatrix->SetAt(nXPos, nYPos, MMK_Space); int aryMove[4] = {0}; while (1) { int nMoveCount = 0; for (int nCnt = 0; nCnt < 4; nCnt++) { if (checkPos(nXPos, nYPos, moveInfo[nCnt][0], moveInfo[nCnt][1]) == true) { aryMove[nMoveCount] = nCnt; nMoveCount++; } } if (nMoveCount == 0) { break; } int nMove = ((rand() >> 1) % nMoveCount); dig(nXPos + moveInfo[aryMove[nMove]][0], nYPos + moveInfo[aryMove[nMove]][1]); } } bool CMazeMaker::Generate2() { ::srand((unsigned int)time(NULL)); int nXStart = ((rand() >> 1) % (m_nXSize - 2)) + 1; int nYStart = ((rand() >> 1) % (m_nYSize - 2)) + 1; dig(nXStart, nYStart); return makeStartGoal(); } struct PosInfo { int xPos; int yPos; }; bool CMazeMaker::Generate3() { ::srand((unsigned int)time(NULL)); int nXStart = ((rand() >> 1) % (m_nXSize - 2)) + 1; int nYStart = ((rand() >> 1) % (m_nYSize - 2)) + 1; m_pMatrix->SetAt(nXStart, nYStart, MMK_Space); list<PosInfo> posList; PosInfo info = {nXStart, nYStart}; posList.push_back(info); while (posList.size() != 0) { int nXPos = (posList.rbegin())->xPos; int nYPos = (posList.rbegin())->yPos; int aryMove[4] = {0}; int nMoveCount = 0; for (int nCnt = 0; nCnt < 4; nCnt++) { if (checkPos(nXPos, nYPos, moveInfo[nCnt][0], moveInfo[nCnt][1]) == true) { aryMove[nMoveCount] = nCnt; nMoveCount++; } } if (nMoveCount == 0) { posList.pop_back(); continue; } int nMove = ((rand() >> 1) % nMoveCount); info.xPos = nXPos + moveInfo[aryMove[nMove]][0]; info.yPos = nYPos + moveInfo[aryMove[nMove]][1]; m_pMatrix->SetAt(info.xPos, info.yPos, MMK_Space); posList.push_back(info); } return makeStartGoal(); } // // コンソール出力用 class CMazeMakerConsole : public CMazeMaker { public: CMazeMakerConsole(){}; virtual ~CMazeMakerConsole(){}; public: void Output(); }; void CMazeMakerConsole::Output() { for (int nYCnt = 0; nYCnt < m_nYSize; nYCnt++) { for (int nXCnt = 0; nXCnt < m_nXSize; nXCnt++) { if (m_pMatrix->GetAt(nXCnt, nYCnt) == MMK_Space) { printf("."); } else { printf("#"); } } puts(""); } _getch(); } // // int _tmain(int argc, _TCHAR* argv[]) { CMazeMakerConsole maker; do { if (false == maker.Initialize(75, 50)) { puts("Initialize Error"); return 0; } } while (false == maker.Generate3()); //失敗するのは、スタート、ゴールが作れなかった場合。偶然そういうことになることもあるので、そうなったら作り直す。 maker.Output(); return 0; }
最初に昔の記憶を頼りにCMazeMaker::Generate1()を作ったけれど、美しくなかったのでGenerate2()を作成。迷路のサイズを増やすとスタックオーバーフローになるので、Generate3()を作成。一応、満足。
########################################################################### .....##...#.#.##.....##......#....#...#.#.#.........#.##.........##.#.....# #.#.##..#.#......###..###.##.#.##.#.###...#.#####.#....##.######....##.##.# #.#..##.#.#.##.###.##.....##...#....#...#.....##..#.##.#..##...####..#..#.# #.##..###.#..#..##..###.#..###.#.####.###.#####..####..#.##..#....##.##.#.# #..##.....##.##..##...#.##..#######...#.#.#...#.##....##.#..###.#..#.##.### #.####.#####.###.###.##..####.......###.###.#.###..##.#..#.##...##.#..#...# #....###......#..#.#....##....########..##..#..#..#####.######.##..##.##.## #.##..##.######.##...####..#####....#..##..###.#.##.##..#......#..###..#..# #..##.#...##....#..#.#..#.##.#...#.##.##..##.....#.....####.####.##.##.##.# ##..#...#..#.#######...##....#.#####..#..#########.##.##.#..##...##..#....# ###.########.##...##########.#...##..##.##.##...####..#....##..###..#####.# #.#..##...##..#.#.....##.....##.##..##..#...###.#.#..###.####.##...##.....# #.##.#..#..##.#.#####.#..#####..#..##..##.#.....#...##.#.#....####.#..##### #..#.#.###.#..#.....#...##.....##.##..##..##.##.#.###....####.#.#..#.###..# #.##.#.##....######.########.###..#..###.##..#....#.##.#...#..#...##...##.# #..#.#..###.##.#....#..#.....##..###..#...#.#######....#.#.#.##.#.####.##.# ##.#.##.##...#.#.#####...#####..##.##.##.##......#####.###.#.#..#..#.#..#.# ##....#..###...#....#..#.....#.##...#.#...#.#.##.....#..##.#...###...##...# #..#####...########.####.##.##....#...#######..#####.####..#####.########.# #.##.#.###..#.....#....###...###########...###..##...#....##.........##...# #..#....###...#.#.####..#..#.....#.#.....#..#..##..###.#.##..#######.#..### ##.####...#######...###.##.#.###.#...######.####..##...#.#..##...#...#.##.# #....####...#...###...#..#.#..####.#....#.....#..##..#.###.##..#.#.###.#..# ####...#..#.#.#..####.##.####......####.#####.##..#.##...#..####.#.#...#.## ##.###.#.##.#.##.#.#...#....##.######.#.##..#.###.######.##...#..#...###..# #..##..#.####.##.#...#.####..#........#..##....##...##....###...######...## #.##..##..##..#..##.####..##.#.######.##..####..#.#..##.###.#.#..#.##..#..# #.##.####.#..##.##..##...###.###...#...##.##.##.####.#..#...####.#..#.###.# #.#...#...#.###..##..#.#...#..#..#...#..#..#.##..##..#.##.#..##..##.#...### #...#...#.#...##..##...#.####.####.#######.#..##.#..##..#.##..##..#...#...# #.###########.###..#####....#...##.#..#....##..#...####.#..##..##.#######.# #....#....##..#.##....###.#####..#...##.######.#####.##.##.###....#.....#.# ###.##.#.##..##..####..#..#...##.###.##......#...##.....##..########.##.#.# #.#.#..#..#.####.#..##...##.#.#..#....######.#.#....#.#..##.#...##...#....# #...#.###...#......####.##..#...###.###...##.#.######.#.##..#.#..##.####.## #.#.#.#.#####.###.##....#..######.#.##..#..#.#..#.....#..##...##.#...#....# #.###.#...##...#..#..####.##.#.##.#.#..##.##.##.#.###.##..######.#.#.####.# #..##.#.#..#.#.####.###.#..#......#...#####..#..#...####.##..#.#.###.##...# ##..#...##.#.#.#........##.#.#.#.####..#....#######..##...##...#..#...###.# ###.######.#.#...####.#..#.#.###.#..##.#.####....###..###..##.###.###...#.# #...#...#..#####...##.####.#..#....##..#..#...##...##...##......#..####.#.# #.###.#...##...#####..##...##.#.##.#..###.#.######..##.###########.#....#.# #..#..##.##..#.#...#.##..######..###.##.#....###.##.##...#.......#.#.#.#### #.##.###..#.##...#.###..##....##........#.##..#...#..#.#.#.###.#.#.###....# #..#...##.#..#####..##.####.#.##.############...#.##.#.#.#...#.###..##.##.# ##.###..###.##...##.#..#....#..###....##....#######..#.###.###...##..###..# #...###..#...##.###.#.##.#####...#.##.#..##.#...#...##..#...###.####.#...## #.#...##...#......#......#.....#...#....##....#...#..##...#...#........#... ###########################################################################
ちなみに http://anond.hatelabo.jp/20070711194709 これを聞いたのは自分。
かなりたくさん書けることがわかりました。