[{"data":1,"prerenderedAt":322},["ShallowReactive",2],{"content-/shogi-board-demo-with-kifu-db":3,"all-pages-for-dir":320,"og-image-/shogi-board-demo-with-kifu-db":321},{"id":4,"title":5,"body":6,"category":297,"description":298,"extension":299,"meta":300,"navigation":301,"ogImage":302,"path":303,"project_name":304,"published":305,"publishedAt":306,"seo":307,"stem":308,"tags":309,"todo":318,"unpublished":305,"updatedAt":302,"__hash__":319},"pages/2026-05/2026-05-08/shogi-board-demo-with-kifu-db.md","将棋盤インタラクティブデモを Vue で実装：Codex/Gemini で局面読み取り、shogidb2 から75手復元するまで",{"type":7,"value":8,"toc":287},"minimark",[9,13,20,23,28,31,34,37,39,43,46,53,98,101,104,107,109,113,116,119,121,125,128,131,133,137,140,143,194,197,200,202,206,213,219,226,232,235,237,241,256,258,261,280,283],[10,11,12],"p",{},"将棋の参考書を読んでいて、「鬼手1」と呼ばれる一手の局面を盤面で動かしながら追いたくなった。紙の上で駒を動かしてもいいのだが、本筋（参考図ルート）と実戦譜が分岐するタイプの解説で、手を戻したり進めたりが多い。Vue で盤面を組んでしまえばクリックで往復できる。",[10,14,15,19],{},[16,17,18],"code",{},"apps/web/app/pages/shogi-board-demo.vue"," に作った。",[21,22],"hr",{},[24,25,27],"h2",{"id":26},"まずは棋譜パーサーと-svg-駒で序盤5手","まずは棋譜パーサーと SVG 駒で序盤5手",[10,29,30],{},"最初は構造の確認だけしたい。棋譜パーサーを書き、SVG で駒を作り、序盤5手だけ進めるところまで動かした。",[10,32,33],{},"駒は最初プレーンな五角形だった。並べてみたら、どう見ても将棋盤に見えない。木目のグラデーションを敷き、縁に立体感を出して影を落とし、文字は書道風のフォントに差し替えた。形も「上が尖って肩がある縦長五角形」に整えると、急に将棋駒の顔になった。",[10,35,36],{},"譜面は最初は1カラムで縦に並んでいた。読みづらい。中央寄せで2:1グリッドに再構成し、解説は盤の下、コントロールと棋譜リストは右に sticky で貼り付けた。盤面を見たまま手を進められるようになった。",[21,38],{},[24,40,42],{"id":41},"鬼手1の局面を-codex-と-gemini-に読ませた","鬼手1の局面を Codex と Gemini に読ませた",[10,44,45],{},"「鬼手1」は藤井八冠 vs 広瀬八段（2021/4/9）の一局から取られている。書籍にはその局面の図が載っているので、ここから盤面の SFEN を作りたい。",[10,47,48,49,52],{},"最初は Codex CLI に画像を投げた。GPT-5.5 を ",[16,50,51],{},"--image"," オプションで叩く。",[54,55,60],"pre",{"className":56,"code":57,"language":58,"meta":59,"style":59},"language-bash shiki shiki-themes vitesse-light vitesse-light","codex exec -m gpt-5.5 --image shogi-pos.png \"この局面のSFENを出力して\"\n","bash","",[16,61,62],{"__ignoreMap":59},[63,64,67,71,75,79,82,85,88,92,95],"span",{"class":65,"line":66},"line",1,[63,68,70],{"class":69},"senZ8","codex",[63,72,74],{"class":73},"sdGka"," exec",[63,76,78],{"class":77},"snbK4"," -m",[63,80,81],{"class":73}," gpt-5.5",[63,83,84],{"class":77}," --image",[63,86,87],{"class":73}," shogi-pos.png",[63,89,91],{"class":90},"sMJiu"," \"",[63,93,94],{"class":73},"この局面のSFENを出力して",[63,96,97],{"class":90},"\"\n",[10,99,100],{},"Codex は局面を読み、駒の配置を返してきた。",[10,102,103],{},"並行して Gemini にも同じ画像を投げた結果が HTML テーブルで返ってきていた。Gemini の出力には「8四は後手の飛車」と書かれている。Codex の出力では同じマスが「△桂」になっていた。",[10,105,106],{},"両方は両立しない。盤面を見比べる必要があったが、ここで Codex 側を採用してしまった。後でコマを動かしてみると駒の動きが将棋ルール上おかしい。気づいて画像を見直すと、8四は確かに飛車だった。Gemini が正しかった。修正して、Codex の局面読み取りを過信しないという教訓を1つ拾った。",[21,108],{},[24,110,112],{"id":111},"鬼手1のシナリオ-参考図ルート","鬼手1のシナリオ: 参考図ルート",[10,114,115],{},"書籍の主軸は参考図ルートで、▲9五角 → △8三飛 → ▲7三角左成 → △同金 → ▲9五桂、と進む。盤面に乗せると駒が綺麗に絡む。書籍の図はこのルートを5手で示している。",[10,117,118],{},"これを「鬼手1参考図」としてコンテンツに追加した。",[21,120],{},[24,122,124],{"id":123},"実戦譜が意味わからない状態になった","実戦譜が「意味わからない」状態になった",[10,126,127],{},"書籍には実戦譜も併記されている。手順を写経して盤に流し込んだら、途中で駒が動けないマスに進んでいる。将棋ルール上整合しない手が混じっている、ように見えた。",[10,129,130],{},"写経のミスかと思って3回読み直したが、紙の手順通りに入れているように見える。これ以上は単独で詰められないと判断して、外の棋譜DBで答え合わせをすることにした。",[21,132],{},[24,134,136],{"id":135},"agent-browser-で-shogidb2-から-kif-を取得","agent-browser で shogidb2 から KIF を取得",[10,138,139],{},"まずは Google で当該対局の棋譜を引こうとした。WebFetch で投げると bot 検知でブロックされる。Bing も同様に弾かれた。",[10,141,142],{},"ここで agent-browser に切り替えた。自分のログイン済み Chrome に繋がっている方の経路だ。Google・Bing は agent-browser でも検知されるが、shogidb2 のサイトは直接アクセスできた。当該対局のページに飛び、KIF と SFEN をブラウザ経由で取り出した。",[54,144,146],{"className":56,"code":145,"language":58,"meta":59,"style":59},"agent-browser open \"https://shogidb2.com/games/...\"\nagent-browser wait --load networkidle\nagent-browser eval 'document.querySelector(\"...\").innerText'\n",[16,147,148,163,177],{"__ignoreMap":59},[63,149,150,153,156,158,161],{"class":65,"line":66},[63,151,152],{"class":69},"agent-browser",[63,154,155],{"class":73}," open",[63,157,91],{"class":90},[63,159,160],{"class":73},"https://shogidb2.com/games/...",[63,162,97],{"class":90},[63,164,166,168,171,174],{"class":65,"line":165},2,[63,167,152],{"class":69},[63,169,170],{"class":73}," wait",[63,172,173],{"class":77}," --load",[63,175,176],{"class":73}," networkidle\n",[63,178,180,182,185,188,191],{"class":65,"line":179},3,[63,181,152],{"class":69},[63,183,184],{"class":73}," eval",[63,186,187],{"class":90}," '",[63,189,190],{"class":73},"document.querySelector(\"...\").innerText",[63,192,193],{"class":90},"'\n",[10,195,196],{},"shogidb2 の SFEN は1手ごとに記録されている。書籍の手順と並べると、書籍側の表記が一部ズレていた。実戦譜は75手まである。各手の SFEN を差分解析して、SFEN差分→指し手変換ロジックを書き、75手の実戦譜を完全復元した。",[10,198,199],{},"コンテンツの切替UI を整え、「基本5手 / 鬼手1参考図 / 鬼手1全棋譜75手」の3モードに分けた。",[21,201],{},[24,203,205],{"id":204},"駒移動アニメーションで-transitiongroup-と格闘した","駒移動アニメーションで TransitionGroup と格闘した",[10,207,208,209,212],{},"最初の盤面は ",[16,210,211],{},"\u003Ctable>"," で組んでいた。駒を動かすときに位置が瞬間移動する。これでは「どこからどこへ動いたか」が追いにくい。",[10,214,215,218],{},[16,216,217],{},"div grid + absolute レイヤー"," 方式に書き直した。駒1つずつに固有 ID を振って TransitionGroup でラップすると、再配置時に CSS で滑らかに動く想定だった。",[10,220,221,222,225],{},"ところが TransitionGroup が transform を内部的に上書きする。FLIP アニメ（First/Last/Invert/Play）で駒の移動を表現する仕組みのため、自分が ",[16,223,224],{},":style"," で書いた transform が上書きされて消える。駒が回転するアニメーションを乗せたかったが、TransitionGroup と inline transform が競合して、回転が一瞬で吹き飛ぶ。",[10,227,228,229,231],{},"加えて、古い inline transform が DOM に残る現象も起きた。こちらは ",[16,230,224],{}," で常に明示上書きすることで解決した。",[10,233,234],{},"回転アニメは諦めた。代わりに「移動先・移動元のマスをハイライト」する方式に切り替え、先手の手は青、後手の手は赤で塗った。盤面の駒は瞬間移動するが、どこからどこへ動いたかは色で追える。アニメーションを諦めた瞬間、UI が一気に落ち着いた。",[21,236],{},[24,238,240],{"id":239},"_7コミットを意味単位で分割","7コミットを意味単位で分割",[10,242,243,244,247,248,251,252,255],{},"1日で ",[16,245,246],{},"_redirects"," の自動生成、VOICEVOX 辞書、measure-deploy、日記コンテンツ、計画書メモ、",[16,249,250],{},".claude"," 設定、将棋デモ、と7種類の変更が混ざっていた。1コミットにまとめるとレビューが効かないので、意味単位で7コミットに分割した。",[16,253,254],{},"git add -p"," で1ハンクずつ振り分けて、コミットメッセージは変更の意図だけ書いた。",[21,257],{},[24,259,260],{"id":260},"今日の学び",[262,263,264,268,271,274],"ul",{},[265,266,267],"li",{},"局面の画像を AI に読ませるなら、Codex と Gemini の出力を必ず突き合わせる。片方を信じて先に進むと、ルール違反の局面で気づくまでにタイムロスが効いてくる。",[265,269,270],{},"WebFetch が bot 検知で止まるサイトは、agent-browser に切り替えると一発で通ることが多い。Google・Bing は agent-browser 越しでも厳しい。",[265,272,273],{},"TransitionGroup の FLIP は inline transform を奪いに来る。駒の transform を自前で握りたいなら TransitionGroup を諦めて、配色や枠線で「動き」を表現する方が早い。",[265,275,276,277,279],{},"1日の差分が意味の違う変更を7つ抱えていたら、",[16,278,254],{}," でコミットを割る。後から差分を読み直す自分が助かる。",[10,281,282],{},"会計士・税理士業務の文脈に橋を架けるなら、AI に資料の数値を読ませた結果はそのまま信じない、別 AI かオリジナル資料で必ず突き合わせる、というところが今日の要点になる。",[284,285,286],"style",{},"html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .snbK4, html code.shiki .snbK4{--shiki-default:#A65E2B;--shiki-dark:#A65E2B}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":59,"searchDepth":165,"depth":165,"links":288},[289,290,291,292,293,294,295,296],{"id":26,"depth":165,"text":27},{"id":41,"depth":165,"text":42},{"id":111,"depth":165,"text":112},{"id":123,"depth":165,"text":124},{"id":135,"depth":165,"text":136},{"id":204,"depth":165,"text":205},{"id":239,"depth":165,"text":240},{"id":260,"depth":165,"text":260},"dev","棋譜パーサーとSVG駒で将棋盤を動かすデモを Vue で組んだ記録。Codex CLI と Gemini で初手の局面を読み取らせて誤判定を踏み、shogidb2 から KIF を引き直して75手の実戦譜を復元、TransitionGroup の transform 上書きで折れて配色ハイライトに切り替えた1日。","md",{},true,null,"/shogi-board-demo-with-kifu-db","mdx-playground",false,"2026-05-08T00:00:00.000Z",{"title":5,"description":298},"2026-05/2026-05-08/shogi-board-demo-with-kifu-db",[310,311,312,313,314,315,152,316,317],"Vue","Nuxt","将棋","SVG","Codex CLI","Gemini","shogidb2","TransitionGroup","memo","uJNP5IPp5xvrwTSFghA1yWxAabmILhjw5dqKI2q1IUk",[],"https://log.eurekapu.com/og/blog/shogi-board-demo-with-kifu-db.png?v=2026-05-08T00%3A00%3A00.000Z&title=%E5%B0%86%E6%A3%8B%E7%9B%A4%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%83%87%E3%83%A2%E3%82%92%20Vue%20%E3%81%A7%E5%AE%9F%E8%A3%85%EF%BC%9ACodex%2FGemini%20%E3%81%A7%E5%B1%80%E9%9D%A2%E8%AA%AD%E3%81%BF%E5%8F%96%E3%82%8A%E3%80%81shogidb2%20%E3%81%8B%E3%82%8975%E6%89%8B%E5%BE%A9%E5%85%83%E3%81%99%E3%82%8B%E3%81%BE%E3%81%A7&author=Kei%20Komatsu&sig=3175ea5d160c4d05",1782528834301]