FatherScorpion's diary

年1更新!...できたらいいなぁ。

【HTG2万円コース/ネタバレ注意】エアガン福袋を買った結果

【H.T.G.2万円コース/ネタバレ注意】エアガン福袋を買った結果

※ネタバレ注意!※

タイトルの通り、H.T.G.さんの2023新春 HTGミリタリー福袋の結果報告となります。Bコース(2万円コース)2つ分のネタバレが含まれますのでご注意下さい。

 

何を買ったのか

前述の通り、2023新春 HTGミリタリー福袋のBコースを購入しました。

www.hercules-gear.jp

サバゲー界隈ではこの時期に各社がエアガン福袋を出すのが恒例なのですが、私にとって今回が初めてのエアガン福袋購入となります。

福袋の名の通り、何が入っているかは分かりません。今回購入したH.T.GさんのBコースには、電動長物1丁(つまり、ARとかDMRとか)が入っている事が事前に告知されています。

一緒にサバゲーをしている某氏と共に1つずつ購入したので、この記事では2つ分の結果をご紹介します。

箱のサイズは同じですね。逆に言えばそれしか分かりません。

 

何が出ると嬉しいか

福袋はガチャの様なものなので、当然当たりハズレが人によってあったりします。

私にとってのハズレは既に持っている銃がダブる事ですが、実の所、私の所持しているエアガンはハンドガン、SMG、SG、レバーアクションライフル(???)の4種類なので、事前告知が正しいとすればハズレを引く事は無いでしょう。

では当たりは何かと言われると、私と某氏は東側の銃が大好きなので、AKやVZKなんかが出てくると死ぬ程喜ぶと思います。

いざ開封の儀

それでは早速中身を確認してみましょう。ネタバレ注意です。

箱を開けると、その中にさらに別の箱が入っていました。

サバゲーマー、ベッドに物を置いて写真を撮りがち

見る人が見るとこの時点で型番を見て何が入っているか分かるらしいのですが、私にはまだ分かりません。

どうやらDOUBLE EAGLEさんのエアガンですね。DEは中国のエアガンブランドで、ここ最近は見た目・性能共に高水準の製品を作られているという噂です。つまり期待できますね!!!

DEの銃は私も某氏も持っていないので、確実にハズレではないという事が分かりました。やったぜ!!!

これは海外製エアガンあるあるですが、外箱がそのままガンケースとして使えるタイプの箱で、これも地味に嬉しいですね。収納や持ち運びに便利です。

さて、ここで残念なお知らせです。今回購入した2つの福袋は、どちらもDOUBLE EAGLEさんの同じ型番の商品でした。つまり同じ銃が被ってしまいました。残念!

ですが、これはエアガン福袋ではよくある事です。逆に言えば2つともハズレではなく、期待できる銃だったという事で、むしろ少し嬉しいまであります。

いざ運命の時

いよいよです、中身を見てみましょう...ワクワク...(以下本体の画像アリ!!!)

 

 

 

 

 

 

 

 

 

 

 

 

これは...

 

!!!!!

HONEY BADGER!!!!!

というわけで、DEのハニーバジャーを引きました!!!

ファッションセンス皆無な服



銃は100点、服装が0点 by 某氏

実の所、下調べをした際にH.T.G.の2万円コースはハニーバジャーが出やすい!という話を聞いていたので、半分予想通りではあります。

ですが、私はハニーバジャーのスポーツラインモデル(軽いプラスチックでできた、使いやすいがあまり人気のないTHE・福袋の銃)が出ると思っていました。しかし!


今回入手したハニーバジャーはメタルハンドガードロングバレル仕様でした!!!

このハニーバジャーという銃、電子トリガーという物が搭載されていて、エアガンとしての性能はかなり高いです。それに加えて見た目もカッコいいとなれば、個人的には大満足です!!!

180発装填のM4ワッフルマガジン。逆張りオタクなので地味に初めてのM4マグでした。

PDWストック。何でもストックにこんな穴を空けておけばアメリカの法律上はピストル扱いになるらしいですね。

おわりに

この記事は東京高専プロコンゼミAdventCalendar2022の12/25の記事です。

荷物が届いたのは12/24だったのですが、何やら配達のお兄さんがニコニコされていたので、子供へのクリスマスプレゼントと間違えられた説があります。成人男性2人への少し早いクリスマスプレゼントになりました。

皆さんも良き聖夜をお過ごしください。

adventar.org

サバゲーはいいぞ

はじめに

この記事は東京高専プロコンゼミ① Advent Calendar 2021の12日目です。

adventar.org

サバゲーとは?

まず最初に、皆さんはサバゲーサバイバルゲーム)という遊びをご存知でしょうか?

サバイバルゲームとは、エアガンを使って撃った撃たれたを楽しむ、大人の戦争ごっこ、あるいはリアル版FPSです。

f:id:FatherScorpion:20211212194820j:plain

中央の人物が筆者です

FPSが好きな方は大勢いらっしゃると思いますが、一度は「現実で撃ち合いをしてみたい!」と思ったことがあるのではないでしょうか?そんな夢を叶えられる遊びがサバイバルゲームです。この記事では、そんなサバゲーの魅力を手短ではありますが伝えられたらなと思います。実際にサバゲーをしてみたい!という方向けの参加ガイドではないので、実際のフィールドではどんな手続きをするのか、といった事は割愛させて頂きます。

