2024/11/25
話題その1 RustでCLIテトリスの続き

じゃあ続きやってくか!まずはステージに移動ブロックが無い場合に新たなブロックを発生させるんだから・・Vecに特定の文字があるかどうかをチェックする述語が欲しい。なるほど、Containか〜

でも、考えてみたら「含まれていない」を調べないといけないのだった。あ、!で否定か〜

いや、ちょっと待てよ?ブロックのCharが複数種類あって、どれも無かったら・・って風に聞かないといけなかったかw 最初面倒かと思ったけど、Vecをイテレータ化してLambdaで判定してBoolを束縛するって言う方法、良さげじゃないか

そして、ここでようやくリテラルと文字列の違いについて考えてみる機会が訪れる。


あ、そういう事か!やっとこさ(多分)理解した!

うーん、この説明も分かりやすい。Claude先生やりますねぇ〜
後は、IfでチェックしてBlock発生関数起動のための乱数とMatchを書けばVec上にデータを書き込む準備が整うな

そして乱数発生も分からないので聞く。うーん・・Crateを導入するのはできる限り避けたいのでRandom()で行くか。一応両方とも書いておく

そしてまた疑問発生。標準入力で入ったデータってどういう型になるんだ?

それは良いとしてバッファをフラッシュって何だ?

あ、そうなのか!今まではPrintln!ばっかり使ってたので知らなかった・・まあ、今回のステージ表示は改行でPrintln!()使ってるから別に良いんだけど、これは知っておかないとな〜

と、ここまで知って欲が出てしまう。もしかして、標準入力のプロンプト待ち操作を時間経過のカウントが出来るループの中に入れ込んだら、プロンプトを強制的に終わらせてブロックの下方移動ルーチンへ飛ばす・・って事が出来るんじゃないかなぁ?と。これならCrosstermいらずでテトリスっぽい挙動が出来そうだが!?
結果は・・なんかThreadを使わないと駄目だと。つまりあれか、並列処理って奴?うーん、さすがにそれは・・
と、ここでClaude先生への質問リミット。4時間くらい待たないといけないってことで今夜はここまでや。
話題その2 Nim
あまりにもRustが好きになれないので、ネットでRustの悪口を検索。「世界でプログラマーに最も愛されている言語」とか絶対に嘘だと思う!
と、そこでNimという言語を知る。ちょっとコレ面白そうじゃないか!

またうまい具合に、もうすぐ解約予定のKindleUnlimitedで読めるNimの解説書が見つかる。驚いたことにコレ、17歳の高校生が書いてるという!!おいおいマジかよ・・
というわけでちょっと読んでみまーす
2024/11/24

前回のステージ表示だけど、関数は外部に持っていくほうが良いよな・・ということでVec<String>を引数にして表示させる部分の関数を書く。が、ここで所有権の問題を思い出す。どういうルールだっけ?
仮引数は&使うんだったか?それを関数内で使う場合に&を書くんだったか?ということで実験、これは動くと。

ところがコレも動く。どっちでも良いのかも知れないけど、どうだったかなあ〜・・

ふんふん、Mainで渡した時点で所有権は移ってると

出たよ、こういう気をつかせたつもりが逆に混乱する気遣い。Displayトレイととやらで出来るなら全部でやってくれたら良いんじゃないか?

MainでCellを再利用するために&cellで渡すべきだ、と、なるほど。けど、&[String]で受けられるのはどういうわけだ?

ぬぐぐ・・こういう所が嫌なんだが!?


なるほど、よく似た形式の配列とかも受けられると・・じゃあ全部リストでエエやん!・・・とはならんのか?ま〜一通りRustを試したら動的型言語をメインで使うようになるであろう。
というわけで、続きます。あれから考えたんだけど、やっぱり一度標準機能だけでなんちゃってテトリス(なんちゃってトリスと名付けよう)を作る気分になってきた。つまり「シレン」と一緒で、こちらのワンアクションに対して「なんちゃってトリミノ」が1行下がるというルールで・・というふうにすれば良いだろう。これでブロックの回転とかのギミックを作って、それを最終的にCrosstermで動くように改造するというアプローチはどうだ!?
ま、そんなにコンパイルしたくないのか・・って話なんですけど。
2024/11/23

