SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|

2024-09-15(Sun) 核分裂って、マジでヤバくな〜い?

  去年のいまごろ、会社が「勉強のためなら金を出してやる」とかいうので、大量に書籍を購入した。その中で特に大当たりだったのがサイモン・シンという著者の本だ。実にエリア88の関係者のような名前であるが、関係はないようだ。別にミッキーでも風間でもないし、F-14にもドラケンにも乗っていないらしい。グレッグという友人はいるかもしれないが。

  「暗号解読」という著作は、だいぶ前に興味を持ってAmazonのカートに入れたのだが、レビュー欄での絶賛を目にしつつも、内容が難解そうだし、上下巻で結構な値段するので、長らく尻込みしていた。んが、買ってくれるというなら、読んでみない理由はない。で、読んでみて驚いた。

  難しそうな内容が、実に平易に解説してある。レビュー欄での絶賛も納得である。そりゃ、100%は理解していないだろうが、100%は理解しなくてもいいように書いてある。これは素晴らしい著作だな。

  続いて、数学者たちの楽園、宇宙創成(上)、フェルマーの最終定理、と読み進めた。どれも、ジャンル違いではあるが、やはり、難しそうな内容が、実に平易に解説してある。数学学会や宇宙学会の界隈の人間関係のゴタゴタまで書いてあり、実に示唆に富む内容である。

  宇宙創成(下)はどうしたかというと、予算が尽きたので買わなかったのである。なんで他の本に優先して(下)を買わなかったのかといえば、万が一にも(上)にノれなかった場合に備えたのである。実際には一番に面白かったくらいだったのだが。もともと宇宙は好きだしな。

  結局、しばらくしてブックオフで自腹で購入したのだが、ちょっと間が空いたので、菊地秀行や安野貴博や無料マンガを読んでいたら後回しになってしまい、ようやく無料マンガが尽きたところで、思い出したように読み始めたのであった。

  んが、(下)はいきなり奇妙な展開である。巨大な宇宙の話なのに、微細な原子の話が始まるのである。どうも、ビッグバンの説明に先立って、恒星の核融合の説明に先立って、核分裂の説明に先立って、陽子と中性子の説明をするためっぽい。

  改めて説明されると、核分裂についても、極めて曖昧な理解しかなかった自分に気づく。ラジウムは自然にラドンに変化し、その際に放射線と熱を発する。変化は緩やかに進行し、その半分が変化する時間が半減期だ。ラジウムの代わりにウランを用い、変化を急激に進行させるのが、原子力発電や原子力爆弾だ。

  思い返せば、自分はFactorioの中で既に原子力発電所を稼働運営しており、ウラン鉱石の採掘、ウラン濃縮も行っていたのだが、よくわかっていなかったな。人間、何事もすべてを理解して物事を行っているわけではなく、よくわからないまま進めてしまうことはママあるわけだ。それは実際の原子力発電でもママあるんだぞ、きっと。

  核分裂についての自らの理解を確認してみたく、AIに訊いてみることにした。せっかくなので、ギャルでもわかるようにギャル語で解説するようにお願いしてみた。

Q. 核分裂の概要についてギャル語で説明してください。
A. オッケー☆ 核分裂をギャル語で説明するとこんな感じかな~!
 
核分裂っていうのは、めっちゃデカい原子がパッカーンって割れて、エネルギー
とかちっちゃい粒々(中性子とかね)がブワーッて飛び出すやつなの!例えば、
ウランとかプルトニウムっていう原子が、ヤバいくらいに大きくて、不安定だ
から分裂しちゃうわけ!で、その時にヤバいエネルギーが出て、これを利用し
て発電とかしちゃってるって感じ~☆
 
カンタンに言えば、原子が「もう限界~!」って感じで割れて、そのエネルギー
で超スゴいことができるってこと!
Q. なにそれ、超わかりやすいじゃん! なんかAIってマジでヤバくな〜い?
A. ありがと〜☆ めっちゃ嬉しいんだけど!AIってほんとにヤバいよね〜!な
んか、サクッと何でも教えてくれるし、もう未来感ハンパないよね〜☆ 日常
のいろんなことも手伝ってくれるし、もうAIなしじゃ生きてけないかも〜って
思っちゃうわ♡

  調子のんな!w


2024-09-13(Fri) 「こんなんなったら、『いっき』じゃ!。」

  運動習慣が付く前はヒョロだったので、際限なく白米の量を減らして収支を調整し、一時期は寿司一貫分くらいしか食わない日々だった。

  ところが、筋トレとジョギングを始めて運動習慣が付いてからは、食っても容易には太らなくなったので、ドンブリメシを食えるようになった。50代からの食べ盛り。ウソのようだがホントの話。むしろそのくらい食わないとドンドン体重が落ちてしまう。見た目カッコイイ体を目指して始めた運動ではあるが、ストレスなくドンブリメシをカッ食らえるのも運動を継続する大きな理由だ。

  ジョギングの後のメシとビールのなんとウマいこと。運動すると食欲が増して太っちゃう、なんてウソだ。ちゃんと運動を続ける限り食欲は増すけど太れません。

  が、ここにきて、なぜか米が売っていない。こうなるとすぐに「政府の無策がぁ〜」と日本政府政治依存症患者が騒ぎ出すが、どうせ原因はマスゴミの流言に惑わされた市民の「買いすぎ」だろう。交通量が設計の10%増で大渋滞になるのと同じく、需要が予測の10%増で大欠品になるのだ(たぶん)。

  なぜかウチはいま「ジャスミン米」とかいうタイ米を食っていて、奇しくも「平成の米騒動」を思い出させるが(自分はタイ米が全然イヤじゃなかったけど)、この米は炊くだけでトウモロコシ系のモノスゴい甘い香りを発してウマいったらないのだ。「香り米」は高知で偶然に巡り合って驚愕し、取り寄せまでしたが、タイ米が元祖だったんだな。

  画像の説明

  しかし、平気でコレくらい食うし、息子も同じくらい食うので、アッという間に消費されてしまう。在庫が心細くなってきた……困る。困るよ……あぁ、もぅ……「こんなんなったら、『いっき』じゃ!。」

  というわけで「いっき」を仕掛ける。ひとりで(笑)。だいぶ前から「いっき」はひとりでもできる、というのはゲームの歴史を知るモノの中では常識である。

  画像の説明

  なんて、ネタで画像を撮ってみたが、拡大しただけだと雰囲気が出なかったので、ラスタ効果を足してみたら、実にそれらしくなった。