それではサバゲーとは具体的にどんな遊びなのか、説明していこうと思います。

紳士のスポーツ、サバゲー

サバゲーFPSと同じく勝利目標の違う多種多様なルールがフィールド(サバゲーができる施設)毎に色々とありますが、それらに共通する基本的なルールをまずは説明します。

サバゲーは前述した通り主にエアガンで撃ち合いを楽しむゲームです。当然、相手を倒す、あるいは倒される手段はエアガンで弾を当てる(当てられる)事になります。

では何処に何発当てれば良いのか?ずばり、頭、腕、胴体などの部位を問わず、また、銃や服などの装備品に被弾しても、原則一発被弾で退場(ヒット)となります。

ではヒットの判定方法はどうするのでしょうか?これは自己申告となり、審判がいたり、被弾した事を知らせる装置があるわけではありません。自分がヒットしたなと感じたら、「ヒット!」等と叫ぶヒットコールをしながら、声と身振りで自分がヒットした事をアピールしつつ退場します。

このように、サバゲーは紳士のスポーツであり、ズルをしようと思えばいくらでもできてしまいます。(ヒットしたのにプレイを続行する人をゾンビ、そのような行動をゾンビ行為等と呼んだりもします。)だからこそ、しっかりとルールを守りお互いに敬意を持ってプレイする事が大切です。このような性質上、サバゲー界隈の民度はかなり高く、一度YouTube等で試合の動画を見てみて欲しいのですが、FPS等の殺伐とした雰囲気を想像しているとその温かみのある空気に驚くかもしれません。

緊張感あふれるスポーツ、サバゲー

f:id:FatherScorpion:20211212201227j:plain

小部屋に突撃をしかける筆者(中央)と仲間たち

サバゲーで使う銃はエアガンなので、撃たれたところで死ぬわけではありません。しかし、発射されるBB弾の速度と威力は中々のもので、上の画像の様なコートを着ていたとしても、「当たったな」と感じる程です(なので専用の目を隠す防具の装着が義務付けられています)。そのため、首筋などの肌が露出した部分に被弾すると中々なものがあります。この「予期しないタイミングで突然被弾する恐怖」はサバゲーならではのものだと思います。

誰が言ったかサバゲーは「倒されるのを楽しむスポーツ」、相手を倒せずとも、戦場の空気を肌で感じつつ、銃声が鳴り響く混沌の中で華々しく散るだけでも楽しい体験ができます。多くのフィールドでは復活が可能なルールを回す事が多いので、倒される事を恐れず何度でも挑戦しましょう!

自分だけの装備を楽しむ

FPSでもそうですが、自分の装備をビルドするのも楽しみの一つです。実のところ一発即死のルール上防具に意味はなく、スナイパーライフルは大抵の場合ハンドガンの下位互換となりますが、それでも憧れは止められません。

f:id:FatherScorpion:20211212203514j:plain

チェコ軍のコート、チェコスロバキアの銃にアメリカのヘルメット、アメリカの事務員の軍服を装備した筆者

(暗いですが)上の画像のような謎装備だって出来ちゃいます。勿論、何かしらの制式装備を揃えるのもカッコいいですね。

愛銃スコーピオSMG。何気にカスタム品です。

ショットガン、ちゃんと散弾が発射できます!

スコーピオンにドラムマガジンをつけた図。BB弾なのでとんでもない数の弾を装弾できます。

ものすごくつかれる。

また、この記事の主な読者であろう高専生なら自分オリジナルの装備だって作れちゃいます。

サバゲー界隈では3Dプリンター製の装備は割と実用的だったりします。

おわりに

このようにとても楽しいサバイバルゲーム、現在はコロナ禍で自粛しているフィールドも多いですが、YouTube等で動画を見てみたり、機会があれば一度体験してみて下さい!

サバゲーはいいぞ

完全食教徒のPCK参加記

はじめに

 この記事は東京高専プロコンゼミのAdventCalender②12月14日分の記事です。遅刻です(すいません...)。

adventar.org

①もあります。

adventar.org

パソコン甲子園(PCK)プログラミング部門に出場しました。

 見出しの通り、2020年度のPCKプログラミング部門(以下PCK)に出場しました。PCKとは競技プログラミングという与えられた問題を解くプログラムを素早く正確に書く能力を競うスポーツ(?)の大会です。プロコンの開発が始まる少し前に先輩から「上手く行けばタダで旅行ができる」とのお誘いを頂いたのをきっかけに出場する事になりました。

 PCKではペアを組んで課題に挑戦するのですが、相方はこの人でした。

  今年はコロナの影響もあり、例年はチームで1つのPCを使うところ、1人1つのPCを使う事が出来ました。そのため、ペアのチームワークが例年以上に重要だったのではないかなと思います。そのため、本番前に2人で色々作戦を練ったりしていました。これについては後程。