Crosstermでのライフゲームではターミナルの表示更新が画面スクロールで再現されてたので不安だったのだけど、迷路ゲームで確認するとちゃんと画面が更新されて実現されていた、ホッ

しかし気がかりはエディタ周り。普通のテキストエディタだと()のペアも見つけづらいし色々と面倒。Paiza.ioもCrosstermなんか使えるはずが無いし(でも、エディタ機能とクラウド保存での別マシンによる共有が便利なので使う)・・
WRTNに何かCrossterm使えて、コンパイルしなくても使えるエディタって無いですか?と聞いてみると・・
えっ!!?Rust PlayGroundでCrosstermが使えるだって!?仕組み的にブラウザからターミナルが呼び出せるとは思えないが・・これ、使えたら革命やで!Rustのプログラミング学習が一気に楽しくなる予感!
ま・・
嘘っぱちだったんですけどね。

一方、Claude先生に確認してみると・・正しい情報をありがとう。ま、そうだよなぁ・・

とりあえずRustでの書き方を完璧に忘れてるので(もともとロクに知らなかったが)、Paizaエディタを使ってCLIで画面表示の実験をするところから始める。
い・・いかん!なんか楽しいのでこのままCLIで同期型のテトリスを作ってしまいそうだ・・。うーん、毎ターン強制的にテトリミノが1段落ちる・その際に標準入力で移動や回転を1アクションだけ出来る・・って仕組みなら(全く楽しそうではないが)プレーンな状態でも作れるやろけど
2024/11/22
とりあえず、テトリスの舞台となるフィールドを表示して、一定の時間でブロックが落ちるけど、非同期でリアルタイムにキー入力は受け付ける・・・って言う根幹部分をCrosstermでどうやったら実現できるのか?ってのをWRTN先生に聞いてみる。そもそも命令が分からないので、1行ずつ軽く解説をしてもらうことにして・・・と

描画は目にも止まらない速さで1マスずつ行ってるということかな?うーん・・任意の部分だけ書き換えが可能なのか?それともブラウン管テレビみたいに左上から右下まで毎フレーム描画するということなのだろうか?ってのを書きながら疑問に思ったので、また今度聞かないと・・

なるほど・・裏で全部描いておいてから一気に切り替えてるのか・・

完全に並行して処理が行われるのではなくて、ブロックが移動したフレームはキー入力を受け付けないという事か

ここがキー入力の判定開始か。Event:pollでBoolが返ってくるという事ですな

うわ〜・・この長さ。これがRustの嫌なところなんだよなぁ。これも後で細かく見ないとな

まあ、これは分かるかな

非同期のMainを作るときにはそもそも形式が違うのか

ん?さっきはFlushで一気に表示するとあったが・・画面表示部分はバッファリングして一気に表示、操作系はリアルタイムに処理するって事かなぁ?これも聞かねば
結果、全然進みませんでしたけど・・まあ、大雑把にどういう仕組みが必要なのかは分かったかな。とりあえず皮算用に従って、まずは止め画面が表示できるようなリスト(Vec)と表示部分を書いてみるかなぁ・・
2024/11/20 ブロック回転問題

