Compare commits
5 Commits
008abd6444
...
1d41b76fa8
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d41b76fa8 | |||
| 7cded275f2 | |||
| 6af6a16a77 | |||
| 10f81cf7f0 | |||
| 054cd41cf6 |
@ -2,8 +2,8 @@
|
|||||||
#define HELP_H
|
#define HELP_H
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
long long fullSet(sets *s);
|
unsigned long long fullSet(sets *s);
|
||||||
long long fullSetBoth(game *g);
|
unsigned long long fullSetBoth(game *g);
|
||||||
void print_bitboard(long long bitboard);
|
void print_bitboard(long long bitboard);
|
||||||
unsigned long long *findSet(game *g, long long bit);
|
unsigned long long *findSet(game *g, long long bit);
|
||||||
unsigned long long *charToSet(game *g, char c);
|
unsigned long long *charToSet(game *g, char c);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{pkgs ? import <nixpkgs> {}}:
|
{pkgs ? import <nixpkgs> {}}:
|
||||||
with pkgs;
|
with pkgs;
|
||||||
mkShell rec {
|
mkShell rec {
|
||||||
packages = [gdb zls uchess cutechess];
|
packages = [gdb zls uchess cutechess stockfish];
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
zig
|
zig
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
long long fullSet(sets *s) {
|
unsigned long long fullSet(sets *s) {
|
||||||
return s->bishops | s->king | s->knights | s->pawns | s->queen | s->rooks;
|
return s->bishops | s->king | s->knights | s->pawns | s->queen | s->rooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long fullSetBoth(game *g) {
|
unsigned long long fullSetBoth(game *g) {
|
||||||
return fullSet(&g->white) ^ fullSet(&g->black);
|
return fullSet(&g->white) ^ fullSet(&g->black);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ void print_bitboard(long long bitboard) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
long long *findSet(game *g, long long bit) {
|
unsigned long long *findSet(game *g, long long bit) {
|
||||||
if (g->white.pawns & bit) {
|
if (g->white.pawns & bit) {
|
||||||
return &g->white.pawns;
|
return &g->white.pawns;
|
||||||
} else if (g->white.knights & bit) {
|
} else if (g->white.knights & bit) {
|
||||||
@ -55,7 +55,7 @@ long long *findSet(game *g, long long bit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long long *charToSet(game *g, char c) {
|
unsigned long long *charToSet(game *g, char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'P':
|
case 'P':
|
||||||
return &g->white.pawns;
|
return &g->white.pawns;
|
||||||
|
|||||||
91
src/main.zig
91
src/main.zig
@ -1,28 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mov = @import("move.zig");
|
const mov = @import("move.zig");
|
||||||
const c = @cImport({
|
const types = @import("types.zig");
|
||||||
@cInclude("main.h");
|
|
||||||
@cInclude("types.h");
|
|
||||||
@cInclude("help.h");
|
|
||||||
@cInclude("eval.h");
|
|
||||||
@cInclude("moves.h");
|
|
||||||
});
|
|
||||||
|
|
||||||
const uciTag = enum {
|
|
||||||
text,
|
|
||||||
move,
|
|
||||||
game,
|
|
||||||
exit,
|
|
||||||
pass,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uciRet = union(uciTag) {
|
|
||||||
text: []const u8,
|
|
||||||
move: []u8,
|
|
||||||
game: *c.game,
|
|
||||||
exit: void,
|
|
||||||
pass: void,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
@ -31,7 +9,7 @@ pub fn main() !void {
|
|||||||
const stdin = std.io.getStdIn();
|
const stdin = std.io.getStdIn();
|
||||||
var reader = stdin.reader();
|
var reader = stdin.reader();
|
||||||
|
|
||||||
var game: *c.game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
var game: *types.game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
defer alloc.destroy(game);
|
defer alloc.destroy(game);
|
||||||
while (true) {
|
while (true) {
|
||||||
const line = try reader.readUntilDelimiterAlloc(alloc, '\n', std.math.maxInt(usize));
|
const line = try reader.readUntilDelimiterAlloc(alloc, '\n', std.math.maxInt(usize));
|
||||||
@ -58,7 +36,7 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uci(str: []const u8, game: *c.game, alloc: std.mem.Allocator) uciRet {
|
fn uci(str: []const u8, game: *types.game, alloc: std.mem.Allocator) types.uciRet {
|
||||||
const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len;
|
const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len;
|
||||||
const tok = str[0..pos];
|
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, "uci")) return .{ .text = "id name RatChess 0.1\nid author rat<3\nuciok\n" };
|
||||||
@ -69,63 +47,58 @@ fn uci(str: []const u8, game: *c.game, alloc: std.mem.Allocator) uciRet {
|
|||||||
return .{ .pass = {} };
|
return .{ .pass = {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uciPos(str: []const u8, alloc: std.mem.Allocator) *c.game {
|
fn uciPos(str: []const u8, alloc: std.mem.Allocator) *types.game {
|
||||||
const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len;
|
const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len;
|
||||||
const tok = str[0..pos];
|
const tok = str[0..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, "fen")) return fenGame(str[pos..], alloc);
|
||||||
if (std.mem.eql(u8, tok, "startpos")) {
|
if (std.mem.eql(u8, tok, "startpos")) {
|
||||||
var game = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
var game = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
game = playMoves(game, str[pos..]);
|
game = mov.playMoves(game, str[pos..]);
|
||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
return fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc); //this should be an error
|
return fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc); //this should be an error
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fenGame(str: []const u8, alloc: std.mem.Allocator) [*c]c.game {
|
fn fenGame(str: []const u8, alloc: std.mem.Allocator) *types.game {
|
||||||
var pos: u8 = 0;
|
var pos: u8 = 0;
|
||||||
var space: u8 = 0;
|
var space: u8 = 0;
|
||||||
const g = alloc.create(c.game) catch return null;
|
var g = alloc.create(types.game) catch unreachable;
|
||||||
|
g.* = std.mem.zeroes(types.game);
|
||||||
for (str) |chr| {
|
for (str) |chr| {
|
||||||
if (pos > 64) {
|
if (chr == ' ') {
|
||||||
if (chr == ' ') space += 1;
|
space += 1;
|
||||||
if (space == 1 and chr == 'b') g.whiteToMove = false;
|
continue;
|
||||||
if (space == 1 and chr == 'w') g.whiteToMove = true;
|
}
|
||||||
|
if (space == 1) {
|
||||||
|
if (chr == 'b') g.whiteToMove = false;
|
||||||
|
if (chr == 'w') g.whiteToMove = true;
|
||||||
|
//continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.ascii.isDigit(chr)) {
|
||||||
|
pos += @truncate(chr - '0');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (std.ascii.isDigit(chr)) pos += @truncate(chr - '0');
|
|
||||||
if (chr == '/') continue;
|
if (chr == '/') continue;
|
||||||
const set: [*c]c_ulonglong = c.charToSet(g, chr);
|
const set: *u64 = mov.charToSet(g, chr);
|
||||||
const bit: u64 = @as(u64, 1) << @truncate(pos);
|
const bit: u64 = @as(u64, 1) << @truncate(pos);
|
||||||
if (set != null)
|
set.* |= bit;
|
||||||
set.* |= @as(c_ulonglong, bit);
|
|
||||||
pos += 1;
|
pos += 1;
|
||||||
}
|
}
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn playMoves(game: [*c]c.game, str: []const u8) [*c]c.game {
|
fn uciGo(game: *types.game, alloc: std.mem.Allocator) []u8 {
|
||||||
if (str.len < 4) return game;
|
var moves = std.ArrayList(types.move).init(alloc);
|
||||||
var splitItr = std.mem.splitSequence(u8, str, " ");
|
|
||||||
while (splitItr.next()) |moveString| {
|
|
||||||
var move: c.move = .{ .To = 0, .From = 0, .Promo = 0 };
|
|
||||||
if (moveString.len < 4) continue;
|
|
||||||
move.From = (moveString[0] - 'a') + (moveString[1] - '1') * 8;
|
|
||||||
move.To = (moveString[2] - 'a') + (moveString[3] - '1') * 8;
|
|
||||||
move.Promo = if (moveString.len == 5) moveString[4] else 0;
|
|
||||||
c.makeMove(game, &move);
|
|
||||||
}
|
|
||||||
return game;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn uciGo(game: *c.game, alloc: std.mem.Allocator) []u8 {
|
|
||||||
var moves = std.ArrayList(c.move).init(alloc);
|
|
||||||
defer moves.deinit();
|
defer moves.deinit();
|
||||||
const str = alloc.alloc(u8, 5) catch unreachable;
|
const str = alloc.alloc(u8, 5) catch unreachable;
|
||||||
const m = c.move{ .From = 0, .To = 8, .Promo = 0 };
|
mov.knightMove(game, &moves);
|
||||||
moves.append(m) catch return str;
|
if (moves.capacity == 0) {
|
||||||
_ = game;
|
@memcpy(str.ptr, "err");
|
||||||
mov.moveTypeToStr(m, str);
|
return str;
|
||||||
|
}
|
||||||
|
mov.moveTypeToStr(moves.items[0], str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,4 +147,6 @@ test "uci position" {
|
|||||||
defer alloc.destroy(out.game);
|
defer alloc.destroy(out.game);
|
||||||
try std.testing.expect(out == .game);
|
try std.testing.expect(out == .game);
|
||||||
try std.testing.expect(out.game.whiteToMove == true);
|
try std.testing.expect(out.game.whiteToMove == true);
|
||||||
|
try std.testing.expect(out.game.white.king != 0);
|
||||||
|
try std.testing.expect(out.game.black.king != 0);
|
||||||
}
|
}
|
||||||
|
|||||||
47
src/move.zig
47
src/move.zig
@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const types = @import("types.zig");
|
||||||
const c = @cImport({
|
const c = @cImport({
|
||||||
@cInclude("main.h");
|
@cInclude("main.h");
|
||||||
@cInclude("types.h");
|
@cInclude("types.h");
|
||||||
@ -7,7 +8,7 @@ const c = @cImport({
|
|||||||
@cInclude("moves.h");
|
@cInclude("moves.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn moveTypeToStr(move: c.move, buf: []u8) void {
|
pub fn moveTypeToStr(move: types.move, buf: []u8) void {
|
||||||
const xTo = @mod(move.To, 8);
|
const xTo = @mod(move.To, 8);
|
||||||
const yTo = @divTrunc(move.To, 8);
|
const yTo = @divTrunc(move.To, 8);
|
||||||
const xFrom = @mod(move.From, 8);
|
const xFrom = @mod(move.From, 8);
|
||||||
@ -20,6 +21,50 @@ pub fn moveTypeToStr(move: c.move, buf: []u8) void {
|
|||||||
buf[4] = move.Promo;
|
buf[4] = move.Promo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn playMoves(game: *types.game, str: []const u8) *types.game {
|
||||||
|
if (str.len < 4) return game;
|
||||||
|
var splitItr = std.mem.splitSequence(u8, str, " ");
|
||||||
|
while (splitItr.next()) |moveString| {
|
||||||
|
var move: types.move = .{ .To = 0, .From = 0, .Promo = 0 };
|
||||||
|
if (moveString.len < 4) continue;
|
||||||
|
move.From = (moveString[0] - 'a') + (moveString[1] - '1') * 8;
|
||||||
|
move.To = (moveString[2] - 'a') + (moveString[3] - '1') * 8;
|
||||||
|
move.Promo = if (moveString.len == 5) moveString[4] else 0;
|
||||||
|
c.makeMove(@ptrCast(game), @ptrCast(&move));
|
||||||
|
}
|
||||||
|
return game;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn charToSet(g: *types.game, chr: u8) *u64 {
|
||||||
|
return switch (chr) {
|
||||||
|
'P' => &g.white.pawns,
|
||||||
|
'N' => &g.white.knights,
|
||||||
|
'B' => &g.white.bishops,
|
||||||
|
'R' => &g.white.rooks,
|
||||||
|
'Q' => &g.white.queen,
|
||||||
|
'K' => &g.white.king,
|
||||||
|
'p' => &g.black.pawns,
|
||||||
|
'n' => &g.black.knights,
|
||||||
|
'b' => &g.black.bishops,
|
||||||
|
'r' => &g.black.rooks,
|
||||||
|
'q' => &g.black.queen,
|
||||||
|
'k' => &g.black.king,
|
||||||
|
else => {
|
||||||
|
std.log.err("you should not be here ${c}$", .{chr});
|
||||||
|
unreachable;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// pub fn pawnMove(arr: std.ArrayList(c.move)) void {
|
// pub fn pawnMove(arr: std.ArrayList(c.move)) void {
|
||||||
// const move = c.move{ .From = 8, .To = 16, .Promo = 0 };
|
// const move = c.move{ .From = 8, .To = 16, .Promo = 0 };
|
||||||
// }
|
// }
|
||||||
|
fn bitboardToMoves(start: u8, moves: u64, arr: *std.ArrayList(types.move)) void {
|
||||||
|
var lmoves = moves;
|
||||||
|
while (lmoves != 0) {
|
||||||
|
const pos = @ctz(lmoves);
|
||||||
|
const m: types.move = .{ .From = start, .Promo = 0, .To = pos };
|
||||||
|
lmoves = lmoves & ~@as(u64, 1) << @truncate(pos);
|
||||||
|
arr.append(m) catch unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
46
src/types.zig
Normal file
46
src/types.zig
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
const c = @cImport({
|
||||||
|
@cInclude("main.h");
|
||||||
|
@cInclude("types.h");
|
||||||
|
@cInclude("help.h");
|
||||||
|
@cInclude("eval.h");
|
||||||
|
@cInclude("moves.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
const uciTag = enum {
|
||||||
|
text,
|
||||||
|
move,
|
||||||
|
game,
|
||||||
|
exit,
|
||||||
|
pass,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const uciRet = union(uciTag) {
|
||||||
|
text: []const u8,
|
||||||
|
move: []u8,
|
||||||
|
game: *game,
|
||||||
|
exit: void,
|
||||||
|
pass: void,
|
||||||
|
};
|
||||||
|
const set = struct {
|
||||||
|
pawns: u64,
|
||||||
|
knights: u64,
|
||||||
|
bishops: u64,
|
||||||
|
rooks: u64,
|
||||||
|
queen: u64,
|
||||||
|
king: u64,
|
||||||
|
};
|
||||||
|
pub const game = struct {
|
||||||
|
black: set,
|
||||||
|
white: set,
|
||||||
|
whiteToMove: bool,
|
||||||
|
};
|
||||||
|
pub const move = struct {
|
||||||
|
From: u32,
|
||||||
|
To: u32,
|
||||||
|
Promo: u8,
|
||||||
|
};
|
||||||
|
// struct {
|
||||||
|
// To: u8,
|
||||||
|
// From: u8,
|
||||||
|
// Promo: u8,
|
||||||
|
// };
|
||||||
@ -5,12 +5,12 @@
|
|||||||
"uciEngines": [
|
"uciEngines": [
|
||||||
{
|
{
|
||||||
"name":"rat",
|
"name":"rat",
|
||||||
"engine":"./a.out",
|
"engine":"./zig-out/bin/RatChess",
|
||||||
"ponder":false
|
"ponder":false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "stockfish",
|
"name": "stockfish",
|
||||||
"engine": "/nix/store/5d7aqjdak73qlsimiismbj0m1h9b566j-stockfish-17/bin/stockfish",
|
"engine": "/nix/store/xrzjqi5m9yphj4p5wgpvnamxs38ap0wv-stockfish-17/bin/stockfish",
|
||||||
"hash": 128,
|
"hash": 128,
|
||||||
"ponder": false,
|
"ponder": false,
|
||||||
"ownBook": false,
|
"ownBook": false,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user