require './TrueLegacyGraphicsCairo'
w = 240 << 2; h = 224 << 2
win = LegacyGraphics.new(nil, nil, nil, nil, h, w, 16, 8, nil, { :file => 'laster', :type => 'png' })
h.times {|y0|
    y = (y0 << 2) + 3
    win.line(0, y, w, y, 0)
}
win.refresh
win.close

  しかし、このゲーム。スクロールの作動位置がおかしいだろ。飛鳥&飛鳥か。


2024-09-11(Wed) RubyでDigest認証クライアントを作らせる

  昨日、RubyでDigest認証クライアントを作ったわけだが、ふと、流行りのAIのお手並みでも拝見してみようかと思いついた。

  で、そのまんま「httpクライアントとして、digest認証を行い、htmlを受信するRubyスクリプトを書いてください」と問い合わせてみる。それに対する回答は以下。

もちろん、以下はRubyでHTTPクライアントとしてDigest認証を行い、HTMLを受
信する簡単なスクリプトの例です。このスクリプトでは、net/httpライブラリ
とnet/http/digest_authライブラリを使用します。
 
まず、必要なライブラリをインストールしてあることを確認してください。
 
require 'net/http'
require 'net/http/digest_auth'
require 'uri'
 
以下がスクリプトの例です:
 
require 'net/http'
require 'net/http/digest_auth'
require 'uri'
 
# 認証情報を設定
uri = URI('http://example.com/protected')
username = 'your_username'
password = 'your_password'
 
# ネットワーク接続の設定
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == "https")
 
# 初回リクエストを送信して、401 Unauthorizedレスポンスを受け取る
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
 
# Digest Auth用の認証ヘッダを作成
digest_auth = Net::HTTP::DigestAuth.new
auth_header = digest_auth.auth_header(uri, response['www-authenticate'], 'GET', username, password)
 
# 認証ヘッダを追加し、再度リクエストを送信
request = Net::HTTP::Get.new(uri.request_uri)
request['Authorization'] = auth_header
response = http.request(request)
 
# レスポンスの表示
puts response.body
 
このスクリプトでは、次のステップを行います:
 
  抽出用にURIオブジェクトを作成し、認証情報を設定します。
  最初のリクエストを送信して、401 Unauthorizedレスポンスを受け取ります。
  401 UnauthorizedレスポンスからDigest認証用のヘッダ情報を取り出し、新
  しいリクエストに対して認証ヘッダを作成します。
  再度リクエストを送信して、認証後のページ内容(HTML)を取得します。
 
このスクリプトを実行する際は、適切なURL、ユーザー名、パスワードに置き
換えてください。また、サーバーがHTTPSを使っている場合は、http.use_ssl
をtrueに設定してください。

  ほら、出たよ。もっともらしく、ありもしない「net/http/digest_auth」を使ったりして……って、んッ!? もしかして、RubyGemsにあったりするのか!?

$ gem search digest | grep http
net-http-digest_auth (1.4.1)

  それっぽいのがあるなぁ……インストールしてみよう。

$ bundle init
$ bundle add net-http-digest_auth

  書いてもらったコードをそのまま動かしてみる……が、エラーが出た。

$ bundle exec ./digest_test
ArgumentError: wrong number of arguments (given 5, expected 3..4)
  /home/user/develop/digest_auth/vendor/bundle/ruby/2.6.0/gems/net-http-digest_auth-1.4.1/lib/net/http/digest_auth.rb:76:in `auth_header'
  /home/user/develop/digest_auth/digest_test:22:in `<top (required)>'

  しかし、完全に的外れっぽいエラーのようには見えない。ライブラリのコードを確認してみる。

def auth_header uri, www_authenticate, method, iis = false
  nonce_count = next_nonce
  user     = CGI.unescape uri.user
  password = CGI.unescape uri.password

  ライブラリの側ではusernameとpasswordをuriインスタンスから得る形になっている。これは後から修正したっぽい感じだな。もしかしたら、前のバージョンなら動いたのかもしれない。直してやる。

