星田オステオパシー

プログラミング学習日記 2024/01/26~

2024/01/31
 昨日Stackoverflowに出しておいた質問に早速外国の聖人から解決策が寄せられていた!しかも3パターンも。1つ目はコチラ。
 Pasteboard%というクラス(多分)を使うのか・・全く目にしたことがない。教えてもらわなかったらずっと知らなかったであろう。とにかく、こんなシンプルな書き方で実行できたとは!


 2つ目がコチラ。こちらはライブラリPictの中のPict->bitmapを使うために2htdpのPict/convertを使うというもの。まさしくこのような目的のためにあるっぽい関数があるんじゃないか。こっちの方が更に王道っぽいかな?1つ目がシンプルだけど。


 これは・・Render-imageとやらを使うみたいだけどライブラリ依存が多いし別にいらんかな・・

 という訳で、まさかの即時解決で恐れ入りました。

 もちろん回答をくれた聖人にはお礼を書いたけど、念のためにサポートしてくれたClaudeにもお礼を言っておいたで。出来ないなりに助けてくれようとしたわけだから(思い切り間違えてたけど)


 という訳でテストの続き。道路建設コマンドをチェック。まあ、分かると言えば分かるからこの表示方法で良いんじゃない?ちなみにバグはゼロでした



 発展カードゲットでエラー発生。そう言えば先日、Pass時にドットリスト形式にしたのに他の部分を変えてなかったのだった。ゲットした段階ではCar部に保存しておいて、Phase切り替え時にCdr部と統合するという形式にしたので他の部分を書き変えていく


 PLAYERのD-CARDSの初期値も空リストのペアに変更


 発展カード、ゲットするばっかりで全然Use-D-Cardのコマンドが表示されないと思ったら、そもそも作ってなかった。Victoryのみは自動で効果が発動するので使用メニューからは取り除いて表示


 手持ちにVictory以外のカードがある場合のみメニューが表示されるようになった

 ではいよいよカードを使っていこう!騎士カードから


 画面表示を作ってないので実にわかりにくい、が、一応動いている



 騎士カードを使ったあと、もう一度Use-D-Cardをする。ちゃんと騎士カードが無くなってメニューから消えているのもOK



 盗賊を追い払った先に町村があるとカードを1枚奪える(相手は任意、カードはランダム)ので、その部分を作る


 OK


 続いてDiscoverカードを使う。これはバグも無くOK


 続いてRoadカード。なんとコレもバグ無しでOK


 候補を表示するのを忘れてたのでDISPにROAD-KOHOを入れるように書き換え


 続いてMonopolyカードを実装する。PLAYER全員に影響するのでどうしてもコードが長くなってしまう。やってるのはDistribute-materialと似てるので改変コピペで


 Monopolyカードのテスト。これもOK


 盗賊システムを作るためにルールを確認する。そう言えば7が出たときにも盗賊を移動させないといけないんだった(資源バーストも7だったかな?)


 こっからが面倒なところだけど気になってた画像表示部分を作ることにする。いらすとやから画像をいただいて縮小、マップ上に表示させる計画。
 盗賊、騎士王、ロンゲストロード


 テスト用に盗賊撃退数KNIGHTを水増しして・・


 SortのオプションでKNIGHT部分をキーにして並べ替え、OK


 騎士王は盗賊撃退数3以上、ロンゲストロードは道路の長さが5以上が条件なので、満たしているかをチェックする述語が必要。しまった・・ロン毛ストロードはPLAYERにスロットを持たせてないので面倒なことに・・


 一旦、PlayerのIndexとそれぞれの道の長さをペアにしたリストを作って、Sortするハメに。OK


 騎士王も同様。仕様を合わせるために両方ともIndexのみを返すように書き換える


 表示部分で条件と組み合わせてグラフィックデータ、座標データを作るためのテスト。騎士王・ロンゲストロードの条件が真ならグラフィックをCons、偽なら'()をConsして、後でNullを取り払う。OK


 という訳で盗賊、騎士王、ロンゲストロードのアイコンを表示する関数?が出来た。この座標合わせが一番手間だった(-_-;)
 パネルIndexに合わせた盗賊の表示処理、計算で出すのは諦めてカッコ悪いけどまんまIndexごとの処理にした。マップを広げるときに一目瞭然なんで。同様の処理が今後も増える可能性があるので独立させるべきだけど・・・


 というわけで一応アイコン表示が出来た~

 これで通しプレイでのテストを終えたら・・・Ver1.0完成って感じじゃないか!?やったぜ!



