可信源码风险提示:保存或下载前请阅读源码和权限声明。
var SAVE_KEY = 'auto_chess_v3';
var g = ui.signal({
page: 'home',
gold: 10,
hp: 100,
round: 1,
streak: 0,
phase: 'prepare',
shop: [],
shopLevel: 1,
myUnits: [],
enemies: [],
bench: [],
bag: [],
logs: ['欢迎'],
selCell: null,
selBench: null,
detailHero: null,
compPage: 0,
winCount: 0
});
function clone(o) {
if (o === null || typeof o !== 'object') return o;
if (Array.isArray(o)) {
var a = [];
for (var i = 0; i < o.length; i++) a.push(clone(o[i]));
return a;
}
var n = {};
for (var k in o) if (o.hasOwnProperty(k)) n[k] = clone(o[k]);
return n;
}
function update(fn) {
var s = clone(g.get());
fn(s);
g.set(s);
}
var HEROES = [
{ id: 'h1', n: '诺手', r: '帝国', j: '战士', c: 1, hp: 650, a: 55, rg: 1, s: '流血:普攻附带5%最大生命伤害' },
{ id: 'h2', n: '德玛', r: '帝国', j: '坦克', c: 1, hp: 850, a: 40, rg: 1, s: '大反派:优先攻击最高血量' },
{ id: 'h3', n: '寒冰', r: '极地', j: '射手', c: 1, hp: 450, a: 60, rg: 3, s: '冰冻:25%冰冻敌人' },
{ id: 'h4', n: '大树', r: '森林', j: '坦克', c: 1, hp: 900, a: 35, rg: 1, s: '回春:每回合回血' },
{ id: 'h5', n: '小法', r: '约德尔', j: '法师', c: 2, hp: 450, a: 80, rg: 3, s: '爆发:优先最低血量' },
{ id: 'h6', n: '劫', r: '忍者', j: '刺客', c: 2, hp: 550, a: 75, rg: 1, s: '影分身:30%双倍伤害' },
{ id: 'h7', n: '奶妈', r: '星神', j: '辅助', c: 2, hp: 500, a: 30, rg: 2, s: '星落:治疗最低队友' },
{ id: 'h8', n: '狐狸', r: '星神', j: '法师', c: 2, hp: 480, a: 65, rg: 2, s: '宝珠:弹射伤害' },
{ id: 'h9', n: '卡特', r: '帝国', j: '刺客', c: 3, hp: 600, a: 70, rg: 1, s: '莲华:50%溅射伤害' },
{ id: 'h10', n: '奥拉夫', r: '极地', j: '战士', c: 3, hp: 750, a: 65, rg: 1, s: '诸神黄昏:攻击两次' },
{ id: 'h11', n: '火男', r: '恶魔', j: '法师', c: 3, hp: 550, a: 75, rg: 3, s: '烈焰:范围溅射' },
{ id: 'h12', n: '亚索', r: '浪人', j: '战士', c: 4, hp: 700, a: 70, rg: 1, s: '狂风绝息斩:无视护甲' },
{ id: 'h13', n: '剑圣', r: '浪人', j: '刺客', c: 3, hp: 600, a: 80, rg: 1, s: '阿尔法突袭:闪避普攻' },
{ id: 'h14', n: '光辉', r: '帝国', j: '法师', c: 4, hp: 500, a: 90, rg: 4, s: '终极闪光:贯穿直线' },
{ id: 'h15', n: '大虫子', r: '虚空', j: '坦克', c: 3, hp: 950, a: 45, rg: 1, s: '破裂:降低敌方防御' },
{ id: 'h16', n: '卡莎', r: '虚空', j: '射手', c: 4, hp: 600, a: 85, rg: 3, s: '虚空突袭:获得护盾' },
{ id: 'h17', n: '挖掘机', r: '虚空', j: '战士', c: 2, hp: 700, a: 50, rg: 1, s: '遁地:恢复生命' },
{ id: 'h18', n: '螳螂', r: '虚空', j: '刺客', c: 1, hp: 500, a: 60, rg: 1, s: '品尝恐惧:孤立无援伤害翻倍' },
{ id: 'h19', n: '龙王', r: '星神', j: '法师', c: 5, hp: 800, a: 100, rg: 4, s: '星弦高落:全屏伤害' },
{ id: 'h20', n: '死歌', r: '亡灵', j: '法师', c: 5, hp: 700, a: 110, rg: 5, s: '安魂曲:轰炸所有敌人' }
];
var EQUIPS = [
{ id: 'e1', n: '大剑', a: 20, hp: 0 },
{ id: 'e2', n: '反曲弓', a: 10, hp: 100 },
{ id: 'e3', n: '大棒', a: 15, hp: 80 },
{ id: 'e4', n: '腰带', a: 0, hp: 250 },
{ id: 'e5', n: '斗篷', a: 5, hp: 180 },
{ id: 'e6', n: '眼泪', a: 8, hp: 120 }
];
var battleTimer = null;
function loadData() {
try {
var d = settingsStorage.getItem(SAVE_KEY);
if (d) {
var p = JSON.parse(d);
update(function(s) { s.winCount = p.w || 0; });
}
} catch(e) {}
}
function saveData() {
try {
var s = g.get();
settingsStorage.setItem(SAVE_KEY, JSON.stringify({ w: s.winCount }));
} catch(e) {}
}
function rollShop() {
update(function(s) {
var pool = HEROES.filter(function(h) { return h.c <= s.shopLevel + 1; });
var nShop = [];
for (var i = 0; i < 3; i++) nShop.push(pool[Math.floor(Math.random() * pool.length)]);
s.shop = nShop;
});
}
function getSynergies(units) {
var j = {}, r = {};
for (var i = 0; i < units.length; i++) {
j[units[i].j] = (j[units[i].j] || 0) + 1;
r[units[i].r] = (r[units[i].r] || 0) + 1;
}
var t = [];
for (var k in j) if (j[k] >= 2) t.push(k + j[k]);
for (var k in r) if (r[k] >= 2) t.push(k + r[k]);
return t.length ? t.join(' ') : '无';
}
function applySynergy(s) {
var j = {}, r = {};
for (var i = 0; i < s.myUnits.length; i++) {
j[s.myUnits[i].j] = (j[s.myUnits[i].j] || 0) + 1;
r[s.myUnits[i].r] = (r[s.myUnits[i].r] || 0) + 1;
}
var atkAdd = 0, hpAdd = 0;
if (j['战士'] >= 2) atkAdd += 15;
if (j['法师'] >= 2) atkAdd += 20;
if (j['坦克'] >= 2) hpAdd += 200;
if (j['刺客'] >= 2) atkAdd += 20;
if (r['帝国'] >= 2) atkAdd += 25;
if (r['极地'] >= 2) hpAdd += 150;
if (r['星神'] >= 2) hpAdd += 150;
if (r['虚空'] >= 2) atkAdd += 30;
if (r['约德尔'] >= 2) hpAdd += 100;
for (var i = 0; i < s.myUnits.length; i++) {
s.myUnits[i].a += atkAdd;
s.myUnits[i].hp += hpAdd;
s.myUnits[i].maxHp += hpAdd;
}
}
function buyHero(idx) {
update(function(s) {
if (s.phase === 'battle' || !s.shop[idx]) return;
var h = s.shop[idx];
if (s.gold < h.c) { s.logs.push('金币不足'); return; }
if (s.bench.length >= 4) { s.logs.push('待命区已满'); return; }
var same = s.bench.filter(function(u) { return u.id === h.id && u.star === 1; });
if (same.length >= 2) {
same[0].star = 2;
same[0].hp = h.hp * 2;
same[0].maxHp = h.hp * 2;
same[0].a = h.a + Math.floor(h.a * 0.8);
s.bench = s.bench.filter(function(u) { return u !== same[1]; });
s.logs.push(h.n + '升至2星');
} else {
s.bench.push({
id: h.id, n: h.n, r: h.r, j: h.j, c: h.c, star: 1,
hp: h.hp, maxHp: h.hp, a: h.a, rg: h.rg, s: h.s
});
}
s.gold -= h.c;
s.shop[idx] = null;
});
}
function selBenchUnit(idx) {
update(function(s) {
if (s.phase === 'battle') return;
if (s.bench[idx]) {
s.selBench = idx;
s.selCell = null;
}
});
}
function clickCell(x, y) {
update(function(s) {
if (s.phase === 'battle') return;
var unitIdx = -1;
for (var i = 0; i < s.myUnits.length; i++) {
if (s.myUnits[i].x === x && s.myUnits[i].y === y) { unitIdx = i; break; }
}
if (s.selBench !== null) {
if (unitIdx !== -1) { s.logs.push('位置被占'); return; }
var bUnit = s.bench.splice(s.selBench, 1)[0];
bUnit.x = x;
bUnit.y = y;
s.myUnits.push(bUnit);
s.selBench = null;
s.selCell = null;
} else if (unitIdx !== -1) {
s.selCell = { x: x, y: y };
s.selBench = null;
} else {
s.selCell = { x: x, y: y };
}
});
}
function sellSelected() {
update(function(s) {
if (s.phase === 'battle' || !s.selCell) return;
for (var i = 0; i < s.myUnits.length; i++) {
if (s.myUnits[i].x === s.selCell.x && s.myUnits[i].y === s.selCell.y) {
s.gold += s.myUnits[i].c;
s.logs.push('出售获得' + s.myUnits[i].c + '金');
s.myUnits.splice(i, 1);
break;
}
}
s.selCell = null;
});
}
function buyEquip() {
update(function(s) {
if (s.gold < 3 || s.phase === 'battle') return;
s.bag.push(EQUIPS[Math.floor(Math.random() * EQUIPS.length)]);
s.gold -= 3;
s.logs.push('获得装备');
});
}
function startBattle() {
var state = g.get();
if (state.phase === 'battle' || !state.myUnits.length) return;
update(function(s) {
s.phase = 'battle';
s.enemies = [];
s.selCell = null;
s.selBench = null;
var count = Math.min(6, 1 + Math.floor(s.round / 2));
for (var i = 0; i < count; i++) {
var h = HEROES[Math.floor(Math.random() * HEROES.length)];
var row = Math.floor(Math.random() * 3);
var col = Math.floor(Math.random() * 4);
var dup = false;
for (var j = 0; j < s.enemies.length; j++) {
if (s.enemies[j].x === col && s.enemies[j].y === row) { dup = true; break; }
}
if (!dup) {
s.enemies.push({
id: h.id, n: h.n, r: h.r, j: h.j, star: 1, team: 1, x: col, y: row,
hp: h.hp + s.round * 50, maxHp: h.hp + s.round * 50,
a: h.a + s.round * 5, rg: h.rg, s: h.s, frozen: 0
});
}
}
for (var i = 0; i < s.myUnits.length; i++) {
s.myUnits[i].team = 0;
s.myUnits[i].frozen = 0;
}
applySynergy(s);
s.logs.push('战斗开始');
});
if (battleTimer) clearTimeout(battleTimer);
battleTimer = setTimeout(battleTick, 500);
}
function battleTick() {
var s = g.get();
if (s.phase !== 'battle') return;
var all = s.myUnits.concat(s.enemies);
var aliveM = 0, aliveE = 0, i, j;
for (i = 0; i < s.myUnits.length; i++) if (s.myUnits[i].hp > 0) aliveM++;
for (i = 0; i < s.enemies.length; i++) if (s.enemies[i].hp > 0) aliveE++;
if (!aliveM || !aliveE) {
update(function(st) {
st.phase = 'prepare';
if (aliveM) {
var inc = 5 + st.streak;
st.gold += inc;
st.streak++;
st.winCount++;
st.round++;
st.logs.push('胜利 +' + inc + '金');
} else {
st.hp -= 10;
st.streak = 0;
st.logs.push('失败 -10血');
}
for (i = 0; i < st.myUnits.length; i++) st.myUnits[i].hp = st.myUnits[i].maxHp;
st.enemies = [];
});
saveData();
return;
}
update(function(st) {
var all = st.myUnits.concat(st.enemies);
for (var i = 0; i < all.length; i++) {
var u = all[i];
if (u.hp <= 0) continue;
if (u.frozen > 0) { u.frozen--; continue; }
var targets = u.team === 0 ? st.enemies : st.myUnits;
var target = null, minD = 999;
for (var j = 0; j < targets.length; j++) {
if (targets[j].hp > 0) {
var d = Math.abs(u.x - targets[j].x) + Math.abs(u.y - targets[j].y);
if (d < minD) { minD = d; target = targets[j]; }
}
}
if (!target) continue;
if (minD <= u.rg) {
var dmg = u.a;
if (u.id === 'h6' && Math.random() < 0.3) dmg *= 2;
target.hp -= dmg;
if (u.id === 'h1') target.hp -= Math.floor(target.maxHp * 0.05);
if (u.id === 'h3' && Math.random() < 0.25) target.frozen = 1;
if (target.hp < 0) target.hp = 0;
} else {
var nx = u.x, ny = u.y;
if (u.x < target.x) nx++; else if (u.x > target.x) nx--;
else if (u.y < target.y) ny++; else if (u.y > target.y) ny--;
var occ = false;
for (var j = 0; j < all.length; j++) {
if (all[j] !== u && all[j].hp > 0 && all[j].x === nx && all[j].y === ny) { occ = true; break; }
}
if (!occ && nx >= 0 && nx < 4 && ny >= 0 && ny < 6) { u.x = nx; u.y = ny; }
}
}
});
battleTimer = setTimeout(battleTick, 500);
}
function goPage(p) {
update(function(s) {
s.page = p;
if (p === 'home') {
s.phase = 'prepare';
s.myUnits = []; s.enemies = []; s.bench = [];
s.selCell = null; s.selBench = null;
}
});
}
function resetGame() {
if (battleTimer) clearTimeout(battleTimer);
update(function(s) {
s.round = 1; s.gold = 10; s.hp = 100; s.streak = 0; s.phase = 'prepare';
s.myUnits = []; s.enemies = []; s.bench = []; s.bag = [];
s.logs = ['重置']; s.selCell = null; s.selBench = null;
});
rollShop();
}
loadData();
rollShop();
ui.showHeader(false);
ui.render(function() {
var s = g.get();
if (s.page === 'home') {
return ui.column([
ui.text('', { id: 'h_s1', size: 50, lines: 1 }),
ui.text('自走棋大师', { id: 'h_t1', size: 32, lines: 1, color: '#f1c40f', align: 'center' }),
ui.text('最高连胜: ' + s.winCount, { id: 'h_t2', size: 16, lines: 1, color: '#1abc9c', align: 'center' }),
ui.text('', { id: 'h_s2', size: 30, lines: 1 }),
ui.stack([
ui.button('开始游戏', function() { goPage('game'); }, { id: 'h_b1', x: 68, y: 0, width: 200, height: 50, lines: 1, background: '#27ae60', color: '#fff' }),
ui.button('英雄图鉴', function() { update(function(st){ st.page = 'compendium'; st.compPage = 0; }); }, { id: 'h_b2', x: 68, y: 65, width: 200, height: 50, lines: 1, background: '#2980b9', color: '#fff' }),
ui.button('退出游戏', function() { if (typeof script !== 'undefined' && script.exit) script.exit(); }, { id: 'h_b3', x: 68, y: 130, width: 200, height: 50, lines: 1, background: '#7f8c8d', color: '#fff' })
], { id: 'h_st', height: 180 })
], { id: 'h_col', gap: 0 });
}
if (s.page === 'compendium') {
var b = [];
var start = s.compPage * 6;
for (var i = 0; i < 6; i++) {
var idx = start + i;
if (idx >= HEROES.length) break;
var h = HEROES[idx];
b.push(ui.button(h.n + ' ' + h.c + '费', (function(hero) {
return function() { update(function(st){ st.page = 'detail'; st.detailHero = hero; }); };
})(h), {
id: 'c_b' + i, x: (i % 2) * 164 + 4, y: Math.floor(i / 2) * 60, width: 160, height: 50,
background: '#2c3e50', color: '#fff'
}));
}
return ui.column([
ui.text('英雄图鉴', { id: 'c_t', size: 22, lines: 1, color: '#f1c40f', align: 'center' }),
ui.stack(b, { id: 'c_s', height: 186 }),
ui.stack([
ui.button('上一页', function() { update(function(st){ if(st.compPage>0) st.compPage--; }); }, { id: 'c_p1', x: 10, y: 0, width: 100, height: 40, background: '#34495e', color: '#fff' }),
ui.button('返回', function() { goPage('home'); }, { id: 'c_p2', x: 118, y: 0, width: 100, height: 40, background: '#7f8c8d', color: '#fff' }),
ui.button('下一页', function() { update(function(st){ if((st.compPage+1)*6<HEROES.length) st.compPage++; }); }, { id: 'c_p3', x: 226, y: 0, width: 100, height: 40, background: '#34495e', color: '#fff' })
], { id: 'c_n', height: 50 })
], { id: 'c_col', gap: 10 });
}
if (s.page === 'detail') {
var h = s.detailHero;
return ui.column([
ui.text(h.n + ' (' + h.c + '费)', { id: 'd_t', size: 24, lines: 1, color: '#f1c40f', align: 'center' }),
ui.text('种族:' + h.r + ' 职业:' + h.j, { id: 'd_i', size: 16, lines: 1, color: '#3498db', align: 'center' }),
ui.text('生命:' + h.hp + ' 攻击:' + h.a, { id: 'd_s', size: 16, lines: 1, color: '#2ecc71', align: 'center' }),
ui.text('技能描述', { id: 'd_st', size: 16, lines: 1, color: '#e67e22', align: 'center' }),
ui.text(h.s, { id: 'd_sk', size: 16, lines: 3, color: '#ecf0f1', align: 'center' }),
ui.stack([
ui.button('返回图鉴', function() { update(function(st){ st.page = 'compendium'; }); }, { id: 'd_b', x: 68, y: 0, width: 200, height: 50, background: '#7f8c8d', color: '#fff' })
], { id: 'd_n', height: 60 })
], { id: 'd_col', gap: 15 });
}
if (s.page === 'bag') {
var eb = [];
for (var i = 0; i < 8; i++) {
var e = s.bag[i];
eb.push(ui.button(e ? e.n : '空', function(){}, {
id: 'e_b' + i, x: (i % 2) * 164 + 4, y: Math.floor(i / 2) * 50, width: 160, height: 40,
background: e ? '#d35400' : '#1e1e1e', color: '#fff'
}));
}
return ui.column([
ui.text('装备背包', { id: 'b_t', size: 22, lines: 1, color: '#f1c40f', align: 'center' }),
ui.stack(eb, { id: 'b_s', height: 200 }),
ui.stack([
ui.button('返回游戏', function() { goPage('game'); }, { id: 'b_b', x: 68, y: 0, width: 200, height: 50, background: '#7f8c8d', color: '#fff' })
], { id: 'b_n', height: 60 })
], { id: 'b_col', gap: 10 });
}
if (s.page === 'game') {
var cells = [];
for (var i = 0; i < 24; i++) {
var r = Math.floor(i / 4), c = i % 4;
var unit = null;
for (var j = 0; j < s.myUnits.length; j++) if (s.myUnits[j].x === c && s.myUnits[j].y === r && s.myUnits[j].hp > 0) { unit = s.myUnits[j]; break; }
if (!unit) for (var j = 0; j < s.enemies.length; j++) if (s.enemies[j].x === c && s.enemies[j].y === r && s.enemies[j].hp > 0) { unit = s.enemies[j]; break; }
var txt = '';
var bg = '#1e1e1e';
if (unit) {
txt = unit.n + (unit.star > 1 ? '2' : '') + (unit.frozen ? '*' : '');
bg = unit.team === 0 ? '#2980b9' : '#c0392b';
}
if (s.selCell && s.selCell.x === c && s.selCell.y === r) bg = '#f39c12';
cells.push(ui.button(txt, (function(x, y) { return function() { clickCell(x, y); }; })(c, r), {
id: 'g_c' + i, x: c * 84, y: r * 42, width: 84, height: 42, lines: 1, background: bg, color: '#fff'
}));
}
var shop = [];
for (var i = 0; i < 3; i++) {
var h = s.shop[i];
shop.push(ui.button(h ? h.n + '(' + h.c + ')' : '空', (function(idx) { return function() { buyHero(idx); }; })(i), {
id: 'g_s' + i, x: i * 108, y: 0, width: 100, height: 32, lines: 1, background: h ? '#2980b9' : '#2c3e50', color: '#fff'
}));
}
var benchBtns = [];
for (var i = 0; i < 4; i++) {
var u = s.bench[i];
benchBtns.push(ui.button(u ? u.n : '空', (function(idx) { return function() { selBenchUnit(idx); }; })(i), {
id: 'g_b' + i, x: i * 80, y: 0, width: 76, height: 30, lines: 1, background: u ? (s.selBench === i ? '#f39c12' : '#16a085') : '#1e1e1e', color: '#fff'
}));
}
return ui.column([
ui.text('R' + s.round + ' 金' + s.gold + ' 血' + s.hp + ' ' + getSynergies(s.myUnits), { id: 'g_t', size: 14, lines: 1, color: '#f1c40f', align: 'center' }),
ui.stack(cells, { id: 'g_grid', height: 252 }),
ui.text(s.logs[s.logs.length - 1], { id: 'g_l', size: 12, lines: 1, color: '#ecf0f1', align: 'center' }),
ui.stack(shop, { id: 'g_shop', height: 34 }),
ui.stack(benchBtns, { id: 'g_bench', height: 32 }),
ui.stack([
ui.button('刷新', function() { update(function(st){ if(st.gold>=2 && st.phase!=='battle'){ st.gold-=2; g.set(st); rollShop(); } }); }, { id: 'g_o1', x: 0, y: 0, width: 80, height: 32, background: '#8e44ad', color: '#fff' }),
ui.button('买装', buyEquip, { id: 'g_o2', x: 84, y: 0, width: 80, height: 32, background: '#d35400', color: '#fff' }),
ui.button('出售', sellSelected, { id: 'g_o3', x: 168, y: 0, width: 80, height: 32, background: '#c0392b', color: '#fff' }),
ui.button('背包', function() { goPage('bag'); }, { id: 'g_o4', x: 252, y: 0, width: 80, height: 32, background: '#34495e', color: '#fff' })
], { id: 'g_ops', height: 34 }),
ui.stack([
ui.button('开战', startBattle, { id: 'g_f', x: 0, y: 0, width: 160, height: 32, background: '#c0392b', color: '#fff' }),
ui.button('重置', resetGame, { id: 'g_r', x: 168, y: 0, width: 80, height: 32, background: '#7f8c8d', color: '#fff' }),
ui.button('返回', function() { goPage('home'); }, { id: 'g_h', x: 252, y: 0, width: 80, height: 32, background: '#34495e', color: '#fff' })
], { id: 'g_bts', height: 34 })
], { id: 'g_col', gap: 2 });
}
});