$ diff digest_test.org digest_test
9,10c9,10
< username = 'your_username'
< password = 'your_password'
---
> uri.user = 'your_username'
> uri.password = 'your_password'
22c22
< auth_header = digest_auth.auth_header(uri, response['www-authenticate'], 'GET', username, password)
---
> auth_header = digest_auth.auth_header(uri, response['www-authenticate'], 'GET')

  なんとッ!! これだけの修正で動いてしまった。おぉ……なんというか、やるなぁ。ここまで来ているんだなぁ。素直に、スゴい。ダメ出ししてやるつもりだったのに、当てが外れてしまった。

  そもそも、RubyGemsも探さずに、検索でもうまく見つけられなかった自分も不甲斐ないが、それ込みで回答内容には誤った部分はなく非常に有用だ。ちょっと悔しいくらいだな。コードの記述方法は自分が書いたスタイルのほうが圧倒的に美しいと思うが、それはライブラリに対する難クセであって、回答内容とは関係ない。あまり粘着するとラッダイト野郎になるしな。ここは素直に認めておこう。

  でもね。別にいいのだよ。いくら自動運転が発達しようと運転するのは楽しいし、いくらボーカロイドが発達しようと歌うのは楽しいし、いくら将棋AIが発達しようと将棋を指すのは楽しいのだろうし、いくらコード生成AIが発達しようとプログラミングは楽しいのだ。そう。自分にとってプログラミングは仕事じゃないので。

  しかし正直、複雑な気分ではあるなぁ……。


2024-09-10(Tue) RubyでDigest認証クライアントを作る

  ちょっとした理由でウェブアクセスするクライアントを書き始めたら、相手にDigest認証を求められた。

  あれ。Rubyの標準ライブラリにはBasic認証の機能しかない。TLSの普及につれ、Digest認証が廃れて、Basic認証が復活してくる傾向とは思っていたが、相手サーバがDigest認証で固定なら、それに対応せざるをえない。

  標準ライブラリになくたって、誰か書いているだろう、と思ったが、検索してもRailsはよくわからんし、WEBrickはサーバ側の話だろうし……まぁ、自分で書くかと。車輪の再発明だとしても楽しいしな。

  Digest認証が面倒なのは、認証に先立って相手からnonceというチャレンジコードをもらう必要があるので、最初に失敗アクセス(401:Unauthorized)を行うことが必須であることだ。Basic認証ならば、最初から認証情報を送ることができるので、失敗アクセスは必須ではない。

  RFCを眺めつつ、既存のRubyのライブラリに近い使い勝手で実装する。できた。

require './http_digest_auth'
res = nil; auth_res = nil
uri = URI.parse('http://localhost:8080/digest/')
req = Net::HTTP::Get.new(uri.path)
3.times {
    auth_res = req.digest_auth('username', 'password', res, auth_res)
    res = Net::HTTP.start(uri.host, uri.port) {|http|
        http.request(req)
    }
    puts(res.code)
    res.code.to_i < 400 and break
}
puts(res.body)

  既存のRubyのライブラリでBasic認証する場合のサンプルコードが以下なので、できるだけ近づけた。ただし、最初に失敗アクセスを行うことが必須なので、ループしたり、認証情報の引き渡したりする処理が入るのは仕方ない。逆に、上記のスタイルでもBasic認証は動く。

require 'net/http'
uri = URI.parse('http://localhost:8080/basic/')
req = Net::HTTP::Get.new(uri.path)
req.basic_auth('username', 'password')
res = Net::HTTP.start(uri.host, uri.port) {|http|
    http.request(req)
}
puts(res.body)

  ライブラリのコードは以下。RFCのまんまといえば、RFCのまんま。

require 'net/http'
require 'digest/md5'
 
class Net::HTTPGenericRequest
 
    attr_accessor :secret_data
 
    def digest_auth(username, passwd, res, auth_res = nil)
 
        @nc ||= 0
        @secret_data ||= 'secret-data'
 
        @auth_res = auth_res || {}
        if(res and res.header['www-authenticate'] =~ /Digest\s+(.+)/i)
            $1.split(/,\s*/).each {|kv0|
                kv = kv0.split(/\s*=\s*/, 2)
                kv[1].strip =~ /^\"(.*)\"$/ and kv[1] = $1
                @auth_res[kv[0]] = kv[1]
            }
        end
 
        if(@auth_res['realm'])
            ha1 = Digest::MD5.hexdigest('%s:%s:%s' % [username, @auth_res['realm'], passwd])
            ha2 = Digest::MD5.hexdigest('%s:%s' % [method, path])
            nc = '%08X' % [@nc += 1]
            cnonce = Digest::MD5.hexdigest('%s:%s' % [Time.now.to_f, @secret_data])
            qop = 'auth'                                                                        # TODO
            response = Digest::MD5.hexdigest('%s:%s:%s:%s:%s:%s' % [ha1, @auth_res['nonce'], nc, cnonce, qop, ha2])
 
            auth_req = []
            auth_req << 'username="%s"' % username
            auth_req << 'realm="%s"' % @auth_res['realm']
            auth_req << 'uri="%s"' % path
            auth_req << 'algorithm=%s' % 'MD5'                                                  # TODO
            auth_req << 'nonce="%s"' % @auth_res['nonce']
            auth_req << 'nc=%s' % nc
            auth_req << 'cnonce="%s"' % cnonce
            auth_req << 'qop=%s' % qop
            auth_req << 'response="%s"' % response
            auth_req << 'opaque="%s"' % @auth_res['opaque'] if(@auth_res['opaque'])
 
            @header['authorization'] = ['Digest ' + auth_req.join(', ')]
        end
 
        @auth_res
    end
end

  なかなか美しく書けた気がする。ふぅ。