1次元リストで回転か〜・・と実際に座標を取りながら考えてみたんですけど。
あ、そうか・・基準点を決めて
横方向の場合は1小さかったらー1行*要素を元から引いて、2小さかったらー2行*要素。1大きかったら1行*要素、2大きかったら2行*要素
行1つ小さかったら基準に+1、行2つ小さかったら基準に+2
・・・と、そういう感じで算出できるな!と。うーん、実際にやってみないと分からなかったな〜
まあ、これで最大の問題は解決できたので・・次回は実際に必要なメソッドとか調べてみますか〜
2024/11/19
話題その1「ゆるコンピュータ科学ラジオ」
以前、P突堤2さんの記事で知った「ゆる言語ラジオ」をじっくり聞けるタイミング(電車内とか)でたまに聞いてるんですけど、サブチャンネルを発見。ザッと見回すとLispを体験するという放送があって・・うーん、笑った。たった40時間で色々と考える人もいるんだなぁ~と。
Lisp・・いずれは数学学習とかの段階で戻るつもりなので待っててね!と。Racketにもコンソール使って非同期の操作が出来て、簡単な音も鳴らせるような仕組みがあったらなぁ。Big-bangでも面倒に感じてしまうのは贅沢すぎるのか
話題その2「Crosstermテトリスの擬似コード(皮算用とも言う)」
WindowsノートだとRustの実行が出来ないので、疑似コードらしきものを考えることでお茶を濁そう
1,まず、全画面データをリスト・・RustだとVecかな?で用意するかな。適当だけど、横20縦60くらい?これをWorldにして、加工しまくる形で多分表現できると思う。
2,テトリミノ構造体として、1,2,3,4,5とかで初期形を作る
111
1
1
とか
2
222
など。
確定したブロックは0。番号ごとに背景色を変えれば見た目テトリスっぽくなるだろう
3,Loop開始
Loop {
画面に何も無いか、0しかなければ新たなテトリミノを最上段に当たるVecに発生させたWorldに置き換える
キーチェックでテトリミノ回転
→アルゴリズムは明日方眼紙を使って考える・・思いつかなかったら、泥臭いけどそれぞれ4パターンを作っておいて置き換えるしかないか・・構造体とか作りたく無いんだよなぁ
画面に1,2,3,4,5がある場合は決まったタイミングで1行ずつ下げた座標に変更するが・・
→変更先のどれかが下枠を超えるか0と同じ座標であれば動かさずに0以外の数値を0にする
1行が全部0ならその行をクリアして、先頭にNull行追加
新たな0以外のブロックが出現する時、どこかに0があればゲームオーバー
→って事を考えると、ブロックの出現は-2あたりで始めて、通常通り処理して0が最上段に来た時点でゲームオーバーってした方が簡単そうだけど・・
}
問題はブロックの回転部分かなぁ・・意地でもWorldの1次元リストだけで処理しようと思ったら、中心軸を検出出来ないといけない事になる気がするので・・うーん
111
①
1
とか
2
2②2
って感じにすればWorldデータだけで回転処理が出来そうな気がするんだけどなぁ・・
明日は回転アルゴリズム部分を方眼用紙で考えて、うまくいったらとっととコードにしてみるかなぁ
2024/11/17 リハビリ開始しました
ようやく大量の雑用を片付けたので、いよいよ学習を再開しようかと。出来れば思考力をアップさせてからにしたかったけど、クンダリーニ覚醒も気の長い話になりそうなので・・
とっととRustのCrosstermを使ってテトリスとかトランキライザーガンもどきを作って、色々とゲームエンジンを試したいんですけどねぇ・・。
最初はライフゲームのコードを改変してテトリスにイキナリ挑戦するつもりだったけど、Crosstermについて別の回でも解説してるようなので、そっちを先に・・となると、それまでのバックナンバーで興味深そうなところだけでもつまみ食いしてからにするか・・となって

結局第4回あたりの電卓から始めると言うね。ま〜以前と比べたら多少は読めるようになってるでしょう。

しかしプログラミング学習、最初からRustにしなくて良かった・・絶対にプログラミングが嫌いになってた自信あるわ〜・・「変数」なのにデフォルトでimmutableっておかし無いスか?なんで毎回mutつけんといかんのかな〜とか!その他いろいろ
2024/09/20 Godotジワジワやってます

例によってノロノロとした歩みで学習を進めてます。公式ドキュメント、日本語化が完全じゃないのと、画面全体での図示が無いから場所が分からなくて効率悪いわ~
あと、Kindle Unlimitedで気軽に読める、川俣晶さんのプログラミング関連書籍を読んでるんですけど・・

SMC-777Cで「リスト」が使えるようになった機種で人工知能が作れる!と意気込んだけどメモリが少なすぎて何もできなかった話とか

国産初のパーソナルコンピュータを追う話

