こんにちは、AM0500です。
今回は、ちいかわに出てくる「下剋上オンライン」をイメージして作ろうとしたらまったく別のゲームができたお話です。ちいかわが好きでいつかあれをゲーム化して公開してみたいと思っていたのですが、まずはAIだとどんなのを作ってくれるのだろうと思い試してみたところ・・・
🔗 実際にプレイしてみる
▼ ブラウザでそのまま遊べます(PC推奨):
👉 ちいかわの下剋上オンラインを作ろうとしたら別ゲームになってしまったゲーム
👉 使用したAI Claude(claude 4 sonnet)はこちら
※英語でとっつきにくく見えますが、やり取りは日本語でできます。
誰でも作れる作成用プロンプトとコピペで遊べるhtmlソースコードを公開していますので、よろしければご利用ください。
🎮 ゲーム画面(スクリーンショット)


📝 一言コメント
ナガノ先生の作品が好きで、ちいかわももちろん大好きで、作中に出てくる「下剋上オンライン」というゲームを再現したら面白いかなと思ってAIに指示してみました。
しかし、AIは流石にちいかわの下剋上オンラインを認識できず、現代版の成り上がりゲームが作成されました。今後、プロンプトを変更して再挑戦予定です。果たして下剋上オンラインは完成するのか?
Bloggerに作品を公開しているのですが、仕様により「¥」や「。」「!」などの文字が使えず、一部の文字を削ったバージョンを公開しています。
オリジナルのソースはこちらのNoteの内容を参照ください。
🧠 使用したClaudeへのプロンプト
以下のような指示だけで、今回のゲームが生成されました。
ちいかわで出てくる「下剋上オンライン」みたいなゲームは作れる?さすがにちいかわで出てくる~は認識されず「下剋上オンライン」という響きから、オリジナルのゲームを作ってくれました。
🕹️ Claudeが返してくれた説明文
ちいかわの「下剋上オンライン」を再現したゲームを作成しました!
ゲームの特徴:
🎯 基本システム
フリーターから社長まで11段階の職業階層
「働く」と「上司に挑戦」の2つのメインアクション
レベル、経験値、お金、体力の管理
⚡ 働くシステム
7種類のランダムイベント(褒められたり、ミスしたり)
職業レベルに応じた基本給与
体力消費と経験値獲得
🔥 挑戦システム
体力30消費で上司に挑戦
レベルと経験値に基づく成功確率
成功すれば昇進、失敗すれば降格の可能性
📊 ハラハラ要素
成功確率は30%~80%の間で変動
降格リスクがあるスリリングな挑戦
体力管理が重要な戦略要素
🎮 ゲームの流れ
働いて経験値とお金を貯める
体力が溜まったら上司に挑戦
成功すれば昇進、失敗すれば降格リスク
社長を目指して頑張る!
原作のハラハラドキドキ感を再現しつつ、長期的な成長要素も盛り込みました。体力は自動回復するので、気長に社長を目指してください!
💡 ソースコード(HTML)
下記がhtmlの中身になります。ご自由にご利用ください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>下剋上オンライン</title>
<style>
body {
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
font-family: 'Meiryo', sans-serif;
color: white;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.game-container {
background: rgba(0, 0, 0, 0.8);
border-radius: 20px;
padding: 30px;
max-width: 800px;
width: 100%;
border: 2px solid #34495e;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
.game-title {
text-align: center;
font-size: 28px;
font-weight: bold;
margin-bottom: 20px;
color: #e74c3c;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
.status-bar {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
padding: 15px;
background: rgba(52, 73, 94, 0.5);
border-radius: 10px;
}
.status-item {
text-align: center;
}
.status-label {
font-size: 12px;
color: #bdc3c7;
margin-bottom: 5px;
}
.status-value {
font-size: 18px;
font-weight: bold;
color: #ecf0f1;
}
.current-job {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background: linear-gradient(135deg, #8e44ad, #9b59b6);
border-radius: 15px;
box-shadow: 0 5px 15px rgba(142, 68, 173, 0.3);
}
.job-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
}
.job-description {
font-size: 14px;
color: #f8f9fa;
opacity: 0.9;
}
.actions {
display: flex;
gap: 15px;
margin-bottom: 30px;
}
.action-btn {
flex: 1;
padding: 15px 20px;
font-size: 16px;
font-weight: bold;
border: none;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s;
color: white;
}
.work-btn {
background: linear-gradient(135deg, #27ae60, #2ecc71);
box-shadow: 0 4px 15px rgba(46, 204, 113, 0.3);
}
.work-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(46, 204, 113, 0.4);
}
.challenge-btn {
background: linear-gradient(135deg, #e74c3c, #c0392b);
box-shadow: 0 4px 15px rgba(231, 76, 60, 0.3);
}
.challenge-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(231, 76, 60, 0.4);
}
.challenge-btn:disabled {
background: #7f8c8d;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.log {
background: rgba(52, 73, 94, 0.3);
border-radius: 10px;
padding: 20px;
max-height: 200px;
overflow-y: auto;
margin-bottom: 20px;
}
.log-entry {
margin-bottom: 10px;
padding: 8px 12px;
border-radius: 5px;
font-size: 14px;
animation: slideIn 0.3s ease-out;
}
.log-success {
background: rgba(46, 204, 113, 0.2);
border-left: 4px solid #2ecc71;
}
.log-failure {
background: rgba(231, 76, 60, 0.2);
border-left: 4px solid #e74c3c;
}
.log-promotion {
background: rgba(241, 196, 15, 0.2);
border-left: 4px solid #f1c40f;
font-weight: bold;
}
.log-demotion {
background: rgba(155, 89, 182, 0.2);
border-left: 4px solid #9b59b6;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.challenge-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: none;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background: #2c3e50;
padding: 30px;
border-radius: 15px;
text-align: center;
max-width: 400px;
width: 90%;
border: 2px solid #34495e;
}
.modal-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 20px;
color: #e74c3c;
}
.modal-text {
margin-bottom: 20px;
line-height: 1.6;
}
.modal-btn {
padding: 10px 20px;
margin: 0 10px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
color: white;
}
.modal-accept {
background: linear-gradient(135deg, #e74c3c, #c0392b);
}
.modal-decline {
background: linear-gradient(135deg, #7f8c8d, #95a5a6);
}
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
margin-top: 20px;
}
.stat-card {
background: rgba(52, 73, 94, 0.5);
padding: 15px;
border-radius: 10px;
text-align: center;
}
.stat-title {
font-size: 12px;
color: #bdc3c7;
margin-bottom: 5px;
}
.stat-value {
font-size: 18px;
font-weight: bold;
color: #ecf0f1;
}
</style>
</head>
<body>
<div class="game-container">
<div class="game-title">下剋上オンライン</div>
<div class="status-bar">
<div class="status-item">
<div class="status-label">レベル</div>
<div class="status-value" id="level">1</div>
</div>
<div class="status-item">
<div class="status-label">経験値</div>
<div class="status-value" id="exp">0</div>
</div>
<div class="status-item">
<div class="status-label">お金</div>
<div class="status-value" id="money">¥1000</div>
</div>
<div class="status-item">
<div class="status-label">体力</div>
<div class="status-value" id="stamina">100</div>
</div>
</div>
<div class="current-job" id="currentJob">
<div class="job-title" id="jobTitle">フリーター</div>
<div class="job-description" id="jobDescription">日雇いのアルバイトをしています</div>
</div>
<div class="actions">
<button class="action-btn work-btn" onclick="work()">働く</button>
<button class="action-btn challenge-btn" id="challengeBtn" onclick="showChallenge()">上司に挑戦</button>
</div>
<div class="log" id="gameLog"></div>
<div class="stats">
<div class="stat-card">
<div class="stat-title">成功回数</div>
<div class="stat-value" id="successCount">0</div>
</div>
<div class="stat-card">
<div class="stat-title">失敗回数</div>
<div class="stat-value" id="failureCount">0</div>
</div>
<div class="stat-card">
<div class="stat-title">昇進回数</div>
<div class="stat-value" id="promotionCount">0</div>
</div>
<div class="stat-card">
<div class="stat-title">降格回数</div>
<div class="stat-value" id="demotionCount">0</div>
</div>
</div>
</div>
<div class="challenge-modal" id="challengeModal">
<div class="modal-content">
<div class="modal-title">上司への挑戦</div>
<div class="modal-text" id="challengeText">
本当に上司に挑戦しますか?<br>
成功すれば昇進、失敗すれば降格の可能性があります。
</div>
<button class="modal-btn modal-accept" onclick="challenge()">挑戦する</button>
<button class="modal-btn modal-decline" onclick="hideChallenge()">やめる</button>
</div>
</div>
<script>
// ゲーム状態
let gameState = {
level: 1,
exp: 0,
money: 1000,
stamina: 100,
jobLevel: 0,
successCount: 0,
failureCount: 0,
promotionCount: 0,
demotionCount: 0,
lastChallengeTime: 0
};
// 職業データ
const jobs = [
{ title: "フリーター", description: "日雇いのアルバイトをしています", salary: 100, challengeReq: 0 },
{ title: "アルバイト", description: "コンビニでバイトしています", salary: 150, challengeReq: 50 },
{ title: "派遣社員", description: "派遣会社で働いています", salary: 200, challengeReq: 100 },
{ title: "契約社員", description: "契約社員として働いています", salary: 300, challengeReq: 200 },
{ title: "正社員", description: "正社員として働いています", salary: 500, challengeReq: 350 },
{ title: "主任", description: "チームのリーダーです", salary: 750, challengeReq: 500 },
{ title: "係長", description: "係をまとめています", salary: 1000, challengeReq: 750 },
{ title: "課長", description: "課の責任者です", salary: 1500, challengeReq: 1000 },
{ title: "部長", description: "部門の責任者です", salary: 2000, challengeReq: 1500 },
{ title: "取締役", description: "会社の役員です", salary: 3000, challengeReq: 2500 },
{ title: "社長", description: "会社のトップです!", salary: 5000, challengeReq: 4000 }
];
// ランダムイベント
const workEvents = [
{ message: "真面目に働きました", exp: 10, money: 0, stamina: -10 },
{ message: "残業をしました", exp: 15, money: 50, stamina: -20 },
{ message: "上司に褒められました", exp: 20, money: 100, stamina: -5 },
{ message: "ミスをしてしまいました", exp: 5, money: -50, stamina: -15 },
{ message: "新しいスキルを覚えました", exp: 25, money: 0, stamina: -10 },
{ message: "同僚と仲良くなりました", exp: 12, money: 0, stamina: -8 },
{ message: "お客さんに感謝されました", exp: 18, money: 80, stamina: -12 }
];
// UI更新
function updateUI() {
document.getElementById('level').textContent = gameState.level;
document.getElementById('exp').textContent = gameState.exp;
document.getElementById('money').textContent = '¥' + gameState.money;
document.getElementById('stamina').textContent = gameState.stamina;
document.getElementById('successCount').textContent = gameState.successCount;
document.getElementById('failureCount').textContent = gameState.failureCount;
document.getElementById('promotionCount').textContent = gameState.promotionCount;
document.getElementById('demotionCount').textContent = gameState.demotionCount;
const currentJob = jobs[gameState.jobLevel];
document.getElementById('jobTitle').textContent = currentJob.title;
document.getElementById('jobDescription').textContent = currentJob.description;
// 挑戦ボタンの状態
const challengeBtn = document.getElementById('challengeBtn');
const canChallenge = gameState.stamina >= 30 && gameState.jobLevel < jobs.length - 1;
challengeBtn.disabled = !canChallenge;
if (gameState.jobLevel >= jobs.length - 1) {
challengeBtn.textContent = "最高位到達";
} else {
challengeBtn.textContent = "上司に挑戦";
}
}
// ログを追加
function addLog(message, type = 'success') {
const logContainer = document.getElementById('gameLog');
const logEntry = document.createElement('div');
logEntry.className = `log-entry log-${type}`;
logEntry.textContent = message;
logContainer.insertBefore(logEntry, logContainer.firstChild);
// ログが多くなったら古いものを削除
while (logContainer.children.length > 10) {
logContainer.removeChild(logContainer.lastChild);
}
}
// 働く
function work() {
if (gameState.stamina < 10) {
addLog("体力不足で働けません", "failure");
return;
}
const currentJob = jobs[gameState.jobLevel];
const event = workEvents[Math.floor(Math.random() * workEvents.length)];
// 基本報酬
gameState.money += currentJob.salary;
gameState.exp += event.exp;
gameState.stamina = Math.max(0, gameState.stamina + event.stamina);
// イベント報酬
if (event.money > 0) {
gameState.money += event.money;
addLog(`${event.message} (+${event.exp}EXP, +¥${currentJob.salary + event.money})`, "success");
} else if (event.money < 0) {
gameState.money = Math.max(0, gameState.money + event.money);
addLog(`${event.message} (+${event.exp}EXP, ${event.money}円)`, "failure");
} else {
addLog(`${event.message} (+${event.exp}EXP, +¥${currentJob.salary})`, "success");
}
gameState.successCount++;
// レベルアップチェック
const expNeeded = gameState.level * 100;
if (gameState.exp >= expNeeded) {
gameState.level++;
gameState.exp -= expNeeded;
gameState.stamina = Math.min(100, gameState.stamina + 20);
addLog(`レベルアップ! レベル${gameState.level}になりました`, "promotion");
}
// 体力回復(少し)
gameState.stamina = Math.min(100, gameState.stamina + 2);
updateUI();
}
// 挑戦モーダルを表示
function showChallenge() {
if (gameState.stamina < 30) {
addLog("体力不足で挑戦できません", "failure");
return;
}
if (gameState.jobLevel >= jobs.length - 1) {
addLog("既に最高位に到達しています", "failure");
return;
}
const nextJob = jobs[gameState.jobLevel + 1];
const challengeText = document.getElementById('challengeText');
challengeText.innerHTML = `
${nextJob.title}への昇進を目指しますか?<br>
必要体力: 30<br>
成功すれば昇進、失敗すれば降格の可能性があります。
`;
document.getElementById('challengeModal').style.display = 'flex';
}
// 挑戦モーダルを非表示
function hideChallenge() {
document.getElementById('challengeModal').style.display = 'none';
}
// 挑戦実行
function challenge() {
hideChallenge();
gameState.stamina -= 30;
// 成功確率計算(レベルと経験値に基づく)
const baseSuccessRate = 0.3;
const levelBonus = gameState.level * 0.05;
const expBonus = Math.min(gameState.exp / 1000, 0.2);
const successRate = Math.min(baseSuccessRate + levelBonus + expBonus, 0.8);
const success = Math.random() < successRate;
if (success) {
// 昇進
gameState.jobLevel++;
gameState.promotionCount++;
gameState.exp += 50;
gameState.money += 500;
const newJob = jobs[gameState.jobLevel];
addLog(`昇進しました! ${newJob.title}になりました!`, "promotion");
if (gameState.jobLevel >= jobs.length - 1) {
addLog("おめでとうございます!社長に到達しました!", "promotion");
}
} else {
// 失敗
gameState.failureCount++;
// 降格の可能性
if (gameState.jobLevel > 0 && Math.random() < 0.4) {
gameState.jobLevel--;
gameState.demotionCount++;
const newJob = jobs[gameState.jobLevel];
addLog(`降格してしまいました... ${newJob.title}になりました`, "demotion");
} else {
addLog("挑戦に失敗しました。次回頑張りましょう", "failure");
}
gameState.money = Math.max(0, gameState.money - 200);
}
updateUI();
}
// 自動体力回復
setInterval(() => {
if (gameState.stamina < 100) {
gameState.stamina = Math.min(100, gameState.stamina + 1);
updateUI();
}
}, 3000);
// ゲーム開始
addLog("下剋上オンラインへようこそ!頑張って社長を目指しましょう!", "promotion");
updateUI();
</script>
</body>
</html>🔔 補足・注意事項
このコードや説明は、Claudeのバージョンや環境によって出力内容が異なる可能性があります。
同じ命令をしても、まったく違うコードが返ってくることもあるので、再現性は参考程度にご覧ください。

0 件のコメント:
コメントを投稿