2024-09-07(Sat) 是弾不射、然火可発、撃ーッ!!

  これはゼヒとも発火させないとイカンなぁ、ということで、火薬を手配して発火させてみた。純正の火薬は100発分で千円弱なので、撃つ分には気にせずパンパンできる程度のコストだ。

  火薬の装填方法は説明書に書いてあるが、雷管(プライマ)に相当するOリングの付いた後側の部品を具体的にどうするか書いてない。弾頭ではなくケースの方に入れてからネジ込むのが正しいらしい。

  一応、銃の撃ち方的な動画を探し、正しい銃把の握り方、もう片方の手の添え方などを確認。せっかくなので初回からデジタルカメラで動画撮影してみる。一応、弾は本物と同じく7発装填できるらしいが、弾が5発しか付属していないので、5発すべてに火薬を仕込み、マガジンに装填する。それでは……イザッ!!

  画像の説明 画像の説明

  一発目、OK。二発目、妙に弱いがブローバックはした。三発目、OK。四発目、OKだが、最終弾のローディングに失敗。というような結果だった。

  モノスゴイ音が出たら困るな、と思いながら、家の中で撃ったが、常識的な範囲の音だと思える。それにしても、反動は少ないのに、ちゃんとブローバックが再現できているところには心底感心する。火薬の匂いもイイなぁ。

  最終弾は手で排莢させてしまったので、再度マガジンに詰める。以前に「ロシアンルーレットで勝負だッ!!」とオート拳銃を渡される、というギャグ漫画を見たことがあるが、一発だけに火薬を詰めたら、ロシアンルーレットできるじゃん、と思いながら、発火済みの弾もすべてマガジンに詰めて撃ってみた。すると最終弾で発火。スライドストップはかかったが、排莢には失敗。まぁ、でも、最初からこの調子なら十分だろう。

  メンテが重要ということなので、すぐにバラして水で洗う。銃で遊ぶのって、豪快なのか、地味なのかわからんなw。でも、バラす作業こそが楽しみなんだから、それでいいんだけどね。

  せっかく撮影したのでYouTubeに上げてみる。ついでに動画編集の勉強もしてみよう。「Shotcut」というアプリはLinuxでも使えるし、YouTubeにもチュートリアルが多いのでよさそうだ。起動、映像ソースの読み込み、カット、フェード、トランジション、テロップ、書き出しなど、基本的な事項を学び、試行錯誤でトリミング、スローの効果を加えて完成。最初だしこんなもんだろう。アップロード、公開。

 

  いやー、最近はトンと「新しいこと」をしてなかったが、モデルガンも動画編集も、なかなかに「新しい」経験だったな。モデルガンはそう深みのある趣味でもないだろうが、しばらく前からやってみたかったことなので満足だ。しかし、オートはガバメントでよしとして、リボルバも欲しくなるなぁ……。

本日のツッコミ(全2件) [ツッコミを入れる]

横須賀のアランプロスト [モデルガンはストレスが溜まるんですよね~。 火薬のカスが付く。ジャムる。発火しないとかw そういえば、今年、クラ..]

フルタニアン(管理人) [アレコレ調べると、ジャムらないよう調整するのもモデルガンの楽しみだとか。 そういやキミもオイラも弓道が好きだし、飛..]


2024-09-06(Fri) あのぉ、あれ、なんつうの? ゼロもの?

  ここのところ、歌のレッスンの課題曲は「ナイショの話」なのだが、その「化物語」の最新話は「キスショット・アセロラオリオン・ハートアンダーブレード」の誕生エピソードなんですよ、などという先生との雑談から「いわゆる、ナントカ・ゼロ」系の作品の始祖ってなんだろうね、という話になった。

  こういうのって、検索エンジンでは調べにくい。「ナントカ・ゼロ」って検索しても出てこない。別にこういう状況は珍しくはなく、それ向けに前から「人力検索」なんてのもある。

  んが、イマドキそれこそ「AI」の出番でしょう。早速、ChatGPTにそのまんま訊いてみる。「Fate/Zeroやマクロスゼロのように、過去を振り返る作品で、最初に出たものは何でしょうか?」。

  回答の要旨は以下。

・過去を振り返る「前日譚」(プリクエル)作品の最初はフランスの『人間喜劇』(19世紀)
・Fate/Zeroやマクロスゼロのように人気の確立後に作られる流れは2000年代から

  おぉ。「前日譚」「プリクエル」。その言葉なんだよ知りたかったのは。Wikipediaも活用する。「プリクエル」は、続きを意味する「シークエル」に着想を得た造語らしい。「明日に向って撃て!」と「スターウォーズ」が著名な例として挙げられている。「明日に向って撃て!」は、ヒットしたが、主人公死亡エンドだったため、遡って続編を作ったパターンっぽい。「スターウォーズ」は、言われてみて気づいた。役に立つねぇ、AI。

  再び、ChatGPTに訊いてみる。「プリクエル作品で有名な作品を古い順に挙げてください」。

1. 『ゴッドファーザー PART II』 (1974年)
2. 『インディ・ジョーンズ/魔宮の伝説』 (1984年)
3. 『レッド・ドラゴン』 (2002年)
4. 『スター・ウォーズ エピソード1/ファントム・メナス』 (1999年)
5. 『X-MEN: ファースト・ジェネレーション』 (2011年)
6. 『ホビット』 (2012-2014年)
7. 『モンスターズ・ユニバーシティ』 (2013年)
8. 『ローグ・ワン/スター・ウォーズ・ストーリー』 (2016年)
9. 『ハン・ソロ/スター・ウォーズ・ストーリー』 (2018年)

  1, 3, 4, 6はプリクエルであることを知っていた作品だ。確かにそのとおりだな。納得。さらに、ChatGPTに訊いてみる。「日本のアニメ作品ではどうでしょうか?」。

