Update .clang-format

This commit is contained in:
Ole Morud
2023-03-26 19:15:46 +02:00
committed by Ole Morud
parent 863328a3de
commit 319428e1bc
15 changed files with 1256 additions and 750 deletions

View File

@@ -1,40 +1,40 @@
CC = clang
LD = ld.lld
CFLAGS = -Iinclude
CC = gcc
#CFLAGS += -O0 -ggdb3
CFLAGS += -Ofast -ggdb3
CFLAGS += -Wall -Wextra -Werror
CFLAGS += -fsanitize=address
LDFLAGS = -fuse-ld=lld
LDFLAGS = -fsanitize=address
CFLAGS += -Wall -Wextra -Wno-unused-function -rdynamic
#CFLAGS += -fsanitize=address
LDFLAGS = -fuse-ld=lld -rdynamic
#LDFLAGS += -fsanitize=address
_OBJ = chess.o common.o graphics.o pieces.o util.o
_OBJ = chess.o
OBJ = $(addprefix obj/, $(_OBJ))
TEST_DIR = testing
all: bin/chess
test: $(TEST_DIR)/bin/test_threatmap
obj:
mkdir -p $@
bin:
mkdir -p $@
docs:
doxygen doxygen-config
$(TEST_DIR):
mkdir -p $@/bin
clean:
rm bin/* obj/*.o
gdb: bin/chess
gdb $<
run: bin/chess
./$<
obj/%.o: src/%.c
$(CC) -o $@ $(CFLAGS) -c $<
bin/chess: $(OBJ)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^
.PHONY: all run gdb clean docs
$(TEST_DIR)/bin/test_%: testing/test_%.c obj/%.o obj/util.o
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^
.PHONY: all clean docs test

View File

@@ -1,4 +1,3 @@
-Iinclude
-Wall
-Wextra
-Werror

View File

@@ -1,142 +0,0 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Terminal Chess"
PROJECT_BRIEF = Chess application for ANSI terminals
OUTPUT_DIRECTORY = docs
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
JAVADOC_BANNER = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
OPTIMIZE_OUTPUT_FOR_C = YES
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
AUTOLINK_SUPPORT = YES
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
NUM_PROC_THREADS = 0
EXTRACT_ALL = YES
CASE_SENSE_NAMES = SYSTEM
SHOW_HEADERFILE = YES
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO
WARN_IF_UNDOC_ENUM_VAL = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LINE_FORMAT = "at line $line of file $file"
INPUT = src
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c *.h
RECURSIVE = YES
EXCLUDE_SYMLINKS = NO
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
FILTER_SOURCE_FILES = NO
USE_MDFILE_AS_MAINPAGE = README.md
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_COLORSTYLE = AUTO_LIGHT
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
OBFUSCATE_EMAILS = YES
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2
MATHJAX_FORMAT = HTML-CSS
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO
SEARCHDATA_FILE = searchdata.xml
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
SKIP_FUNCTION_MACROS = YES
TAGFILES = tags
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES

View File

@@ -1,26 +0,0 @@
#include <stdbool.h> /* true, false, bool */
#include <stddef.h> /* ptrdiff_t */
#include <stdint.h> /* int32_t */
/** Type representing piece/tile on a chessboard */
typedef int32_t tile_t;
/** Type representing index of a chessboard tile */
typedef ptrdiff_t index_t;
#define BOARD_SIZE ((index_t)(8 * 8))
#define WHITE ((tile_t)1)
#define BLACK ((tile_t)-1)
#define E ((tile_t)0) ///< empty tile
#define K ((tile_t)1) ///< king
#define Q ((tile_t)2) ///< queen
#define R ((tile_t)3) ///< rook
#define B ((tile_t)4) ///< bishop
#define N ((tile_t)5) ///< knight
#define P ((tile_t)6) ///< pawn
#define ROW ((index_t)8)
#define COL ((index_t)1)

View File

@@ -1,8 +0,0 @@
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "common.h"
void print_board(const tile_t board[BOARD_SIZE]);
#endif

View File

@@ -1,12 +0,0 @@
#ifndef PIECES_H
#define PIECES_H
#include "common.h"
bool move_ok(const tile_t board[BOARD_SIZE],
index_t from,
index_t to,
int player);
#endif

View File

