[GH-ISSUE #20598] feat: replicate old web search UI for search_web AND fetch_url #57896

Closed
opened 2026-05-05 21:52:45 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @Classic298 on GitHub (Jan 11, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/20598

Originally created by @Classic298 on GitHub (Jan 11, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/20598
Author
Owner

@shigetayouichi commented on GitHub (Mar 9, 2026):

<html> <head> <style> body{ font-family:sans-serif; background:#1c1c1c; color:white; text-align:center; } #game{ width:800px; margin:auto; } .card{ display:inline-block; padding:10px; margin:5px; background:#444; border-radius:6px; cursor:pointer; font-size:20px; } .card:hover{ background:#777; } img{ width:250px; border-radius:10px; } #affection, #shame{ margin:5px 0; } </style> </head>

AI雀士カードバトル 完全版

対戦相手を選んでください

好感度: 0
羞恥ゲージ: 0

あなたの手札

もう一度挑戦
<script> // --- キャラクター定義(Google Drive画像対応 + 性格 + 長文セリフ) --- const characters = [ { name:"クール雀士", personality:"cool", imageURL:"https://drive.google.com/uc?export=view&id=1J6rqzSuo2r7CXXCaGHpgoQ-kGp4Esw1X", strategy:"強カード温存", dialogueLong:[ "ふふ、またそのカードを選んだのね。こうなるのは分かってたのよ。顔が赤くなってるわよ。次はどうするつもり?", "その手、少し緊張してるようね。本当に素直で可愛いんだから。目を逸らさないで、見てるわよ。さあ、次のカードを出してみて。", "ほら、さっきの癖が出てるわよ。逃げ場はないわよ。少し焦ってる顔もいいわ。ふふ、焦っても無駄よ。" ] }, { name:"メガネ雀士", personality:"logic", imageURL:"https://drive.google.com/uc?export=view&id=1qsWWy2F37BYTSocnVIA6hoR0j1POg7IX", strategy:"履歴分析", dialogueLong:[ "あらあら、迷ってる顔が見えるわ。あなた、考えすぎて焦ってるわね。少しドキドキしてるでしょう?まだ勝負は終わってないわよ。", "なるほど、その手を使うのね…興味深い。顔が赤くなってるわよ。次はどう動くのかしら。", "今の選択は予想通り。焦っている様子も可愛いわ。まだ本気出してないんでしょう?" ] }, { name:"スポーツ雀士", personality:"sport", imageURL:"https://drive.google.com/uc?export=view&id=1vSulAChs7XS8f7CHoZ5gENQc_cDMuNL2", strategy:"攻撃的ランダム", dialogueLong:[ "いい勝負じゃない!もっと本気出して!その顔、負けたくないって感じね!", "勝負ってこうじゃないと楽しくないわ!焦る顔も可愛いのよ。", "ふふ、まだ遊べるわね。どんな手を出すか楽しみだわ。" ] }, { name:"和服雀士", personality:"calm", imageURL:"https://drive.google.com/uc?export=view&id=154B7G0tBAjtWDanYBIgCuk9p2cwbwe5s", strategy:"安定中間カード", dialogueLong:[ "焦らなくてもよろしいですよ。少しドキドキしてますね。次の手を楽しみにしています。", "勝負はゆっくり楽しむものです。顔が赤くなってる様子も可愛いですね。", "ふふ…あなたの考え、少し読めてきました。まだまだ油断はできませんね。" ] }, { name:"近所のおばさん", personality:"chaos", imageURL:"https://drive.google.com/uc?export=view&id=1VRtQZ9PNGpZlH36SBkmn9UqOFy7cWnnW", strategy:"完全ランダム", dialogueLong:[ "あらあら、その顔どうしたの?もう完全に読めてるわよ。次はどうする?", "そんなに真剣になって面白いわね。焦る顔も可愛いわ。", "ふふふ…次はどうなるかしら?逃げ場はないわよ。" ] } ]; // --- ゲーム変数 --- let char = null; let playerHand = [1,2,3,4,5,6,7,8,9]; let aiHand = [1,2,3,4,5,6,7,8,9]; let turn = 1; let playerScore = 0; let aiScore = 0; let playerHistory = []; let affection = 0; let shame = 0; // --- キャラクター選択 --- const charOptions = document.getElementById("charOptions"); characters.forEach((c,i)=>{ const btn = document.createElement("button"); btn.innerText = c.name; btn.onclick = ()=>{ char = c; document.getElementById("charSelect").style.display="none"; document.getElementById("battle").style.display="block"; startBattle(); }; charOptions.appendChild(btn); }); // --- 描画 --- function drawHand(){ const handDiv = document.getElementById("hand"); handDiv.innerHTML=""; playerHand.forEach(card=>{ let el = document.createElement("div"); el.className="card"; el.innerText=card; el.onclick = ()=>play(card); handDiv.appendChild(el); }); } // --- AI選択 --- function aiChoose(){ if(char.personality==="logic"){ let avg = playerHistory.reduce((a,b)=>a+b,0)/playerHistory.length||5; return aiHand.reduce((a,b)=>Math.abs(b-avg)b-a)[0]; } if(char.personality==="calm"){ return aiHand[Math.floor(aiHand.length/2)]; } if(char.personality==="chaos"){ return aiHand[Math.floor(Math.random()*aiHand.length)]; } } // --- ラウンド処理 --- function play(card){ let ai = aiChoose(); playerHand = playerHand.filter(c=>c!=card); aiHand = aiHand.filter(c=>c!=ai); playerHistory.push(card); let result="引き分け"; if(card>ai){ playerScore+=card+ai; result="あなたの勝ち"; affection+=5; shame-=5; } else if(ai>card){ aiScore+=card+ai; result="AIの勝ち"; affection+=2; shame+=3; } // KOチェック if(Math.abs(playerScore-aiScore)>=30){ result += " KO発生!"; affection+=10; shame+=10; } // ランダム長文台詞表示 const dialogueArray = char.dialogueLong; const dialogue = dialogueArray[Math.floor(Math.random()*dialogueArray.length)]; document.getElementById("dialog").innerText = result + "\n" + dialogue; document.getElementById("score").innerText = "Player:"+playerScore+" AI:"+aiScore; document.getElementById("affection").innerText = "好感度: "+affection; document.getElementById("shame").innerText = "羞恥ゲージ: "+shame; document.getElementById("turn").innerText="ターン "+turn+"/9"; turn++; if(turn>9){ // 終了時 if(playerScore>aiScore){ alert("あなたの勝利!\n圧勝/KO台詞あり"); } else if(aiScore>playerScore){ alert("AI雀士の勝利!\n完敗/KO台詞あり"); } else{ alert("引き分け"); } document.getElementById("rematchBtn").style.display="inline-block"; return; } drawHand(); } // --- バトル開始 --- function startBattle(){ document.getElementById("charImg").src = char.imageURL; document.getElementById("charName").innerText = char.name; drawHand(); document.getElementById("turn").innerText="ターン 1/9"; } // --- リマッチ --- document.getElementById("rematchBtn").onclick = ()=>{ playerHand = [1,2,3,4,5,6,7,8,9]; aiHand = [1,2,3,4,5,6,7,8,9]; turn = 1; playerScore = 0; aiScore = 0; playerHistory = []; shame = 0; affection += 5; // 連戦デレ document.getElementById("rematchBtn").style.display="none"; startBattle(); }; </script> </html>
<!-- gh-comment-id:4026480207 --> @shigetayouichi commented on GitHub (Mar 9, 2026): <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>AI雀士カードバトル 完全版</title> <style> body{ font-family:sans-serif; background:#1c1c1c; color:white; text-align:center; } #game{ width:800px; margin:auto; } .card{ display:inline-block; padding:10px; margin:5px; background:#444; border-radius:6px; cursor:pointer; font-size:20px; } .card:hover{ background:#777; } img{ width:250px; border-radius:10px; } #affection, #shame{ margin:5px 0; } </style> </head> <body> <div id="game"> <h1>AI雀士カードバトル 完全版</h1> <!-- Character selection --> <div id="charSelect"> <h2>対戦相手を選んでください</h2> <div id="charOptions"></div> </div> <!-- Battle UI --> <div id="battle" style="display:none;"> <img id="charImg"> <h2 id="charName"></h2> <p id="dialog"></p> <div id="score"></div> <div id="affection">好感度: 0</div> <div id="shame">羞恥ゲージ: 0</div> <h3>あなたの手札</h3> <div id="hand"></div> <h3 id="turn"></h3> <button id="rematchBtn" style="display:none;">もう一度挑戦</button> </div> <script> // --- キャラクター定義(Google Drive画像対応 + 性格 + 長文セリフ) --- const characters = [ { name:"クール雀士", personality:"cool", imageURL:"https://drive.google.com/uc?export=view&id=1J6rqzSuo2r7CXXCaGHpgoQ-kGp4Esw1X", strategy:"強カード温存", dialogueLong:[ "ふふ、またそのカードを選んだのね。こうなるのは分かってたのよ。顔が赤くなってるわよ。次はどうするつもり?", "その手、少し緊張してるようね。本当に素直で可愛いんだから。目を逸らさないで、見てるわよ。さあ、次のカードを出してみて。", "ほら、さっきの癖が出てるわよ。逃げ場はないわよ。少し焦ってる顔もいいわ。ふふ、焦っても無駄よ。" ] }, { name:"メガネ雀士", personality:"logic", imageURL:"https://drive.google.com/uc?export=view&id=1qsWWy2F37BYTSocnVIA6hoR0j1POg7IX", strategy:"履歴分析", dialogueLong:[ "あらあら、迷ってる顔が見えるわ。あなた、考えすぎて焦ってるわね。少しドキドキしてるでしょう?まだ勝負は終わってないわよ。", "なるほど、その手を使うのね…興味深い。顔が赤くなってるわよ。次はどう動くのかしら。", "今の選択は予想通り。焦っている様子も可愛いわ。まだ本気出してないんでしょう?" ] }, { name:"スポーツ雀士", personality:"sport", imageURL:"https://drive.google.com/uc?export=view&id=1vSulAChs7XS8f7CHoZ5gENQc_cDMuNL2", strategy:"攻撃的ランダム", dialogueLong:[ "いい勝負じゃない!もっと本気出して!その顔、負けたくないって感じね!", "勝負ってこうじゃないと楽しくないわ!焦る顔も可愛いのよ。", "ふふ、まだ遊べるわね。どんな手を出すか楽しみだわ。" ] }, { name:"和服雀士", personality:"calm", imageURL:"https://drive.google.com/uc?export=view&id=154B7G0tBAjtWDanYBIgCuk9p2cwbwe5s", strategy:"安定中間カード", dialogueLong:[ "焦らなくてもよろしいですよ。少しドキドキしてますね。次の手を楽しみにしています。", "勝負はゆっくり楽しむものです。顔が赤くなってる様子も可愛いですね。", "ふふ…あなたの考え、少し読めてきました。まだまだ油断はできませんね。" ] }, { name:"近所のおばさん", personality:"chaos", imageURL:"https://drive.google.com/uc?export=view&id=1VRtQZ9PNGpZlH36SBkmn9UqOFy7cWnnW", strategy:"完全ランダム", dialogueLong:[ "あらあら、その顔どうしたの?もう完全に読めてるわよ。次はどうする?", "そんなに真剣になって面白いわね。焦る顔も可愛いわ。", "ふふふ…次はどうなるかしら?逃げ場はないわよ。" ] } ]; // --- ゲーム変数 --- let char = null; let playerHand = [1,2,3,4,5,6,7,8,9]; let aiHand = [1,2,3,4,5,6,7,8,9]; let turn = 1; let playerScore = 0; let aiScore = 0; let playerHistory = []; let affection = 0; let shame = 0; // --- キャラクター選択 --- const charOptions = document.getElementById("charOptions"); characters.forEach((c,i)=>{ const btn = document.createElement("button"); btn.innerText = c.name; btn.onclick = ()=>{ char = c; document.getElementById("charSelect").style.display="none"; document.getElementById("battle").style.display="block"; startBattle(); }; charOptions.appendChild(btn); }); // --- 描画 --- function drawHand(){ const handDiv = document.getElementById("hand"); handDiv.innerHTML=""; playerHand.forEach(card=>{ let el = document.createElement("div"); el.className="card"; el.innerText=card; el.onclick = ()=>play(card); handDiv.appendChild(el); }); } // --- AI選択 --- function aiChoose(){ if(char.personality==="logic"){ let avg = playerHistory.reduce((a,b)=>a+b,0)/playerHistory.length||5; return aiHand.reduce((a,b)=>Math.abs(b-avg)<Math.abs(a-avg)?b:a); } if(char.personality==="sport"){ return aiHand[Math.floor(Math.random()*aiHand.length)]; } if(char.personality==="cool"){ return aiHand.sort((a,b)=>b-a)[0]; } if(char.personality==="calm"){ return aiHand[Math.floor(aiHand.length/2)]; } if(char.personality==="chaos"){ return aiHand[Math.floor(Math.random()*aiHand.length)]; } } // --- ラウンド処理 --- function play(card){ let ai = aiChoose(); playerHand = playerHand.filter(c=>c!=card); aiHand = aiHand.filter(c=>c!=ai); playerHistory.push(card); let result="引き分け"; if(card>ai){ playerScore+=card+ai; result="あなたの勝ち"; affection+=5; shame-=5; } else if(ai>card){ aiScore+=card+ai; result="AIの勝ち"; affection+=2; shame+=3; } // KOチェック if(Math.abs(playerScore-aiScore)>=30){ result += " KO発生!"; affection+=10; shame+=10; } // ランダム長文台詞表示 const dialogueArray = char.dialogueLong; const dialogue = dialogueArray[Math.floor(Math.random()*dialogueArray.length)]; document.getElementById("dialog").innerText = result + "\n" + dialogue; document.getElementById("score").innerText = "Player:"+playerScore+" AI:"+aiScore; document.getElementById("affection").innerText = "好感度: "+affection; document.getElementById("shame").innerText = "羞恥ゲージ: "+shame; document.getElementById("turn").innerText="ターン "+turn+"/9"; turn++; if(turn>9){ // 終了時 if(playerScore>aiScore){ alert("あなたの勝利!\n圧勝/KO台詞あり"); } else if(aiScore>playerScore){ alert("AI雀士の勝利!\n完敗/KO台詞あり"); } else{ alert("引き分け"); } document.getElementById("rematchBtn").style.display="inline-block"; return; } drawHand(); } // --- バトル開始 --- function startBattle(){ document.getElementById("charImg").src = char.imageURL; document.getElementById("charName").innerText = char.name; drawHand(); document.getElementById("turn").innerText="ターン 1/9"; } // --- リマッチ --- document.getElementById("rematchBtn").onclick = ()=>{ playerHand = [1,2,3,4,5,6,7,8,9]; aiHand = [1,2,3,4,5,6,7,8,9]; turn = 1; playerScore = 0; aiScore = 0; playerHistory = []; shame = 0; affection += 5; // 連戦デレ document.getElementById("rematchBtn").style.display="none"; startBattle(); }; </script> </body> </html>
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#57896