Compare commits
7 Commits
da8eb581e3
...
d6fa809505
| Author | SHA1 | Date | |
|---|---|---|---|
| d6fa809505 | |||
| eccd8efdba | |||
| ca1e62397c | |||
| 059f672c17 | |||
| f9dda928b2 | |||
| bb3bc4442a | |||
| 93e7ff61e0 |
@ -1,5 +1,5 @@
|
|||||||
#ifndef EVAL_H
|
#ifndef EVAL_H
|
||||||
#define EVAL_H
|
#define EVAL_H
|
||||||
move *findBest(move* move, size_t size, game* g);
|
move *findBest(move* move, long long size, game* g);
|
||||||
void makeMove(game *g, move* m);
|
void makeMove(game *g, move* m);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
long long fullSet(sets *s);
|
long long fullSet(sets *s);
|
||||||
long long fullSetBoth(game *g);
|
long long fullSetBoth(game *g);
|
||||||
void print_bitboard(long long bitboard);
|
void print_bitboard(long long bitboard);
|
||||||
long long *findSet(game *g, long long bit);
|
unsigned long long *findSet(game *g, long long bit);
|
||||||
long long *charToSet(game *g, char c);
|
unsigned long long *charToSet(game *g, char c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
int cmain();
|
int cmain();
|
||||||
game *fenGame(char *str);
|
game *fenGame(char *str);
|
||||||
void playMoves(game *g, char *moves);
|
game *playMoves(game *g, char *moves);
|
||||||
char* uciGo(game *g);
|
char* uciGo(game *g);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
13
src/main.c
13
src/main.c
@ -15,9 +15,7 @@
|
|||||||
#define BUFF_SIZE 4096
|
#define BUFF_SIZE 4096
|
||||||
|
|
||||||
game *fenGame(char *str);
|
game *fenGame(char *str);
|
||||||
void playMoves(game *g, char *moves);
|
game *playMoves(game *g, char *moves);
|
||||||
long long *findSet(game *g, long long bit);
|
|
||||||
long long *charToSet(game *g, char c);
|
|
||||||
|
|
||||||
int cmain() {
|
int cmain() {
|
||||||
setbuf(stdin, NULL);
|
setbuf(stdin, NULL);
|
||||||
@ -73,8 +71,8 @@ char* uciGo(game *g){
|
|||||||
cnt += queenMove(g,(mov+cnt));
|
cnt += queenMove(g,(mov+cnt));
|
||||||
move *m = findBest(mov,cnt,g);
|
move *m = findBest(mov,cnt,g);
|
||||||
if(m == NULL){
|
if(m == NULL){
|
||||||
printf("bestmove 0000\n");
|
//printf("bestmove 0000\n");
|
||||||
return "";
|
return "0000";
|
||||||
}
|
}
|
||||||
|
|
||||||
char *end = "";
|
char *end = "";
|
||||||
@ -123,7 +121,7 @@ game *fenGame(char *str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long long bit = 1ULL << (rank * 8 + file);
|
long long bit = 1ULL << (rank * 8 + file);
|
||||||
long long *set = charToSet(g, *str);
|
unsigned long long *set = charToSet(g, *str);
|
||||||
if (set)
|
if (set)
|
||||||
*set |= bit;
|
*set |= bit;
|
||||||
file++;
|
file++;
|
||||||
@ -134,7 +132,7 @@ game *fenGame(char *str) {
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playMoves(game *g, char *moves) {
|
game* playMoves(game *g, char *moves) {
|
||||||
char *moveStr;
|
char *moveStr;
|
||||||
moveStr = strtok_r(moves, " ", &moves);
|
moveStr = strtok_r(moves, " ", &moves);
|
||||||
moveStr = strtok_r(moves, " ", &moves);
|
moveStr = strtok_r(moves, " ", &moves);
|
||||||
@ -146,5 +144,6 @@ void playMoves(game *g, char *moves) {
|
|||||||
makeMove(g, &m);
|
makeMove(g, &m);
|
||||||
moveStr = strtok_r(moves, " ", &moves);
|
moveStr = strtok_r(moves, " ", &moves);
|
||||||
}
|
}
|
||||||
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
119
src/main.zig
119
src/main.zig
@ -1,7 +1,11 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const mov = @import("move.zig");
|
||||||
const c = @cImport({
|
const c = @cImport({
|
||||||
@cInclude("main.h");
|
@cInclude("main.h");
|
||||||
@cInclude("types.h");
|
@cInclude("types.h");
|
||||||
|
@cInclude("help.h");
|
||||||
|
@cInclude("eval.h");
|
||||||
|
@cInclude("moves.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
const uciTag = enum {
|
const uciTag = enum {
|
||||||
@ -14,7 +18,7 @@ const uciTag = enum {
|
|||||||
|
|
||||||
const uciRet = union(uciTag) {
|
const uciRet = union(uciTag) {
|
||||||
text: []const u8,
|
text: []const u8,
|
||||||
move: []const u8,
|
move: []u8,
|
||||||
game: *c.game,
|
game: *c.game,
|
||||||
exit: void,
|
exit: void,
|
||||||
pass: void,
|
pass: void,
|
||||||
@ -27,18 +31,21 @@ 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");
|
var game: *c.game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
|
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));
|
||||||
defer alloc.free(line);
|
defer alloc.free(line);
|
||||||
switch (uci(line, game)) {
|
switch (uci(line, game, alloc)) {
|
||||||
.text => |value| {
|
.text => |value| {
|
||||||
try std.io.getStdOut().writer().print("{s}", .{value});
|
try std.io.getStdOut().writer().print("{s}", .{value});
|
||||||
},
|
},
|
||||||
.move => |value| {
|
.move => |value| {
|
||||||
try std.io.getStdOut().writer().print("bestmove {s}\n", .{value});
|
try std.io.getStdOut().writer().print("bestmove {s}\n", .{value});
|
||||||
|
alloc.free(value);
|
||||||
},
|
},
|
||||||
.game => |value| {
|
.game => |value| {
|
||||||
|
alloc.destroy(game);
|
||||||
game = value;
|
game = value;
|
||||||
},
|
},
|
||||||
.exit => {
|
.exit => {
|
||||||
@ -51,51 +58,119 @@ 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 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" };
|
||||||
if (std.mem.eql(u8, tok, "isready")) return .{ .text = "readyok\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, "go")) return .{ .move = uciGo(game, alloc) };
|
||||||
if (std.mem.eql(u8, tok, "position")) return .{ .game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1") };
|
if (std.mem.eql(u8, tok, "position")) return .{ .game = uciPos(str[(pos + 1)..], alloc) };
|
||||||
if (std.mem.eql(u8, tok, "exit")) return .{ .exit = {} };
|
if (std.mem.eql(u8, tok, "exit")) return .{ .exit = {} };
|
||||||
return .{ .pass = {} };
|
return .{ .pass = {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uciPos(str: []const u8) [*c]c.game {
|
fn uciPos(str: []const u8, alloc: std.mem.Allocator) *c.game {
|
||||||
var buffer: [256]u8 = undefined;
|
const pos = std.mem.indexOfAny(u8, str, " \t\n\r") orelse str.len;
|
||||||
const len = @min(str.len, buffer.len - 1);
|
const tok = str[0..pos];
|
||||||
@memcpy(buffer[0..len], str[0..len]);
|
//var game = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
buffer[len] = 0;
|
if (std.mem.eql(u8, tok, "fen")) return fenGame(str[pos..], alloc);
|
||||||
|
if (std.mem.eql(u8, tok, "startpos")) {
|
||||||
|
var game = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
|
game = playMoves(game, str[pos..]);
|
||||||
|
return game;
|
||||||
|
}
|
||||||
|
return fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc); //this should be an error
|
||||||
|
}
|
||||||
|
|
||||||
const game = 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 = true;
|
||||||
|
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 {
|
||||||
|
if (str.len < 4) return game;
|
||||||
|
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;
|
return game;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uciGo(game: *c.game) []const u8 {
|
fn uciGo(game: *c.game, alloc: std.mem.Allocator) []u8 {
|
||||||
return std.mem.span(c.uciGo(game));
|
var moves = std.ArrayList(c.move).init(alloc);
|
||||||
|
defer moves.deinit();
|
||||||
|
const str = alloc.alloc(u8, 5) catch unreachable;
|
||||||
|
const m = c.move{ .From = 0, .To = 8, .Promo = 0 };
|
||||||
|
moves.append(m) catch return str;
|
||||||
|
_ = game;
|
||||||
|
mov.moveTypeToStr(m, str);
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
test "uci uci" {
|
test "uci uci" {
|
||||||
const game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const out = uci("uci", game);
|
defer _ = gpa.deinit();
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
const game = uciPos("fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
|
defer alloc.destroy(game);
|
||||||
|
|
||||||
|
const out = uci("uci", game, alloc);
|
||||||
try std.testing.expect(out == .text);
|
try std.testing.expect(out == .text);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "uci ready" {
|
test "uci ready" {
|
||||||
const game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const out = uci("isready", game);
|
defer _ = gpa.deinit();
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
const game = uciPos("fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
|
defer alloc.destroy(game);
|
||||||
|
|
||||||
|
const out = uci("isready", game, alloc);
|
||||||
try std.testing.expect(out == .text);
|
try std.testing.expect(out == .text);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "uci go" {
|
test "uci go" {
|
||||||
const game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const out = uci("go", game);
|
defer _ = gpa.deinit();
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
const game = uciPos("fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
|
defer alloc.destroy(game);
|
||||||
|
|
||||||
|
const out = uci("go", game, alloc);
|
||||||
try std.testing.expect(out == .move);
|
try std.testing.expect(out == .move);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "uci position" {
|
test "uci position" {
|
||||||
const game = uciPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const out = uci("position startpos", game);
|
defer _ = gpa.deinit();
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
const game = uciPos("fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", alloc);
|
||||||
|
defer alloc.destroy(game);
|
||||||
|
|
||||||
|
const out = uci("position startpos", game, alloc);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/move.zig
Normal file
25
src/move.zig
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const c = @cImport({
|
||||||
|
@cInclude("main.h");
|
||||||
|
@cInclude("types.h");
|
||||||
|
@cInclude("help.h");
|
||||||
|
@cInclude("eval.h");
|
||||||
|
@cInclude("moves.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn moveTypeToStr(move: c.move, buf: []u8) void {
|
||||||
|
const xTo = @mod(move.To, 8);
|
||||||
|
const yTo = @divTrunc(move.To, 8);
|
||||||
|
const xFrom = @mod(move.From, 8);
|
||||||
|
const yFrom = @divTrunc(move.From, 8);
|
||||||
|
|
||||||
|
buf[0] = @intCast(xFrom + 'a');
|
||||||
|
buf[1] = @intCast(yFrom + '0' + 1);
|
||||||
|
buf[2] = @intCast(xTo + 'a');
|
||||||
|
buf[3] = @intCast(yTo + '0' + 1);
|
||||||
|
buf[4] = move.Promo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn pawnMove(arr: std.ArrayList(c.move)) void {
|
||||||
|
// const move = c.move{ .From = 8, .To = 16, .Promo = 0 };
|
||||||
|
// }
|
||||||
@ -28,22 +28,22 @@ int pawnMove(game *g, move *moves) {
|
|||||||
|
|
||||||
// forword
|
// forword
|
||||||
int to = i + movdir;
|
int to = i + movdir;
|
||||||
p = (promo & (1ULL << to)) ? 'q' : 0;
|
|
||||||
if (to >= 0 && to < 64 && !(occupied & (1ULL << to))) {
|
if (to >= 0 && to < 64 && !(occupied & (1ULL << to))) {
|
||||||
|
p = (promo & (1ULL << to)) ? 'q' : 0;
|
||||||
moves[index++] = (move){.From = i, .To = to, .Promo = p};
|
moves[index++] = (move){.From = i, .To = to, .Promo = p};
|
||||||
}
|
}
|
||||||
|
|
||||||
// left
|
// left
|
||||||
to = i + capLeft;
|
to = i + capLeft;
|
||||||
p = (promo & (1ULL << to)) ? 'q' : 0;
|
|
||||||
if (i % 8 > 0 && (to >= 0 && to < 64) && (enemy & (1ULL << to))) {
|
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};
|
moves[index++] = (move){.From = i, .To = to, .Promo = p};
|
||||||
}
|
}
|
||||||
|
|
||||||
// right
|
// right
|
||||||
to = i + capRight;
|
to = i + capRight;
|
||||||
p = (promo & (1ULL << to)) ? 'q' : 0;
|
|
||||||
if (i % 8 < 7 && (to >= 0 && to < 64) && (enemy & (1ULL << to))) {
|
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};
|
moves[index++] = (move){.From = i, .To = to, .Promo = p};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,6 +78,7 @@ int knightMove(game *g, move *moves) {
|
|||||||
(fileDiff == 2 && rankDiff == 1)))
|
(fileDiff == 2 && rankDiff == 1)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(to < 0 || to > 63) continue;
|
||||||
long long destBit = 1ULL << to;
|
long long destBit = 1ULL << to;
|
||||||
if (occupied & destBit)
|
if (occupied & destBit)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user