
例えば日本最古のエロゲーと言われるハドソンの「野球拳」。アスキーアートでこのエロさに勝てるのだろうか?

以前Kiroに作ってもらったツールはちょっと使いづらかったので、UIは不要なのでターミナルから直接呼び出して、フォルダ内に入ってる画像ファイルを全部まとめて文字列に変換するツールをGeminiに頼んで見る。最初提案したのは純粋な文字列だったんだけど、Bubble TeaのLipglossを使ったらフルカラーでドット絵風に出来ると言う


こちらを使用して・・

どん!うーん、アスペクト比も問題だけどそもそも解像度が低すぎる。横80くらいは大丈夫じゃないか?

はい、ドン!80x60でもう一度。
Geminiが気を利かせて縦横のバランスを取るために1マスを半角2つに設定したためにやたらと横長に。解像度も落ちるし普通に半角スペースにしてもらうか・・

おっ!?

結構いいバランスじゃないか!

ちなみに文字列オンリーでやってもらったら・・これは・・

うーん、Kiroの文字列とはクオリティが違いすぎる

ということで、Kiroを呼びだして前に作ってもらったツールのアルゴリズムを流用して、CLIツールにしてもらう。けど、こうして比べてみるとやっぱりカラーには敵わないか!

基本的な変換アルゴリズムは一緒だと思うんですよね。ただ、置き換えるキャラクターが・・Geminiはこれ。要するに暗いところはキャラクターの面積が小さく、明るいところは出来る限りビットマップ?の面積が大きいものを割り当てると。

一方でKiroはこう。まさしくドット絵を再現するためにあるんじゃないのか?と言う半角キャラを使っての表現なわけで・・Kiro、やるもんだ
というわけでどうせBubble Teaを使って作るのならばカラーのドット絵を使ってのモンスターやアイテムの表現が良くないか?と思うわけですが・・

データの中身はこう。先程の2枚のドット絵を表現するのに、このエスケープシーケンスの塊をテキストデータとして持ってるわけですが、2枚で実に容量が80kb超。もはやJpeg画像と変わらないじゃないかw(圧縮が効かないからだろうな)。まあ、現代のマシンからしたら誤差みたいなもんなんですけどねぇ。うーん、どうすっかなぁ・・一晩、断続的に悩んだけど「やっぱりカラーで」行きますか。

折角なのでこの変換プログラムも読んでみますか。
画像変換のライブラリが多分、_ "image/jpeg"とかなんでしょうね。後はPath/filepathでファイル出力が出来るようになりそう

最上段のlipgloss.SetColorProfile(termenv.TrueColor)ってのがあるんですが、最初これが無かったのでファイル出力する時にカラー情報のエスケープシーケンスが出力されず、ただの半角が並ぶだけになってました。
files, _ := os.ReadDir(" ...って部分で実行フォルダ直下のAssetsってフォルダにアクセス、中身を取り出せる、と。フォルダの中身は1枚ずつの画像ファイルです。
で、そのFilesをイテレータで回して取り出し
拡張子を取り出してるのか、なるほど。専用のfilepath.Extってのがあるってのが凄いっすね
NameにはTrimSuffixってのでファイル名部分を取り出して余計な部分を切り飛ばしてるのかな?まあ、後で調べよう。
Dataには作ってある関数で例のエスケープシーケンスまみれデータを格納と
で、最後に整形して出力するんだけど・・ここでPrintfなのか・・Sprintfを使うかと思ったのに・・あ、そうか!ターミナルで出力するためのPrintfか。でも、それを go run main.go > monster_data.goって書くだけでファイルに書き込めるって凄くない?

上の追加2行は結果的には不要だったと思われる。効果が無かったので!
続いて・・あ、えっ!?なんと意外なことにここでまたファイルを開き直してる?さっき作ったファイル名はここでパス指定に使うためだったのか・・なんか無駄に思えるが・・後で聞く。最後はDeferで自動手仕舞いは、なるほど。
imageライブラリのDecodeを使って
Bounds・・境界?まあ、サイズなんだろうけど元画像のサイズを取得
続いてターミナルでのサイズを設定してるみたいだけど
Scaleに変換用の比率を入れてるわけか、元画像をターミナルサイズで割るから・・圧縮率じゃなくて拡大率を出してるんだよなぁ・・逆なイメージあるけど・・

追加可能な型の文字列を用意して
ははーん、なるほどScaleの謎が解けた。画像のピクセルを走査するのに倍率分だけ飛ばして行うことでターミナルのマス数に適合させてるわけか、カシコすぎる!
cは画像ピクセルの通し番号になるのかな?.Atで座標を指定しておいて、通し番号の座標に変換しないと次のRGBAでデータを取れないわけか?
hex?と思ったけど、なるほど8ビットに変換してRGB数値の文字列を生成
StyleにRGB彩色の半角スペースを追加
なるほど〜・・書けと言われても書けないが理屈は分かった(気がする)。
というわけで、いよいよ次回は実際にエンカウントしてモンスターを表示するところをやってみるか!
と、思ったけど

前に気になることを聞いてたんですよね・・ハーフブロック?そんな事出来るのか!試さずにはいられない・・

とりあえず修正コードを出してもらって・・(この後数回修正が必要でした)

同じ画像を使って・・こちらがノンハーフ版

こっちがハーフブロック版、ダーッ!すごい!

これがノンハーフ

こっちがハーフ版、もはや実写だコレ!
というわけで、こっちにします。

ではコードを拝見しよう!
あれ?ほとんど一緒だな? TopColorには今までどおりの座標
BottomColorにはXは一緒でYだけ倍率分足したところを入れると
なぬ?前面と背面で色を変えて、ハーフブロックを前面のキャラにして表示するって方法でやってたのか!もっとシステム的な事をしてると思ってた・・これなら自分で考えついても良かったなぁ

後は色を変換する関数が必要だと。
いや〜興味深かったっすねぇ〜