diff --git a/headers/help.h b/headers/help.h index 56a533d..7b57f31 100644 --- a/headers/help.h +++ b/headers/help.h @@ -5,7 +5,7 @@ long long fullSet(sets *s); long long fullSetBoth(game *g); void print_bitboard(long long bitboard); -long long *findSet(game *g, long long bit); -long long *charToSet(game *g, char c); +unsigned long long *findSet(game *g, long long bit); +unsigned long long *charToSet(game *g, char c); #endif diff --git a/src/main.c b/src/main.c index 3f16ed0..1e67a3c 100644 --- a/src/main.c +++ b/src/main.c @@ -16,8 +16,6 @@ game *fenGame(char *str); game *playMoves(game *g, char *moves); -long long *findSet(game *g, long long bit); -long long *charToSet(game *g, char c); int cmain() { setbuf(stdin, NULL); @@ -123,7 +121,7 @@ game *fenGame(char *str) { } long long bit = 1ULL << (rank * 8 + file); - long long *set = charToSet(g, *str); + unsigned long long *set = charToSet(g, *str); if (set) *set |= bit; file++; diff --git a/src/main.zig b/src/main.zig index 4fa2a61..d5195dc 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,6 +2,7 @@ const std = @import("std"); const c = @cImport({ @cInclude("main.h"); @cInclude("types.h"); + @cInclude("help.h"); }); const uciTag = enum { @@ -27,11 +28,12 @@ pub fn main() !void { const stdin = std.io.getStdIn(); var reader = stdin.reader(); - var game: *c.game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + var game: *c.game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc); + defer alloc.destroy(game); while (true) { const line = try reader.readUntilDelimiterAlloc(alloc, '\n', std.math.maxInt(usize)); defer alloc.free(line); - switch (uci(line, game)) { + switch (uci(line, game, alloc)) { .text => |value| { try std.io.getStdOut().writer().print("{s}", .{value}); }, @@ -39,6 +41,7 @@ pub fn main() !void { try std.io.getStdOut().writer().print("bestmove {s}\n", .{value}); }, .game => |value| { + alloc.destroy(game); game = value; }, .exit => { @@ -51,35 +54,48 @@ pub fn main() !void { } } -fn uci(str: []const u8, game: *c.game) uciRet { +fn uci(str: []const u8, game: *c.game, alloc: std.mem.Allocator) uciRet { const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len; const tok = str[0..pos]; if (std.mem.eql(u8, tok, "uci")) return .{ .text = "id name RatChess 0.1\nid author rat<3\nuciok\n" }; if (std.mem.eql(u8, tok, "isready")) return .{ .text = "readyok\n" }; if (std.mem.eql(u8, tok, "go")) return .{ .move = uciGo(game) }; - if (std.mem.eql(u8, tok, "position")) return .{ .game = uciPos(str[(pos + 1)..]) }; + if (std.mem.eql(u8, tok, "position")) return .{ .game = uciPos(str[(pos + 1)..], alloc) }; if (std.mem.eql(u8, tok, "exit")) return .{ .exit = {} }; return .{ .pass = {} }; } -fn uciPos(str: []const u8) [*c]c.game { +fn uciPos(str: []const u8, alloc: std.mem.Allocator) [*c]c.game { const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len; const tok = str[0..pos]; - var game = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); - if (std.mem.eql(u8, tok, "fen")) return fenGame(str[pos..]); + var game = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc); + if (std.mem.eql(u8, tok, "fen")) return fenGame(str[pos..], alloc); if (std.mem.eql(u8, tok, "startpos")) { game = playMoves(game, str[pos..]); } return game; } -fn fenGame(str: []const u8) [*c]c.game { - var buffer: [256]u8 = undefined; - const len = @min(str.len, buffer.len - 1); - @memcpy(buffer[0..len], str[0..len]); - buffer[len] = 0; - - return c.fenGame(&buffer); +fn fenGame(str: []const u8, alloc: std.mem.Allocator) [*c]c.game { + var pos: u8 = 0; + var space: u8 = 0; + const g = alloc.create(c.game) catch return null; + for (str) |chr| { + if (pos > 64) { + if (chr == ' ') space += 1; + if (space == 1 and chr == 'b') g.whiteToMove = false; + if (space == 1 and chr == 'w') g.whiteToMove = false; + continue; + } + if (std.ascii.isDigit(chr)) pos += @truncate(chr - '0'); + if (chr == '/') continue; + const set: [*c]c_ulonglong = c.charToSet(g, chr); + const bit: u64 = @as(u64, 1) << @truncate(pos); + if (set != null) + set.* |= @as(c_ulonglong, bit); + pos += 1; + } + return g; } fn playMoves(game: [*c]c.game, str: []const u8) [*c]c.game { diff --git a/src/moves.c b/src/moves.c index e1ba8d1..735e9f5 100644 --- a/src/moves.c +++ b/src/moves.c @@ -28,22 +28,22 @@ int pawnMove(game *g, move *moves) { // forword int to = i + movdir; - p = (promo & (1ULL << to)) ? 'q' : 0; if (to >= 0 && to < 64 && !(occupied & (1ULL << to))) { + p = (promo & (1ULL << to)) ? 'q' : 0; moves[index++] = (move){.From = i, .To = to, .Promo = p}; } // left to = i + capLeft; - p = (promo & (1ULL << to)) ? 'q' : 0; if (i % 8 > 0 && (to >= 0 && to < 64) && (enemy & (1ULL << to))) { + p = (promo & (1ULL << to)) ? 'q' : 0; moves[index++] = (move){.From = i, .To = to, .Promo = p}; } // right to = i + capRight; - p = (promo & (1ULL << to)) ? 'q' : 0; if (i % 8 < 7 && (to >= 0 && to < 64) && (enemy & (1ULL << to))) { + p = (promo & (1ULL << to)) ? 'q' : 0; moves[index++] = (move){.From = i, .To = to, .Promo = p}; } } @@ -78,6 +78,7 @@ int knightMove(game *g, move *moves) { (fileDiff == 2 && rankDiff == 1))) continue; + if(to < 0 || to > 63) continue; long long destBit = 1ULL << to; if (occupied & destBit) continue;