子供の頃からずっと理想のSLGで遊ぶことを夢見てた話
なんかは面白かったですねぇ!特にSLGはゲームデザインに関わる話で興味深かった。例の黒田幸宏さん作「孫子」が対人の外交に特化してて戦闘がオマケみたいだったのに拍子抜けしてたけど、実は戦略ゲームの抽象度をトコトンまで上げた結果だったのか!と驚いた次第。ま~ソレゆえに対CPU戦に落とし込むのは無理やろなぁ・・
2024/09/11 やる気が湧いてきた!
Cametanさんの「端末の話」を拝見。何気なく読み始めたんですが・・
なんかめっちゃ燃えてきたわ!色々と合点がいった点があって

~~~~~~~~~

プログラミング学習始めてずっと違和感あったのコレですわ。だからRustでCrosstermの機能を知ったときに震えたんだと思う

読んでてうわぁ・・夢のようだ・・と思ってしまいました

うーん、これはいい話だなぁ・・
たまたま先日見た「大昔のパソコンサンデー」の動画で印象的なシーンがありましてね。超初期なので(BASIC講座のコーナーとかある)、司会の小倉智昭さん自らが北海道のハドソンまで行って開発者にインタビューするというシーンがありまして、そこで小倉さんプログラマーに対して
「プログラミングをしていて一番の喜びを感じる時ってのはどういう時なんでしょうかね?」
と尋ねる。ソレにしたいして(怪しげな風貌の)プログラマーさん
「そうですね・・こうやったら動くんじゃないかな?と仕組みを考えてそれを実際にプログラムしてみて、ちゃんと動いた時には、やった!ってな感じで・・これは何事にも代えられない喜びですねぇ・・」
と応える。ま、ここまでは「ふんふん」って感じなんだけど・・そこで小倉さんが凄いのが
「なるほど・・でもハドソンさんってカセットテープにすでに出来上がったゲームを入れて販売されてますよね?これってお客さんからその喜びを奪ってるって事にはなりませんか?」(*確か日本で最初にゲームプログラムを販売したのがハドソンだったんじゃないかな?)
とか全く空気の読めないツッコミを入れてしまう。プログラマーさん、グッ!と唸って何も言えない・・というシーンがあったんですよね。見てるコッチも聞いた瞬間にリアルで「あっ!(言いよった)」って声を出してしまいましたからね。

あ、これか!と。僕がずっとコンピュータに愛着というか執着を持ってるのは子供の頃にPC6001でこういう世界に触れてたのに飛び込むことが出来なくて、結局はファミコン以降プログラムの消費者になっておもちゃとしてのコンピュータで遊びを体感することが出来なかったからじゃないんだろうかと。
ところで

って部分も気になったのでDOSBOXで動くゲームってどうやって作るんだろうか?と検索してたら
こういう記事があって・・現状ちょっと体験するのは大変そうだなぁと。検索してもMS-DOSゲームプログラミングとかで引っかからないし(PS4などでDOSのゲームを動かすってのはある)。
ま、そんなのはCLIで飽きるほど作ってから考えろよ、と。そういうわけでRustのCrosstermには大変期待しております

RustでもWavファイルを再生したり

単純なBeep音的な効果音を鳴らしたり出来る模様
2024/09/10
その1:RustでCLIのテトリスを作ってみようと妄想する
ライフゲームのコードを改造すればテトリスが作れそうな気がして、バイトのモップがけをしながら仕組みを妄想する。
●最低限必要なのはフィールドのどこにTrueがあるかを保存したWORLD構造体だけなハズ、という点で共通してる。
●Updateで積み上がってる以外の座標データを下に移動させる操作をして
●移動後に積み上がってるTrue座標と競合する時点で固定化
●フィールドに固定化されてないTrueが存在しない場合は新たにブロックを表すTrueのグループをフィールドに発生させる
●ゲームオーバーは新規で発生させる座標にすでにTrueがあったら
●Updateごとに各行を走査して全部Trueの部分はクリアする
●Updateの途中に非同期でキー入力を受け付けて稼働中のTrueグループの座標を変化させる部分をつくる
●Trueの種類はテトリミノの種類ごと、固定化されたブロックで適当に文字列を割り当ててMatchで色を変える
こんくらいで一応テトリスっぽい動きになりそうじゃないかな?実際のコードは明日から書こう、と
その2:ボードゲームデジタル化企画のために無限力を借力する