@@ -1,11 +0,0 @@
#include "common.h"
int64_t get_sign(int64_t n);
bool tile_empty(tile_t t);
index_t abs_index(index_t i);
index_t column(index_t i);
index_t row(index_t i);
tile_t abs_tile(tile_t t);
tile_t get_color(tile_t t);
bool same_color(tile_t a, tile_t b);
bool opposite_color(tile_t a, tile_t b);

56
src/board.h Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <assert.h>
typedef uint64_t bitmap_t;
typedef uint_fast8_t index_t;
typedef int_fast8_t piece_t;
enum tile_info {
EMPTY = 0b0000,
KING = 0b0001,
QUEEN = 0b0010,
ROOK = 0b0011,
BISHOP = 0b0100,
KNIGHT = 0b0101,
PAWN = 0b0110,
COLOR_BIT = 0b1000,
PIECE_UNKNOWN=-1
};
struct board {
static_assert(sizeof(bitmap_t) == 64/8, "bitmap_t must be 64 bits long");
bitmap_t pieces[4]; // 4 bits correspond to 1 tile
};
static inline bitmap_t bit(index_t i)
{
return 0b111UL << 3*i;
}
static bool is_white(piece_t piece)
{
return piece % 2 == 0;
}
static bool is_black(piece_t piece)
{
return piece % 2 == 1;
}
static piece_t piece_at(struct board* board, index_t tile)
{
for (size_t i = 0; i < sizeof board->pieces / board->pieces[0]; i++) {
if (bit(tile) & board->pieces[i]) {
return i;
}
}
return PIECE_UNKNOWN;
}

File diff suppressed because it is too large Load Diff

45
src/cool_assert.h Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include <stdio.h>
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#undef assert
#ifdef assert
#error "assert is already defined!"
#endif
static void print_backtrace()
{
void* array[10];
char** strings;
int size, i;
size = backtrace(array, 10);
strings = backtrace_symbols(array, size);
if (strings != NULL)
{
printf ("Obtained %d stack frames.\n", size);
for (i = 0; i < size; i++)
printf ("%s\n", strings[i]);
}
free(strings);
exit(EXIT_FAILURE);
}
static int assertion_fail(const char* msg)
{
fprintf(stderr, "assertion `%s` failed!\n", msg);
print_backtrace();
exit(EXIT_FAILURE);
}
#ifndef NDEBUG
#define assert(expr) ((void)((expr) || (assertion_fail(# expr), 0)))
#else
#define assert(expt) (void)0
#endif

View File

@@ -1,95 +0,0 @@
#include "graphics.h"
#include "common.h"
#include "util.h"
#include <stdio.h>
/** Set background to dark blue */
#define BG_DARKBLUE() setcolor(0, 100, 100, 150)
/** Set background to light blue */
#define BG_LIGHTBLUE() setcolor(0, 150, 150, 200)
/** Set foreground to black */
#define FG_BLACK() setcolor(1, 0, 0, 0)
/** Set foreground to white */
#define FG_WHITE() setcolor(1, 0xff, 0xff, 0xff)
/** 0x2659 == ♙ */
#define UNICODE_CHESS_SYMBOL 0x2659
static inline void
setcolor(const int mode, const int r, const int g, const int b);
/**
* Sets the foreground or background color for subsequent writes.
*
* Uses Select Graphic Renditions (SGR) to set the color of the terminal output.
* See https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit for more details.
*
* \param mode 0 - change background, 1 - change foreground, 2 - reset colors
* \param r amount of red (0 to 255)
* \param b amount of blue (0 to 255)
* \param g amount of green (0 to 255)
*/
static inline void
setcolor(const int mode, const int r, const int g, const int b)
{
if (mode == 2)
printf("\033[0m");
else
printf("\033[%i;2;%i;%i;%im", mode ? 38 : 48, r, g, b);
};
/**
* Prints the board
*
* Uses unicode symbols and ANSI escape features to print a chessboard on the
* display.
*
* \param board A pointer to a list of tiles representing the board state
*
* */
void print_board(const tile_t board[BOARD_SIZE])
{
/* https://en.wikipedia.org/wiki/Chess_symbols_in_Unicode
The unicode symbols for the pieces are calculated from adding
0x2653 (#define'd as UNICODE_CHESS_SYMBOL) with the piece value. */
for (size_t i = 0; i < 8; i++) {
printf("\n %zu ", 8 - i); // number coordinates
for (size_t j = 0; j < 8; j++) {
tile_t t = board[i * 8 + j];
if ((i + j) % 2)
BG_DARKBLUE();
else
BG_LIGHTBLUE();
if (tile_empty(t)) {
printf(" ");
continue;
}
if (t > 0)
FG_WHITE();
else
FG_BLACK();
printf("%lc ", UNICODE_CHESS_SYMBOL + abs_tile(t));
}
setcolor(2, 0, 0, 0); // reset text attributes
}
/* horizontal letter coordinates */
printf("\n ");
for (int i = 0; i < 8; i++)
printf(" %c", 'a' + i);
}