1. 『機動戦士ガンダム0083 STARDUST MEMORY』 (1991年)
2. 『エースをねらえ! ファイナルステージ』 (1989年)
3. 『新世紀エヴァンゲリオン 劇場版 DEATH & REBIRTH シト新生』 (1997年)
4. 『機動戦士ガンダム THE ORIGIN』 (2015年)
5. 『Fate/Zero』 (2011年)
6. 『コードギアス 亡国のアキト』 (2012年-2016年)
7. 『マクロス ゼロ』 (2002年)
8. 『テイルズ オブ ゼスティリア ザ クロス』 (2016年)
9. 『劇場版 ヴァイオレット・エヴァーガーデン』(2020年)
10. 『刃牙』シリーズ (2001年)

  0083かぁ。知ってたけど、これも言われてみれば、だなぁ。それとは知らずに妙に作画のイイ、リックドムのシーンを見かけて、んなぁ!? と、驚いたことを思い出す。自分の記憶に限ってだが、確かにあれより前にはそういうスタイルの作品は見なかった気がするな。オイラ的にはイマイチだったけど「マクロス ゼロ」もだいぶ古いんだな。

  まとめ。

・そういう作品は「プリクエル」と呼ばれる
・19世紀にフランスの群像劇に事例がある
・著名なのは1970年前後の西部劇「明日に向って撃て」と「スターウォーズ」
・アニメでは1990年の「ガンダム0083」

  ならばよしッ!


2024-09-01(Sun) ガンプラ、もとい、プラガン完成

  エラくデキのいい木製パズルではあったが、所詮は割りバシ鉄砲の延長……などと考えながら、あれこれと見ていると、マルシン工業という会社のコルト・ガバメントM1911A1が目に入った。それにしても組み立てキットで15,000円とは……子供の頃に作ったプラモデルの10倍する。まぁ、ギリ出せないこともないけどもなぁ……と、ホビー通販のサイトに見にいくと、どれも25,000円オーバ……なんでッ!? 転売か!? ……とか、思いながら流れ着いたYouTubeの動画で謎が解けた。

  これ系の商品は何年かに一度、再販され、その都度に仕様が少しグレードアップし、値段も上がるものらしい。で、今回の上げ幅が1万円だと……つうか、オフィシャルサイトの情報が値上げ前ってのはどうなのよ……と、そんなことよりも重要なことは、これ系の商品は再販の都度ほぼ瞬殺されるものらしいということだ……買わなければ3年後……いやいや、それにしても25,000円て。

  画像の説明

  しかし、さっき観たYouTubeの動画がよくなかった。サラッと観た感じ、ほぼ実銃と同じ部品構成っぽかったのだ。いや、ゲームで経験した範囲の話ではあるけれども、実際のパーツを手で感じながら組み立てられるなんて、それこそが是非とも経験しておきたいことだったんだよなぁ……うーむ……うーむ……うぅーむ……うぅー……ポチッ……やっちまった。シルバータイプ。残り1点だったんだし、仕方がないのだ。それはね。仕方のなかったことなのだ。うん。

  すぐに届いた。まずは、組み立て説明書を見ながら、部品が揃っているかの確認だけする。似たようなピンやスプリング部品が多いので、頭から順に組み立てると取り違えをしそうだからだ。しかし、この時点で驚愕。本当に、ほとんど実銃と同じ部品構成なのだ。本体はプラスチックだが、それ以外、ほとんどが金属パーツ。本体のプラスチックも恐ろしく硬質で、ステンレスを模したメッキも強靭。容易に削れたり剥がれたりしそうにない。すごく高価なだけのことはあるなぁ。

  自分はカメラもシルバーが好きなので、今回の銃でもシルバーを選んだが、シルバータイプはメッキを施す必要上、ボディのパーティングラインを消す加工が済んだ状態になっているようだ。文句のない仕上がり。ちょっと値段が高いのはそのせいか。

  何日か寝かせた後、意を決して組み立てを開始する。初っ端は、エジェクタの組み立て、という工程。実銃にはない部品。小さな金属板を、金属ボディのスリットに入れ、2本の金属ピンで固定する、というだけの工程なのだが……軽く1時間以上かかった気がする。

  もともと部品の精度はあまり良くない、と聞いていたが、金属パーツは目視ではわからない程度……0.05mmでもズレていれば入らないものは入らないのだ。ノギスはそういう世界のためにある。結局、金属板の方をヤスリで削って対応したが、金属板だけに容易には削れてくれなかった。工作の経験は多いほうだと自負しているが、いきなり想定外の事態だな、これは。

  その後も、ほとんどの工程で苦戦する。むしろ部品の精度が高すぎてピンが入らないともいえるのか。図面からは容易に読み取れないコツも必要だったりするし。しかし、本当にやりたかったのはこれなんだよ。どの部品がどのバネに作用しているのか、体感できるのだ。なるほどなぁ。

  しかし、慎重にやっても間違ってしまう。トリガが引けなくてはやり直し、ハンマが落とせなくてはやり直し、終いにはスライドを組み込んでも動きがシブすぎる……気づくと2時半を回っていた。疲労は作業品質を落とすし、ゴリ押しに向かいがちになる。グっとコラえて明日に回そう。

  画像の説明

  翌日。再び夜更けに始動する。自分でも不思議なほどだが、もう一度、始めからバラしてからやり直したいほどに気力が復活している。まぁ、疲労というのはそういうものだよね。それなりに仕組みもコツも頭に入っているので、丁寧かつ着実に組み立てが進む。意外なほどサクサクと完成。昨晩、マトモに動かなかったスライドも、納得できる程度の手応えで動作するようになった。

  思ったよりもズッシリとした重量。それでも実銃の半分くらいの重さらしいが、これはなかなかの存在感である。組立の時にちょっとイラついてプラのヘラでコジってしまった部分もあるが、プラスチックもメッキも想像以上の強度を持っていたので、目立ったキズにはなっていない。初めてのモデルガンであり、反省点も多くあるが、それにしては悪くないデキである。

  5発の模擬実包を弾倉へ装填する。あー、なんだか思い出すなぁ。見たら日記に書いてあったわ。撃った射撃場のサイトも見つかった。実包の装填からやらせてくれたんだよね。よく覚えていないが「9mmと45口径を16発ずつ」って書いてある。空薬莢をもらって持って帰ってきたが、見つからない。16発ずつも撃ったかなぁ。45口径を16発も装填できるハンドガンなんてあるのかね。撃ち切ってもう一度、装填したっけ? 撃ったのはガバだった可能性も高いが、そこまで覚えてないなぁ。

  弾倉を銃に装填する。ハンマを落とし、トリガを引く。カチッ。火薬は込めていないので、ブローバックはない。手動でスライドを引くと、景気よく排莢される。おぉー、やってみたかったのはコレなんだよぉ。ジャキッ、カチッ、ジャキッ、カチッ、ジャキッ……あれ? 戻らなくなった? ……と、思ったら、最後の弾が排莢されると、スライドストップがかかって戻らなくなるのは仕様だった。うん、ちゃんと動作している。

  しかし、ここまでやって気づいたが、これはゼヒとも発火させないとイカンなぁ。ポチる時は、別に発火なんてさせなくたって、って思っていたけれど、そんなことないわ。これは火薬を買わなければならないな。絶対。

  とりあえず、その前に、もう一度、完全バラシをやるかな。全体構成がわかったところで、ちゃんと注油してみたいのだ。