ケイブンシャの大百科で目にして以来、ずっと気になっていたボードゲーム「伝説巨神イデオン」。とうとうヤフオクで買ってしまいました・・送料込み3800円!今更一緒にプレイしてくれる人もいないので、実はルールブックだけ見れたら十分だったんですけど・・

箱は汚いし、死蔵された在庫特有の臭さがあるんですけど内容物はまさかの手つかずw。サイコロは1つ無くなってたので売れ残り在庫じゃなくて「買ったけどプレイしようという奇特な友人が居なかった」人が売ったのかな?
というわけで、ルールを把握した後GUIゲームのネタに挑戦したるかい!と。用済みなったら売ってしまおう・・臭いし!
多分、というか間違いなく対COMは実装が大変なので対人用ツールになるんだけど、出来ればオンライン対戦出来るようにしたいなぁ・・探せば方法は存在するはず!
2024/09/09 WindowsにRust入れるのが本当にダルい
宿直バイトAには劇遅だけど使い勝手が良いLinux化したChromebookマシンを持ち込んでいて、昨夜戯れにRust環境を入れてライフゲームを実行して見ました。結果、何の問題も無し。これはやはりRustでCLIゲームをつくるところから始めよう!と決意。

そして本日、いつも図書館に持ち込むWindowsマシンにRust環境を作るか!とやってみたところVSCの導入を促されて、従ったリンク先のバージョンがCommuntyだったので設定などの操作方法が分からず。改めていわゆるVSCを導入して実行してみようとしたところがコレ。
もう考えるのも嫌になったので決めました。
WindowsマシンではGodotでGUIゲーム、LinuxマシンではRustでCLIゲームを並行して作っていく!と。
2024/09/07 えッ!?ん~・・どうしようRust

Rustを使ってライフゲームを作る・・という例の記事。ようやくコードが読めるようになったので最後に読んで理解してからGodot行くか!と。
いきなりライブラリ(Rustではクレイト・・こういう同じ概念にわざわざ別の名前をつけるところが嫌いだ)で知らないものだらけ。WRTN先生に聞く(Claude先生は最近質問数の上限が引き下げられてすぐに限界が来てしまう・・)。
気になったのはCrossterm・・へぇ?ターミナルの操作?

ターミナルアプリケーション・・?

非同期入力・・おいおいまさか?

こういう疑問が湧いてきますよね?

くわっ!マジか!!当面、僕がやりたかったのってまさしくソレなんだよなぁ!こういう事が可能になる仕組みがあったのか~・・RacketではGUIベースで作れる仕組みがあったけど、昔の「電源ON!プログラミングしか出来ることがないw」という、あの時代からやり直したかったワケ。うわ~どうしようかなぁ・・

うひ~

簡単な骨組みも教えてくれる。う~ん、大昔に諦めたことが今では出来そうな気がしてきた

ま、それはそれとして今日のメインであるライフゲームのコードも見てみよう。メイン部分、ふんふん・・まあ大体わかるけど、なんでMain関数なのに返り値がResult型で指定されてるんだ?

へぇ~・・まあ、覚えておこう

まあ、これは初期化だし別に・・

描画部分か。これはRustのCrosstermで何か作るんだったら丸ごと参考にできるな

突然、もしかしてRacketみたいにターミナルモードでも画像ファイルとか扱えたりしないかな?と気になって質問。やっぱり駄目か~・・キャラクターを作るのが面倒っぽいので一応ね。

うーん、望むような解決方法は無いな

うーん、よく出来てる(・_・;)
この関数はしっかりと理解してパターンとして収めておかないとイカンな

まず、これで任意の周囲8マス座標を指定できてるってのがナルホドポイント1

5で割った端数ってのは分かるとして、その前に5を足しておくってのが思いつかんな~