完全食はいいぞ

 ところで、皆さんは完全食という偉大なる食物をご存知ですか?完全食とは「完全栄養食」の事で、それを食べるだけで食事に必要な栄養を全て摂取する事ができる正に人類の英知の結晶とも言える食べ物です。ドリンクタイプ、グミタイプ、パンなど様々な種類があり、いずれも通常の食事に比べて遥かに短時間で食事を済ます事ができます。あのカップ麺と比べてみても、同時に調理を開始したと仮定すれば、カップ麺のフタを開けて、子袋を取り出して、粉末スープを入れて、お湯をそそいで...等とやっている間に物によってはもう食後の後片付けに入っているレベルです。しかもそれでいて、先ほど述べたように食事に必要な栄養は完全に網羅できるというのですから素晴らしいですね。いわゆるサプリメントなどの「補助栄養食品」とは格が違います。「完全栄養食」ですからね。なんなら普通の食事よりも栄養バランスが良いです。ですがやはり、食事で大切なのは栄養もそうですが味もそうですよね。完全食は別に不味いという訳ではありませんが、確かに、味という面では他の食事に劣ってしまいます。ですがご安心ください!完全食メーカーは日々味の改良に心血を注いでおり、最近では「不味くはない」から「普通においしい」と言えるほどにまでその味は改善されています!例を挙げると、COMPという日本のメーカーの完全食は、先日ドリンクタイプ用のフレーバーという物を発売しました。元々COMPのドリンクタイプの味は豆乳のような味なのですが、このフレーバーを入れると美味しいカフェラテやアップルシナモンの味に早変わりするのです!私も飲んだ事がありますが、特にカフェラテ味がおススメで、自販機で売られているそれと比べても遜色の無い美味しさです!さあ、これでもう何も躊躇う必要はありませんね?皆さんも是非完全食を一度体験してみて下さい!完全食はいいぞ!

 

 タイトルにもありますが、我がチーム「完全食はいいぞ」のメンバーは2人とも熱狂的な完全食信者です。完全食の素晴らしさを競プロ同志諸君に伝えるべくチーム一丸となって競技に挑みました。

予選

 PCKは予選と本選に分かれていて、予選で上位10チーム以内、もしくはそれ以外のチームの中で各地域ごとの上位何チームかに入ったチームが本選に進む事ができます。私達は後者の地域枠を狙っていたのですが、何せ東京地区はライバルが多いので、本選に行けるかは五分五分といった所でした。

 ちなみに本選に行くとは言いましたが、コロナの影響で予選本選共にオンライン開催となりました。当然タダ旅行も無しです。悲しいですね。

 肝心の内容ですが、PCKでは全12問の問題を競技時間以内に出来るだけ多く解く事になります。基本的には1問目が一番簡単で番号が大きい程難しくなります。当然難しい問題程得点も高いです。そこで、当初は自分が奇数番の問題を解いて相方が偶数番を...という作戦を立てていましたが、一度過去問を解いてみた所、6~7問目まではサクサク解けるが、それ以降は急激に難しくなるという事が分かりました。という事は即ち、予選は実質7~8問目以降の問題を如何に多く解くかという勝負になります。そこで相方と練った作戦が、

 高難度問を相方に丸投げし、自分はプライドを捨てて6~7問目までの問題全てを担当するというものでした。この役割分担は相方の方が競プロerとしての実力があるからなのですが、普通のチームではこうもあっさりとプライドを捨てる事はできなかったでしょう。これも全て完全食を信じる者の結束の強さがなせる技と言えるでしょうね。

 具体的な問題の内容は割愛しますが、結果的にこの作戦が大ハマリしました。その結果、我ら「完全食はいいぞ」は見事本選出場の権利を手に入れる事が出来ました。

本選

 後日学校に参加賞が贈られてきました。お菓子が美味しかったです。

~完~

AtCoder緑になりました。

久しぶりの更新です。タイトルの通り、AtCoder緑になれたので色変記事とやらを書いてみようと思います。基本的には感想多め、入茶~現在までにやってきた事を書いていこうと思います。

ABC167にて緑化

f:id:FatherScorpion:20200511021910p:plain
2020年5月10日開催のAtCoder Beginner Contest 167にて緑化しました。


目標パフォは1081.67でした。当時私は4桁パフォなど数える程しか取ったことがなかったので、上手く行けば緑化できるかなぁ~程度の気持ちで挑みました。問題の内容としては、Cがbit全探索、Dが考察実装系と得意分野が重なった事もあり、4完時点で緑パフォ4桁後半。この時点で希望が見え始めました。
ただ、この時点で予想レートは810ぐらいだったので、割と心臓バクバクでした。

それでもなんとか


無事緑化できました。
ちなみにこの回で色変した人がTLで結構多かったです。

感想

素直に嬉しいです。同時に、ここから厳しくなるぞとも感じています。

なぜ緑になれたか。

ぶっちゃけて言うと殆ど某ウイルスのせいです。

私は高専という学校に通っていて、ただでさえ高専は春休みが長い(2月中には春休みが始まる)です。その上授業開始が遅れたので、4ヶ月近くも休みがありました。とにかく時間が余っていたので、APG4bを進めたり、螺旋本を買って読んだりと、競プロにかける時間が明らかに増えました。これが緑化に繋がった事は明らかだと思います。

緑になるまでに何をしたか

