Chess
Qwen 3.8 27B GGUF · full

Reviews & generation details
Reviews
No human review yet. Unreviewed does not mean unsuccessful.
Generation context
Imported historical artifact. Its exact original instructions and lineage are not known.
Generation prompt · exact text unavailable
See the current prompt for reference. It may differ from the instructions used to generate this artifact.
Inspect original source 9,798 bytes · SHA-256 4be6fb8da18b
<script>
/* =====================================================================
SECTION 5 — Move generation (pseudo-legal, then legality filtered)
move: { from, to, piece, cap, promo?, dbl?, ep?, castle? }
===================================================================== */
function genPseudo(st, from){
const bd = st.bd;
const out = [];
const p = bd[from];
if (!p) return out;
const w = isW(p), t = p.toLowerCase();
const R = from >> 3, F = from & 7;
const add = (to, extra) => out.push(Object.assign({ from, to, piece: p, cap: bd[to] || null }, extra || {}));
if (t === 'p'){
const dir = w ? -1 : 1, startR = w ? 6 : 1, promoR = w ? 0 : 7;
const nr = R + dir;
if (nr >= 0 && nr < 8){
const one = nr * 8 + F;
if (!bd[one]){
if (nr === promoR){ for (const q of ['q','r','b','n']) add(one, { promo:q }); }
else add(one);
if (R === startR && !bd[(R + 2 * dir) * 8 + F]) add((R + 2 * dir) * 8 + F, { dbl:true });
}
for (const df of [-1, 1]){
const f = F + df;
if (f < 0 || f > 7) continue;
const to = nr * 8 + f, tp = bd[to];
if (tp){
if (w ? !isW(tp) : isW(tp)){
if (nr === promoR) for (const q of ['q','r','b','n']) add(to, { promo:q });
else add(to);
}
} else if (to === st.ep){
add(to, { ep:true });
}
}
}
}
else if (t === 'n' || t === 'k'){
for (const [dr, df] of (t === 'n' ? KN : KG)){
const r = R + dr, f = F + df;
if (r < 0 || r > 7 || f < 0 || f > 7) continue;
const tp = bd[r * 8 + f];
if (!tp || (w ? !isW(tp) : isW(tp))) add(r * 8 + f);
}
if (t === 'k') addCastles(st, out, w);
}
else {
const dirs = t === 'r' ? RD : t === 'b' ? BD : QD;
for (const [dr, df] of dirs){
let r = R + dr, f = F + df;
while (r >= 0 && r < 8 && f >= 0 && f < 8){
const tp = bd[r * 8 + f];
add(r * 8 + f);
if (tp) break;
r += dr; f += df;
}
}
}
return out;
}
/* Castling: rights + empty squares + not in check and not passing
through (or into) an attacked square. King and rook targets only. */
function addCastles(st, out, w){
const bd = st.bd, c = st.castling;
const enemy = w ? 'b' : 'w';
const att = s => attacked(bd, s, enemy);
if (w){
if (c.wk && bd[61] === null && bd[62] === null && bd[63] === 'R' &&
!att(60) && !att(61) && !att(62))
out.push({ from:60, to:62, piece:'K', cap:null, castle:'k' });
if (c.wq && bd[59] === null && bd[58] === null && bd[57] === null && bd[56] === 'R' &&
!att(60) && !att(59) && !att(58))
out.push({ from:60, to:58, piece:'K', cap:null, castle:'q' });
} else {
if (c.bk && bd[5] === null && bd[6] === null && bd[7] === 'R' &&
!att(4) && !att(5) && !att(6))
out.push({ from:4, to:6, piece:'k', cap:null, castle:'k' });
if (c.bq && bd[3] === null && bd[2] === null && bd[1] === null && bd[0] === 'R' &&
!att(4) && !att(3) && !att(2))
out.push({ from:4, to:2, piece:'k', cap:null, castle:'q' });
}
}
function allPseudo(st){
const out = [], bd = st.bd, w = st.turn === 'w';
for (let i = 0; i < 64; i++){
const p = bd[i];
if (p && isW(p) === w) out.push(...genPseudo(st, i));
}
return out;
}
/* The legal-move generator: pseudo-legal, then reject anything that
leaves the moving side's king attacked. The UI only ever shows what
this function produces, so illegal states are unreachable. */
function legalMoves(st, from){
const cands = from != null ? genPseudo(st, from) : allPseudo(st);
const out = [];
const enemy = opp(st.turn);
for (const m of cands){
const u = makeMove(st, m);
if (!attacked(st.bd, findKing(st.bd, st.turn), enemy)) out.push(m);
unmakeMove(st, m, u);
}
return out;
}
/* =====================================================================
SECTION 6 — Make / unmake move
===================================================================== */
function makeMove(st, m){
const u = { piece: m.piece, cap: null, ep: st.ep, cast: { ...st.castling }, half: st.half };
const bd = st.bd, p = m.piece, w = isW(p), t = p.toLowerCase();
bd[m.from] = null;
if (m.ep){
const cs = w ? m.to + 8 : m.to - 8;
u.cap = bd[cs];
bd[cs] = null;
} else {
u.cap = bd[m.to];
bd[m.to] = null;
}
bd[m.to] = m.promo ? (w ? m.promo.toUpperCase() : m.promo) : p;
if (m.castle){
if (w){
if (m.to === 61){ bd[61] = bd[63]; bd[63] = null; }
else { bd[59] = bd[56]; bd[56] = null; }
} else {
if (m.to === 6){ bd[5] = bd[7]; bd[7] = null; }
else { bd[3] = bd[0]; bd[0] = null; }
}
}
const c = st.castling;
if (t === 'k'){ if (w){ c.wk = c.wq = false; } else { c.bk = c.bq = false; } }
if (m.from === 63 || m.to === 63) c.wk = false;
if (m.from === 56 || m.to === 56) c.wq = false;
if (m.from === 7 || m.to === 7) c.bk = false;
if (m.from === 0 || m.to === 0) c.bq = false;
const d = m.to - m.from;
st.ep = (t === 'p' && (d === 16 || d === -16)) ? (m.from + m.to) >> 1 : null;
st.half = (t === 'p' || u.cap) ? 0 : st.half + 1;
if (st.turn === 'b') st.full++;
st.turn = opp(st.turn);
st.rep.push(posKey(st));
return u;
}
function unmakeMove(st, m, u){
st.turn = opp(st.turn);
if (st.turn === 'b') st.full--;
st.half = u.half;
st.ep = u.ep;
st.castling = u.cast;
st.rep.pop();
const bd = st.bd, p = u.piece, w = isW(p);
bd[m.from] = p;
if (m.ep){
const cs = w ? m.to + 8 : m.to - 8;
bd[cs] = u.cap;
bd[m.to] = null;
} else {
bd[m.to] = u.cap;
}
if (m.castle){
if (w){
if (m.to === 61){ bd[63] = bd[61]; bd[61] = null; }
else { bd[56] = bd[59]; bd[59] = null; }
} else {
if (m.to === 6){ bd[7] = bd[5]; bd[5] = null; }
else { bd[0] = bd[3]; bd[3] = null; }
}
}
}
/* =====================================================================
SECTION 7 — FEN, SAN, terminal states
===================================================================== */
function toFEN(st){
const rows = [];
for (let r = 0; r < 8; r++){
let row = '', gap = 0;
for (let f = 0; f < 8; f++){
const p = st.bd[r * 8 + f];
if (!p) gap++;
else { if (gap){ row += gap; gap = 0; } row += p; }
}
if (gap) row += gap;
rows.push(row);
}
const c = st.castling;
const cc = (c.wk?'K':'') + (c.wq?'Q':'') + (c.bk?'k':'') + (c.bq?'q':'');
return rows.join('/') + ' ' + st.turn + ' ' + (cc || '-') + ' ' +
(st.ep == null ? '-' : sqName(st.ep)) + ' ' + st.half + ' ' + st.full;
}
function fromFEN(fen){
const parts = fen.trim().split(/\s+/);
const bd = new Array(64).fill(null);
const rows = parts[0].split('/');
for (let r = 0; r < 8; r++){
let f = 0;
for (const ch of rows[r]){
if (ch >= '1' && ch <= '8') f += +ch;
else { bd[r * 8 + f] = ch; f++; }
}
}
const cast = parts[2] || '-';
return {
bd,
turn: parts[1] === 'b' ? 'b' : 'w',
castling: { wk: cast.includes('K'), wq: cast.includes('Q'), bk: cast.includes('k'), bq: cast.includes('q') },
ep: (parts[3] && parts[3] !== '-') ? nameToSq(parts[3]) : null,
half: +(parts[4] || 0),
full: +(parts[5] || 1),
rep: []
};
}
/* Standard algebraic notation (without the +/# suffix, added by the caller). */
function san(st, m, legal){
if (m.castle) return m.castle === 'k' ? 'O-O' : 'O-O-O';
const t = m.piece.toLowerCase();
let s = '';
if (t !== 'p'){
s = m.piece;
const others = legal.filter(o => o !== m && o.piece === m.piece && o.to === m.to && o.from !== m.from);
if (others.length){
const sf = others.some(o => (o.from & 7) === (m.from & 7));
const sr = others.some(o => (o.from >> 3) === (m.from >> 3));
if (!sf) s += FILE_CH[m.from & 7];
else if (!sr) s += String(8 - (m.from >> 3));
else s += FILE_CH[m.from & 7] + String(8 - (m.from >> 3));
}
} else if (m.cap || m.ep){
s = FILE_CH[m.from & 7];
}
if (m.cap || m.ep) s += 'x';
s += sqName(m.to);
if (m.promo) s += '=' + m.promo.toUpperCase();
if (m.ep) s += ' e.p.';
return s;
}
function insufficientMaterial(bd){
const minors = [];
for (let i = 0; i < 64; i++){
const p = bd[i];
if (!p || p === 'K' || p === 'k') continue;
const t = p.toLowerCase();
if (t === 'p' || t === 'r' || t === 'q') return false; // not a dead position
minors.push({ t, i, w: isW(p) });
}
if (minors.length <= 1) return true; // K vs K, K+B vs K, K+N vs K, K+B+B/K+N+N
if (minors.length === 2 && minors[0].t === 'b' && minors[1].t === 'b'){
const a = minors[0], b = minors[1];
if (a.w !== b.w && (((a.i >> 3) + (a.i & 7)) & 1) === (((b.i >> 3) + (b.i & 7)) & 1))
return true; // K+B vs K+B, same-square colour
}
return false;
}
/* Returns null if the game continues, else a result object. */
function terminalState(st, noMoves, chk){
if (noMoves){
if (chk) return { type:'mate', res: st.turn === 'w' ? '0-1' : '1-0',
title:'Checkmate', detail:(st.turn === 'w' ? 'Black' : 'White') + ' wins' };
return { type:'stale', res:'\u00BD\u2013\u00BD', title:'Stalemate', detail:'Draw by stalemate' };
}
if (insufficientMaterial(st.bd))
return { type:'mat', res:'\u00BD\u2013\u00BD', title:'Draw', detail:'Insufficient material' };
if (st.half >= FIFTY_MOVE_LIMIT)
return { type:'fifty', res:'\u00BD\u2013\u00BD', title:'Draw', detail:'Fifty-move rule' };
const key = posKey(st);
if (st.rep.filter(k => k === key).length >= 3)
return { type:'rep', res:'\u00BD\u2013\u00BD', title:'Draw', detail:'Threefold repetition' };
return null;
}
</script>