2024/01/30 バグ取りを続ける

 村を建設する場所がおかしい・・原因は途中までマップの交点座標を1からスタートしてた為。途中から0スタートにしたので齟齬が生じているのだった。計算式は面倒臭すぎたのでMemberで端を判定。ついでにRoad-kiteru?の不要な部分を消す



 同様に隣の交点に村や町があるか?というのを調べる述語もおかしくなってしまったので書き換え。
 判定は計算式でやってたけど、4で割り切れる16も端以外の座標で使われてたりして厄介だった(前は1スタートで右端は5だったので問題が無かった)ので、Memberで調べるようにした。これ楽ちんで確実


 あと、その場所に村や町があっても#tとなってしまってたので対策


 結果、村建設可能ポイントは正しくリストアップ出来るようになった


 村から町へのレベルアップもOK



 Pass時にSCOREが計算されるのもOK。町で2点、ロンゲストロードで2点の合計4点


 DISPを有効にして町へのレベルアップ可能箇所を表示・・うーん、色がねぇ・・。緑黄青赤は使ってしまってるので黒くらいしか分かりやすい色がないんだよなぁ


 続いて、Phase最初にダイスを振ってるのだけど表示してなくて寂しい。さらに各プレイヤーの獲得カードを表示したくなったので着手。
 Distribute-material関数により、4x5(Player4 Material5)のAppendされた1次元リストが返ってくるので、それを頭から5つずつでPlayerで分けて、それぞれのMaterial用にIndexを返し、獲得枚数と合体リストを作る。その後、獲得0枚は排除して、Car部とCadr部をキーにしてStringsを生成する狙い


 Formatを使ってテンプレートに当てはめる。本番ではCadr部は*Material-list*を使って資源名を差し込む


 というわけでPhaseの最初にメッセージが表示されるようになった


 村建設候補場所も表示できるようにする。やっぱり赤が見やすいかなぁ・・・


 というわけで、残るは「盗賊=騎士」関連、その他発展カードのテスト・・。そうそう忘れてた!初期設定をするためのルーチンが必要だ。最初に村を2つとそれぞれに道路を2つずつ繋げるんだったな。でもな〜・・マップが狭いので最初から村を2つずつは厳しいか。ランダムで村を散らして、道2本だけは任意で置くってのがいい感じかも知れん。別枠にマップを表示できるようになったらもっと広いマップが使えるのだが・・




2024/01/29 マップ表示について試行錯誤する
 マップの表示が出来ないという不具合が発生。こうなったらREPLとは別の枠を表示して、そこでマップを常時表示しつつ行動選択をREPL枠で行う・・という「それが出来たら最高だな」というのを狙ってドキュメントを読む。
 5時間くらい読んだけど・・無理や~(-_-;)

 具体的に言うと・・画像を表示するFrame%はOK。Canvas%で単純に画像を表示するというのが難しい・・サンプルを参考にしてローカルファイルの画像ファイルをBitmapで変換してRacket/drawのメソッドで表示できるんだけど、変数に束縛した画像を読み込むことが出来ない・・こっちの方が楽に出来て当たり前のような気がするんだけど出来ない。

 このままではプログラミングが楽しくなくなってしまう・・と思ったので

 ついに初stackoverflowにて質問を投稿してしまった。確かに、スタックしてオーバーフローしてるわ~・・ナイスネーミング。

 で、投稿した直後・・・

 え~・・とりあえずREPL枠内での表示には成功しました。表示できなかった原因は超絶シンプルでPlace-imagesで返ってきた画像をDisplayに渡してなかった・・というもの。いや、だって普段Displayしなくても表示されるんだもの!!
 まあでも別枠で表示できたらそれに越したことはないので無駄では無いが!


 というわけでデバッグ継続。まずはトレード・・いきなりバグってます。鉄を4枚差し出したのに減ってない


 これを


 こうして解決。

 よしよし・・この調子でStackoverflowのお助けを待ちながら続きをテストしていくか!