自分を振り返りつつ、何が緑になるために必要なのかも考えてみています。果たして緑になりたての人が偉そうに語ってよいのでしょうか。

競プロ的思考を身に着ける

他の方もおっしゃっていましたが、緑になる為には「競プロ用の訓練」が必須だと思います。私は高専プロコンでの開発が実質初のプログラミングでしたが、自分が開発した範囲では使ったアルゴリズムは全探索だけでした。完成版は先輩方がリファクタリングをして下さったおかげでスッキリしたコードになっていると思いますが、開発中のコードは兎に角無駄が多い、極端な話、x=100-nの計算をする時にfor文でx--をn回するみたいなクソコードを書いていた気がします。

流石にそれは大袈裟と思うかもしれませんが、灰コーダーの時期は冗談抜きでこんなコードを書いてたと思います。何故ならそれで動くから。競プロerの皆さんは計算量が多いと聞くと10^18ぐらいを想像すると思いますが、当時の私は1000でも多いと感じ、それを一瞬で計算し終わるコンピューターすげーという感じでした。

競プロ的思考とは言い換えると「無駄を削ろうとする考え方」だと思っていて、「ここの処理無駄が多いな」となった時に、「別に動くしいいや」となるか、「どうにかして削ろう」となるか、あるいはそもそも無駄な事をしている事に気が付けるかだと思っています。

これはアルゴリズムを学ぶきっかけにもなったと思います。私はどうやったら無駄を削れるんだろうと考える様になってから初めて、数多のアルゴリズムに触れる様になりました。

数学(算数)は必ずしも必要ではなさそう

最初に言うと私は相対的には数弱な人間だとは思います。なので、今でも数学問題はパスか未証明偶然ACが8割近くを占めています。それでも緑にはなれたので、数学が必ずしも必要である、とは思いませんでした。勿論解けるに越したことはありませんが、どちらかと言うとアルゴリズムに重点を置いた方が良い気はします。

とはいえ、数学的な問題をアルゴリズム的観点からばかり考察してしまい、「この問題、競プロの問題じゃなくて数学の試験で出てたら解けてただろうなぁ」となった経験も度々ありました。これはかなり勿体ない気がするので、一応数学的な考察もするだけしてみる方が良いとは思います。

早解きは狙ってする物ではない

早解きは大事です。早解き出来ると出来ないではパフォーマンスに大きく差が出ますし、同じ3完なのにあいつは水パフォで俺は灰パフォ...とかになると早解きをせねば...!!!となると思います。

ただ、私は早解きは「する」物ではなく、「出来るようになる」物だと思っています。自分を例にすると、昔の私はC問題に90分フルで使うのもザラでしたが、今は安定して30分以内にはCが解けるようになってはいます。ですが、実を言うと早解きを意識しているのはむしろ昔の方で、今は「絶対にペナを出さない」という真逆のスタンスでコードを書いています。

ここで言う昔と言うのは灰~茶前半の頃なのですが、当時はCが解けず2完という事が多く、AとBを死ぬ気で早解きする事に心血を注いでいました。今考えるとこれは失敗だと思っていて、テストケースすら通らないコードを大量に投下し、毎度毎度ペナが笑えるぐらいの量になっていました。

当たり前の話ですが、急いで早解きしてペナ5分を貰うより、じっくりとテストケースを通して確実にACする方が遥かにお得です。また、そもそも早解きして上がるレートは安定せず、コンテスト開始直前には常に気が張った状態になりますし、失敗した時の喪失感はエグイ物があるので、精神衛生上宜しくないです。私はこれで一時期コンテストの日になるのが苦しくなったりもしました。

という訳で、早解きをするよりかは、CやDを解けるようになる為の勉強をする方が精神的にも楽ですし実力もつくと思っています。結果としてはこちらの方が早解きが自然と出来るようになりました。

そしてやっぱりアルゴリズム

最終的に一番大事なのはこれだと思います。考察を頑張る必要があったり、実装が重めだったりする問題は、頑張れば解けます。ですが、特定のアルゴリズムが必要な問題は、知らなければどうあがいても解けません。

...ですが、今の私が使えるアルゴリズムは、実は二分探索とbit全探索、後は再起関数での木グラフ探索ぐらいです。DPは何ですかそれはという感じですし、累積和あたりもネットで調べながらなら...といった感じです。幅優先探索深さ優先探索あたりは頭では分かりますが実装はうーん。

何でこんな感じになっているかと言うと、アルゴリズムは「必要になったら覚える」というスタイルで覚えてきたからです。一時期、F問題の解説にDPと書かれていたり、TLでDP便利、DP覚えた!というツイートが流れて来たりとDPという単語を目にする機会が多くなったことがありました。そこで当時の私はDPを覚えようと「DP アルゴリズム」で検索したり、DPで解く問題にチャレンジしたりしてみましたが...結果挫折しました。

なぜなのか、と考えた時、一番の理由は「そもそもDPで何が出来るか」を良く理解できていなかった(今でもそうですが)からだと思います。

