<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial‑scale=1.0, maximum‑scale=1.0, user‑scalable=no">
<title>国际象棋</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#222;display:flex;flex-direction:column;align-items:center;padding:10px;color:#fff;font-family:system-ui}
#board{
  display:grid;
  grid-template-columns:repeat(8,1fr);
  width:min(96vw,480px);
  aspect-ratio:1/1;
  border:4px solid #444;
}
.square{
  display:flex;align-items:center;justify-content:center;
  font-size:min(12vw,50px);
  user-select:none;
}
.light{background:#f0d9b5}
.dark{background:#b58863}
.selected{background:#87ceeb}
.valid{background:#73ad73}
#info{margin:8px 0;font-size:18px}
</style>
</head>
<body>
<div id="info">白方走棋</div>
<div id="board"></div>
<script>
const pieces=[
['r','n','b','q','k','b','n','r'],
['p','p','p','p','p','p','p','p'],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['P','P','P','P','P','P','P','P'],
['R','N','B','Q','K','B','N','R']
];
const symbols={
'K':'♔','Q':'♕','R':'♖','B':'♗','N':'♘','P':'♙',
'k':'♚','q':'♛','r':'♜','b':'♝','n':'♞','p':'♟'
};
let board=pieces.map(r=>[...r]);
let turn='white';
let sel=null;
const boardEl=document.getElementById('board');
const infoEl=document.getElementById('info');

function render(){
  boardEl.innerHTML='';
  for(let y=0;y<8;y++){
    for(let x=0;x<8;x++){
      const div=document.createElement('div');
      div.className='square '+( (x+y)%2?'dark':'light' );
      div.dataset.x=x;div.dataset.y=y;
      const p=board[y][x];
      if(p)div.textContent=symbols[p];
      if(sel&&sel.x===x&&sel.y===y)div.classList.add('selected');
      div.onclick=()=>click(x,y);
      boardEl.appendChild(div);
    }
  }
  infoEl.textContent=turn==='white'?'白方走棋':'黑方走棋';
}

function isWhite(c){return c&&c===c.toUpperCase()}
function isBlack(c){return c&&c===c.toLowerCase()}
function ownPiece(c){
  if(turn==='white')return isWhite(c);
  return isBlack(c);
}

function click(x,y){
  const p=board[y][x];
  if(sel){
    if(!ownPiece(p)&&canMove(sel.x,sel.y,x,y)){
      board[y][x]=board[sel.y][sel.x];
      board[sel.y][sel.x]='';
      turn=turn==='white'?'black':'white';
      sel=null;render();
      return;
    }
  }
  if(ownPiece(p)) sel={x,y};
  else sel=null;
  render();
}

function canMove(x1,y1,x2,y2){
  const pc=board[y1][x1].toUpperCase();
  const dx=x2-x1,dy=y2-y1;
  const target=board[y2][x2];
  if(target&&ownPiece(target))return false;
  switch(pc){
    case'P':{
      const dir=isWhite(board[y1][x1])?-1:1;
      if(dx===0&&dy===dir&&!target)return true;
      if(Math.abs(dx)===1&&dy===dir&&target)return true;
      return false;
    }
    case'R':return checkLine(x1,y1,x2,y2);
    case'B':return checkDiag(x1,y1,x2,y2);
    case'Q':return checkLine(x1,y1,x2,y2)||checkDiag(x1,y1,x2,y2);
    case'N':return (Math.abs(dx)===2&&Math.abs(dy)===1)||(Math.abs(dx)===1&&Math.abs(dy)===2);
    case'K':return Math.abs(dx)<=1&&Math.abs(dy)<=1;
  }
  return false;
}

function checkLine(x1,y1,x2,y2){
  if(x1!==x2&&y1!==y2)return false;
  const sx=Math.sign(x2-x1),sy=Math.sign(y2-y1);
  let cx=x1+sx,cy=y1+sy;
  while(cx!==x2||cy!==y2){
    if(board[cy][cx])return false;
    cx+=sx;cy+=sy;
  }
  return true;
}

function checkDiag(x1,y1,x2,y2){
  if(Math.abs(x2-x1)!==Math.abs(y2-y1))return false;
  const sx=Math.sign(x2-x1),sy=Math.sign(y2-y1);
  let cx=x1+sx,cy=y1+sy;
  while(cx!==x2||cy!==y2){
    if(board[cy][cx])return false;
    cx+=sx;cy+=sy;
  }
  return true;
}

render();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial‑scale=1.0, maximum‑scale=1.0, user‑scalable=no">
<title>国际象棋</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#222;display:flex;flex-direction:column;align-items:center;padding:10px;color:#fff;font-family:system-ui}
#board{
  display:grid;
  grid-template-columns:repeat(8,1fr);
  width:min(96vw,480px);
  aspect-ratio:1/1;
  border:4px solid #444;
}
.square{
  display:flex;align-items:center;justify-content:center;
  font-size:min(12vw,50px);
  user-select:none;
}
.light{background:#f0d9b5}
.dark{background:#b58863}
.selected{background:#87ceeb}
.valid{background:#73ad73}
#info{margin:8px 0;font-size:18px}
</style>
</head>
<body>
<div id="info">白方走棋</div>
<div id="board"></div>
<script>
const pieces=[
['r','n','b','q','k','b','n','r'],
['p','p','p','p','p','p','p','p'],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['P','P','P','P','P','P','P','P'],
['R','N','B','Q','K','B','N','R']
];
const symbols={
'K':'♔','Q':'♕','R':'♖','B':'♗','N':'♘','P':'♙',
'k':'♚','q':'♛','r':'♜','b':'♝','n':'♞','p':'♟'
};
let board=pieces.map(r=>[...r]);
let turn='white';
let sel=null;
const boardEl=document.getElementById('board');
const infoEl=document.getElementById('info');

function render(){
  boardEl.innerHTML='';
  for(let y=0;y<8;y++){
    for(let x=0;x<8;x++){
      const div=document.createElement('div');
      div.className='square '+( (x+y)%2?'dark':'light' );
      div.dataset.x=x;div.dataset.y=y;
      const p=board[y][x];
      if(p)div.textContent=symbols[p];
      if(sel&&sel.x===x&&sel.y===y)div.classList.add('selected');
      div.onclick=()=>click(x,y);
      boardEl.appendChild(div);
    }
  }
  infoEl.textContent=turn==='white'?'白方走棋':'黑方走棋';
}

function isWhite(c){return c&&c===c.toUpperCase()}
function isBlack(c){return c&&c===c.toLowerCase()}
function ownPiece(c){
  if(turn==='white')return isWhite(c);
  return isBlack(c);
}

function click(x,y){
  const p=board[y][x];
  if(sel){
    if(!ownPiece(p)&&canMove(sel.x,sel.y,x,y)){
      board[y][x]=board[sel.y][sel.x];
      board[sel.y][sel.x]='';
      turn=turn==='white'?'black':'white';
      sel=null;render();
      return;
    }
  }
  if(ownPiece(p)) sel={x,y};
  else sel=null;
  render();
}

function canMove(x1,y1,x2,y2){
  const pc=board[y1][x1].toUpperCase();
  const dx=x2-x1,dy=y2-y1;
  const target=board[y2][x2];
  if(target&&ownPiece(target))return false;
  switch(pc){
    case'P':{
      const dir=isWhite(board[y1][x1])?-1:1;
      if(dx===0&&dy===dir&&!target)return true;
      if(Math.abs(dx)===1&&dy===dir&&target)return true;
      return false;
    }
    case'R':return checkLine(x1,y1,x2,y2);
    case'B':return checkDiag(x1,y1,x2,y2);
    case'Q':return checkLine(x1,y1,x2,y2)||checkDiag(x1,y1,x2,y2);
    case'N':return (Math.abs(dx)===2&&Math.abs(dy)===1)||(Math.abs(dx)===1&&Math.abs(dy)===2);
    case'K':return Math.abs(dx)<=1&&Math.abs(dy)<=1;
  }
  return false;
}

function checkLine(x1,y1,x2,y2){
  if(x1!==x2&&y1!==y2)return false;
  const sx=Math.sign(x2-x1),sy=Math.sign(y2-y1);
  let cx=x1+sx,cy=y1+sy;
  while(cx!==x2||cy!==y2){
    if(board[cy][cx])return false;
    cx+=sx;cy+=sy;
  }
  return true;
}

function checkDiag(x1,y1,x2,y2){
  if(Math.abs(x2-x1)!==Math.abs(y2-y1))return false;
  const sx=Math.sign(x2-x1),sy=Math.sign(y2-y1);
  let cx=x1+sx,cy=y1+sy;
  while(cx!==x2||cy!==y2){
    if(board[cy][cx])return false;
    cx+=sx;cy+=sy;
  }
  return true;
}

render();
</script>
</body>
</html>