20
src/map.h Normal file
View File

@@ -0,0 +1,20 @@
enum chess_piece {
EMPTY = 0,
KING = 1,
QUEEN = 2,
ROOK = 3,
BISHOP = 4,
KNIGHT = 5,
PAWN = 6,
PIECE_COUNT,
};
static bool board_equals(
struct board_map {
};

View File

@@ -1,230 +0,0 @@
#include "common.h"
#include "util.h"
bool bishop_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
bool cardinal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
bool king_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
bool knight_move_ok(index_t from, index_t to);
bool pawn_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
bool queen_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
bool rook_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
/**
* Check if a move is valid
*
* \param board Pointer to list of tiles representing board state
* \param from Tile to move piece from
* \param to Tile to move piece to
* \param player The current player to move
*
* \return true if move is valid, false otherwise
* */
bool move_ok(const tile_t board[BOARD_SIZE],
index_t from,
index_t to,
int player)
{
/* player must own piece it moves */
if (board[from] * player < 0)
return false;
/* empty tiles can't be moved */
if (tile_empty(board[from]))
return false;
/* player can't take their own pieces or move a piece onto itself */
if (same_color(board[from], board[to]))
return false;
/* check piece specific moves */
switch (abs_tile(board[from])) {
case P:
return pawn_move_ok(board, from, to);
case B:
return bishop_move_ok(board, from, to);
case R:
return rook_move_ok(board, from, to);
case N:
return knight_move_ok(from, to);
case K:
return king_move_ok(board, from, to);
case Q:
return queen_move_ok(board, from, to);
}
return false;
}
/**
* Check if move is a valid pawn move
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece starts at
* \param to Index of board piece wants to move to
*
* \return true if move is valid, false otherwise
*/
bool pawn_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
const index_t direction = -1 * get_color(board[from]),
diff = (to - from) * direction;
switch (diff) {
case ROW: /* single move */
return tile_empty(board[to]);
case ROW - COL: /* diagonal attack */
case ROW + COL:
return opposite_color(board[to], board[from]);
case 2 * ROW: /* double move */
return tile_empty(board[to])
&& tile_empty(board[from + ROW * direction])
&& (row(from) == 1 || row(from) == 6);
default: /* any other move is illegal */
return false;
}
}
/**
* Check if `to` is on a diagonal line of `from`
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if \p to is on a diagonal line of \p from
*/
bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
// clang-format off
const index_t col_diff = column(to) - column(from),
row_diff = row(to) - row(from),
x = get_sign(col_diff),
y = get_sign(row_diff) * ROW,
step = x + y;
// clang-format on
if (abs_index(col_diff) != abs_index(row_diff))
return false;
for (index_t p = from + step; p != to; p += step)
if (! tile_empty(board[p]))
return false;
return true;
}
/**
* Check if index `to` is on a cardinal line of `from`
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if \p to and \p from share a column or row
*/
bool cardinal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
const index_t col_diff = column(to) - column(from),
row_diff = row(to - from);
if (row_diff > 0 && col_diff > 0)
return false;
const index_t step =
row_diff ? ROW * get_sign(row_diff) : get_sign(col_diff);
for (index_t p = from + step; p != to; p += step)
if (! tile_empty(board[p]))
return false;
return true;
}
/**
* Check if move is a valid bishop move
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if move is valid, false otherwise
*/
bool bishop_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
return diagonal_move_ok(board, from, to);
}
/**
* Check if move is a valid rook move
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if move is valid, false otherwise
*/
bool rook_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
return cardinal_move_ok(board, from, to);
}
/**
* Check if move is a valid knight move
*
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if move is valid, false otherwise
*/
bool knight_move_ok(index_t from, index_t to)
{
const index_t x = abs_index(column(to) - column(from)),
y = abs_index(row(to - from));
return (x == 1 && y == 2) || (x == 2 && y == 1);
}
/**
* Check if move is a valid king move
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if move is valid, false otherwise
*/
bool king_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
const index_t abs_x = abs_index(column(to) - column(from)),
abs_y = abs_index(row(to) - row(from));
// TODO: check if move causes check
(void)board;
return abs_x <= 1 && abs_y <= 1;
}
/**
* Check if move is a valid queen move
*
* \param board Array of tiles representing chess board state
* \param from Index of board piece is at
* \param to Index of board piece tries to move to
*
* \return true if move is valid, false otherwise
*/
bool queen_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
{
return diagonal_move_ok(board, from, to)
|| cardinal_move_ok(board, from, to);
}