分かりやすいように、逆にアルゴリズムを理解できた時の話をします。私が最初に覚えたアルゴリズムは二分探索なのですが、そのきっかけとなったのはこの問題です。
atcoder.jp
この問題は、色々処理をした結果、tan(x)=定数 となるxを見つければ良い事が分かります。ここで、xの取り得る範囲は0 < x < 90だと分かるので、この範囲を総当たりで探索すればxが見つかるのですが...。このx、整数だけではなく小数、さらには10^-6刻みまで取る事が分かります。なので全探索となると、0.000001~89.999999まで、つまりO(9*10^7)となり間に合いません。また、私もこの範囲であればxが90に近づけば近づくほどtan(x)は大きくなるという事は知っていました。ここで、今の状況を纏めると、

  • 総当たり以外の方法はなさそう
  • xが大きくなる程数値は大きくなる(単調増加)

という事が分かっています。色々工夫はしてみますがどうしても駄目、当時の私はここで解説PDFを見て、二分探索という文字列を見つけます。当時伸び悩んでいた私は、ここで初めてアルゴリズムを覚えてみるかという気になり、「二分探索 アルゴリズム」で検索をしました。出てきたサイトを読み進めてみると...なんと分かる、分かるのです。先ほどのDPの例と違い、解説が何を言っているのか手に取るように分かるのです。

なぜ分かるのか、それはやはり、二分探索がどのような時に使えるのかという事を理解していたからでしょう。ある巨大な数列の中から目当ての数を探すとき、その数列に単調性があれば、まずその数列のちょうど半分の数を取る。もしその数値が目当ての数よりも大きい(あるいは小さい)ならば、それよりも大きい(小さい)数はどう考えても目当ての数ではない。ならば、目当ての数はそれよりも小さい(大きい)所にあるので、取り上げた半分の数よりも大きい(小さい)全体の半分にもなる数は比べるまでも無く切り捨てられる...。そのような状況を身をもって体験した私には、二分探索という物が何を目的としていて、いかに素晴らしいのかが良く理解できたのでした。

という訳で、私は新しいアルゴリズムを、「良い所まで解けたが明確な課題が見つかり解けなかった問題」の解説に名前が登場した時に覚えるようにしていました。

例外として、APG4bに登場したアルゴリズムはその通りではありません。自分は1週間に1度程度の頻度でAPG4bを進めているのですが、そこで登場するという事は自分の身の丈に合ったアルゴリズムという事ですし、理解できない事は無いと思うからです。実際ABC167のC問題はbit全探索でしたが、bit全探索をAPG4b以外でACしたのは今回が初だったりします。覚えられるときに貪欲にアルゴリズムを覚える事は決して無駄ではないと思います。

長い!まとめろ!

  • どこかに無駄があるか、その無駄をどうやったら削れるか考えよう!
  • 数学は必須ではないが最初から諦めはせず、手札の1つとしては考えておこう!
  • 早解きを狙うよりは新しい事を覚えよう!その方が早解きはいつの間にか出来るようになっている!

以上になります。

最後に

次なる目標は水色ですが、まだ水パフォを出した事が無いので今後何かしらの努力はしないといけないなとは思います。レートの停滞期がすぐそこに迫っている事をひしひしと感じますが、今年中に水色になる事を目標に頑張ります。

本当の最後に私事ですが、新しい後輩に青コーダーがいるらしいのでいつの日か彼を超えたいです。未来の自分よ、頑張ってくれ。

ラズパイ起動時にIPアドレスを自動表示させてみる話

はじめに

この記事は東京高専プロコンゼミAdventCalendar② 14日目の記事です。

adventar.org ①もあります。

adventar.org

ラズベリーパイ初心者向けの記事になります。筆者自身も初心者ですので強い人は鼻で笑いながら見て下さい。 暫くは前座が続きますので、記事の本題だけを見たいという方は「IPアドレスゲッターを作ろう」、またはその少し前まで読み飛ばして下さい。

ラズベリーパイって楽しいね

皆さんはRaspberryPi(ラズベリーパイ/ラズパイ)をご存じでしょうか?言わずと知れた小型コンピュータですね。組み込み開発や最近はやりのIoTなんかではよく使われていると思います。最近弊校では組み込みマイスターが行われている事もあり、自分の周りでもラズパイを使っている人を良く見るようになりました。

SSH使ってる?

ところで、皆さんはラズベリーパイをどのように操作しているでしょうか。電源ケーブルを繋いで、キーボードを繋いで、マウスを繋いで、ディスプレイを繋いで...なんて事をしている方も多いかと思います。ラズパイを初めて触った時には、ほとんどの人がこんな感じの事をいちいち準備していると思います。正直、めんどくさいですよね。自分自身もこれがめんどくさくて一時期ラズパイに全く触れなくなった時期もありました。 しかし、周りの強い人達がラズパイを使っているのを見ると、ラズパイ本体に電源コードくらいは刺さっているかもしれませんが、別のノートパソコンかなんかで作業をしていたりしませんか?詳しい説明は省きますが、これはラズパイにノートパソコンからSSH接続というものを行っていて、ラズパイを遠隔操作できるようにしています。これ、実際にやってみると痛感しますがめっちゃ楽です。今まではラズパイのちっちゃい本体に無数のコードを接続して、片付けて、とやっていたのが、「はい、電源コードさしまーす。」「はいノートパソコンでソフト開きまーす。」「はい使えるようになりましたー。」で終わってしまうので作業効率が格段にアップします。片付けも電源を落とすだけですむのでとっても簡単。ぜひまだSSH接続をしてないよーという方は今からでも是非お試しください。

