Files
l-language/test/programs/45_gomoku.l
T
Serendipity 6ebe551ee3 fix: AST_PARAMETER 增加数组元素类型字段 + 五子棋集成测试
问题: 函数参数声明 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>
2026-06-07 18:48:04 +08:00

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");
}