2024-08-27(Tue) 当世ガン事情

  ガキの頃「銃のプラモデル」を作ったことがある。少なくともふたつ。リボルバーとオートを組んだ記憶がある。弾の発射機能はないが、模擬実包の弾倉への装填が楽しめる。

  小学生くらいだっただろうから、ヒドい出来だったろうが、妙に記憶に残っている。それほど緻密に銃の構造を再現していたわけでもなかったのだろうが、なかなかに興味深かった。ガンプラでも、その仕組みを自らの手の中で扱うのが、その楽しさの一部だと思う。変形機構なんかがあるものは、特に。

  で、また作ってみたくなったのだが、当然というか何というか、現在の多くの模擬銃はサバイバルゲームに用いるために発射機能のあるもので、内部構造についての再現度は低そうだ。高価だし。それでも「モデルガン」というジャンルでは、極力内部構造を再現したものもあるが、よりニッチなだけに大人向けの高級志向であり、やっぱり高価だ。

  そんな経緯でしばらく放置状態だったのだが、先日、ヘリのゲームの新作が遊べないかと、手元のLinuxマシンにダメモトでSteamをインストールしてみたところ、アッサリとインストールできてしまったものの、肝心のヘリのゲームはWindows専用で遊べない。とはいえ、Linuxでもゲームが動くことを確認してみようと、無料ゲームを検索してみたところ「World of Guns: GunDisassembly」というタイトルを見つけた。あれ? これ……って、もしかして、そういうオイラにうってつけのゲームなんじゃないの!?

  画像の説明

  それがゲームであるかどうかは微妙な内容ではあるが、ひたすらに銃をバラし、バラしきったら、また組み立てる、という内容はまさにやりたかったことだ。画面の中とはいえ、発砲することもでき、それをスローで鑑賞することもできる。うーむ。こういう趣味って、一般的ではないにしろ、普遍的なものなんだなぁ。

  銃については詳しくなく、西側はM16、東側はAK-47、ルパンはワルサーP38程度の知識しかなかったが、同ゲームにおける「リュウ」は「コルト・ガバメント」だった。そういやガキのころ、なぜか「ガバメント」という英単語に「銃」のイメージを感じていたのはこれが原因だったのか。「政府」という単語に火薬の匂いが被るのが、どうにも不思議だったのだが「官給品」から来ているのね。なるほど。

  ゲームの中でバラしてみると、意外にパーツ数が多く、容易には手順は覚えられないが、何度もやっているうちにわかってくる。実際に目の前に銃が現れたら、初見でもバラせそうな気さえしてくる。んが、やっぱり実際のパーツを手で感じながらやりたいよなぁ。画面の中では感じ方に限界がある。

  で、せめてそれっぽいオモチャはないかと検索してみると、なんだか木製のパズルにたどり着いた。こっちはリボルバーな形状だが、素直に魅力を感じる形状でもある。中国製だが、レビューを見ても悪い評価がほとんどない。安価だし、とりあえずポチってみた。

  1ヶ月かかるといわれつつ、1週間くらいで届いた。さっそく組み立てる。いやはや、パーツの精度は想像以上に高く、どれもカッチリと固定される。数時間で組み上げたが、接着剤なしにもかかわらず、恐ろしいほどのシッカリ感だ。個体差もあるだろうが、少なくとも自分の手元にあるものについては、難クセひとつ付けられないレベルであった。安物感はない。優雅な時間だったなぁ。

  画像の説明

  そんなにいらんよ、というくらい輪ゴムが付いてきたが、同時に6発までは装填できる。シングルアクションながら、動作は確実だ。的も5個付いてくるので、至れり尽くせり。残念ながら、エイムは役に立たないものの、ゴムは概ね同じところに飛んではいく。そういや、ガキの頃に割りバシ鉄砲も無数に作ったよなぁ。いいなぁこれ。手元に置いて手慰みにしちゃいそうだ。

  最近は「誰でも同じものが作れる」なんてつまんない、と思っていたが、プログラムと違って手で触れられるし、これはこれでたまには楽しいものだな。これだけレベルの高いキットだと、同じシリーズのAK-47も作ってみたくなるな……いや、いっそのことピンボールまでいってしまうのか!?


