GPT5来了-小白编程的时代来了

GPT5来了,编程能力强的一批,小白也能编程了的感觉。下面以中国象棋游戏,人机对弈为例,来展示一下过程,我使用的dify工作流来对接的GPT5。

完整代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>中国象棋人机对弈(α-β 搜索)</title>
<style>
  body { text-align:center; }
  canvas { background-color: #f8d796; margin-top:20px; }
</style>
</head>
<body>
<h2>中国象棋人机对弈(完整规则 + α-β 搜索 AI)</h2>
<canvas id="board" width="540" height="600"></canvas>
<script>
const canvas=document.getElementById('board');
const ctx=canvas.getContext('2d');
const gridSize=60; const cols=9, rows=10;

// 初始棋局
let pieces=[
  {x:0,y:0,s:'b',t:'車'},{x:1,y:0,s:'b',t:'馬'},{x:2,y:0,s:'b',t:'象'},
  {x:3,y:0,s:'b',t:'士'},{x:4,y:0,s:'b',t:'將'},{x:5,y:0,s:'b',t:'士'},
  {x:6,y:0,s:'b',t:'象'},{x:7,y:0,s:'b',t:'馬'},{x:8,y:0,s:'b',t:'車'},
  {x:1,y:2,s:'b',t:'炮'},{x:7,y:2,s:'b',t:'炮'},
  {x:0,y:3,s:'b',t:'卒'},{x:2,y:3,s:'b',t:'卒'},{x:4,y:3,s:'b',t:'卒'},
  {x:6,y:3,s:'b',t:'卒'},{x:8,y:3,s:'b',t:'卒'},
  {x:0,y:9,s:'r',t:'車'},{x:1,y:9,s:'r',t:'馬'},{x:2,y:9,s:'r',t:'相'},
  {x:3,y:9,s:'r',t:'仕'},{x:4,y:9,s:'r',t:'帥'},{x:5,y:9,s:'r',t:'仕'},
  {x:6,y:9,s:'r',t:'相'},{x:7,y:9,s:'r',t:'馬'},{x:8,y:9,s:'r',t:'車'},
  {x:1,y:7,s:'r',t:'炮'},{x:7,y:7,s:'r',t:'炮'},
  {x:0,y:6,s:'r',t:'兵'},{x:2,y:6,s:'r',t:'兵'},{x:4,y:6,s:'r',t:'兵'},
  {x:6,y:6,s:'r',t:'兵'},{x:8,y:6,s:'r',t:'兵'},
];

let sel=null, turn='r';

function pieceAt(x,y){ return pieces.find(p=>p.x===x && p.y===y); }

function drawBoard(){
  ctx.clearRect(0,0,canvas.width,canvas.height);
  ctx.strokeStyle='#000'; ctx.lineWidth=1;
  // 横线
  for(let i=0;i<rows;i++){
    ctx.beginPath();
    ctx.moveTo(0.5,0.5+i*gridSize);
    ctx.lineTo((cols-1)*gridSize+0.5,0.5+i*gridSize);
    ctx.stroke();
  }
  // 竖线
  for(let i=0;i<cols;i++){
    ctx.beginPath();
    ctx.moveTo(0.5+i*gridSize,0.5);
    if(i===0||i===cols-1){
      ctx.lineTo(0.5+i*gridSize,(rows-1)*gridSize+0.5);
    } else {
      ctx.lineTo(0.5+i*gridSize,(rows/2-1)*gridSize+0.5);
      ctx.moveTo(0.5+i*gridSize,(rows/2)*gridSize+0.5);
      ctx.lineTo(0.5+i*gridSize,(rows-1)*gridSize+0.5);
    }
    ctx.stroke();
  }
  // 九宫斜线
  ctx.beginPath();
  ctx.moveTo(3*gridSize+0.5,0.5);
  ctx.lineTo(5*gridSize+0.5,2*gridSize+0.5);
  ctx.moveTo(5*gridSize+0.5,0.5);
  ctx.lineTo(3*gridSize+0.5,2*gridSize+0.5);
  ctx.moveTo(3*gridSize+0.5,(rows-3)*gridSize+0.5);
  ctx.lineTo(5*gridSize+0.5,(rows-1)*gridSize+0.5);
  ctx.moveTo(5*gridSize+0.5,(rows-3)*gridSize+0.5);
  ctx.lineTo(3*gridSize+0.5,(rows-1)*gridSize+0.5);
  ctx.stroke();
  // 楚河汉界
  ctx.font='28px serif';
  ctx.fillText('楚河',gridSize*1.5,gridSize*4.5);
  ctx.fillText('汉界',gridSize*5.5,gridSize*4.5);
}

function drawPieces(){
  pieces.forEach(p=>{
    let px=p.x*gridSize, py=p.y*gridSize;
    ctx.beginPath();
    ctx.fillStyle='#fff';
    ctx.arc(px,py,24,0,Math.PI*2);
    ctx.fill();
    ctx.strokeStyle='#000'; ctx.stroke();
    ctx.fillStyle= p.s==='r'?'red':'black';
    ctx.font='20px serif';
    ctx.textAlign='center';
    ctx.textBaseline='middle';
    ctx.fillText(p.t,px,py);
    if(sel===p){
      ctx.strokeStyle='blue';
      ctx.lineWidth=2; ctx.stroke();
      ctx.lineWidth=1;
    }
  });
}

// 工具函数
function inPalace(x,y,side){
  if(side==='r') return (x>=3&&x<=5&&y>=7&&y<=9);
  else return (x>=3&&x<=5&&y>=0&&y<=2);
}
function faceToFace(){
  let rGen=pieces.find(p=>p.t==='帥'), bGen=pieces.find(p=>p.t==='將');
  if(!rGen || !bGen) return false;
  if(rGen.x!==bGen.x) return false;
  let minY=Math.min(rGen.y,bGen.y), maxY=Math.max(rGen.y,bGen.y);
  for(let y=minY+1;y<maxY;y++){ if(pieceAt(rGen.x,y)) return false; }
  return true;
}

// 棋规
function canMove(p,x,y){
  if(x<0||x>=cols||y<0||y>=rows) return false;
  if(p.x===x && p.y===y) return false;
  let target=pieceAt(x,y);
  if(target && target.s===p.s) return false;
  let dx=x-p.x, dy=y-p.y;
  let adx=Math.abs(dx), ady=Math.abs(dy);

  switch(p.t){
    case '車':case '车':
      if(dx!==0 && dy!==0) return false;
      if(dx===0){
        for(let yy=p.y+Math.sign(dy);yy!==y;yy+=Math.sign(dy)){ if(pieceAt(p.x,yy)) return false; }
      } else {
        for(let xx=p.x+Math.sign(dx);xx!==x;xx+=Math.sign(dx)){ if(pieceAt(xx,p.y)) return false; }
      }
      break;
    case '炮':
      if(dx!==0 && dy!==0) return false;
      let count=0;
      if(dx===0){
        for(let yy=p.y+Math.sign(dy);yy!==y;yy+=Math.sign(dy)){ if(pieceAt(p.x,yy)) count++; }
      } else {
        for(let xx=p.x+Math.sign(dx);xx!==x;xx+=Math.sign(dx)){ if(pieceAt(xx,p.y)) count++; }
      }
      if(target) return count===1; else return count===0;
    case '馬':case '马':
      if(!((adx===2&&ady===1)||(adx===1&&ady===2))) return false;
      if(adx===2 && pieceAt(p.x+dx/2, p.y)) return false;
      if(ady===2 && pieceAt(p.x, p.y+dy/2)) return false;
      break;
    case '象':case '相':
      if(adx!==2 || ady!==2) return false;
      if((p.s==='r' && y<5) || (p.s==='b' && y>4)) return false;
      if(pieceAt(p.x+dx/2, p.y+dy/2)) return false;
      break;
    case '士':case '仕':
      if(adx!==1 || ady!==1) return false;
      if(!inPalace(x,y,p.s)) return false;
      break;
    case '將':case '帅':
      if(!inPalace(x,y,p.s)) return false;
      if(adx+ady!==1) return false;
      break;
    case '兵':
      if(p.s==='r'){
        if(y>p.y) return false;
        if(p.y>4){ if(adx!==0 || ady!==1) return false; }
        else { if(adx+ady!==1) return false; }
      } else { // 黑方兵
        if(y<p.y) return false;
        if(p.y<5){ if(adx!==0 || ady!==1) return false; }
        else { if(adx+ady!==1) return false; }
      }
      break;
    case '卒':
      if(p.s==='b'){
        if(y<p.y) return false;
        if(p.y<5){ if(adx!==0 || ady!==1) return false; }
        else { if(adx+ady!==1) return false; }
      } else { // 红方卒
        if(y>p.y) return false;
        if(p.y>4){ if(adx!==0 || ady!==1) return false; }
        else { if(adx+ady!==1) return false; }
      }
      break;
  }
  // 将帅不见面
  let backup={x:p.x,y:p.y};
  let killed=target?pieces.indexOf(target):-1;
  p.x=x; p.y=y;
  if(killed>=0) pieces.splice(killed,1);
  let illegal=faceToFace();
  if(killed>=0) pieces.splice(killed,0,target);
  p.x=backup.x; p.y=backup.y;
  if(illegal) return false;
  return true;
}

// 鼠标点击
function handleClick(e){
  if(turn!=='r') return;
  let rect=canvas.getBoundingClientRect();
  let x=Math.round((e.clientX-rect.left)/gridSize);
  let y=Math.round((e.clientY-rect.top)/gridSize);
  let p=pieceAt(x,y);
  if(sel){
    if(canMove(sel,x,y)){
      let target=pieceAt(x,y);
      if(target) pieces=pieces.filter(pp=>pp!==target);
      sel.x=x; sel.y=y;
      sel=null; turn='b'; draw();
      setTimeout(aiMove,300);
    } else if(p && p.s==='r'){ sel=p; }
    else sel=null;
  } else {
    if(p && p.s==='r') sel=p;
  }
  draw();
}

// 评估:红分-黑分
const values = {
  '車':900,'车':900,
  '馬':450,'马':450,
  '炮':450,
  '兵':100,'卒':100,
  '相':200,'象':200,
  '仕':200,'士':200,
  '帥':10000,'將':10000
};
function evaluate(){
  let score=0;
  pieces.forEach(p=>{
    let val = values[p.t] || 0;
    if(p.s==='r'){
      if(p.t==='兵' && p.y<5) val+=30;
      score += val;
    } else {
      if(p.t==='卒' && p.y>4) val+=30;
      score -= val;
    }
  });
  return score;
}
function generateMoves(side){
  let moves=[];
  pieces.filter(pp=>pp.s===side).forEach(p=>{
    for(let x=0;x<cols;x++){
      for(let y=0;y<rows;y++){
        if(canMove(p,x,y)){
          moves.push({p,x,y});
        }
      }
    }
  });
  return moves;
}
function makeMove(m){
  m.killed=pieceAt(m.x,m.y);
  if(m.killed) pieces=pieces.filter(pp=>pp!==m.killed);
  m.oldX=m.p.x; m.oldY=m.p.y;
  m.p.x=m.x; m.p.y=m.y;
}
function undoMove(m){
  m.p.x=m.oldX; m.p.y=m.oldY;
  if(m.killed) pieces.push(m.killed);
}
function alphaBeta(depth, alpha, beta, maxPlayer){
  if(depth===0) return evaluate();
  let side=maxPlayer?'b':'r';
  let moves=generateMoves(side);
  if(moves.length===0) return maxPlayer?-999999:999999;
  if(maxPlayer){
    let v=-Infinity;
    for(let mv of moves){
      makeMove(mv);
      v=Math.max(v, alphaBeta(depth-1, alpha, beta, false));
      undoMove(mv);
      alpha=Math.max(alpha, v);
      if(alpha>=beta) break;
    }
    return v;
  } else {
    let v=Infinity;
    for(let mv of moves){
      makeMove(mv);
      v=Math.min(v, alphaBeta(depth-1, alpha, beta, true));
      undoMove(mv);
      beta=Math.min(beta, v);
      if(beta<=alpha) break;
    }
    return v;
  }
}
function aiMove(){
  let depth=2;
  let bestScore=-Infinity, bestMove=null;
  let moves=generateMoves('b');
  for(let mv of moves){
    makeMove(mv);
    let score=alphaBeta(depth-1,-Infinity,Infinity,false);
    undoMove(mv);
    if(score>bestScore){
      bestScore=score; bestMove=mv;
    }
  }
  if(bestMove) makeMove(bestMove);
  turn='r'; draw();
}

// 绘制
function draw(){ drawBoard(); drawPieces(); }

canvas.addEventListener('click',handleClick);
draw();
</script>
</body>
</html>

运行效果:

评价:象棋棋盘画的不完整,可以对弈。小白编程的时代来了。GPT5具有智能体(代表老师)的感觉了,引导你一步一步完成初始设定的目标。

基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制方法。通过结合数据驱动技术与Koopman算子理论,将非线性系统动态近似为高维线性系统,进而利用递归神经网络(RNN)建模并实现系统行为的精确预测。文中详细阐述了模型构建流程、线性化策略及在预测控制中的集成应用,并提供了完整的Matlab代码实现,便于科研人员复现实验、优化算法并拓展至其他精密控制系统。该方法有效提升了纳米级定位系统的控制精度与动态响应性能。; 适合人群:具备自动控制、机器学习或信号处理背景,熟悉Matlab编程,从事精密仪器控制、智能制造或先进控制算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①实现非线性动态系统的数据驱动线性化建模;②提升纳米定位平台的轨迹跟踪与预测控制性能;③为高精度控制系统提供可复现的Koopman-RNN融合解决方案; 阅读建议:建议结合Matlab代码逐段理解算法实现细节,重点关注Koopman观测矩阵构造、RNN训练流程与模型预测控制器(MPC)的集成方式,鼓励在实际硬件平台上验证并调整参数以适应具体应用场景。
提供了一套完整的基于51单片机的DDS(直接数字频率合成)信号波形发生器设计方案,适合电子爱好者、学生以及嵌入式开发人员学习和实践。该方案详细展示了如何利用51单片机(以AT89C52为例)结合AD9833 DDS芯片来生成正弦波、锯齿波、三角波等多种波形,并且支持通过LCD12864显示屏直观展示波形参数或状态。 内容概述 源码:包含完整的C语言编程代码,适用于51系列单片机,实现了DDS信号的生成逻辑。 仿真:提供了Proteus仿真文件,允许用户在软件环境中测试整个系统,无需硬件即可预览波形生成效果。 原理图:详细的电路原理图,指导用户如何连接单片机、DDS芯片及其他外围电路。 PCB设计:为高级用户准备,包含了PCB布局设计文件,便于制作电路板。 设计报告:详尽的设计文档,解释了项目背景、设计方案、电路设计思路、软硬件协同工作原理及测试结果分析。 主要特点 用户交互:通过按键控制波形类型和参数,增加了项目的互动性和实用性。 显示界面:LCD12864显示屏用于显示当前生成的波形类型和相关参数,提升了项目的可视化度。 教育价值:本资源非常适合教学和自学,覆盖了DDS技术基础、单片机编程和硬件设计多个方面。 使用指南 阅读设计报告:首先了解设计的整体框架和技术细节。 环境搭建:确保拥有支持51单片机的编译环境,如Keil MDK。 加载仿真:在Proteus中打开仿真文件,观察并理解系统的工作流程。 编译与烧录:将源码编译无误后,烧录至51单片机。 硬件组装:根据原理图和PCB设计制造或装配硬件。 请注意,本资源遵守CC 4.0 BY-SA版权协议,使用时请保留原作者信息及链接,尊重原创劳动成果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jacky_wxl(微信同号)

喜欢作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值