/* Copyright 2018 Romain "Artefact2" Dal Maso <artefact2@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include "gumble.h"
#include "moves.h"

#define ADD_IF_VALID(DIRECTION) do {				\
		if(CCH_IS_SQUARE_VALID(DIRECTION(sq))) {	\
			lut |= (1ULL << DIRECTION(sq));			\
		}											\
	} while(0)

#define ADD_WHILE_VALID(DIRECTION) do {									\
		for(tsq = DIRECTION(sq); CCH_IS_SQUARE_VALID(tsq); tsq = DIRECTION(tsq)) { \
			lut |= (1ULL << tsq);										\
		}																\
	} while(0)

static void knight(void) {
	cch_board_bitmap_t lut;
	cch_square_t sq;
	puts("static cch_board_bitmap_t knight_lut[] = {");
	for(sq = 0; sq < 64; ++sq) {
		lut = 0;
		ADD_IF_VALID(CCH_NNW);
		ADD_IF_VALID(CCH_NNE);
		ADD_IF_VALID(CCH_SSW);
		ADD_IF_VALID(CCH_SSE);
		ADD_IF_VALID(CCH_WWN);
		ADD_IF_VALID(CCH_WWS);
		ADD_IF_VALID(CCH_EEN);
		ADD_IF_VALID(CCH_EES);
		printf("\t%lluULL,\n", lut);
	}
	puts("};");
}

static void king(void) {
	cch_board_bitmap_t lut;
	cch_square_t sq;
	puts("static cch_board_bitmap_t king_lut[] = {");
	for(sq = 0; sq < 64; ++sq) {
		lut = 0;
		ADD_IF_VALID(CCH_NORTH);
		ADD_IF_VALID(CCH_SOUTH);
		ADD_IF_VALID(CCH_WEST);
		ADD_IF_VALID(CCH_EAST);
		ADD_IF_VALID(CCH_NORTHWEST);
		ADD_IF_VALID(CCH_NORTHEAST);
		ADD_IF_VALID(CCH_SOUTHWEST);
		ADD_IF_VALID(CCH_SOUTHEAST);
		printf("\t%lluULL,\n", lut);
	}
	puts("};");
}

static void rook(void) {
	cch_board_bitmap_t lut;
	cch_square_t sq, tsq;
	puts("static cch_board_bitmap_t rook_lut[] = {");
	for(sq = 0; sq < 64; ++sq) {
		lut = 0;
		ADD_WHILE_VALID(CCH_NORTH);
		ADD_WHILE_VALID(CCH_SOUTH);
		ADD_WHILE_VALID(CCH_WEST);
		ADD_WHILE_VALID(CCH_EAST);
		printf("\t%lluULL,\n", lut);
	}
	puts("};");
}

static void bishop(void) {
	cch_board_bitmap_t lut;
	cch_square_t sq, tsq;
	puts("static cch_board_bitmap_t bishop_lut[] = {");
	for(sq = 0; sq < 64; ++sq) {
		lut = 0;
		ADD_WHILE_VALID(CCH_NORTHWEST);
		ADD_WHILE_VALID(CCH_NORTHEAST);
		ADD_WHILE_VALID(CCH_SOUTHWEST);
		ADD_WHILE_VALID(CCH_SOUTHEAST);
		printf("\t%lluULL,\n", lut);
	}
	puts("};");
}

int main(void) {
	knight();
	putchar('\n');
	king();
	putchar('\n');
	rook();
	putchar('\n');
	bishop();
}
