Commit e7d574bc authored by Artefact2's avatar Artefact2

Create minimum working binary, no rules or engine yet

parents
cmake_minimum_required(VERSION 2.8)
project(chess-engine-placeholder C)
add_definitions("-g -Wall --std=c11")
#ADD_DEFINITIONS("-fdata-sections -ffunction-sections -flto -fuse-linker-plugin -fvisibility=hidden")
#SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
add_subdirectory(src)
This diff is collapsed.
default: build
cd build && cmake ..
build:
mkdir build
clean:
rm -Rf build
.PHONY: default clean
add_executable(engine-cli engine-cli.c engine.c)
/* 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 <stdlib.h>
#include <assert.h>
#include "engine.h"
static cch_board_t* board;
static void prompt_move(const char* prompt) {
char strmove[6]; /* a1a2\n\0 */
unsigned short move;
cch_return_t r;
while(1) {
fputs(prompt, stdout);
if(fgets(strmove, 6, stdin) == NULL) {
exit(1);
}
/* XXX: accept shorter algebraic notation */
if(strmove[0] < 'a' || strmove[0] > 'h'
|| strmove[1] < '1' || strmove[1] > '8'
|| strmove[2] < 'a' || strmove[2] > 'h'
|| strmove[3] < '1' || strmove[3] > '8'
|| strmove[4] != '\n' || strmove[5] != '\0') {
puts("I do not understand that move.");
if(strmove[0] == '\n' || strmove[1] == '\n' || strmove[2] == '\n' || strmove[3] == '\n' || strmove[4] == '\n') {
continue;
}
/* Clear the input buffer */
while(getchar() != '\n');
continue;
}
move = (strmove[0] - 'a') << 9 | (strmove[1] - '1') << 6 | (strmove[2] - 'a') << 3 | (strmove[3] - '1');
r = cch_play_move(board, move);
if(r == CCH_OK) {
break;
} else {
assert(r == CCH_ILLEGAL_MOVE);
puts("That is an illegal move.");
}
}
}
static void print_board(void) {
static const char* pstr[] = { "K", "Q", "R", "N", "B", "P", ".", "p", "b", "n", "r", "q", "k" };
const char* pieces = cch_pieces(board);
char x, y;
/* XXX: use fancy coloring (VT100) */
/* XXX: highlight last move */
for(x = 0; x < 8; ++x) {
printf("%d ", 8 - x);
for(y = 0; y < 8; ++y) {
fputs(pstr[pieces[y * 8 + (7 - x)] + CCH_KING], stdout);
}
putchar('\n');
}
fputs("\n ", stdout);
for(x = 'a'; x <= 'h'; ++x) putchar(x);
putchar('\n');
}
int main(int argc, char** argv) {
cch_game_state_t s;
char prompt[32];
cch_init_board(&board);
do {
print_board();
putchar('\n');
switch(s = cch_game_state(board)) {
case CCH_WHITE_TO_PLAY:
snprintf(prompt, 32, "White to play. %u. ? ", cch_turn_number(board));
prompt_move(prompt);
break;
case CCH_BLACK_TO_PLAY:
snprintf(prompt, 32, "Black to play. %u. ... ? ", cch_turn_number(board));
prompt_move(prompt);
break;
default:
/* XXX: show better message */
printf("Game over (%d).\n", s);
break;
}
} while(s <= CCH_BLACK_TO_PLAY);
cch_free_board(board);
return 0;
}
/* 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 "engine.h"
#include <stdlib.h>
#include <string.h>
static char boardinit[] = {
CCH_ROOK, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_ROOK, /* a1, ..., a8 */
CCH_KNIGHT, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_KNIGHT, /* b1, ..., b8 */
CCH_BISHOP, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_BISHOP,
CCH_QUEEN, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_QUEEN,
CCH_KING, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_KING,
CCH_BISHOP, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_BISHOP,
CCH_KNIGHT, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_KNIGHT,
CCH_ROOK, CCH_PAWN, 0, 0, 0, 0, -CCH_PAWN, -CCH_ROOK,
};
void cch_init_board(cch_board_t** b) {
*b = malloc(sizeof(cch_board_t));
if(*b == NULL) {
exit(127);
}
memcpy((*b)->board, boardinit, 64);
(*b)->side = true;
(*b)->turn = 1;
}
void cch_free_board(cch_board_t* b) {
free(b);
}
cch_return_t cch_play_move(cch_board_t* b, unsigned short move) {
if(move >> 6 >= 64 || b->board[move >> 6] == 0) {
/* Empty squares can't move */
return CCH_ILLEGAL_MOVE;
}
if(b->side ^ (b->board[move >> 6] > 0)) {
/* Can't move a white piece during black's turn v-v. */
return CCH_ILLEGAL_MOVE;
}
/* XXX: magic goes here */
b->board[move & 63] = b->board[move >> 6];
b->board[move >> 6] = 0;
if(b->side) b->side = false;
else {
b->side = true;
++b->turn;
}
return CCH_OK;
}
cch_game_state_t cch_game_state(const cch_board_t* b) {
/* XXX: magic goes here too */
return b->side ? CCH_WHITE_TO_PLAY : CCH_BLACK_TO_PLAY;
}
unsigned int cch_turn_number(const cch_board_t* b) {
return b->turn;
}
const char* cch_pieces(const cch_board_t* b) {
return b->board;
}
/* 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.
*/
#pragma once
#ifndef INCLUDE_CCH_H
#define INCLUDE_CCH_H
#include <stdbool.h>
typedef struct {
char board[64]; /* cch_piece_t: a1, a2, ..., b1, b2, ..., h7, h8 */
bool side; /* true => white to play */
unsigned int turn;
} cch_board_t;
typedef enum {
CCH_OK = 0,
CCH_ILLEGAL_MOVE,
CCH_INVALID_CALL,
} cch_return_t;
typedef enum {
CCH_WHITE_TO_PLAY,
CCH_BLACK_TO_PLAY,
CCH_CHECKMATE_WHITE, /* XXX: todo */
CCH_CHECKMATE_BLACK, /* XXX: todo */
CCH_STALEMATE_WHITE, /* XXX: todo */
CCH_STALEMATE_BLACK, /* XXX: todo */
CCH_DRAW_THREEFOLD, /* XXX: todo */
CCH_DRAW_FIFTY_MOVE_RULE, /* XXX: todo */
} cch_game_state_t;
typedef enum {
CCH_EMPTY = 0,
CCH_PAWN = 1,
CCH_BISHOP = 2,
CCH_KNIGHT = 3,
CCH_ROOK = 4,
CCH_QUEEN = 5,
CCH_KING = 6,
} cch_piece_t; /* + for white, - for black */
/* Set up starting position of pieces, etc. */
void cch_init_board(cch_board_t**);
/* Free resources allocated by cch_init_board(). */
void cch_free_board(cch_board_t*);
/* Play a move. Argument is ((s << 6) | d) where s is the start point
* and d is the destination. Numbers go from 0 (A1) to 63 (H8). */
cch_return_t cch_play_move(cch_board_t*, unsigned short);
/* Get the current status of the game. */
cch_game_state_t cch_game_state(const cch_board_t*);
/* Get the current turn number. */
unsigned int cch_turn_number(const cch_board_t*);
/* Get the position of pieces on the board. Indices go from 0 (A1) to 63 (H8). */
const char* cch_pieces(const cch_board_t*);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment