6ebe551ee3
问题: 函数参数声明 i64[N] 只在 TypeInfo 存储数组信息, AST_PARAMETER 仅存 TypeKind(TYPE_ARRAY), 丢失元素类型和大小, 导致 sema 将参数 数组误判为 i32[N], codegen 生成 void GEP 而崩溃。 修复: - AST_PARAMETER 新增 arr_elem_type/arr_elem_struct/arr_size 字段 - parser 传入 parse_type_expr 的完整数组信息 - sema 将数组信息从 AST 节点复制到 Symbol - codegen 为数组参数生成正确的 LLVMArrayType 附加: 45_gomoku.l — 5x5 五子棋双AI对弈, 测试数组/函数/循环/字符串 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
64 lines
2.6 KiB
Plaintext
64 lines
2.6 KiB
Plaintext
// === 五子棋 5x5 — L Language 综合测试 (带简单AI) ===
|
|
fn idx(x: i64, y: i64) -> i64 { return y * 5 + x; }
|
|
|
|
fn count_dir(b: i64[25], x: i64, y: i64, dx: i64, dy: i64, color: i64) -> i64 {
|
|
var cx = x + dx; var cy = y + dy; var n = 0;
|
|
while cx >= 0 { if cx > 4 { return n; } if cy < 0 { return n; } if cy > 4 { return n; }
|
|
if b[idx(cx, cy)] != color { return n; }
|
|
n = n + 1; cx = cx + dx; cy = cy + dy; }
|
|
return n;
|
|
}
|
|
|
|
fn score_pos(b: i64[25], x: i64, y: i64, c: i64) -> i64 {
|
|
if b[idx(x, y)] != 0 { return -1; }
|
|
var h = count_dir(b, x, y, 1, 0, c) + count_dir(b, x, y, -1, 0, c);
|
|
var v = count_dir(b, x, y, 0, 1, c) + count_dir(b, x, y, 0, -1, c);
|
|
var d = count_dir(b, x, y, 1, 1, c) + count_dir(b, x, y, -1, -1, c);
|
|
var e = count_dir(b, x, y, 1, -1, c) + count_dir(b, x, y, -1, 1, c);
|
|
if h > 2 { return 1000; } if v > 2 { return 1000; }
|
|
if d > 2 { return 1000; } if e > 2 { return 1000; }
|
|
return h + v + d + e;
|
|
}
|
|
|
|
fn ai(b: i64[25], c: i64) -> i64 {
|
|
var bx = 2; var by = 2; var bs = -1; var x = 0;
|
|
while x < 5 { var y = 0; while y < 5 {
|
|
var s = score_pos(b, x, y, c);
|
|
if s > bs { bs = s; bx = x; by = y; }
|
|
y = y + 1; } x = x + 1; }
|
|
return by * 100 + bx;
|
|
}
|
|
|
|
fn won(b: i64[25], x: i64, y: i64) -> bool {
|
|
var c = b[idx(x, y)]; if c == 0 { return false; }
|
|
if count_dir(b, x, y, 1, 0, c) + count_dir(b, x, y, -1, 0, c) > 2 { return true; }
|
|
if count_dir(b, x, y, 0, 1, c) + count_dir(b, x, y, 0, -1, c) > 2 { return true; }
|
|
if count_dir(b, x, y, 1, 1, c) + count_dir(b, x, y, -1, -1, c) > 2 { return true; }
|
|
if count_dir(b, x, y, 1, -1, c) + count_dir(b, x, y, -1, 1, c) > 2 { return true; }
|
|
return false;
|
|
}
|
|
|
|
fn print5(b: i64[25]) -> void {
|
|
var r = 0; while r < 5 {
|
|
var line = ""; var c = 0; while c < 5 {
|
|
var v = b[idx(c, r)];
|
|
if v == 0 { line = line + ". "; }
|
|
if v == 1 { line = line + "X "; }
|
|
if v == 2 { line = line + "O "; }
|
|
c = c + 1; } print_str(line); r = r + 1; }
|
|
}
|
|
|
|
fn main() -> void {
|
|
var b: i64[25] = b; var i = 0; while i < 25 { b[i] = 0; i = i + 1; }
|
|
b[idx(2, 2)] = 1; var turn = 2; var n = 1;
|
|
while n < 25 {
|
|
var mv = ai(b, turn); var y = mv / 100; var x = mv - y * 100;
|
|
b[idx(x, y)] = turn;
|
|
if turn == 1 { print_str("X: "); } else { print_str("O: "); }
|
|
print_i64(x); print_i64(y);
|
|
if won(b, x, y) { print5(b); if turn == 1 { print_str("X wins!"); } else { print_str("O wins!"); } return; }
|
|
n = n + 1; if turn == 1 { turn = 2; } else { turn = 1; }
|
|
}
|
|
print5(b); print_str("Draw");
|
|
}
|