以下是一个简单的OIer(信息学竞赛选手)重生模拟器的HTML实现。这个模拟器允许用户体验从零开始成为OI选手的过程。
<!DOCTYPE html>
<html lang="zh-***">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OIer重生模拟器</title>
<style>
body {
font-family: 'Microsoft YaHei', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
color: #333;
}
h1 {
color: #2c3e50;
text-align: center;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
}
.game-container {
background-color: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-bottom: 20px;
}
.stat {
background-color: #eaf2f8;
padding: 10px;
border-radius: 5px;
text-align: center;
}
.stat-value {
font-size: 24px;
font-weight: bold;
color: #2980b9;
}
.actions {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
margin-bottom: 20px;
}
button {
padding: 10px;
border: none;
border-radius: 5px;
background-color: #3498db;
color: white;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #2980b9;
}
button:disabled {
background-color: #95a5a6;
cursor: not-allowed;
}
.log {
height: 200px;
overflow-y: auto;
border: 1px solid #ddd;
padding: 10px;
background-color: #f9f9f9;
border-radius: 5px;
margin-bottom: 20px;
}
.log-entry {
margin-bottom: 5px;
padding-bottom: 5px;
border-bottom: 1px dashed #eee;
}
.event {
color: #e74c3c;
font-weight: bold;
}
.achievement {
color: #f39c12;
font-weight: bold;
}
.year-display {
text-align: center;
font-size: 18px;
margin-bottom: 15px;
color: #2c3e50;
}
.restart-btn {
background-color: #e74c3c;
width: 100%;
padding: 12px;
font-size: 16px;
}
.restart-btn:hover {
background-color: #c0392b;
}
</style>
</head>
<body>
<div class="game-container">
<h1>OIer重生模拟器</h1>
<div class="year-display">
年龄: <span id="age">12</span>岁 | 年份: <span id="year">2023</span>年
</div>
<div class="stats">
<div class="stat">
<div>编程能力</div>
<div class="stat-value" id="coding">1</div>
</div>
<div class="stat">
<div>算法知识</div>
<div class="stat-value" id="algorithm">1</div>
</div>
<div class="stat">
<div>数学能力</div>
<div class="stat-value" id="math">1</div>
</div>
<div class="stat">
<div>体力</div>
<div class="stat-value" id="energy">100</div>
</div>
<div class="stat">
<div>金钱</div>
<div class="stat-value" id="money">1000</div>
</div>
<div class="stat">
<div>声望</div>
<div class="stat-value" id="reputation">0</div>
</div>
</div>
<div class="actions">
<button id="study-code">学习编程</button>
<button id="study-algo">学习算法</button>
<button id="study-math">学习数学</button>
<button id="practice">刷题练习</button>
<button id="***pete">参加比赛</button>
<button id="rest">休息</button>
<button id="work">兼职赚钱</button>
<button id="buy-book">购买书籍</button>
</div>
<div class="log" id="game-log">
<div class="log-entry">你重生了!现在是2023年,你12岁,决定成为一名OI选手!</div>
</div>
<button class="restart-btn" id="restart">重新开始</button>
</div>
<script>
// 游戏状态
const state = {
age: 12,
year: 2023,
coding: 1,
algorithm: 1,
math: 1,
energy: 100,
money: 1000,
reputation: 0,
books: 0,
***petitions: 0,
awards: 0,
daysPassed: 0
};
// DOM元素
const elements = {
age: document.getElementById('age'),
year: document.getElementById('year'),
coding: document.getElementById('coding'),
algorithm: document.getElementById('algorithm'),
math: document.getElementById('math'),
energy: document.getElementById('energy'),
money: document.getElementById('money'),
reputation: document.getElementById('reputation'),
log: document.getElementById('game-log')
};
// 按钮
const buttons = {
studyCode: document.getElementById('study-code'),
studyAlgo: document.getElementById('study-algo'),
studyMath: document.getElementById('study-math'),
practice: document.getElementById('practice'),
***pete: document.getElementById('***pete'),
rest: document.getElementById('rest'),
work: document.getElementById('work'),
buyBook: document.getElementById('buy-book'),
restart: document.getElementById('restart')
};
// 添加日志
function addLog(message, type = 'normal') {
const entry = document.createElement('div');
entry.className = 'log-entry';
if (type === 'event') entry.classList.add('event');
if (type === 'achievement') entry.classList.add('achievement');
entry.textContent = message;
elements.log.appendChild(entry);
elements.log.scrollTop = elements.log.scrollHeight;
}
// 更新UI
function updateUI() {
elements.age.textContent = state.age;
elements.year.textContent = state.year;
elements.coding.textContent = state.coding;
elements.algorithm.textContent = state.algorithm;
elements.math.textContent = state.math;
elements.energy.textContent = state.energy;
elements.money.textContent = state.money;
elements.reputation.textContent = state.reputation;
// 更新按钮状态
buttons.***pete.disabled = state.energy < 30 || state.algorithm < 3;
buttons.practice.disabled = state.energy < 20;
buttons.studyCode.disabled = state.energy < 15;
buttons.studyAlgo.disabled = state.energy < 15 || state.coding < 2;
buttons.studyMath.disabled = state.energy < 15;
buttons.work.disabled = state.energy < 25;
buttons.buyBook.disabled = state.money < 500;
}
// 随机事件
function randomEvent() {
const events = [
{
condition: () => state.algorithm >= 5 && Math.random() < 0.3,
message: "你被邀请参加省队集训!(+50声望)",
effect: () => { state.reputation += 50; }
},
{
condition: () => state.reputation >= 100 && Math.random() < 0.2,
message: "你被知名大学提前录取!(+100声望)",
effect: () => { state.reputation += 100; }
},
{
condition: () => Math.random() < 0.1,
message: "你感冒了,休息几天吧...(-20体力)",
effect: () => { state.energy = Math.max(0, state.energy - 20); }
},
{
condition: () => state.books > 2 && Math.random() < 0.15,
message: "你读的书派上用场了!(+2算法知识)",
effect: () => { state.algorithm += 2; }
},
{
condition: () => state.***petitions > 5 && Math.random() < 0.25,
message: "你获得了一笔奖学金!(+2000金钱)",
effect: () => { state.money += 2000; }
}
];
const possibleEvents = events.filter(e => e.condition());
if (possibleEvents.length > 0 && Math.random() < 0.4) {
const event = possibleEvents[Math.floor(Math.random() * possibleEvents.length)];
addLog(event.message, 'event');
event.effect();
}
}
// 检查成就
function checkAchievements() {
const achievements = [
{
condition: () => state.coding >= 5 && !state.hasCodingAchievement,
message: "成就解锁:编程小能手!(+10声望)",
effect: () => {
state.reputation += 10;
state.hasCodingAchievement = true;
}
},
{
condition: () => state.algorithm >= 10 && !state.hasAlgoAchievement,
message: "成就解锁:算法大师!(+30声望)",
effect: () => {
state.reputation += 30;
state.hasAlgoAchievement = true;
}
},
{
condition: () => state.***petitions >= 3 && !state.has***peteAchievement,
message: "成就解锁:比赛达人!(+20声望)",
effect: () => {
state.reputation += 20;
state.has***peteAchievement = true;
}
},
{
condition: () => state.reputation >= 50 && !state.hasReputationAchievement,
message: "成就解锁:小有名气!(+50金钱)",
effect: () => {
state.money += 50;
state.hasReputationAchievement = true;
}
}
];
achievements.forEach(achievement => {
if (achievement.condition()) {
addLog(achievement.message, 'achievement');
achievement.effect();
}
});
}
// 时间流逝
function passTime(days) {
state.daysPassed += days;
// 每30天增加1岁
if (state.daysPassed >= 365) {
state.daysPassed -= 365;
state.age++;
state.year++;
addLog(`又过了一年!你现在${state.age}岁了。`);
// 每年自动恢复一些体力
state.energy = Math.min(100, state.energy + 30);
// 随机事件
randomEvent();
}
// 检查成就
checkAchievements();
}
// 游戏动作
buttons.studyCode.addEventListener('click', () => {
state.coding += 1;
state.energy -= 15;
addLog("你学习了编程基础,编程能力+1");
passTime(7);
updateUI();
});
buttons.studyAlgo.addEventListener('click', () => {
state.algorithm += 1;
state.energy -= 15;
addLog("你学习了算法知识,算法能力+1");
passTime(7);
updateUI();
});
buttons.studyMath.addEventListener('click', () => {
state.math += 1;
state.energy -= 15;
addLog("你学习了数学知识,数学能力+1");
passTime(7);
updateUI();
});
buttons.practice.addEventListener('click', () => {
const gain = Math.floor(Math.random() * 2) + 1;
state.algorithm += gain;
state.coding += gain;
state.energy -= 20;
addLog(`你刷了一些题目,编程和算法能力+${gain}`);
passTime(3);
updateUI();
});
buttons.***pete.addEventListener('click', () => {
state.***petitions++;
const performance = Math.floor((state.algorithm + state.coding + state.math) / 3) + Math.floor(Math.random() * 5);
if (performance > 10) {
state.reputation += 30;
state.money += 1000;
addLog("你在比赛中获得了金牌!(+30声望, +1000金钱)");
} else if (performance > 7) {
state.reputation += 20;
state.money += 500;
addLog("你在比赛中获得了银牌!(+20声望, +500金钱)");
} else if (performance > 5) {
state.reputation += 10;
state.money += 200;
addLog("你在比赛中获得了铜牌!(+10声望, +200金钱)");
} else {
addLog("你在比赛中表现一般,但积累了经验");
}
state.energy -= 30;
passTime(14);
updateUI();
});
buttons.rest.addEventListener('click', () => {
state.energy = Math.min(100, state.energy + 30);
addLog("你休息了一段时间,体力恢复了");
passTime(5);
updateUI();
});
buttons.work.addEventListener('click', () => {
const earnings = 200 + Math.floor(Math.random() * 300);
state.money += earnings;
state.energy -= 25;
addLog(`你做了一些兼职工作,赚了${earnings}元`);
passTime(10);
updateUI();
});
buttons.buyBook.addEventListener('click', () => {
state.money -= 500;
state.books++;
const bookType = ["算法", "编程", "数学"][Math.floor(Math.random() * 3)];
addLog(`你购买了一本${bookType}书籍,可以更好地学习了`);
passTime(2);
updateUI();
});
buttons.restart.addEventListener('click', () => {
if (confirm("确定要重新开始游戏吗?")) {
// 重置状态
state.age = 12;
state.year = 2023;
state.coding = 1;
state.algorithm = 1;
state.math = 1;
state.energy = 100;
state.money = 1000;
state.reputation = 0;
state.books = 0;
state.***petitions = 0;
state.awards = 0;
state.daysPassed = 0;
// 清除日志
elements.log.innerHTML = '';
addLog("你重生了!现在是2023年,你12岁,决定成为一名OI选手!");
// 更新UI
updateUI();
}
});
// 初始化UI
updateUI();
</script>
</body>
</html>
使用说明
- 将上面的代码复制到一个文本编辑器中
- 保存为
.html文件(例如oier-simulator.html) - 用浏览器打开该文件即可开始游戏
游戏功能
- 属性系统:编程能力、算法知识、数学能力、体力、金钱和声望
- 多种活动:学习编程、学习算法、学习数学、刷题练习、参加比赛、休息、兼职赚钱、购买书籍
- 随机事件:游戏中会随机触发各种事件
- 成就系统:达到特定条件会解锁成就
- 时间流逝:随着年龄增长,你会遇到更多机会和挑战
游戏目标
努力提升自己的各项能力,参加比赛获得奖项,最终成为OI大神!
你可以根据需要修改代码,调整游戏平衡性或添加更多功能。