はてなキーワード: PROTOTYPEとは
この間、増田でプレイしたゲームを晒してたのを見て面白かったから自分のも晒してみる。
おすすめがあったら教えてくれ。
↓
Rocket League
Sid Meier's Civilization V
RimWorld
METAL GEAR SOLID V: THE PHANTOM PAIN
Heat Signature
7 Days to Die
Assassin's Creed IV Black Flag
Sniper Elite 4
Reassembly
METAL GEAR SOLID V: GROUND ZEROES
The Witcher 3: Wild Hunt
Kerbal Space Program
Watch_Dogs 2
Tom Clancy's Ghost Recon® Wildlands
Tom Clancy's Splinter Cell Blacklist
Dungeon Warfare
Far Cry 4
Graveyard Keeper
Starbound
INSIDE
Stardew Valley
Project Zomboid
Papers, Please
BioShock Infinite
Universe Sandbox
Portal 2
Avorion
Starbound - Unstable
Superflight
DARK SOULS™ II
How to Survive
Quantum Break
Undertale
GRIS
Age of Empires® III: Complete Collection
Gunpoint
片道勇者
Garry's Mod
The Talos Principle
Return of the Obra Dinn
Rebel Galaxy
Game Builder
Valiant Hearts: The Great War™ / Soldats Inconnus : Mémoires de la Grande Guerre™
DiRT Rally
Invisible, Inc.
UNDEFEATED
Sins of a Solar Empire: Rebellion
Wallpaper Engine
The Witness
Age of Empires II (2013)
The Flood
VRChat
Grow Home
Age of Empires II (2013): The Forgotten
Assassin's Creed III Remastered
Audio Party Pack (オーディオ・パーティパック)
BioShock 2
BioShock 2 Remastered
BioShock Remastered
Borderlands 2: Headhunter 1: Bloody Harvest
Borderlands 2: Headhunter 2: Wattle Gobbler
Borderlands 2: Headhunter 3: Mercenary Day
Borderlands 2: Headhunter 4: Wedding Day Massacre
Borderlands 2: Headhunter 5: Son of Crawmerax
Borderlands: The Pre-Sequel
BROKE PROTOCOL: Online City RPG
Cities: Skylines - After Dark
Cities: Skylines - Green Cities
Cities: Skylines - Mass Transit
Civilization V - Scrambled Continents Map Pack
Crusader Kings II
Crusader Kings II: African Portraits
Crusader Kings II: South Indian Portraits 5 Year Anniversary Gift
Cuisine Royale
Dead Rising 3 DLC1
Dead Rising 3 DLC2
Dead Rising 3 DLC3
Dead Rising 3 DLC4
Door Kickers
Evolvation
For Honor
Fortified
Hacknet
Insurgency
Killing Floor Mod: Defence Alliance 2
Murderous Pursuits
PAYDAY 2
Pinball FX3
Prismata
Regions Of Ruin
Satellite Reign
Sid Meier's Civilization III: Complete
Sid Meier's Civilization V: Brave New World
Starpoint Gemini 2
Stellaris: Original Game Soundtrack
Streamline
The Escapists 2 - Dungeons and Duct Tape
The Flame in the Flood
The LEGO® NINJAGO® Movie Video Game
The Talos Principle - Bonus Content
The Talos Principle - Prototype
The Talos Principle - Soundtrack
The Talos Principle: Road To Gehenna
The Witcher 2: Assassins of Kings Enhanced Edition
The Witcher: Enhanced Edition
Viscera Cleanup Detail: Shadow Warrior
Yume Nikki
ZACH-LIKE
もっと良い書き方があったらご指摘ください
const ngWords = [ /安倍/, /低能|低脳/, /麻生太郎はすごいあほだ/ ] ;
if(document.location.href.startsWith("https://anond.hatelabo.jp")) {
sections = document.getElementsByClassName('section');
Array.prototype.slice.call(sections).forEach(function(section, i, all) {
contain = Array.prototype.slice.call(section.children).filter(function(child, j, all) {
return ngWords.filter((ngWord) => {
if(ngWord.test(child.innerText)) {
return true;
}
if(contain){ section.style.display = 'none'; }
});
}
if(document.location.href.startsWith("https://anond.hatelabo.jp")) {
sections = document.getElementsByClassName('section');
Array.prototype.slice.call(sections).forEach(function(section, i, all) {
contain = Array.prototype.slice.call(section.children).filter(function(p, j, all) {
return true;
} else if(/低能|低脳/.test(p.innerHTML)) {
return true;
}
if(contain){ section.style.display = 'none'; }
});
}
下記をscript.user.jsなど適当な名前で保存し、Chrome機能拡張に突っ込んでおく
Vanilla JSで書いてみたが、書き慣れていないのでエレガントではないかもしれない
if(document.location.href.startsWith("https://anond.hatelabo.jp")) {
sections = document.getElementsByClassName('section');
Array.prototype.slice.call(sections).forEach(function(section, i, all) {
ps = section.getElementsByTagName('p');
contain = Array.prototype.slice.call(ps).filter(function(p, j, all) {
return true;
} else if(/低能|低脳/.test(p.innerHTML)) {
return true;
}
if(contain){ section.style.display = 'none'; }
});
}
元増田です。
SPAは、クライアントが自立した1プログラムとして状態を管理する。サーバはUIと同様の非同期なイベント発生源/イベント発行先の一つとして扱う。またReactとReduxの組は、データベースサーバとサーバサイドページ生成のスタイルを、サーバとブラウザでやるようにシフトさせたものともみなせるだろう。
手間がかかりません?さらにもともとほぼサーバー側だけで済んでいたものを分けることでCSRFやSQLiなどの変なバグを仕込む可能性だってありますよね。これに見合うメリットが見えないのですがいかがでしょうか。
そしてReact自体には、JSX構文もbabelもいらない。JSXタグを書くよりむしろReact.DOM.div({...},...)等で書いたほうがプログラミングでは扱いやすい。JSXはサーバサイドページ生成のテンプレート言語利用文化に寄せた表現に過ぎないといえる。そして今ではbabelで変換する対象もES6 modulesのexport/importだけだ。これも分割ファイル対応のためにwebpackあたりを使うなら、ついでにbabelでES6 modulesも、といった程度のこと。
というかですね、そもそもVをロジックの中にベタ書きしちゃうの嫌なんですよね。シンタックスハイライトとかインデントも効かないじゃないですか。そういう点ではAngularJSが一番気持ちいいですが。。
まあそれはそれとして、なるほど、JSXは別にどうでもいい、というのはわかりました。まぁそれならわからんでもないです。
すでに一般に忘れられつつあるprototype, Dojo, Mooと同格であるjQueryのほうが五年後も活発にメンテされるのかどうか怪しいだろう。もちろん、レガシーなものとしては残り続けるだろうが。
ここわかんないですね。活発なメンテがそんなに重要なのかな?ということです。まあモダンな感じで書きたいということは理解できますが、それさえクリアされていればいいんじゃないでしょうか。そうでもないですか?
まずReactの特徴は、「状態データから変換してビューを生成する」スタイルに統一されることにある。
これはjQueryをはじめとするDOM操作モデルでの、「初期状態ビューの作成」と「(イベントに伴う)状態変化からの部分ビュー変更」で構成するスタイルから脱却され、たとえば部分処理の積み重ねから想定外の状態が生まれることを防ぐ。
SPAは、クライアントが自立した1プログラムとして状態を管理する。サーバはUIと同様の非同期なイベント発生源/イベント発行先の一つとして扱う。またReactとReduxの組は、データベースサーバとサーバサイドページ生成のスタイルを、サーバとブラウザでやるようにシフトさせたものともみなせるだろう。
そしてReact自体には、JSX構文もbabelもいらない。JSXタグを書くよりむしろReact.DOM.div({...},...)等で書いたほうがプログラミングでは扱いやすい。JSXはサーバサイドページ生成のテンプレート言語利用文化に寄せた表現に過ぎないといえる。そして今ではbabelで変換する対象もES6 modulesのexport/importだけだ。これも分割ファイル対応のためにwebpackあたりを使うなら、ついでにbabelでES6 modulesも、といった程度のこと。
すでに一般に忘れられつつあるprototype, Dojo, Mooと同格であるjQueryのほうが五年後も活発にメンテされるのかどうか怪しいだろう。もちろん、レガシーなものとしては残り続けるだろうが。
Reactのモデルは関数型プログラミングのモデルそのものであって、そういう観点ではすでに何年も続いたものであり、React自体は消えたとしてもその手法は長く続くことになる。
Array.prototype.forEach = function(f){ for(var i = 0; i < this.length; i++) f(this[i], i); };
じゃ駄目なのか。
AngularJSをお勧めする記事と、AngularJSの駄目さを指摘する記事を読んだ。
http://albatrosary.hateblo.jp/entry/2014/10/06/073638
http://mizchi.hatenablog.com/entry/2014/10/06/162103
http://diary.hatenablog.jp/entry/2014/10/06/165007
読んでる中で何点か「どういう意味だろう?」ってわからない箇所があったので誰か私に手斧を投げて教えて下さい。(わからないから「なるほど」とも「それは違うだろ」とも思えない)
これって代わりに何すればよい?
ここは「ふむ」って思ったんだけどたとえばじゃあどうすればよかっただろうか?ってののイメージができない。できれば具体例が欲しい。
一番良くわからなかったのがこのあたり。これって優先度を表に出せってことなのかな? ただその後の文読むとそもそも優先度って仕組み自体がアチョーって感じな気もする。
あ、まず前提として、
はたして貴女を幸福にするかどうか、それはまた別問題だけれど。
IT系の超かしこい男なども多く、
多くっつーかIT系でないのにプログラミング大好き男っていうのは超かしこい学生(まぁこれは有望株)か研究者系なんか、
あとはまったくかしこくもないクセに頭いいつもりして「Lispやってます(キリッ ハローワールドくらいですが」とか言っちゃうアホしかいないわけで、
したがって、釣り師たる女たちにとっては、
なかなかあなどれない釣り場です。
では、プログラミング大好き男に「どの言語が好き?」と訊ねられたとき、
まず最初に、その男がCOBOLのようなタイプのレガシーコードと
あとはC/C++、そして(TechEdに参加するほどではないけれど)VisualBasicが大好きな、
貴女はかれの目を見て、微笑みとともに質問など無視して、こう言いましょう、
「わたしが、仕様書を作ってあげる♪」
これこそまさに必殺の答えです。
そこでプログラミング大好き男が、えへへ、とやにさがったならば、
貴女は、ひそかに、「コピペ量産しやすい技術的ポイントを抑えた仕様書」あたりを
ひそかに練習しておきましょう。これで成功まちがいなしです。
しかし、ここでは、もう少しハイブロウな(?)いわゆるプログラミング好きの男の
落とし方をお伝えしましょう。
「わたしは、JVM上のScalaが好き。
型推論もあるしラムダ式やクロージャもスクリプト言語みたいに書けるの、豊富な組み込みのコレクションメソッドはいつも便利だし、
XMLリテラルもCaseクラスによるパターンマッチもTraitベースのMixi-inも、大好き♪」
もしも貴女がそう答えたならば、
かれの貴女への恋心は、
20%増量になるでしょう。
なぜって、Scalaは、
コンパイルは遅いながらも、そこがまた
ちょっぴりメモリを多く積めばいい富豪プログラミングみたいなふんいきをかもしだしていて。
質高くふるまっていて、なおかつ、
JVM上で動くくせにJavaが「やるやる」と言ったまま実装してなかったラムダ式と仮想拡張メソッド、型推論を実装した功績もあって。
したがってScalaこそは、
本来なんの接点もないまったく縁もゆかりもない別々の世界に生きている、
インタプリタ言語大好きな綺麗系OLと、玉もあれば石も混じっている、そんなプログラミング大好き男たちが、
この世界で唯一(いいえ、JVM系列のJRuby、Clojure と並んで唯三)遭遇しうる場所です。
●
では、参考までに、危険な回答を挙げておきましょう。
プログラミング大好き男に「どの言語が好き?」と訊ねられたとき、
「MicrosoftのVisual Basic for Applicationが好き♪ 週3回は Excelでコーディングするの。」
特にOfficeは平凡ながら、ま、無難にまとめてあるものの、
しかし、「新UIのリボンUI!」「メトロUI対応!」とかなんとか無意味な自慢を吹聴し、
VBAはさらにプログラミングについての謬見を撒き散らした罪がありますから、プログラミング大好き男にとっては天敵なんです。
ティーガー戦車乗りのオットー・カリウスは「ティーガー乗りなら誰でも片側の履帯がはずれ僚車に牽引されて帰ってきた経験を持つはずだ」 って言ったけど
社内SEかSIerなら誰でもクソみたいな前任者が書いたクソみたいなExcel-VBAコードを直した経験があるはずなんです。
また、もしも貴女が「PHPが大好き♪ あたしが書いたPHPのWebサイトが、さくらサーバに7件あるよ♪」
と答えたとしても、同様の効果をもたらすでしょう、
なぜって、PHPは、1990年代にはWeb系を目指す人にとっては簡単で要件を満たすWebサイトが簡単に作れる輝きの道だったものの、
しかし2000年代そうそうから、セキュリティ関係の問題で転落し、
いまや、あの貧弱な言語能力では、Rubyの魅力に遥かに及びません。
(注1)
「わたし、.NET FrameworkのC#が好き、フォームアプリでも書くけど、
最高に好きなのはASP.net♪ SQLServer連携も、ajax control toolkitもすっごくおいしいの。」
と、答えたとしたらどうでしょう?
なるほど、貴女の趣味は高く、
たしかに.NET Frameworkは、C# が cool であるのみならず、
.NET Framework上で動く F# や IronPythonやIronRuby、マネージJScriptも最高においしいんですけれど、
しかし、貴女の答えを聞いて、プログラミング大好き男はきっとおもうでしょう、
(なんだよ、MS信者な女だな、カネかかりそう)って。
(注2)
貴女が、プログラミングが大好きで、言語の名を挙げるにしても、
たとえば、JavaScript(node.js)ならば安心でしょう、
なぜならば、JavaScriptは、かけだしのプログラミング初心者にもマニアにもともに愛されるめずらしい言語で、
貴女がその名前を挙げても必ずしも、(jQueryがやっとの初心者と思われることはあっても)あなたがプログラミング言語おた宣言をしているとは受け取られないでしょう。
むしろ「へぇ。ちゃんとprototypeは使ってる?」と聞かれたら「当たり前じゃない。むしろnode.jsでいいMVCフレームワークが分からないんだけど…」と話を振ってみましょう。
男は嬉々として、30個くらいのnode.jsのフレームワークを教えてくれることでしょう。(まぁどれもどれで帯に短し襷に長しなんですが)
あるいはRighno上で動かしたコードをnodeへ移植する話とか、CoffeeScript、甚だしきはClojureScriptを振ってみてもいいかもしれません。
しかし、たとえば、世界が(つーか竹内先生とポール・グレアムが)誇る超絶関数型言語の名作、Common Lispにせよ、
selfと書きまくることと海外で使われてることに定評のあるPythonにせよ、
バージョンアップごとに言語仕様が変わり、かなり素敵なものではあるもののobsolatedな罠にはまりやすいRubyにせよ、
まったく読めない$_だらけで頭悪い仕様をリセットしてPerl6にする(そしてまた全く読めない)Perlにせよ、
気さくなクジラ飛行机さんがふるまう素敵においしい日本語プログラミング言語のひまわり・なでしこにせよ、
基地外トリッキー言語の代表BrainFxck・Glass・Missa・WhiteSpaceにせよ、
ましてや貴女が、「Haskellが大好き♪ わたし、プロジェクト・オイラーの問題もうほとんどHaskellで、解いちゃった♪」
と答えたならば、どうでしょう?
これはかなり博打な答え方で、
なるほど、Haskellは、純粋関数型でありつつも副作用のある操作が行える超絶名言語ゆえ、
あなたがそう答えた瞬間、プログラミング大好き男がいきなり超笑顔になって、
「へぇ、やっぱりHaskellなら大抵の問題は4行以内くらいで解いちゃった?」とか言いながら
鼻の下がだら~んと伸びちゃう可能性もあるにはありますが、
しかし、逆に、(なんだよ、この女、プログラミングおたくかよ)とおもわれて、どん引きされる可能性もまた大です、
なぜって、必ずしもプログラミング大好き男がプログラミング大好き女を好きになるとは、限らないですから。
男たちは、女を導き高みへ引き上げてあげることが大好きゆえ、
もしも貴女が、「Haskellが大好き♪」なんて言ってしまうと、
そこにはもはや、男が貴女に圏論のモナドを教育する余地がまったく残されていません、
したがって貴女のその答えは、
プログラミング大好き男の貴女への夢を潰してしまうことに他なりません。
ま、ざっとそんな感じです、貴女の目にはプログラマーたちはバカでスケベで鈍感に見えるでしょうが、
しかし、ああ見せて、プログラマーはプログラマーで繊細で、おざなりに扱われると傷つきやすく、ローカル変数の名前一つにも気を使い、女と自分の将来に夢を持っています、
貴女の答え方ひとつで、プログラマーの貴女への夢は大きくふくらみもすれば、
一瞬で、しぼんでしまいもするでしょう。
●
では、スキットを繰り返しましょう。
「わたしは、JVM上のScalaが好き。
型推論もあるしラムダ式やクロージャもスクリプト言語みたいに書けるの、豊富な組み込みのコレクションメソッドはいつも便利だし、
XMLリテラルもCaseクラスによるパターンマッチもTraitベースのMixi-inも、大好き♪」
そして、その瞬間、プログラミング大好き男の目がらんらんと輝いたなら、
貴女はこう重ねましょう、
「それからね、いま、わたしが使ってみたいWebアーキテクチャは、
Play Framework、素敵なリアルタイム嗜好のアーキテクチャって噂を聞いたから。
あなたのお暇なときがあったら、わたしをPlayへ連れてって♪」
これでもう完璧です。
PlayFrameworkと、Play(遊ぶ・じゃれる)のダブルミーニングでかれの股間も刺激しちゃえます。
そうなったらこっちのもの、
デートの日には、ペアプロ用に Happy Hacking Keyboard をばっちり決めて、かわいい下着をつけて(注3)、
github.comの通販で売ってるoctcatのTシャツか、facebookの「いいね!」ボタンがムネのところにあるTシャツ、 あるいは初音ミク(ないし彼のお気に入りのアニメキャラ。北米ならMyLittlePonyで鉄板なんだけど)のコスプレを着てゆきましょう。
その日から、プログラミング大好き男は貴女の虜になるでしょう。
注1:
(と、書いたもののPHPの現状をよく知りません。グローバル変数だらけになるのとか旧ASPみたいなもんなのかなぁ。count($array); とか書くのアホと思うがpythonも同じだった)
(あと、マジで単機能とかTwitter連携とか診断メーカー的なのでもPHPで7つも作ってる女子居たら付き合いたい)
注2:
もっとも。objective-Cなんていう言語をやることに比べれば個人で行う程度なら金のかからない手法もなくはないのですが。
注3:
プログラマーにとっての「かわいい下着」と、女性にとっての「かわいい下着」の定義にずれがあるので注意。
半数くらいのプログラマーはしましまぱんつが可愛いと思ってる気がするので、妙齢の女性が着用するには抵抗あると思うが、ボーダー柄のコットンショーツ(ただしキャラ絵のは除く)とか、
過度でないていどにフリルがついたものがオススメ。また、色は、レッドだとプログラミング大好き男は引いてしまう(だってそれはコンパイルエラーのときの色だ)ので、薄ピンクかホワイト、薄ブルー、せめて黒(に差し色でピンクとか)あたりに留めたい。
補記:
元ネタ: http://tabelog.com/tokyo/A1301/A130101/13002457/dtlrvwlst/3464106/
補記2:
「プログラマー」か「プログラマ」かの問題については、特に意味は無いが前者を採用した。
補記3:
言うまでも無いけど、ネタです。
いっせーの! Webにのって さあ出かけよう ブラウザとのランデブー ユーザーが大事 実装が大事 JS、マジ大好き ユーザーの痛み それ言語のせい? UIの動き UXのつもり 今までのJSのポジションを 越えた未来は どうなるの? ねぇどうせWebKitでしよ ダメ? ダメ! ECMA標準だけ 油断も隙もない APIとのボーダー越えたい そうもっと! 大胆で ちょっと強引? 俺ワールド全開 優しいJSも いじわるなJSも ひとりじめ 型つけてみて やっぱやめて ウラハラ alt-js Java以上C++未満の JS、マジ最高 V8だけが きらめいて 遠い背中も 追いかけたよ これからの最適化 フローグラフの分まで伝えたい ぎゅってしてPNaClコンパイル ダメ? ダメ! 不埒です CSS3に甘えたい GPUに触れたい どこまで? APIのボーダー教えて おっとっと! 手強い IEの仇 ムキになったら 古いシステムも Flashの将来も 譲れない 実装して やっぱやめて 一方通行プロセス W3C信じて プラグイン書いて No more E4X 動的なの? 静的なの? 型推論好き? 好き! 好きだから 笑わず答えて Ion Monkey 越えよう おっとっと! 大胆で ちょっと強引? prototypeを知ったら JSでの設計や コーディングも変わるの? 答えてよ! ときめき 走り出す わくわくコーディング Self以上 Scheme未満の JS、超愛してる!!
このお話はたぶんフィクションです。実在の個人や企業とはあんまり関係ありません。そういうことにしろください。
10年前、20代になったばかりの頃の僕は、今思えば本当に最低な生活を送っていた。高校を中退し、実家とは疎遠で、友達もなく、金もなく、夢も希望もなく、ただバイト先と自宅を行き来するだけの毎日。いつも視界には霞がかかったようで、底の見えない空虚さだけが僕の心を支配していた。
それでも趣味らしいものはあった。オンボロマシンにRedHatを入れ、ダイヤルアップの細い回線で自宅サーバを立て、Perlでガラクタのようなプログラムを動かす。そんな子供じみた遊びだけど、プログラムを組んでいるときだけは空虚さを忘れ、画面の中に没頭できた。
ただ、そのときの僕はもうすでにいろんなものに打ちのめされていて、若者にありがちな全能感などというものは霧散していた。自分がプログラミングで何かを成すだとか、それを仕事にしようなんてことは一切頭になかった。このまま夢も希望もなく人生を終えるのだと、そう思っていた。
それでも転機は訪れる。
勤めていた工場で派遣切りにあった僕は、「働きたくないでござる! 絶対に働きたくないでござる!」とか言いながらニート生活をしていた。そろそろ翌月の家賃も払えなくなってきたころ、派遣会社から電話がかかってきた。「プログラム開発の仕事があるんですがやりませんか?」と。そういや履歴書だかスキルシートだかに、Perlがどうたらとか書いたっけ。実務経験もない中卒に仕事まわすとかwww ……とは思ったものの、このままでは本気でホームレス一直線だったので引き受けた。
派遣された先は従業員数10人くらい、パートさん含めても50人くらいの小さな会社だった。現在手書きの伝票でやっている処理をWeb化したいのだという。システム担当者はおらず、事務員さんがExcelやAccessを使える程度。すべて僕一人でやらなければならない。マジか。
ともあれ、まずはサーバである。後々の運用を考えるとLinux系は使えない。事務所の片隅に放置されていたWindows 2000マシンにApacheを入れてそれでよしとした。
次はデータベース。でもこの頃の僕は「正規化ってなんれすか?」というレベルだったので基礎から勉強した。なんかMySQLってのがいいらしい→社長に申請→「今Access使ってるからそれでいけ」→「はい」→パフォーマンスの面で問題出るだろうなとは思ったがしょうがない。
次は言語。最初はPerlで書こうと思ってたけど、PHPってのが流行ってるらしいのでこっちにした。ウホッ! いい言語……。
そして業務内容を把握するため、現場をあっちこっち駆けずり回りながらヒアリングする。ときには部長から愚痴を聞かされ、ときにはパートのおばちゃんから誘惑され、そんなこんなを繰り返し、仕様をつめていく。
そして数ヶ月かけて開発したシステムの稼働である。そのときのことは今でも忘れない。
現場の人がラインからデータを入力する。サーバにデータが送られてくる。別の事業所からも送信されてきてる。問題ない。事務員さんが伝票処理を行う。問題ない。すげえ、ちゃんと動いてる。お遊びで作ったプログラムではなく、本当に本気の業務用プログラムである。それを僕が1人で作ったのだ。このプログラムで業務がまわり、利益を生み出すのだ。社会に対して、何らかの作用を及ぼすのだ。僕みたいなクズにでも、そんなことが可能だったのだ。
そのことに気付いたときの感動を、僕は今でも忘れない。
それからちょっといろいろあって、ホームレスになった。うん、急展開なのはわかってる。でもこの間のことは語ってもあまり面白くないし、公序良俗に反する話もあるのでざっくりはしょる。どうせフィションなんだから細かいことを気にしてはいけない。
話を戻そう。
ホームレスになってからの数日はひどい精神状態だった。足元から世界が崩れていく感覚。視界がぐにゃりと歪む。帰りたい。でも帰る家がない。だからホームレスというのか……というトートロジーを何度繰り返しただろうか。
もうあまり覚えていないけど、このときの僕は本当にもう何もかもどうでもよくなってたと思う。ただ、自分の全財産がバッグ1つしかないということに対する心地よさ、開放感があったのはよく覚えてる。そんな状況で地べたに座り込んで見る風景。きっと、今はもう見えない。あの頃の僕にしか見えない風景が、そこにはあった。
いろんな人と出会い、流れ流れて、最終的に西成のあいりん地区にたどり着いた。関西圏の人には説明不要かもしれないけど、よく言えば日雇い労働者の街、ぶっちゃけて言えばホームレスのメッカである。今はもう綺麗になってしまったし、治安もそこそこよくなったけど、僕がいた頃はまさに「カオス」としか表現のしようがない状況だった。
どこから持ってきたんだといいたくなるようなガラクタばかりを並べた泥棒市。簡素な骨組みにビニールシートをかぶせただけの飲み屋。「ないかーないかー」と声が聞こえてきたので見てみると、警察署の近くなのに道端で堂々と丁半博打をやっている。コンビニのトイレの張り紙には「トイレが詰まる原因になるので注射器を捨てないでください」とある。いやトイレが詰まるとかの前に気にすることがあるだろ。ケンカなんて日常茶飯事。頭から血を流したおっさんが普通に歩いてる。数百人規模で並ぶ三角公園の炊き出しは圧巻。四角公園の炊き出しでは誰もいない場所にワンカップの瓶とかがたくさん並んでる。何かと思って聞いてみたら「あれで並んどることになってん」と返ってくる。学食の席取りルールみたいだ。ああもう全然書ききれない。
でも一番印象に残っているのは、南海線の高架下、うず高く積まれたゴミ山の前でガラクタを解体していたおっちゃんのこと。奇声を発しながらハンマーを振り下ろしていたおっちゃん。その両目は、これ以上ないほどにキラキラと輝いていた。その鉄屑を売った金でビールが何本買えるか皮算用でもしているのか、あるいは幸せになる魔法の薬でもキメているのか、そのときの僕にはわからなかったけど。
そして、人生を投げ出していた僕に付き合ってくれたおっちゃん、あなたのことも忘れません。モーニングをおごってくれて、いろんな話をしてくれて、聞いてくれて、役所の福祉課まで連れて行ってくれたおっちゃん。あなたがいなければ、僕は今でも西成でぬるま湯の日々を送っていたかもしれない。
いろんな人に助けられて、ホームレスの施設に入ることになった。舞洲という人工島にあるのだけど、これがまた周囲に何もないのだ。スポーツ関連施設、ゴミ処理場、物流センターが点在するくらい。コンビニ1件ありゃしない。だけど施設での生活は意外にも楽しかった。2段ベッドが6つ並んだ12人部屋。むさくるしいけど、みんなバラエティに富んでいた。刑務所上がりのいかついおっちゃん、虚言癖のひどいおっちゃん、ほとんど一日中寝てるじいちゃん、薬のフラッシュバックがひどい兄ちゃん。そんな人達の中で過ごせば、自分がどれほどクズであっても気にならない。やはり僕はこちら側の人間だと再認識した。
市街地にある施設へ移ってからはいろんな仕事をした。生駒の山奥にドブさらいに行ったり、事務所移転のバイトで腰をやってしまいそうになったり、なんやかんやあったけど、長くなるのではしょろう。結局のところ、またプログラマをすることになるのである。
そろそろ身バレしそうな領域に入ってきたのでここでもう一度強調する。このお話はたぶんフィクションです! たぶんフィクションです! 大事なことなので2回言いました。
そう、またプログラマとして働くことになった。今度は従業員数300人くらいの大きな会社である。日本人なら誰でも知ってるであろう大企業の子会社ということもあり、本社からの出向社員は東大京大卒当たり前みたいな状況。そんな人達の前で中卒の僕が前に座ってプレゼンやら仕様検討会やらをするのだ。何の罰ゲームだよ……。
最初に思ったのは、「ここにいる人達は育ちがいい」ということだった。みんな礼儀正しい。喋り方や立ち居振る舞いまで、今まで僕がいた世界とは何もかもが違っていた。まるでドラマに出てくるような「ちゃんとした人生を送っている人達」だ。そんな人達に囲まれていると、「生きていてごめんなさい」と言いたくなる。本当に。
他に驚いたこと。社内で連絡を取り合うのにメール使ってる。やばい。社内メーリングリストとかもある。やばい。定期的にミーティングとか勉強会とかもする。なにそれ怖い。自分がいっぱしの社会人になったかのような錯覚に陥る。ちょっと前まで西成でゴミ拾いのバイトしてたのに。「勘違いするんじゃない! 西成の日々を思い出せ!」と何度も自分に言い聞かせ、自我を保った。
とはいえ、萎縮してばかりもいられない。気付いたことはどんどん提案した。あちこちに散らばっている共通の処理をライブラリ化したり、サーバで負荷がかかっている部分を改善したり。却下されたものも多かったけど、採用されたものもそれなりにあった。業務の改善案を考えるのは楽しい。誰かがプログラマの三大美徳に「無精」を上げていたっけ。極度のめんどくさがりで、楽をするための苦労は惜しまない僕には、こういう仕事は天職なのかもしれない。
システム開発の方も順調に進んでいた。この頃はMicrosoftですらWeb版のOfficeを出すような状況で、デスクトップアプリに比べても遜色ないレベルのWebアプリがどんどん出てきていた。この会社で開発しているのも、そんなAjax技術を多用したWebアプリだ。JavaScriptを用いた本格的な開発に最初はとまどったけど、書けば書くほど言語が自分の手に馴染んだ。クロージャ、prototypeといった基礎をちゃんと学ぶと、書けるコードのレベルが段違いに上がっていくのが楽しかった。
仕様にもこだわった。実際に使う人がどんなふうに操作するのか、何度も何度も脳内でシミュレートし、どんなUIが最適なのか、データ構造はどうするべきか考え、実行速度とメンテナンス性の板挟みに苦しみ、何度も何度もリファクタリングを繰り返す。
そのとき開発していたシステムは、メイン画面でほとんどの処理を行うタイプのものだったのだけど、そのメイン画面のJavaScriptコードは最終的に1万行を超えた。もうこの頃にはJavaScriptでのオブジェクト指向的な開発手法というものも自分なりに構築されつつあった。そしてこのカチャカチャとした手触りの、安物のオモチャのような言語は、僕の一番好きな言語になったのだった。
そんなある日、僕が作ったシステムのメインユーザーである他部署の偉い人が来て、開口一番こう言った。
この機能が素晴らしい、とか、あの発想はなかったわ、とか、とにかくべた褒めして、そして去っていった。機能追加要望の前口上だと思って身構えていた僕は拍子抜けした。「あの人が他人を褒めることなんてめったにないよ、すごいね」と近くの席の人が言う。
どこにもはまることのない歪な歯車。その僕が、社会という大きな機械の中に組み込まれる音だったのだと思う。まあすぐに外れてしまうのだけど。その一瞬だけは、僕は確かに社会の一部になれたのだ。
これからどうするか? 今の技術力ならそれなりのところに就職できるかもしれない。でも僕にはやってみたいことがあった。半年かけて海外を旅するのだ。
今、僕の手元にはまとまったお金がある。こんなのは人生で初めてのことだ。そして僕は今、どこにも所属していない。どんなところに行ったっていいし、何をしたっていい。この先、そんな状況がどれだけあるだろうか? 人生長いのだ、そりゃあ何度だってあるかもしれない。でも今回やりたいことをやらなかったのなら、僕はきっと何度だってやらずにいるままだろう。
もちろん怖くなかったわけじゃない。なにせ海外なんて行ったことがなかったのだ。ずっと極貧の生活をしてきた僕は、国内旅行だって満足にしたことがない。
いろいろと考えた。ない頭を使って考えた。自分の英語は通じる? 病気になったときは? 荷物をなくしたら? あれこれ考えると心配事ばかりが頭をめぐって、わけがわからなくなる。
最終的に決定打になったのは、自分が何も持っていないという、この状況だった。
そう、僕は何も持っていない。家族も友達も、夢も希望も。だけど、そんな人間だからこそできることがあるんじゃないかと思ったのだ。何も持たないからこそ、どこにだって行けるし、何にだってなれる。それはタロットカードの「愚者」みたいなものだ。愚かな者は恐れも何も知らぬからこそ、無限の可能性を秘めている。
心を決めたら後は早かった。
パスポートを取得した。航空券を手配した。住民票を海外転出した。トランクルームを借りた。住んでいた部屋を引き払った。
空港へ向かう電車の中で、懐かしい感覚に襲われた。あの日、ホームレスになったばかりのころの感覚。世界が足元から崩れていく感覚。でもあのときとは決定的に違うことがあった。それは、今回は自分が望んでこうなったのだということ。流されるまま生きてきた僕が、初めて自分の人生に対して主導権を得た。それだけが決定的に違っていた。それだけで十分だった。足の震えは、これからの旅路への、期待に対する震えなのだった。
自分とは異なる人種、異なる言語。街の看板すらまともに読めない。レストランの注文すらおぼつかない。ちょっと電車に乗るのも大仕事だ。それでも時間をかけてひとつひとつなんとかしていった。
見知らぬ街の匂い、喧騒、バケツをひっくり返したようなスコール、旅の中で出会う怪しい人、優しい人。僕の前でたくさんの風景が流れていく。
川辺のレストランで昼ご飯を食べた後ボケーッとしていると、猫が膝の上に乗ってくる。動くのもめんどくさくてボケーッとしてたら日が暮れてた。そのまま猫と一緒に晩ご飯を食べた。そんな日もあった。
長距離列車に乗っていたとき、車内食にピーナッツバターのようなものが付いていたので、普通にパンに塗って食べた。でも梅干的なものだったらしく、めちゃくちゃ酸っぱかった。「すっぱ! すっぱ!」とかやってたら向かいの席の女の子が爆笑していた。僕も笑った。そんな日もあった。
最初は少し移動するのにも大変な思いをした。でもいつの間にか、ローカルバスに乗って気ままに旅するようになっていた。
たどたどしかった英語も、日常会話程度なら普通に喋れるようになっていた。
いろんな国のバックパッカーにもたくさん出会った。お互いつたない英語でやりとりするのも楽しかった。今度は彼らの国にも行ってみよう。だからいつか世界一周に出ようと、僕は心に決めた。
こんな旅に出たところで自分は何一つ変わらないと思ってた。でも、何かが変わってきている。それが何なのかはわからない。たとえば図太さだったり、適当さだったり、そういうのもあるのだけど、何か違う。それよりもっとプリミティブなもの。感情になる前の感情、行動になる前の行動。マグマのような熱量を持ったドロドロとしたものが、自分の中に渦巻いているのを感じる。それがいつ形を成すのかはわからない、今はまだ。だけどいつかどこかで、忘れた頃にひょっこり出てくるんじゃないかと思う。そのときを楽しみにしていよう。
そして夢のような日々は終わる。
日本に帰ってきたとき、手持ちの金は10万以下だった。部屋は解約していたので住むところもなかった。普通にホームレスだった。僕は焦らず慌てず、西成へ向かった。
しばらくはドヤ(安宿)に泊まった。一番安いところなら500円から泊まれる。西成はいいところだ。
前の会社から戻ってこないかと誘われたけど、「働きたくないでござる! 絶対に働きたくないでござる!」と言って断った。
いや働きたくなかったのは本当だけど、もう1つ理由があった。職業訓練で組み込み系を学ぼうと思っていたのだ。
スマートフォン含むタブレット端末の市場がこれからも拡大していくのは間違いない。そうすると必要になってくるのは組み込み系の知識。いやアプリ作るだけなら必要ないかもしれないが、そういった知識があれば、自分ができることの幅がぐんと広がると思う。
それに、今の僕には基礎的な力が圧倒的に足りない。すべてを独学で、我流でやってきたけど、やはり限界を感じる場面が多々あった。だから今回ちゃんと体系的に学んで、足元を固めようと思ったのだ。
結果的には正解だったと思う。本当に基礎の基礎から学べた。
ブレッドボードを用いて回路を組むところから始まって、アセンブラ、C言語、組み込みLinuxでのデバイスドライバ開発、アプリ開発。これまで高級言語の十分に進化しきった部分にしか触れてこなかった僕にとっては、どれも難しかったけど、どれも面白かった。これからどういう道に進むかまだわからないけど、ここで学んだことは絶対に無駄にならないと思う。
そうして職訓で勉強するかたわら、悶々と考えていたことがある。世界一周についてだ。
今はまだ金もないし、そんな金を稼げるあてもないのだけど、いつか(たぶん10年後くらいには)行こうと本気で思っている。
ルートだけでも今から考えておこうと思って、いろいろと旅程検討アプリを試してみたのだけど、どれもいまいち使い勝手が悪い。海外のものも含めて探しまくったけど、自分が思うようなものは見つからなかった。
だったらもう自分で作るしかない。せっかくだから就活のときにポートフォリオとして使えるよう、ちゃんとしたWebアプリを作ることにした。
最初の1ヶ月は地図APIの選定と、検証コードを書き捨てるだけで終わった。
2ヶ月目は基礎部分の構築だけで終わった。
3ヶ月目に本気を出し、ほぼできあがった。
そしてベータ版をリリースした。 http://planetter.com/
それが先週の話。
だからこのお話はここで終わりだ。正確に言うなら、ここから先の展開はまだわからない。
10年間を振り返ってみて思う。あの頃と比べて、何か変わっただろうか?
家族や親類とは縁が切れたままだし、いまだに人付き合いは苦手だし、金はないし、夢も希望もない。それは今でも変わらない。ただ、あの頃あれほど感じていた空虚さは、跡形もなく消えている。
西成の高架下で見た光景を思い出す。ガラクタを解体していたおっちゃん。あのキラキラした目。たぶんあの瞬間に僕は、自分にとって一番大切なものは何なのか、心の深い部分で理解したんだと思う。
世界一周だなんだというのも本当はどうでもいい。僕はただ、いつだってドキドキしていたいのだ。
初めて人を好きになったときの気持ち。知らない街で暮らし始めたときの気持ち。そして、プログラムが思い通りに動いたときの気持ち。
それを持ち続けていたいのだ。いつだって新しい世界にワクワクしていたいのだ。
ふと目を閉じれば、まぶたの裏に映る、あの日のメッセージ。
"Hello world!"
このお話はたぶんフィクションです。実在の個人や企業とはあんまり関係ありません。でも、ここに綴った僕の想いは、ノンフィクションです。
Fooのプロトタイプ | Foo.prototypeのプロトタイプ | |
---|---|---|
class Foo | Function.prototype | Object.prototype |
class Foo extends Class | Class | Class.prototype |
class Foo extends NullOrObject | Function.prototype | NullOrObject |
writable | configurable | enumerable | |
---|---|---|---|
Foo.prototype | ☓ | ☓ | ☓ |
Foo.constructor | ○ | ○ | ☓ |
Foo.prototype.* | ○ | ○ | ☓ |
JavaScript って生き物っぽいって思ったのがきっかけだった。
なんか菌?に遺伝子いれてたんぱく質を生産させるやつ? Function は菌の細胞膜で prototype は遺伝子で、だから prototype に全然関係ない違う生物の遺伝子を生きてる菌に入れちゃったり。そうすると全然ちがうたんぱく質が生産されたり。prototype にべべーっとコピーして追加するのなんてまさしくそれっぽい。
だってプロトタイプベースって、生き物しかいない世界じゃない?基本的に。インスタンスってのは生き物じゃない設計図があってそれにしたがって出来た生き物がインスタンスってイメージあんだけど。プロトタイプベースの世界にはそんな設計図も生き物じゃないものもないよね?なのにわざわざインスタンスっていうのに何か違和感?ご都合主義的なもの感じる。クラスは型で、インスタンスを実体だとかなんとかって氾濫してるせいかな。多分この辺の用語が JavaScript をわかりにくくさせてる気がする。
僕の感覚では、オブジェクトってのは生き物で、クラスベースってのは神が設計図に基づいて生き物を生産してる世界で、インスタンスベースってのは生き物が生き物を複製してる世界のイメージだ。多分、原始の生物はインスタンスベースみたいな世界で、海の中にうようよしてたんだろうな、とか。
オブジェクトじゃないものは、生き物じゃない死んでるたんぱく質や RNA の破片みたいな。それだけじゃなにもできないみたいな。それだけじゃ命がないから、生き物の殻に詰めるってのが JavaScript のコンストラクタのイメージ。
Perl の bless したらこれはもう命入ったよ生き物だからねっあとは勝手にしてねってのも、Python の名前空間さえあればなんとかなるよねってのも、JavaScript のハッシュさえあれば世界作れるよねってのも、みんなどこか似ている。ちゃんと OOP を理解できてるかは別としてもこの三つはわりとすぐやりたいことができた。昔 Java の本を買ってきて挫折したのにくらべたら、なぜかずっとわかりやすかった。(bless という命名はすごく洒落てる)
全然関係ないけど、Django の日本語リファレンスは何か萌える。ラクダ本の日本語訳はむかつくのに。
プログラミングを始めたばっかりの時は、なんだか難しい用語の意味を理解しないと OOP がわからないと思ってた。それは僕らの住んでる世界とは全然関係のないプログラミングの技術ってやつだと思ってた。
でも多分違う。
世界が動く仕組みさえあれば、あとは作り手に世界の成り立ちを抽象化する表現力さえあれば、世界は勝手に表現されていくし、動き出してく。たまたま僕らの世界はオブジェクトなもので溢れていて、プログラミング言語が進化すれば世界に似るのも当然だろう。いや逆か。プログラミング言語が世界に似てきたから、オブジェクトなんていう世界に似た概念が出てきたってことか。なんだか難しい用語ってのは、その表現の一部分の技術に名前をつけてるだけなんだな、と。例えば何とか歌唱法や何々画法とか何とかレトリックとかパースの取り方みたいなのと同じ。それは表現を理解する手助けにはなるけど、その意味を知る事がイコール表現力をあげることにはならないんだよね。これに気づくのに遠回りしすぎたなあ。
(知識を得るだけで、100% 還元される人もいるかもしれないけど、そんなのは一部の天才だけだと思う。殆どの凡人はそうはいかない。とはいえ、元の錬度が低ければ、コツをいくつか教わるだけでいきなりうまくいくこともある。ただ、それをまるまんま実力だと思うのは、どんな分野でも危険だ。恋愛テクニックやらを必死に読んでる連中が男女間の深い人間関係を上手くやれてるとはちょっと想像できない!)
プログラミングで表現力を上げるにはどうすればいいんだろう。きっと他と同じだろうな。いい表現を沢山味わって、世界をよく観察して、どう成り立ってるかどう動いてるか、私達はそれをどう認知しているのか、考えることかもしれない。漫画家を志す人が美術解剖学を学んだり、優れた画家が絵筆で世界を生々しく描写するように、優れたプログラマは世界のなりたちをプログラムに写し取ったり、世界の仕組みを作る事が出来るのだと思う。
http://anond.hatelabo.jp/20110316202255
亀仙流やつ鶴仙流など、世の中にはいくつかの流派があり、それぞれ カメハメ波やドドン波、舞空術などの技(メソッド)がある。 実際に技を使う場合、技を覚えているZ戦士(インスタンス)が必要。
クラス = 流派
メソッド = 技
インスタンス = Z 戦士
というのはおもしろいと思うし, 例えばゲームを作るなら実際にそういう実装になると思う.
例)セルを作りましょう。 class Cell extends Goku,Veget,Picoro,Tenshinhan,Kuririn{ .... } cell_inst = new Cell(); cell_inst.shotKienzan(); //Kuririnをextendsしているので気円斬が使えます。
しかし, ここではクラス = Z 戦士になってしまっているので, 混乱を招くだろう.
むしろ, 「JavaScript における prototype」 に絞って説明するのはどうだろう.
(ついでに「撃つ」の現在形は shot でなく shoot ですね)
var Goku = function () {}; Goku.prototype.shootKamehameha = function () { console.log("波!!!"); }; var goku = new Goku; goku.shootKamehameha(); // 波!!! var Gohan = function () {}; Gohan.prototype = new Goku; var gohan = new Gohan; gohan.shootKamehameha(); // 波!!!
そしてセルによる吸収は, 動的な継承として考えるのがより自然だろう.
var Goku = function () {}; Goku.prototype.shootKamehameha = function () { console.log("波!!!"); }; var Vegeta = function () {}; Vegeta.prototype.shootBigBangAttack = function () { console.log("ビッグバンアタック!!!"); }; var Cell = function () {}; // 吸収メソッド Cell.prototype.absorb = function (target) { for (var method in target) { this[method] = target[method]; } }; var goku = new Goku; var vegeta = new Vegeta; var cell = new Cell; cell.absorb(goku); // 悟空を吸収 cell.absorb(vegeta); // ベジータを吸収 cell.shootKamehameha(); // 波!!! cell.shootBigBangAttack(); // ビッッグバンアタック!!!
そして次にクロージャの使用例として挙げられた次の例.
例)連続エネルギー波 var shotRenzokuEnergy = function( count ){ var shotEnergy = function(){ //エネルギー波を放ちます }; for(var i=0;i<count;i++){ shotEnergy(); } };
この実装では, shotRenzokuEnergy を実行するたびに shotEnergy が毎回定義されてしまい, 非効率である.
以下のように書き換えることで, shootEnergy の定義は, shootRenzokuEnergy の定義時の 1 回のみとなる.
var shootRenzokuEnergy = (function () { var shootEnergy = function () { console.log("エネルギー波!!!"); }; return function (count) { for (var i = 0; i < count; i++) { shootEnergy(); } }; })(); shootRenzokuEnergy(10); // エネルギー波!!! x 10
メンバメソッドとは違うもの。JavaScript では
Public なメンバメソッド → prototype チェインなどで付加した関数
となっている。
わざわざ外に出して関数化するほどのことでもないよな、とか
この関数からしか呼ばないのに、並列に関数を置きたくないな、とか思うことがあるでしょう。
JavaScript ならこんな思いに見事に答えてくれます。
たとえば個人情報が云々なので文字列のマスク処理を作ろうとしましょう。
String.prototype.mask = function() { var maskedText = ""; for(var ix = 0; ix < this.length; ix++){ maskedText += mask1(this.substring(ix, 1)); } return maskedText; function mask1(character) { var maskedCharacter = ""; swith(chr) { case 数字: 処理A, 個別処理 case 英字: 処理B, 個別処理 case 全数字: 処理A, 個別処理 case 全英字: 処理B, 個別処理 case ひらがな: 処理C, 個別処理 case カタカナ: 処理C, 個別処理 case 漢字: 処理D, 個別処理 default: 未処理 } return maskedCharacter; } };
こういうメソッドを作った時、処理A、処理B、処理Cは冗長な処理になっているわけです。
個別処理があるのでbreakしなければいいや、というわけでもありません。
しかしこの処理A,B,Cはこの関数外に置くような処理でもないわけです。
この関数内でしか使いませんし、むしろ使って欲しくないわけです。
function mask1(character) { var maskedCharacter = ""; swith(chr) { case 数字: shoriA(), 個別処理 case 英字: shoriB(), 個別処理 case 全数字: shoriA(), 個別処理 case 全英字: shoriB(), 個別処理 case ひらがな: shoriC(), 個別処理 case カタカナ: shoriC(), 個別処理 case 漢字: 処理D, 個別処理 default: 未処理 } return maskedCharacter; function shoriA() { 処理A } function shoriB() { 処理B } function shoriC() { 処理C } }
こう書けるのです。
JavaScript で一番好きなのはこの内部関数です。
少し遅れた感があるけど、解いてみた。
出力がテキストでないけど・・・。
仕事の合間を使ってやったものの、昼前に始めたのが5時頃にようやくできる程度。
これを25分とは尋常じゃないな、大口叩くだけあってよっぽど優秀なんだろう。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <meta http-equiv="Content-Language" content="ja"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta http-equiv="Content-Style-Type" content="text/css"> <style type="text/css"> <!-- pre { font-family: monospace; } --> </style> <script type="text/javascript"> <!-- window.onload = function() { var q = new Map(); q.load("maptest.txt"); q.search(); var answer = document.getElementsByTagName("pre").item(0); var answerText = "\r\n"; for(var ix = 0; ix < q.route.length; ix++) { answerText += q.route[ix].join("") + "\r\n"; } answer.firstChild.data = answerText; alert("終了しました。"); }; /** マップオブジェクト */ function Map() { this.ymap = []; this.route = []; } //マップの読み込み Map.prototype.load = function(filePath) { //ファイルシステム var fileSystem = new ActiveXObject("Scripting.FileSystemObject"); //ファイル読み込み var file = fileSystem.OpenTextFile(filePath); while(!file.AtEndOfLine) { var fileBuffer = file.ReadLine(); this.ymap.push(fileBuffer.split("")); } file.Close(); fileSystem = null; }; //マップの探索 Map.prototype.search = function() { var that = this; //マップコピー var ymap = this.ymap.concat(); for(var y = 0; y < ymap.length; y++) { ymap[y] = ymap[y].concat(); for(var x = 0; x < ymap[y].length; x++) { if(ymap[y][x] == "S") var start = new MapNode(y, x); if(ymap[y][x] == "G") var goal = new MapNode(y, x); } } var openList = []; var closeList = []; start.costf = start.distance(goal); openList.push(start); //経路探索 while(openList.length > 0) { var node = openList.shift(); //探索終了 if(goal.equal(node)) { createRoute(node); break; } closeList.push(node); //隣接ノードの作成 var tonari = []; if( ymap[node.positionY][node.positionX - 1] == " " || ymap[node.positionY][node.positionX - 1] == "G" ) tonari.push(new MapNode(node.positionY, node.positionX - 1, node)); if( ymap[node.positionY - 1][node.positionX] == " " || ymap[node.positionY - 1][node.positionX] == "G" ) tonari.push(new MapNode(node.positionY - 1, node.positionX, node)); if( ymap[node.positionY][node.positionX + 1] == " " || ymap[node.positionY][node.positionX + 1] == "G" ) tonari.push(new MapNode(node.positionY, node.positionX + 1, node)); if( ymap[node.positionY + 1][node.positionX] == " " || ymap[node.positionY + 1][node.positionX] == "G" ) tonari.push(new MapNode(node.positionY + 1, node.positionX, node)); //隣接ノードの検索 for(var tx = 0; tx < tonari.length; tx++) { var openIn = false; var closeIn = false; tonari[tx].cost = node.cost + 1; var costf = tonari[tx].cost + tonari[tx].distance(goal); tonari[tx].costf = costf; //オープンリストから検索し入れ替える。 for(var ox = 0; ox < openList.length; ox++) { if(tonari[tx].equal(openList[ox])) { openIn = true; if(costf < openList[ox].costf) { openList.splice(ox, 1); push(openList, tonari[tx]); } break; } } //クローズリストから検索し、オープンリストへ移す。 for(var cx = 0; cx < closeList.length; cx++) { if(tonari[tx].equal(closeList[cx])) { closeIn = true; if(costf < closeList[cx].costf) { closeList.splice(cx, 1); push(openList, tonari[tx]); } break; } } //どちらにもない場合、オープンリストへ追加する。 if(!openIn &amp;&amp; !closeIn) push(openList, tonari[tx]); } } //適切な位置に追加する。 function push(array, item) { for(var ix = 0; ix < array.length; ix++) { if(item.costf < array[ix].costf) { array.splice(ix, 0, item); return; } } array.push(item); } //ルートマップの作成 function createRoute(lastNode) { var node = lastNode.parent; while(node.parent) { ymap[node.positionY][node.positionX] = "$"; node = node.parent; } that.route = ymap; } }; /** マップノード */ function MapNode(y, x, parentNode) { this.positionY = y; this.positionX = x; this.parent = parentNode; this.cost = 0; this.costf = 0; } //同一ノードかチェックする。 MapNode.prototype.equal = function(targetNode) { if( this.positionY == targetNode.positionY &amp;&amp; this.positionX == targetNode.positionX ) return true; return false; }; //直線距離を求める。 MapNode.prototype.distance = function(targetNode) { sabunY = this.positionY - targetNode.positionY; sabunX = this.positionX - targetNode.positionX; return sabunY ^ 2 + sabunX ^ 2; }; // --> </script> <title>経路探索:A*</title> </head> <body> <pre>&nbsp;</pre> </body> </html>