ナルホドポイント2。Forで二重ループをさせてiをベクターのインデックスにしてそのまま判定しつつBoolを更新・・うーん、美しい!
今回はナルホドポイント1,2だけは丸暗記する努力をしよう。
しかしRustとGodot・・どうしようっかなぁ・・RustはずっとPlaygroundでやってきたので環境を作るのが面倒なんだよなぁ。けど、CrosstermでのCLIゲーム作りは非常に魅力的。でもどうせ作るならRust環境なくても実行できる形式で出力できるGodotで簡易GUIベースで作ってしまっては?とも思える。
うーん・・明日LR占いで決めようか(-_-;)
2024/09/06 Godotを入れてみる

Unityっぽいけど激軽!って噂のゲームエンジンGodotを導入してみました。調べたところ現行のVer4シリーズよりVer3の方がネットの資料も多くて入門向きだって話だったので3のスクリプト版(.net版じゃない方)をダウンロード・・容量70メガバイトか・・多分インストーラーなんだろうな~と思ったら!まさかの非インストールタイプの実行ファイルで容量は70メガバイトポッキリ!そりゃ軽いはずだよ・・Racketの3分の1もない。ライブラリは別途DLするんだろうか?じゃなかったらコンパクトすぎる!
そして上の画像はWEBアプリで擬似実行環境となってて、ここで(英語だけど)チュートリアルを使って基本的な学習が出来るという。お~・・ちょっと初心者向け過ぎるところから始まるけど、英語の勉強も兼ねてると思えば。
というわけで続きます。インストール不要ってのがすごいなぁ・・
あ、Scilabは・・そのうちやります!
2024/09/05 手持ちのボードゲームをデジタル化する、計画

Rustはとりあえず体験できたけど、ゲームエンジンで安定したものが無いっぽいので(あと、Rustの所有権は面倒なので)、次は初めてのゲームエンジンを体験してみよう!と。
まずは何を作るのかを決めないといけないので倉庫を漁って20年前に道端で拾ったボードゲーム「孫子」を取り出してルールブックを読み始めました。
・驚いたことにクロちゃんこと黒田幸弘さんがデザインしていた
・マルチプレイ前提のデザインでメインは外交なのでゲーム化は難しい
と判明。うーん、これはちょっと・・ただ、デザインノートとか古代中国の歴史を概観したヒストリカルノートが面白いので読み物として楽しんでます。ゲーム化もコンピュータゲーム用にアレンジしたらやってやれない事は無いかも・・?
Rustは構造体を対象にしたselfがメソッドでわーる構造体としてチェイン出来て、再帰的な動きと破壊的変更を使うことで手軽に狙った動作が出来そうなことが判明したので、とりあえずもうエエか・・って感じですかね!
2024/09/04 RustでBrain*uck、ループ部分のオリジナル仕様にこだわる

とりあえず自分なりに出来た気がするので実験してみる。えーと、カウンタの初期化を実装してないので、2,4...になるはず?

ファッ!?なんでやねん

こうすると?

はわわ・・どうなってんのw

挙動が謎なので途中で値を表示するようにしてみる

うーん・・ちゃんと新たなコマンド(今回は3回ループ)は生成されてるよなぁ・・
+++[>+++<]だとちゃんと動くのに+++[>+++<]>>+++>++>+とかだとおかしくなる。

ポインタの数値もおかしいし・・・
ま、これを読んでる人はもう分かってらっしゃいますね?

[があると新たなコマンドが生成されて、]までが繰り返されて]以降のコマンドと合成されて実行されるのですが、終わったあとに]以降が普通に1回目のループで実行されるからなんですね!もうバカッ!
と、ここまで判明したところで時間切れ。いや~原因究明の過程でClaude先生からは何度も「これは本来推奨されるBrain*uckの挙動ではありません、ご再考を・・」ってたしなめられたわ~。そんなん分かっとるわ!自分で考えた方法で出来るかどうか確かめたいんだワ。
わざわざ]以降のコマンドを合成する必要がないと判明したので問題は解決したも同然だな?
そして更に・・これってもしかしてネストでもちゃんと動くって事なのでは?それにデザイン的にメソッドが同じスタイルで書かれてる方が美しいじゃないか!コードは汚いが。