2024/01/28 更にテストをしていく
 マップが表示できないのは致命的なのでClaude先生に聞いてみる。理想を言うとリスナー(?)部分でメニューとメッセージ表示、行動の選択を行い、グラフィックは別フレームで表示できると嬉しいのだが・・


 一応、そういうことは可能な模様。いやまあ、アテにならないのですが・・
 でも、コレが出来たらかなり楽しいことになりそうなんだよなぁ




 ついでにちょっとおかしかった部分を修正しておく。プレイヤー名やデータもヤヤコシイので0開始のIndex準拠に変更する


 うーん、メニューの番号表示が出来てない


 FormatとString-appendを組み合わせて行けたら楽だなぁ~と思って試したらうまく行った。



 というわけで、とりあえず「Trade」は出来るようになった(多分)


 続いて「村建設」。ちょっとエラーは出たけど修正完了。多分、出来てる(表示で確認できないので)


 表示が出来ないと本当にどうしようもないので、Claudeに教えてもらった別フレーム表示のコードを試す。まあ、動かないんですけどね・・。でも別フレームの実現は出来そうなので、しばらくドキュメントを解読してやり方を模索するしかないか。もしくは例のBig-bangを使って完全にGUI化するかだけど・・入力部分が面倒なんだよなぁ・・


 ちなみに、行動選択でMapを表示するようにしてみたらどうだろうか?と実験。通常Passとなる部分にPlace-statusを置いてみる


 むっ!表示された!けど、そこでプログラムが終わってしまう。Place-imagesも値を返すという意味では同じなんだけど・・問題はPlace-imagesの後に通常の式を追加できるかだなぁ・・止まってしまったら意味がないから。次回はそこんところ実験しよう。出来るのならばメニューに組み込むことは出来るかも



2024/01/27 テストをしていく
 とりあえず前日に時間切れになってしまったMonopolyを書いてしまう。PLAYERを全員更新しないといけないので束縛の嵐


 というわけで遂にMain-loop-readが(一応)完成。ここからはドキドキのテスト開始

 ゲッ?

 いきなりエラーが出て焦ったが、原因判明。そう言えばTransparentをつけないとデータをイジれないのだった


 どういうつもりか、現在のPLAYERのCARDだけ参照して全員分がリストになってると思いこんでいたり


 それに気づかなくて関数を辿ってデータの形を確認したり。書いてる時には絶対に忘れないと思ってるような事でも平気で忘れてて驚く。出力の形は特にコメントでこまめに書いておくべきだなぁ


 Monopolyの時に使った全プレイヤーを分解する部分をコピペ



 そしてデータを弄ったあとに再構成。うーん・・前にも思ったけど、やっぱり変に構造体にしないで普通のリストにするべきだな・・参照するだけなら構造体で、データをイジるならシンプルなリストにしておくべきでは?


 そして遂に・・・最初のメニューと入力フォームが出た!
 だが・・あれ?おかしいな?このメニューの前にPlace-statusでマップが表示されるように書いたのに出てこない


 とりあえず放置して0のパスから実行。だがエラー。これは出るだろうなと思ってたんだけど、Phaseの移行時に発展カードのCar部をCdr部に統合するように書いたんだけど、発展カードを引いてない場合にはPairリストじゃないのでエラーが出るのであった。最初にPair?で確認してからにする。が、今書いてて判明したけど、発展カードも複数枚引けるので普通のConsじゃなくてAppendにしないと・・


 その他こまごま間違ってたけど、とりあえずPassは出来るようになったのだった。やったぜ!

 ただ・・マップが表示されないのは不安だなぁ。これが出来ないとなると、計画が根底から崩れるんだけどw キャラクターベースで完全CLI形式なら出来るんだけどなぁ
 