でも、面倒なんでしょう?

しかし、こう思う人もいると思います。「でも、そのSSH接続ってやつをやるためにまた面倒な事をしなければいけないんでしょ?」、と。確かに、「ラズベリーパイ SSH接続」で検索をしてみると、やれ環境変数だの、やれnanoだのvimだの、頭が痛くなるような単語が続きます。実際自分自身、先輩からSSH接続の事を教えて頂いた後に上記のような手段でSSH接続を試み、1カ月近く格闘した末諦めました。このように、成程普通にやればSSH接続とは何とも難しそうです。普通にやれば

そこで登場TeraTerm

TeraTermって何だよ!という話ですが、ようするにSSH接続用のソフトウェアです。使い方は簡単、ソフトを起動して、ラズパイのIPアドレスを打ち込むだけ。予めラズパイ側で少し設定しておくべきこともありますが、インストール時間を含めなければ5分もかかりません。詳しい使い方はネットで調べれば出てくるのでそちらを参照してください。設定のためにラズパイにモニターやらなんやらを繋ぐ必要はありますが、これさえ終わればようやく快適なラズパイライフを送れそうです。

ねえ待ってよ!やっぱりモニター必要だよ!

はい、もう感付いている方もいるかもしれませんが、これでもまだモニターやマウス、キーボードと無縁な生活を送る事はできません。非常に便利なTeraTermですが、こいつを使うには何が必要でしたか?そうですね、IPアドレスです。さて、TeraTermにはIPアドレスの自動補完機能があるので、最後に打ち込んだIPアドレスは覚えておく必要はありません。ですが、最後に使ったIPアドレス以外のIPアドレスを打ち込まなければならない機会もありますね?例えば、

  1. 新しいネットワークに繋いだ時。

  2. 前に繋いだことがある別のネットワークに繋いだ時。

  3. 定期的にIPアドレスが変わる現象が発生した時。

こんな時です。こんな時には、IPアドレスを知るためにやっぱりモニター等を繋ぐ必要が出てきてしまいますね。 ですが、ですがですよ。1番は仕方ないとしても、2番3番の為に面倒な事をするのは癪なわけですよ。だってラズパイは一度繋いだネットワークには起動時に自動で繋いでくれるのに、そこでわざわざ人間が手間を掛けなければならないとは納得できません。しかも1カ月に1度とかならまだしも、自分のように学校や家など一日に幾つものネットワークにラズパイを接続する身としては結局SSH接続の利点が殆ど消え去ってしまい非常に不服です。パソコン上から同一ネットワークに繋がれている機器のIPアドレスを取得するコマンドを打つという手もありますが、これも何か嫌です。メモを取れば良い?嫌です。 あーあ、こんな時にラズベリーパイのIPアドレスを起動時に自動で表示してくれる何かがあれば便利なのになぁなんて思ってしまいます。皆さんもそう思いますよね? でもそんな限られた用途の物なんてありません。一体どうすれば...。そうだ、無ければ自分で作れば良いのです!

IPアドレスゲッターを作ろう

ここからが本題です。今私の手元には7シグメントLED、つまり数字を表すのに使う全部点灯すると8になる例のアレがあります。こいつをうまく使ってラズパイ起動時にIPアドレスが表示される装置を作ろうと思います。 まずはPhythonでコードを書きます。以下にコードを書きますが、まずはどんな事をしているのかを予め書いておきます。詳細な説明はしませんのでニュアンスで理解して下さい。

① Phythonのターミナルコマンドを打った結果を取得する関数を使い、IPアドレスが含まれた文字列を取得する。

Phython以外にもあるのかもしれませんが、プログラム上でターミナルコマンドを使えるのだなと地味に感動しました。打っているコマンド自体は「ip a show wlan0」で、よくIPアドレスを確認するのに使うコマンドの範囲限定版ですね。ただ、これだけだとIPアドレス以外の文字列も含まれているので、

② 先ほど取得した文字列の中からIPアドレスを抽出する。

文字列操作でIPアドレスだけを取り出して行きます。後は単純に

③ 1秒間隔ぐらいでIPアドレスの数字を順番に表示する。

どうでもいいですが7シグメントLEDって小数点も表現できるんですよね。実はそれを知ったからこそこれを作ろうと思ったまであります。IPアドレスにも小数点(ドット)は含まれてますからね。 また、今回は見逃し防止の為にIPアドレスを2周回すと共に、これが最初だよという事を示す横棒(-)を各周の最初に2秒表示させる事にします。それと、ラズパイの起動直後にはまだインターネットに接続できていないので、10秒プログラムの最初にディレイを挟んでいます。デバッグ用にCtrl+Cで強制終了できるようにもしています。 では以下がコードです。

# -*- coding: utf-8 -*-
import subprocess
import RPi.GPIO as GPIO
import time
time.sleep(10)
cmd = subprocess.check_output(["ip", "a", "show", "wlan0"])

hoge = cmd.find("inet ")
IP = cmd[hoge+5:]
IP = IP[:IP.find("/")]
print(IP)

