还是AI 编程:
提示词: 五子棋了解吗?帮我用aardio编写一个人机对战版程序

import win.ui;
import gdip;
/*DSG{{*/
var winform = win.form(text="五子棋 (人机对战版) - 挑战AI";right=560;bottom=580)
winform.add(
plus={cls="plus";left=0;top=0;right=560;bottom=580;db=1;dl=1;dr=1;dt=1;notify=1;z=1}
);
/*}}*/
// ==========================================
// 1. 游戏配置
// ==========================================
var boardSize = 15;
var cellSize = 35;
var margin = 30;
var pieceRadius = 15;
// 状态: 0:空, 1:黑子(玩家), 2:白子(电脑)
var boardData = {};
var isPlayerTurn = true;
var isGameOver = false;
var lastMove = null;
// 重置游戏
var resetGame = function(){
boardData = ..table.array(boardSize, ..table.array(boardSize, 0));
isPlayerTurn = true; // 玩家执黑先行
isGameOver = false;
lastMove = null;
winform.text = "五子棋 (人机对战) - 轮到你了";
winform.plus.redraw();
}
resetGame();
// ==========================================
// 2. 基础逻辑 (胜负判定)
// ==========================================
var countLine = function(r, c, dr, dc, color){
var count = 0;
// 正向
var i = 1;
while(true){
var nr, nc = r + dr*i, c + dc*i;
if(nr<1 || nr>boardSize || nc<1 || nc>boardSize || boardData[nr][nc] != color) break;
count++; i++;
}
// 反向
i = 1;
while(true){
var nr, nc = r - dr*i, c - dc*i;
if(nr<1 || nr>boardSize || nc<1 || nc>boardSize || boardData[nr][nc] != color) break;
count++; i++;
}
return count + 1;
}
var checkWin = function(r, c, color){
if(countLine(r, c, 1, 0, color) >= 5) return true;
if(countLine(r, c, 0, 1, color) >= 5) return true;
if(countLine(r, c, 1, 1, color) >= 5) return true;
if(countLine(r, c, 1, -1, color) >= 5) return true;
return false;
}
// ==========================================
// 3. AI 核心算法 (评分引擎)
// ==========================================
// 评分表 (权重)
var scoreTable = {
win5 = 100000; // 连五
live4 = 10000; // 活四 (两头空)
dead4 = 1000; // 死四 (一头堵)
live3 = 1000; // 活三
dead3 = 100; // 死三
live2 = 100; // 活二
dead2 = 10; // 死二
}
// 计算某一点在某个方向上的棋型分数
var evaluateLine = function(r, c, dr, dc, color){
var count = 1; // 假设落子在此
var emptyEnds = 0;
// 向前探
var i = 1;
while(true){
var nr, nc = r + dr*i, c + dc*i;
if(nr<1 || nr>boardSize || nc<1 || nc>boardSize) break; // 边界
if(boardData[nr][nc] == color) count++;
else {
if(boardData[nr][nc] == 0) emptyEnds++; // 遇到空位
break; // 遇到敌方或空位都停止计数
}
i++;
}
// 向后探
i = 1;
while(true){
var nr, nc = r - dr*i, c - dc*i;
if(nr<1 || nr>boardSize || nc<1 || nc>boardSize) break;
if(boardData[nr][nc] == color) count++;
else {
if(boardData[nr][nc] == 0) emptyEnds++;
break;
}
i++;
}
// 评分规则
if(count >= 5) return scoreTable.win5;
if(count == 4) return (emptyEnds == 2) ? scoreTable.live4 : (emptyEnds == 1 ? scoreTable.dead4 : 0);
if(count == 3) return (emptyEnds == 2) ? scoreTable.live3 : (emptyEnds == 1 ? scoreTable.dead3 : 0);
if(count == 2) return (emptyEnds == 2) ? scoreTable.live2 : (emptyEnds == 1 ? scoreTable.dead2 : 0);
return 0;
}
// 计算某点总分 (进攻 + 防守)
var getPointScore = function(r, c){
var score = 0;
// 1. 进攻分 (如果电脑下这,对自己有多大好处)
var myScore = 0;
myScore += evaluateLine(r, c, 1, 0, 2); // 横
myScore += evaluateLine(r, c, 0, 1, 2); // 竖
myScore += evaluateLine(r, c, 1, 1, 2); // 捺
myScore += evaluateLine(r, c, 1, -1, 2);// 撇
// 2. 防守分 (如果玩家下这,对电脑有多大威胁)
var enemyScore = 0;
enemyScore += evaluateLine(r, c, 1, 0, 1);
enemyScore += evaluateLine(r, c, 0, 1, 1);
enemyScore += evaluateLine(r, c, 1, 1, 1);
enemyScore += evaluateLine(r, c, 1, -1, 1);
// 策略:进攻为主,但如果有致命威胁要防守
// 简单的加法通常就足够聪明了
return myScore + enemyScore;
}
// AI 思考并落子
var computerMove = function(){
var maxScore = -1;
var bestPoints = {}; // 存所有最高分的点
// 遍历所有空位
for(r=1; boardSize){
for(c=1; boardSize){
if(boardData[r][c] == 0){
var s = getPointScore(r, c);
// 如果是中心点,略微加分 (开局抢占天元)
if(r==8 && c==8) s += 10;
if(s > maxScore){
maxScore = s;
bestPoints = {{r=r, c=c}};
} elseif(s == maxScore){
..table.push(bestPoints, {r=r, c=c});
}
}
}
}
// 如果有多个最高分,随机选一个
var move = bestPoints[1];
if(#bestPoints > 1){
move = bestPoints[..math.random(1, #bestPoints)];
}
if(move){
boardData[move.r][move.c] = 2; // 白子
lastMove = move;
winform.plus.redraw();
if(checkWin(move.r, move.c, 2)){
isGameOver = true;
winform.text = "五子棋 - AI获胜! (右键重开)";
win.msgbox("电脑赢了!人类还需要努力啊。");
} else {
isPlayerTurn = true;
winform.text = "五子棋 - 轮到你了";
}
}
}
// ==========================================
// 4. 绘图渲染 (保持不变)
// ==========================================
winform.plus.onDrawForegroundEnd = function(graphics, rc){
graphics.smoothingMode = 4;
var brushBg = gdip.solidBrush(0xFFDEB887);
graphics.fillRectangle(brushBg, 0, 0, rc.right, rc.bottom);
brushBg.delete();
var penLine = gdip.pen(0xFF000000, 1);
for(i=1; boardSize){
var pos = margin + (i-1) * cellSize;
graphics.drawLine(penLine, margin, pos, margin+(boardSize-1)*cellSize, pos);
graphics.drawLine(penLine, pos, margin, pos, margin+(boardSize-1)*cellSize);
}
penLine.delete();
var stars = {4, 8, 12};
for(i=1; #stars){
for(j=1; #stars){
var x, y = margin+(stars[j]-1)*cellSize, margin+(stars[i]-1)*cellSize;
var b = gdip.solidBrush(0xFF000000); graphics.fillEllipse(b, x-3, y-3, 6, 6); b.delete();
}
}
for(r=1; boardSize){
for(c=1; boardSize){
var val = boardData[r][c];
if(val == 0) continue;
var x, y = margin+(c-1)*cellSize, margin+(r-1)*cellSize;
var color = (val == 1) ? 0xFF000000 : 0xFFFFFFFF;
var b = gdip.solidBrush(color);
graphics.fillEllipse(b, x-pieceRadius, y-pieceRadius, pieceRadius*2, pieceRadius*2);
b.delete();
if(val == 2){
var p = gdip.pen(0xFFCCCCCC, 1); graphics.drawEllipse(p, x-pieceRadius, y-pieceRadius, pieceRadius*2, pieceRadius*2); p.delete();
}
}
}
if(lastMove){
var x, y = margin+(lastMove.c-1)*cellSize, margin+(lastMove.r-1)*cellSize;
var b = gdip.solidBrush(0xFFFF0000); graphics.fillRectangle(b, x-3, y-3, 6, 6); b.delete();
}
}
// ==========================================
// 5. 鼠标交互
// ==========================================
winform.plus.onMouseDown = function(wParam, lParam){
if(wParam == 0x204){ // 右键重开
if(win.msgboxTest("确定要重新开始吗?", "五子棋")) resetGame();
return;
}
if(isGameOver || !isPlayerTurn) return; // 游戏结束或AI思考时禁止点击
var x, y = win.getMessagePos(lParam);
var c = ..math.round((x - margin) / cellSize) + 1;
var r = ..math.round((y - margin) / cellSize) + 1;
if(r < 1 || r > boardSize || c < 1 || c > boardSize) return;
if(boardData[r][c] != 0) return;
// --- 玩家落子 ---
boardData[r][c] = 1; // 黑子
lastMove = {r=r, c=c};
winform.plus.redraw();
if(checkWin(r, c, 1)){
isGameOver = true;
winform.text = "五子棋 - 玩家获胜!";
win.msgbox("恭喜!你战胜了AI!");
} else {
isPlayerTurn = false;
winform.text = "五子棋 - AI思考中...";
// 延迟一点点执行,让UI先刷新出玩家的子,看起来更自然
winform.setTimeout(computerMove, 50);
}
}
winform.show();
win.loopMessage();