受到popdes001帖子的启发,试试看Gemini3对aardio到底了解多少,用它写了个数独,前后功能调试加修改也就不到半个小时。
Gemini对aardio的使用真的很不错啊;

import win.ui;
import win.ui.menu;
import win.ui.accelerator;
/*DSG{{*/
var mainWin = win.form(text="aardio 数独专业版 - 最终修复版";right=683;bottom=780;bgcolor=0xFFFFFF)
mainWin.add(
btnClearAll={cls="plus";text="全部清除";left=410;top=720;right=510;bottom=760;bgcolor=0xC0C0C0;color=0xFFFFFF;notify=1;z=5};
btnClearSelect={cls="plus";text="清除选中";left=277;top=720;right=377;bottom=760;bgcolor=0xA0A0A0;color=0xFFFFFF;notify=1;z=6};
btnGenerate={cls="plus";text="随机出题";left=10;top=720;right=110;bottom=760;bgcolor=0xB0B28F;color=0xFFFFFF;notify=1;z=1};
btnMode={cls="plus";text="模式: 数字";left=143;top=720;right=243;bottom=760;bgcolor=0xD77800;color=0xFFFFFF;notify=1;z=2};
lbError={cls="plus";text="错误次数: 0 / 5";left=543;top=720;right=663;bottom=760;color=0x0000FF;dr=1;font=LOGFONT(h=-16;weight=700);z=3};
lbTip={cls="plus";text="操作: 键盘 1-9 输入 | 红色为错, 蓝色为对, 黑色为题";left=60;top=575;right=540;bottom=600;color=0x808080;z=4}
)
/*}}*/
var cells = {};
var solution = {};
var errorCount = 0;
var isNoteMode = false;
var activeRow, activeCol = 0, 0;
var currentCellFontSize = -25; // 新增:用于同步缩放后的字体大小
// 颜色定义
var COLOR_NORMAL = 0xFFEFEFEF;
var COLOR_BLOCK = 0xFFB5B5B5;
var COLOR_HIGHLIGHT = 0xFFE1F5FE;
var COLOR_SAME_VAL = 0xFFFFF9C4;
var COLOR_FOCUS = 0xFF81D4FA;
var COLOR_RED = 0xFFFF0000;
var COLOR_BLUE = 0xFF0078D7;
var COLOR_BLACK = 0xFF222222;
// --- 数独逻辑 ---
namespace sudoku {
isSafe = function(grid, r, c, n) {
for(i=1;9) if(grid[r][i]==n || grid[i][c]==n) return false;
var sr, sc = r-(r-1)%3, c-(c-1)%3;
for(i=sr;sr+2) for(j=sc;sc+2) if(grid[i][j]==n) return false;
return true;
}
fill = function(g) {
for(r=1;9) for(c=1;9) {
if(g[r][c]==0) {
var ns = {1;2;3;4;5;6;7;8;9};
for(i=9;2;-1) { var j=..math.random(1,i); ns[i],ns[j]=ns[j],ns[i] }
for(i=1;9) if(isSafe(g,r,c,ns[i])) {
g[r][c]=ns[i]; if(fill(g)) return true; g[r][c]=0;
}
return false;
}
}
return true;
}
generate = function(count) {
var g={}; for(i=1;9) g[i]={0;0;0;0;0;0;0;0;0};
fill(g);
var sol = {}; for(i=1;9) sol[i]={..table.unpack(g[i])};
var rmd=0; while(rmd<count){
var r,c=..math.random(1,9),..math.random(1,9);
if(g[r][c]!=0){ g[r][c]=0; rmd++ }
}
return g, sol;
}
}
updateUI = function() {
var activeVal = "";
if(activeRow > 0 && activeCol > 0) activeVal = cells[activeRow + "_" + activeCol].text;
for(row=1;9) for(col=1;9) {
var c = cells[row + "_" + col];
var bIdx = math.ceil(row/3)*3 - (3-math.ceil(col/3));
var bg = (bIdx % 2 == 1) ? COLOR_BLOCK : COLOR_NORMAL;
if(activeVal != "" && c.text == activeVal && !c.isNote) bg = COLOR_SAME_VAL;
var aBIdx = (activeRow > 0) ? (math.ceil(activeRow/3)*3 - (3-math.ceil(activeCol/3))) : 0;
if(row == activeRow || col == activeCol || bIdx == aBIdx) bg = (bg == COLOR_SAME_VAL) ? 0xFFFFF176 : COLOR_HIGHLIGHT;
if(row == activeRow && col == activeCol) bg = COLOR_FOCUS;
c.background = bg;
c.redraw();
}
}
var handleInput = function(n) {
if(!activeRow) return;
var c = cells[activeRow + "_" + activeCol];
if(c.fixed) return;
if(!isNoteMode) {
c.text = tostring(n);
c.isNote = false;
c.notes = {};
if(solution[activeRow][activeCol] == n) {
c.color = COLOR_BLUE;
c.font = LOGFONT(h=currentCellFontSize;weight=700); // 使用动态字体大小
c.fixed = true;
} else {
c.color = COLOR_RED;
c.font = LOGFONT(h=currentCellFontSize;weight=700); // 使用动态字体大小
errorCount++;
mainWin.lbError.text = "错误次数: " + errorCount + " / 5";
if(errorCount >= 5) {
mainWin.msgboxErr("游戏结束!");
mainWin.btnGenerate.oncommand();
return;
}
}
} else {
if(c.text != "" && !c.isNote) return;
c.notes[n] = !c.notes[n];
var noteStr = "";
for(i=1;9) if(c.notes[i]) noteStr ++= i;
c.isNote = true;
// 草稿字体通常为正式字体的 1/2 到 1/3
c.font = LOGFONT(h=math.round(currentCellFontSize/2.5));
c.color = 0xFF548D00;
c.text = noteStr;
}
updateUI();
}
// 初始创建格子
for(row=1;9) {
for(col=1;9) {
var name = "cell_" + row + "_" + col;
mainWin.add({ [name] = { cls="plus"; left=0; top=0; right=50; bottom=50; border={left=1;top=1;right=1;bottom=1;color=0xFFCCCCCC}; align="center"; valign="middle"; z=1; row=row; col=col; } })
cells[row + "_" + col] = mainWin[name];
mainWin[name].onMouseDown = function() { activeRow, activeCol = owner.row, owner.col; updateUI(); }
}
}
// 初始创建数字按钮
for(i=1;9) {
var btnName = "btnNum" + i;
mainWin.add({ [btnName]={cls="plus";text=tostring(i);left=0;top=0;right=50;bottom=50;bgcolor=0xFFEEEEEE;notify=1} });
mainWin[btnName].oncommand = function() { handleInput(i) }
}
mainWin.btnGenerate.oncommand = function() {
var p, sol = sudoku.generate(45);
solution = sol;
errorCount = 0;
mainWin.lbError.text = "错误次数: 0 / 5";
for(r=1;9) for(c=1;9) {
var ctrl = cells[r + "_" + c];
ctrl.text = p[r][c] ? tostring(p[r][c]) : "";
ctrl.fixed = p[r][c] > 0;
ctrl.isNote = false; ctrl.notes = {};
ctrl.font = LOGFONT(h=currentCellFontSize;weight=700); // 使用动态字体大小
ctrl.color = (p[r][c] > 0) ? COLOR_BLACK : COLOR_BLUE;
}
activeRow, activeCol = 0, 0; updateUI();
}
// --- 窗口自适应重绘函数 ---
resizeUI = function(){
var rect = mainWin.getClientRect();
var cw, ch = rect.width(), rect.height();
var boardSize = ..math.min(cw * 0.85, ch * 0.7);
var cellSize = boardSize / 9;
var offsetX = (cw - boardSize) / 2;
var offsetY = 40;
// 重要:更新当前的动态字体大小
currentCellFontSize = -math.round(cellSize * 0.6);
for(row=1;9) {
for(col=1;9) {
var ctrl = cells[row + "_" + col];
if(ctrl){
ctrl.setPos(offsetX + (col-1)*cellSize, offsetY + (row-1)*cellSize, cellSize - 1, cellSize - 1);
// 更新现有数字的字体
if(!ctrl.isNote){
ctrl.font = LOGFONT(h = currentCellFontSize; weight=700);
} else {
ctrl.font = LOGFONT(h = math.round(currentCellFontSize/2.5));
}
}
}
}
var numBtnY = offsetY + boardSize + 15;
for(i=1;9){
var btn = mainWin["btnNum" + i];
if(btn) btn.setPos(offsetX + (i-1)*cellSize, numBtnY, cellSize - 2, 45);
}
var tipY = numBtnY + 65;
mainWin.lbTip.setPos(offsetX, tipY, boardSize, 25);
var btnY = tipY + 35;
var actionBtns = { "btnGenerate"; "btnMode"; "btnClearSelect"; "btnClearAll" };
var errorLabelW = ..math.max(120, boardSize * 0.25);
var btnW = (boardSize - errorLabelW) / 4;
for(i, name in actionBtns){
mainWin[name].setPos(offsetX + (i-1) * btnW, btnY, btnW - 5, 40);
}
mainWin.lbError.setPos(offsetX + boardSize - errorLabelW, btnY, errorLabelW, 40);
}
mainWin.onPosChanged = function(flags,hwndInsertAfter,x,y,cx,cy){
resizeUI();
}
// 加速键保持不变
var accelTable = win.ui.accelerator({
{ vkey = '1'#; oncommand = function() handleInput(1) };
{ vkey = '2'#; oncommand = function() handleInput(2) };
{ vkey = '3'#; oncommand = function() handleInput(3) };
{ vkey = '4'#; oncommand = function() handleInput(4) };
{ vkey = '5'#; oncommand = function() handleInput(5) };
{ vkey = '6'#; oncommand = function() handleInput(6) };
{ vkey = '7'#; oncommand = function() handleInput(7) };
{ vkey = '8'#; oncommand = function() handleInput(8) };
{ vkey = '9'#; oncommand = function() handleInput(9) };
{ vkey = 0x61; oncommand = function() handleInput(1) };
{ vkey = 0x62; oncommand = function() handleInput(2) };
{ vkey = 0x63; oncommand = function() handleInput(3) };
{ vkey = 0x64; oncommand = function() handleInput(4) };
{ vkey = 0x65; oncommand = function() handleInput(5) };
{ vkey = 0x66; oncommand = function() handleInput(6) };
{ vkey = 0x67; oncommand = function() handleInput(7) };
{ vkey = 0x68; oncommand = function() handleInput(8) };
{ vkey = 0x69; oncommand = function() handleInput(9) };
{ vkey = 0x08; oncommand = function() mainWin.btnClearSelect.oncommand() };
{ vkey = 0x2E; oncommand = function() mainWin.btnClearSelect.oncommand() };
}, mainWin );
// 清除和模式切换逻辑保持不变
mainWin.btnClearAll.oncommand = function() {
for(r=1;9) for(c=1;c<=9;c++) {
var ctrl = cells[r + "_" + c];
if(!ctrl.fixed) { ctrl.text = ""; ctrl.notes = {}; ctrl.isNote = false; }
}
updateUI();
}
mainWin.btnClearSelect.oncommand = function() {
if(activeRow && activeCol) {
var ctrl = cells[activeRow + "_" + activeCol];
if(!ctrl.fixed) {
ctrl.text = "";
ctrl.notes = {};
ctrl.isNote = false;
updateUI();
}
}
}
mainWin.btnMode.oncommand = function() {
isNoteMode = !isNoteMode;
mainWin.btnMode.text = isNoteMode ? "模式: 草稿" : "模式: 数字";
mainWin.btnMode.background = isNoteMode ? 0xFFFFA500 : 0xFF66BB6A;
}
mainWin.btnGenerate.oncommand();
resizeUI();
mainWin.show();
win.loopMessage();