GPIO.setmode(GPIO.BCM)

GPIO.setup(14,GPIO.OUT)
GPIO.output(14,GPIO.HIGH)
#左下

GPIO.setup(15,GPIO.OUT)
GPIO.output(15,GPIO.HIGH)
#下

GPIO.setup(18,GPIO.OUT)
GPIO.output(18,GPIO.HIGH)
#右下

GPIO.setup(23,GPIO.OUT)
GPIO.output(23,GPIO.HIGH)
#小数点

GPIO.setup(24,GPIO.OUT)
GPIO.output(24,GPIO.HIGH)
#右上

GPIO.setup(25,GPIO.OUT)
GPIO.output(25,GPIO.HIGH)
#上

GPIO.setup(8,GPIO.OUT)
GPIO.output(8,GPIO.HIGH)
#左上

GPIO.setup(7,GPIO.OUT)
GPIO.output(7,GPIO.HIGH)
#中央

allGPIO = {14, 15, 18, 23, 24, 25, 8, 7}

try:
    for x in range(2):
        for a in allGPIO:
            GPIO.output(a,GPIO.HIGH)
        GPIO.output(7,GPIO.LOW) #最初である事を示す'-'
        time.sleep(2)

        for y in range(len(IP)):
            for b in allGPIO:
                GPIO.output(b,GPIO.HIGH)

            n = IP[y]
            print(n)
            if n == ".":
                GPIO.output(23,GPIO.LOW)
            if n == "0":
                GPIO.output(14,GPIO.LOW)
                GPIO.output(15,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(25,GPIO.LOW)
                GPIO.output(8,GPIO.LOW)
            if n == "1":
                GPIO.output(18,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
            if n == "2":
                GPIO.output(25,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
                GPIO.output(14,GPIO.LOW)
                GPIO.output(15,GPIO.LOW)
            if n == "3":
                GPIO.output(15,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(25,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
            if n == "4":
                GPIO.output(8,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
            if n == "5":
                GPIO.output(25,GPIO.LOW)
                GPIO.output(8,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
                GPIO.output(15,GPIO.LOW)
            if n == "6":
                GPIO.output(25,GPIO.LOW)
                GPIO.output(8,GPIO.LOW)
                GPIO.output(14,GPIO.LOW)
                GPIO.output(15,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
            if n == "7":
                GPIO.output(8,GPIO.LOW)
                GPIO.output(25,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
            if n == "8":
                GPIO.output(14,GPIO.LOW)
                GPIO.output(15,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(25,GPIO.LOW)
                GPIO.output(8,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
            if n == "9":
                GPIO.output(8,GPIO.LOW)
                GPIO.output(25,GPIO.LOW)
                GPIO.output(24,GPIO.LOW)
                GPIO.output(7,GPIO.LOW)
                GPIO.output(18,GPIO.LOW)
                GPIO.output(15,GPIO.LOW)
            time.sleep(1)

except KeyboardInterrupt:
        print("おしまい!")
        GPIO.cleanup()

GPIO.cleanup()

7シグメントLEDとの接続ですが、以下の様になっています。ちなみに共通アノードのやつです。なんだよそれ、という方は調べてみて下さい。多分一瞬で理解できると思います。

14 左下
15 下
18 右下
23 小数点
24 右上
25 上
8  左上
7  中央

左の番号はラズパイのピン番号で、BCM番号です。右側は位置を表しています。左下とか中央とかは何を表しているかというと、小数点を右下に置いた時に、例えば1を点ける時には右上と右下が点くようなイメージです。横棒だと中央だけですね。

さて、最後に起動時にプログラムを実行する方法ですが、全て下記のサイト様を参考にさせて頂きました。そちらを読んで頂ければ簡単に終わると思います。

qiita.com

いざ実戦。

結果は以下の動画を見て下さい。分かりやすいように起動時のディレイを0にして普通のデバッグ時に撮影しています。起動してからの動画も取りはしましたが絵面が地味すぎたので没にしました。ちなみにちゃんと動きますのでご安心を。

ちゃんと動く...?

おっと、何やら動作がおかしいですね...?変な表示だったり、画面上の数字と点灯した数字が合わなかったりしていますね。 実はこれ、左下のLEDが焼き切れています。電子工作初心者故に抵抗を忘れて接続した所一瞬だけ赤色の閃光が走った後に沈黙しました。ちなみに動画では100Ωの抵抗を使っているのでとても眩しいです。1kΩぐらいだとちょうど良くなりました。 本当は新しいLEDを発注していたのですが、記事執筆現在到着していないため壊れたLEDを使用する事になりました。

兎にも角にもこれで記事はお仕舞です。皆さんも電子工作をする際には十分気を付けて下さいね。

Unityで破壊可能オブジェクトを作ったお話

はじめに

この記事は東京高専プロコンゼミAdventCalendar② 14日目の記事です。

adventar.org

①もあります。

adventar.org

ちなみに筆者はブログを書くのは初めてです。変なところがあったら笑って見て下さい。

 

破壊可能オブジェクト?

本題に入りますが、皆さんは破壊可能オブジェクト(と私が勝手に言っている物)をご存じでしょうか?読んで字の如く、破壊できるオブジェクトの事ですね。ゲームや何かでよく見かける事かと思います。

破壊可能オブジェクトが出てくるゲームは数多くあると思いますが、私が真っ先に思い浮かべるのはレインボーシックスシージ(R6S)です。一応説明するとR6Sは銃で撃ち合うFPSゲームです。大きな特徴として殆どのオブジェクトを破壊する事ができるのですが、まあほんとに何でも壊すことができます。

f:id:FatherScorpion:20191214150152j:plain

花瓶などの小物やプレイヤーが設置するバリケードなんかは勿論、床や壁なんかもバンバン粉砕できます。

自分はプロコンが終わった直後にR6Sを買い、試験そっちのけで一日中プレイする自堕落な日々を過ごしていました。

また、そのころ弊ゼミ自由部門ではUnityを使っていたこともあり、Unityをある程度使えるようになっていたので、気分転換がてら自主製作の簡単なゲームを作ろうとしていました。

で、面白いゲームを作るには何が必要かな~などと考えていたのですが、まあここまで前振りをしていたら答えはもう自明ですね。破壊です。

破壊できるキューブを作ろう

最初はオブジェクトを破壊する爆弾を作ろうかと思っていましたが、その前にまず壊される側のオブジェクトが必要だなと思ったのでそれを作ってみました。

最初は単純に、あらかじめ細切れにしておいたキューブを用意して、それに別の物体が衝突すれば上手いこと弾け飛ぶのではないかと考えていました。

 f:id:FatherScorpion:20191213160604j:plain

今回は1×1×1の立方体を10×10×10個敷き詰めます。Unity世界では大きさ1=1mだったと思うので大きめの部屋くらいのサイズはありますね。スクリプトを組んで生成したので隙間なくギッチリ埋まっていると思います。

準備が出来たので早速配置をしてみますが、ここで問題発生です。

  f:id:FatherScorpion:20191213162351j:plain

はい、無事破壊できましたね()。

地面から少し浮かせた地点に先ほどの集合体を配置したところ、地面に衝突した数秒後にこうなりました。しかしまあこれは想定内ではあります。では接地した状態で配置するとどうなるかといえば、

f:id:FatherScorpion:20191213162922p:plain

こうなります。いくら接地した状態とはいえ、重力なりなんなり何かしらの力が働いている以上物体は完全に静止するまで少し時間がかかります。そして1000個ある内の1個でもキューブが動いてしまえば、連鎖的に崩壊が始まってしまいます。

また、最下段にある比較的静止した状態のキューブに注目すると、うっすらと、いえ、がっつりとキューブ間の隙間が見えてしまっています。

確かにこの方法でも調整すれば壊れるオブジェクトは作成できるでしょうが、いかんせん自壊した感が強く、自分で破壊したという達成感、エクスタシーを得ることが出来ません。別の方法を模索する必要がありそうです。

衝突検知のスクリプトを組む

恐らく、世にあるゲームの破壊可能オブジェクトは最初からバラバラに分かれている訳ではなく、何かしらの判定を検知してバラバラになっています(と勝手に思っています)。なので、そんな挙動を再現するプログラムを書いてみようと思います。

内容を大まかに説明すると、

  1. 10×10×10のキューブを用意する。これにスクリプトをアタッチする。

  2. 物体の衝突を検知する。

  3. キューブを削除し、さっきまで使っていた細切れキューブを同じ場所に出現させる。

これで見かけ上はキューブが破壊されたように見える筈です。 早速ですが以下がコードとなります。C#です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Flagments : MonoBehaviour
{
    public void SummonFlagments()
    {
        GameObject flagment = (GameObject)Resources.Load("Flagments");
        Instantiate(flagment, this.transform.position + new Vector3(-4.5f, -4.5f, -4.5f), this.transform.rotation);
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (!collision.gameObject.CompareTag("Ground"))
        {
            SummonFlagments();
            Destroy(this.gameObject);
        }
    }
}

関数名とかは超適当ですが許して下さい。内容は殆ど前述の通りですね。細切れキューブをプレハブにしておいて、衝突を検知したらそいつを呼び出すようにしてあります。後は衝突判定をGroundタグが付いたオブジェクト以外にしてあります。このGroundタグはあらかじめ地面に付けてあります。地面に触れた瞬間弾け飛んでは意味が無いですからね。

最後にこいつを10×10×10キューブにアタッチするだけです。では適当な物体をぶつけてみたいと思います。

f:id:FatherScorpion:20191214184937j:plain

ちょうどいい場所にサイコロがあったのでこいつを発射します。過去に自分が、

blender-cg.net

こちらのサイトを参考に作りかけのまま放置していた物体です。マテリアルが適応されていない(作っていない)ので真っ白ですね。適当にスペースキーを押したらキューブにサイコロが放たれるスクリプトでも書くとします。コードは割愛させて頂きます。

いざ発射

以下の動画が全てを語ってくれていると思います。

非常に気持ち良く吹き飛んでくれたかなと思います。

という訳で記事の内容は終わりです。いずれ細切れキューブのプレハブ生成も自動化して、あらゆる大きさのオブジェクトにも対応させたりしたいですね。

おしまい