2024/01/26 発展カードを書いていく
 まずは騎士カードを書いていくか・・と考えると盗賊システムを実装しないといけない。ルールを確認。
 うーん・・もともとマップが小さいので中央に設定する砂漠は無しで良いか。初期配置はランダムで


 盗賊のいるパネルからは資源が配分されないので、Distribute-material関数を書き換える。ROBBERは盗賊のいるパネルIndexなので、対応リストから外すように書く


 資源カードの更新はMain-loop-diceでとっとと行ってしまうようにする。ここで更新した後にMain-loop-readへ


 Knightのメッセージ部分の実験、OK。
 同時にマップにも追い払う先のIndexを表示する予定


 表示部分でパネルの上にIndexを表示する部分。色を変えるだけでは駄目かなぁ?まあ、調整はテストをやってからで


 DISPでの場合分けを追加。


 では実際のコード。まずは騎士カードを使うときのメニューを表示する部分、返すのは追い払う先のパネルIndex


 次に移動先のパネルに属しているプレイヤーから1枚資源カードを奪えるので、そのためのメニューを表示


 奪うカードはランダムなのでShuffleした資源IndexリストからCarで選ぶようにする



 Answer1 Answer2を使って奪う相手とカードを決めて、引いて足して新たな要素を再構成して・・という流れ。この流れ・・面倒だなぁ。List-setと同じようにStruct-setとかあったら良いのに。
 しかしこの束縛の数よ・・命名規則が鍵やな・・次回のゲームからは最初から気をつけよう。騎士ポイントも増やしておく



 使用した発展カードは手持ちから消さないといけないのでRemove。もしかしてマッチした要素が全部消えるかも?と不安になったのでテスト。1つしか消えないので良かった



 続きまして~発展カードの「街道建設」。カードを出せば可能な場所なら道路を二個敷設出来るという強力なカード(個人的な感想)。
 メニュー部分はほぼ同じだけど座標を2つゲットしないといけないのでAnswerを2つ入力、Valuesで本体へ返すようにする


 返ってきた値でいつものごとくR-MAPを更新し新しいWORLDを作ってMain-loop-readに返す。これは楽ちんだったな(ただし未テスト)

 続いて「発見カード」も作る。カードを出すと欲しい資源カードを二枚もらえるということで・・リストに追加するためのテストをする。Answerの1と2を用意して、CARDSに対応するIndexを入力。For/listで(Range 0 5)を回してAnswerと同じだった場合には1、Answer1と2が同じだった場合には2、それ以外は増やさないので0という具合の加算用リストを作る。


 あっ、そうか・・Answer1と2が同じ場合の方がレアだから条件式の順番を変えないと。OK


 例によってMenu表示と入力部分をまず作って


 Menuから返ってきた数値を使って追加用リストを作ってPlayerの手持ちカードに合算したものを作って、PLAYERを作ってPLAYER-LISTを作ってWORLDを作る、と。こういうのこそテンプレにしてマクロで出すべきなのかも知れない・・


 続いて(まだやるのかw)、「独占」を実装する。選んだ種類の資源を全プレイヤーから全部取り上げてしまうというカード。中盤で鉄を独占すると強かった思い出。
 とりあえず思ったように動かすための基本部分をテスト。For/foldかな?と思ったけどズバリFor/sumなんてのがあったので採用。リスト要素それぞれのIndex0部分を合算する、OK


 念のために奪われた状態の資源カードリストにするための動作確認。


 新たに作った資源カードのリストをCARD構造体に変換して、再構成用のそれぞれの変数に一気に束縛するための動作テスト。OK

 と、ここまで書いて時間切れ。あとはMonopolyのMenuと本体を書くんだけど、基本的には今までのと同じ形なので大丈夫だろう。ただ、全プレイヤーの値を変更しないといけないので変数の数がえらいことになりそうだ・・

 この調子なら明日の夜にはテストプレイが可能な状態に持っていけそう。うーん、ドキドキしてきた
名前:
コメント:

※文字化け等の原因になりますので顔文字の投稿はお控えください。

コメント利用規約に同意の上コメント投稿を行ってください。

 

※ブログ作成者から承認されるまでコメントは反映されません。

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事