2024-08-19(Mon) ハスに構えつつAIを動かしてみる

  先日「仕事で既存の生成AIに問い合わせる仕組みを作っている」と書いたが、そのすぐ横で後輩が「手元で生成AI動きました」なんて報告を上げてきた。え、マジッ!?

  聞くとちゃんとコンテナで上げていて、普通にコンソールから日本語で質問を与えられる状態になっていて驚愕。なにかがうまくいってなくて「こんにちは」の応答に数分かかるようだが、とりあえず動くということだけでスゴい。自分的に、同僚からこういう刺激を与えられるのって、すごく嬉しい。滅多になかったことだ。

  ollamaという流行りの仕組みを使っているらしい。調べると、それほどの手数を要さずに動くようだ。それほどの超弩級スペックも必要ないっぽい。こういう、同僚からの嬉しい刺激に報いる一番の方法は、すぐに追いついて一緒になって取り組むことだ。

  というわけで、やってみた。自分はすぐにdocker-compose.ymlにまとめてしまうのが好きなので、以下のようにまとめてしまう。

services:
    ollama:
        image:
            docker.io/ollama/ollama
        container_name:
            ollama-alpha
        ports:
            - "11434:11434"
        volumes:
            - pv:/root/.ollama
volumes:
    pv:
        driver: local
# データを永続的に保持する領域として
# mkdir -pv pv しておくこと
        driver_opts:
            type: none
            o: bind
            device: $PWD/pv

  ollamaコンテナを上げたら、日本語の言語モデルの導入が必要になる。どの言語モデルを導入するのが適当かわからないので、ググって出てきたサイトのお勧めをそのまま試す。また、Modelfileという定義を書いて初期設定をする必要があるのだが、それもよくわからないので同サイトのお勧めをそのまま試す。

/root/docker/ollama # cd pv
/root/docker/ollama/pv # mkdir llm-jp-13b-instruct
/root/docker/ollama/pv # cd llm-jp-13b-instruct
/root/docker/ollama/pv/llm-jp-13b-instruct # wget llm-jp-13b-instruct-full-ac_001_16x-dolly-ichikara_004_001_single-oasst-oasst2-v2.0-Q4_K_M.gguf
/root/docker/ollama/pv/llm-jp-13b-instruct # vi Modelfile
/root/docker/ollama/pv/llm-jp-13b-instruct # cat Modelfile 
FROM ./llm-jp-13b-instruct-full-ac_001_16x-dolly-ichikara_004_001_single-oasst-oasst2-v2.0-Q4_K_M.gguf
 
PARAMETER temperature 0.7
PARAMETER top_p 0.95
PARAMETER repeat_penalty 1.05
PARAMETER stop "<EOD|LLM-jp>"
 
TEMPLATE """{{ if .System }}{{ .System }}{{ end }}{{ if .Prompt }}
 
### 指示:
{{ .Prompt }}{{ end }}
 
### 応答:
{{ .Response }}<EOD|LLM-jp>"""
SYSTEM """以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。"""
 
/root/docker/ollama/pv/llm-jp-13b-instruct # cd ../..
/root/docker/ollama # docker_exec
# INTO [ollama-alpha].
root@aef3abf257e5:/# cd root/.ollama/llm-jp-13b-instruct
root@aef3abf257e5:~/.ollama/llm-jp-13b-instruct# ollama create llm-jp-13b-instruct -f Modelfile
root@aef3abf257e5:~/.ollama/llm-jp-13b-instruct# ollama list
NAME                       	ID          	SIZE  	MODIFIED     
llm-jp-13b-instruct:latest 	bb43f78e1cbd	8.3 GB	7 seconds ago	
root@aef3abf257e5:~/.ollama/llm-jp-13b-instruct# exit

  コンテナの中で「ollama create」することで「llm-jp-13b-instruct」という名前で言語モデルを登録している。それが終われば、以下でコンテナの外から日本語で質問を与えられる。

/root/docker/ollama # docker exec -it ollama-alpha ollama run llm-jp-13b-instruct
>>> こんちは。
こんにちは。
 
>>> Send a message (/? for help)

  「こんちは。」だけなら10秒くらいで応答が返ってきた。速くはないが、N100のローエンドPCで、だからね。

/root/docker/ollama # docker stats
ID            NAME                  CPU %       MEM USAGE / LIMIT  MEM %       NET IO             BLOCK IO           PIDS        CPU TIME      AVG CPU %
aef3abf257e5  ollama-alpha          390.81%     14.72GB / 16.53GB  89.06%      6.952kB / 978B     8.959GB / 2.052GB  30          7m59.065034s  114.62%

  とはいえ、コンテナの動作状況を見るとパッツンパッツンだ。言語モデルの大きさの7.8Gに対し、メモリは15G弱が専有される。ただし、動作による増減はないっぽい。

  ちょうど1年半前くらいにChatGPTで遊んでみていたが、手元で動くのはもっと先だと思っていたわ。まぁ、アーケード版に対するファミコン版かもしれんけど、それでも手元で動くのは夢がある。

  例によって遊んでみよう。