View File

@@ -1,130 +0,0 @@
#include "util.h"
#include "common.h"
/**
* Get sign of a number
*
* \param n positive or negative integer
*
* \return 1 if number is positive
* -1 if number is negative
* 0 if number is zero
*/
int64_t get_sign(int64_t n)
{
if (n == 0)
return 0;
if (n >= 0)
return 1;
return -1;
}
/**
* Get the color of a tile
*
* \param t tile to check
*
* \return WHITE (1) if tile is white,
* BLACK (-1) if tile is black,
* 0 if the tile is empty
*/
tile_t get_color(tile_t t)
{
return (tile_t)get_sign(t);
}
/**
* Calculate the absolute value of an index_t value
*
* \param p positive or negative index_t
*
* \return the absolute value of p
*/
index_t abs_index(index_t i)
{
if (i < 0)
return -1 * i;
return i;
}
/**
* Calculate the absolute value of a tile_t value
*
* \param t positive or negative tile_t
*
* \return the absolute value of t
* */
tile_t abs_tile(tile_t t)
{
if (t < 0)
return -1 * t;
return t;
}
/**
* Check if tile is has no piece on it
*
* \param t tile to check if empty
*
* \return true if tile is empty, false otherwise
* */
bool tile_empty(tile_t t)
{
return t == E;
}
/**
* Get row of index
*
* \param i index to get row number of
*
* \return row number of i
* */
index_t row(index_t i)
{
return i / ROW;
}
/**
* Get column of index
*
* \param i index to get column number of
*
* \return column number of i
* */
index_t column(index_t i)
{
return i % ROW;
}
/**
* Check if two tiles have pieces of the opposite color
*
* \param a Tile to compare
* \param b Tile to compare it with
*
* \return true if a and b are opposite colors, false otherwise
* */
bool opposite_color(tile_t a, tile_t b)
{
return a * b < 0;
}
/**
* Check if two tiles have pieces of the same color
*
* \param a Tile to compare
* \param b Tile to compare it with
*
* \return true if a and b are opposite colors, false otherwise
* */
bool same_color(tile_t a, tile_t b)
{
return a * b > 0;
}

60
testing/test_threatmap.c Normal file
View File

@@ -0,0 +1,60 @@
#include "threatmap.h"
// uint64_t pawn_threatmap(const tile_t board[BOARD_SIZE], index_t index);
// uint64_t bishop_threatmap(const tile_t board[BOARD_SIZE], index_t index);
// uint64_t rook_threatmap(const tile_t board[BOARD_SIZE], index_t index);
// uint64_t knight_threatmap(index_t index);
// uint64_t king_threatmap(const tile_t board[BOARD_SIZE], index_t index);
// uint64_t queen_threatmap(const tile_t board[BOARD_SIZE], index_t index);
// uint64_t threatmap(const tile_t board[BOARD_SIZE], int color_attacking);
// void print_threatmap(uint64_t threatmap);
void test_threatmap()
{
const tile_t e4[] = {
-R, -N, -B, -Q, -K, -B, -N, -R,
-P, -P, -P, -P, -P, -P, -P, -P,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, P, E, E, E, E,
E, E, E, E, E, E, E, E,
P, P, P, E, P, P, P, P,
R, N, B, Q, K, B, N, R
};
const tile_t lonely_bishop[] = {
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, B, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
};
const tile_t lonely_rook[] = {
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, R, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E,
};
(void)lonely_rook; (void)lonely_bishop; (void)e4;
//print_threatmap(threatmap(e4, WHITE));
print_threatmap(threatmap(lonely_bishop, WHITE));
//print_threatmap(threatmap(lonely_rook, WHITE));
}
int main()
{
test_threatmap();
return 0;
}