Totally Blind Chess
Just Everything
Generates a list of every possibly legal move, shuffles it, then cycles through it repeatedly.
Since there are only 1792 possibly legal moves, this will never forfeit due to the 2000-attempt rule.
This is meant as a template that other answers can build on.
#! /usr/bin/python
import sys
import random
_, color, seed = sys.argv[:3]
random.seed(seed)
colnames = "abcdefgh"
rownames = "12345678" if color == "w" else "87654321"
def coord2code((col, row)):
return colnames[col] + rownames[row];
def buildmoves((col, row)):
# Knight moves
for x in (1, 2, -2, -1):
if x+col >= 0 and x+col <= 7:
for y in (2/x, -2/x):
if y+row >= 0 and y+row <= 7:
yield (x+col, y+row)
# Bishop moves
for x in range(1,8):
if col+x <= 7:
if row+x <= 7:
yield (col+x, row+x)
if row-x >= 0:
yield (col+x, row-x)
if col-x >= 0:
if row+x <= 7:
yield (col-x, row+x)
if row-x >= 0:
yield (col-x, row-x)
# Rook moves
for x in range(1,8):
if col+x <= 7:
yield (col+x, row)
if col-x >= 0:
yield (col-x, row)
if row+x <= 7:
yield (col, row+x)
if row-x >= 0:
yield (col, row-x)
def allmoves():
for row in range(8):
for col in range(8):
for to in buildmoves((row, col)):
yield ((row, col), to)
movelist = [(coord2code(a), coord2code(b)) for (a,b) in allmoves()]
random.shuffle(movelist)
while True:
for (a, b) in movelist:
print a, b
Zombie March
Slowly walks all its pieces forward across the board, in a random order (but favoring pawns).
The first 5 moves sent specifically counter the scholar's mate.
#! /usr/bin/python
import sys
import random
_, color, seed = sys.argv[:3]
random.seed(seed)
moveorder = [(2, 2), (1, 1), (0, 2), (0, 1), (1, 2), (2, 1), (2, 0), (1, 0)]
moveorder7 = [(4, 0), (3, 0), (2, 0), (1, 0), (0, -4), (0, -3), (0, -2), (0, -1), (4, -4), (3, -3), (2, -2), (1, -1), (1, -2), (2, -1)]
colorder = random.sample([2, 3, 4, 5], 4) + random.sample([0, 1, 6, 7], 4)
roworder = [1, 2, 3, 4, 5, 6, 7, 0]
colnames = "abcdefgh"
rownames = "12345678" if color == "w" else "87654321"
def buildmoves((col, row), (x, y)):
if row+y > 7 or row+y < 0:
return
if x == 0:
yield (col, row+y)
return
if col < 4:
if col+x <= 7:
yield (col+x, row+y)
if col-x >= 0:
yield (col-x, row+y)
else:
if col-x >= 0:
yield (col-x, row+y)
if col+x <= 7:
yield (col+x, row+y)
def coord2code((col, row)):
return colnames[col] + rownames[row];
# Some fixed behavior (counter foolsmate)
print coord2code((6, 1)), coord2code((6, 2))
print coord2code((4, 1)), coord2code((4, 3))
print coord2code((3, 1)), coord2code((3, 3))
print coord2code((6, 2)), coord2code((7, 3))
print coord2code((3, 3)), coord2code((2, 4))
iter = 0
while True:
iter += 1
for row in roworder:
for move in (moveorder if row*(1+iter*random.random()/10)<7 else random.sample(moveorder7, 8)):
for col in colorder:
for to in buildmoves((col, row), move):
print coord2code((col, row)), coord2code(to)
Scholar
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
enum { WHITE, BLACK };
int main(int argc, char **argv)
{
assert(argc == 3);
int color;
switch (argv[1][0])
{
case 'w': color = WHITE; break;
case 'b': color = BLACK; break;
default: assert(0);
}
if(color == WHITE) {
printf("e2 e3\n");
printf("d1 h5\n");
printf("f1 c4\n");
printf("h5 f7\n");
}
else {
printf("e7 e6\n");
printf("d8 h4\n");
printf("f8 c5\n");
printf("h4 f2\n");
}
srand(atoll(argv[2]));
for ( ;; )
{
printf("%c%c %c%c\n", rand() % 8 + 'a', rand() % 8 + '1', rand() % 8 + 'a', rand() % 8 + '1');
}
}
Scholar simply tries for a 4-move checkmate (with a 10% chance of a 2-move check that can result in a forfeit), then moves randomly after that. I tried adding in some nonrandom moves that were more likely to be legal, but at least in the naive way I did it that made the bot worse--more likely to forfeit when in check, I think.