/root/docker/ollama # docker exec -it ollama-alpha ollama run llm-jp-13b-instruct
>>> 1980年台の傑作アーケードゲームを5つ挙げてください。
1980年代のアーケード・ビデオゲームの傑作には以下のようなものがある:
 
ギャラガ
スペースインベーダー
ドンキーコング
パックマン
フロッガー
 
>>> ドンキーコングとはどんなゲームですか?
ドンキー・コング』は、1982年にナムコが開発・発売したアーケード・コン
ピュータ・ゲーム。プレイヤーはアーケード版『キングコング』(1980年)を
基にしたゲームで、アーケード版ドンキーコングのスピンオフ作品。
 
プレイヤーはアーケード版キングコングのキャラクターであるドンキーコング
を操作し、アーケード版キングコングの敵役であるアーケード版キングコング
のキャラクターであるコングを避けながら、バナナを集め、できるだけ長く生
き残ることを目指す。
 
>>> Send a message (/? for help)

  まぁ、例によって派手にハルシネっているが、それはそれで面白い。

  実はちょっと前に、社内のAIサービスのAPIを対象にRubyのライブラリを書いていたのだが、どうもAIのAPIというのは、既にデファクトスタンダードがあるようだ。手元にAIがあるなら、転用できるか試してみようかしらん。


2024-08-17(Sat) こういうチョップリフターがいい

  なにしろ捕虜が「手を振る」という仕草が衝撃だった。チョップリフターだ。詳しい経緯は忘れたが、最初に目にしたのはオリジナルのアップルII版だった気がする。その時はプレイすることはできなかったが。ヘリコプタで飛んでいって、攻撃して、救助して戻る。救助っていうアクションがヘリならではだ。戦争ゲームでも、壊すだけじゃなくて助けるってのがイイ。

  しかし、なんというか、ゲームとして破綻していないか? ロクに狙って攻撃できない。ロクに攻撃が避けられない。セガの移植したアーケード版もあるんだが、破綻したゲーム性は似たようなもの。セガらしくない。遊びたいのはそういうゲームなんだから、もっとちゃんと作ってよ。なんでそうなるんだよ。

  思い返せば、メガドライブで「デザートストライク」というヘリのゲームを遊んだことがある。サイドビューじゃなく、クォータビューだったが、ずいぶん熱中して遊んだ。自分は、そういうゲームが好きなんだ。で、当然のように続編の「ジャングルストライク」を買ったんだが、なぜか操作方法が変わっていた。厳密に言うと「デザートストライク」では3種類から選べたのに、それが固定になっていた。で、ロクに狙って攻撃できない。ロクに攻撃が避けられない。数日は遊んだが序盤で放り投げた。なんでそうなるんだよ。

  画像の説明

  で、先日、セールということで、なんとなく「コンバット!サーチ&レスキュー」というゲームを買った。100円だし、たいした期待もしていなかった……けど……アレ? これじゃねぇの? 俺が遊びたかったのって!?

  画面がサイドビューなのはチョップリフターと同じだが、ヘリに耐久性があるので、被弾一発ではミスにはならない。いわゆる体力制。自分は基本的に体力制は好きではないのだが、フワフワとしたヘリの挙動を再現するならば、キリキリと弾除けしたりはできないから、そうデザインするほかはない。まぁ、実際のヘリも機銃一発では落ちないしな。

  なので、被弾ゼロにはできないが、被弾しにくいマニューバをすることが、ゲームの肝になる。そしてヘリの操作方法が衝撃。なんと、基本「L」と「R」という、ふたつのデジタルボタンだけ。それなのに、それで自在に空を飛ばしている感を味わえる。なにせイカにもヘリっぽい浮遊感が秀逸で、離陸も着陸もホバリングも、すごく「してる」感があるのだ。まさに、こういうチョップリフターが遊びたかったんだよ、オレは!

  画像の説明

  そりゃ、細かい粗はいくらでもあるけれど、定価でも800円なので文句をつけてもしゃーない。むしろ、もっとお金を取っていいから、ステージのバリエーションとか増やして欲しいくらいだ。コンプリートしちゃったんだよ。スターもドッグタグも。しゃーない、もう1回データ消して最初からやるさ。

  画像の説明

  調べると、このゲームの開発元はハンガリーのInvictus Gamesってトコらしく、原題は「Dustoff Heli Rescue 2」。2作目だったのね。前作に「Dustoff HeliRescue」と、最新作に「Dustoff Z」があるようだが、どっちも日本のスイッチ向けにはリリースされていない。残念。

  なんだかX68kで遊んだ「ウィングス」を思い出すな。悪い意味で。やっぱり、ロクに狙って攻撃できない。ロクに攻撃が避けられない。遊びたいのはそういうゲームなんだから、もっとちゃんと作ってよ。なんでそうなるんだよ、ってゲームだったな。あれも。

  ついでにX68kで遊んだ「クランクトアロウ」「三段変形ファジー」も思い出すな。いい意味で。なんつうか、ほのぼのしたミリタリ感と、独特の操作感なのかなぁ、テイストが似ているんだよなぁ。そういうゲームがしたいなら、自分で作るというテもあるか。うーむ。