Skip to content

Commit

Permalink
move the 2 Smith notation functions to cl_chess_utils & add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ettore committed May 11, 2016
1 parent 134267d commit 9ace924
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 274 deletions.
4 changes: 1 addition & 3 deletions CLChessUtils/cl_chess_defs.h
Expand Up @@ -4,7 +4,7 @@
*
Copyright (c) 2004 Richard D. Bischoff
Copyright (c) 2010 Ettore Pasquini (mofifications)
Copyright (c) 2010 Ettore Pasquini (modifications)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
Expand Down Expand Up @@ -61,7 +61,6 @@ typedef enum {

typedef enum {
GAME_NONE,
GAME_NEW,
GAME_INACTIVE,
GAME_USERWHITE,
GAME_USERBLACK,
Expand Down Expand Up @@ -121,7 +120,6 @@ extern int WOB_rects[64];

char CVPieceToChar(CHESSVIEW_PIECES p);
CHESSVIEW_PIECES charToChessPiece(char x);
double min(double x, double y);
// signed char means boolean here
signed char isPieceWhite(CHESSVIEW_PIECES p);
signed char isPieceBlack(CHESSVIEW_PIECES p);
Expand Down
206 changes: 167 additions & 39 deletions CLChessUtils/cl_chess_utils.c
Expand Up @@ -5,46 +5,174 @@
* Copyright 2010 Cubelogic. All rights reserved.
*/

#include <string.h>

#include "cl_chess_utils.h"

void fen2board(CHESSVIEW_PIECES board[64], const char *fen)

void cl_fen2board(const char *fen, CHESSVIEW_PIECES board[64])
{
int i;
int fi = 0;
int row = 7;
int col = 0;
int index;

for (i = 0; i < 64; ++i)
board[i] = CV_EMPTY;

// scan input fen up to the first ' ' that is only the first field of the
// full FEN string, i.e. the one containing the static board pos info.
// Eg: rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq f3 0 1
// up to here, not including the 'b' ----^
// after all that's all we need to just display the board position.
while ( fen[fi] != ' ' )
{
index = 8*row + col;
switch (fen[fi]) {
case 'R': board[index] = CV_WROOK; break;
case 'N': board[index] = CV_WKNIGHT; break;
case 'B': board[index] = CV_WBISHOP; break;
case 'Q': board[index] = CV_WQUEEN; break;
case 'K': board[index] = CV_WKING; break;
case 'P': board[index] = CV_WPAWN; break;
case 'r': board[index] = CV_BROOK; break;
case 'n': board[index] = CV_BKNIGHT; break;
case 'b': board[index] = CV_BBISHOP; break;
case 'q': board[index] = CV_BQUEEN; break;
case 'k': board[index] = CV_BKING; break;
case 'p': board[index] = CV_BPAWN; break;
case '-': break;
case '/': --row; col = -1; break;
default:
col += fen[fi] - '1';
}
++col;
++fi;
}
for (int i = 0; i < 64; ++i) {
board[i] = CV_EMPTY;
}

if (fen == NULL) {
return;
}

int index;
int fi = 0;
int row = 7;
int col = 0;
int fen_len = (int)strlen(fen);

// scan input fen up to the first ' ' that is only the first field of the
// full FEN string, i.e. the one containing the static board pos info.
// Eg: rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq f3 0 1
// up to here ----^
// after all that's all we need to just display the board position.
while (fi < fen_len && fen[fi] != ' ') {
index = 8*row + col;
switch (fen[fi]) {
case 'R': board[index] = CV_WROOK; break;
case 'N': board[index] = CV_WKNIGHT; break;
case 'B': board[index] = CV_WBISHOP; break;
case 'Q': board[index] = CV_WQUEEN; break;
case 'K': board[index] = CV_WKING; break;
case 'P': board[index] = CV_WPAWN; break;
case 'r': board[index] = CV_BROOK; break;
case 'n': board[index] = CV_BKNIGHT; break;
case 'b': board[index] = CV_BBISHOP; break;
case 'q': board[index] = CV_BQUEEN; break;
case 'k': board[index] = CV_BKING; break;
case 'p': board[index] = CV_BPAWN; break;
case '-': break;
case '/': --row; col = -1; break;
default : col += fen[fi] - '1'; break;
}
++col;
++fi;
}
}


/**
This format is defined as follows:
<from square><to square>[<capture indicator>][<promoted to>]
2 chars 2 chars 0 or 1 char 0 or 1 char
The capture indicator is one of pnbrqkEcC.
'pnbrqk' indicates the type of piece captured.
'E' indicates an en-passant capture
'c' indicates a short castling move (coordinates are for the king's movements)
'C' indicates a long castling move
If it's not a capture, or castling move, the field is empty.
The promotion information is one of "NBRQ", indicating the promoted piece.
Example:
e4g5p is a N move from e4 to g5 capturing a pawn.
f7f8Q is a queening move
f7g8nQ is a pawn move capturing a knight and queening.
One advantage of this system that it's easy to parse, and it's reversible--you
can walk forward and backward through the move list only knowing the current
position at a given time.
The notation is a "improvement" of a notation suggested by Warren Smith.
Note: bughouse plunks are the same in all move formats, e.g. "Q@f7+"
Mystery kriegspiel moves are either "?" or of the form "?xb1".
*/
void cl_gen_smith(char *smith, int from, int to,
char promote, CHESSVIEW_PIECES board[64])
{
int bi = 0;

CHESSVIEW_PIECES frompiece = board[from];
CHESSVIEW_PIECES topiece = board[to];

memset(smith, 0, 8);
smith[bi++] = (from % 8) + 'a';
smith[bi++] = (from / 8) + '1';
smith[bi++] = (to % 8) + 'a';
smith[bi++] = (to / 8) + '1';

// capture indicator
switch (topiece) {
case CV_WPAWN:
case CV_BPAWN:
smith[bi++] = 'p';
break;
case CV_WKNIGHT:
case CV_BKNIGHT:
smith[bi++] = 'n';
break;
case CV_WBISHOP:
case CV_BBISHOP:
smith[bi++] = 'b';
break;
case CV_WROOK:
case CV_BROOK:
smith[bi++] = 'r';
break;
case CV_WQUEEN:
case CV_BQUEEN:
smith[bi++] = 'q';
break;
case CV_WKING:
case CV_BKING:
smith[bi++] = 'k';
break;
case CV_EMPTY:
// en passant
if (frompiece == CV_WPAWN && from >= A4Tag && from <= 39) {//wpawn on row 5
if ((to == from + 7 && board[to-8] == CV_BPAWN)
|| (to == from + 9 && board[to-8] == CV_BPAWN)) {
smith[bi++] = 'E';
}
}
else if (frompiece == CV_BPAWN && from >= 24 && from <= 31) {//bpawn on row 4
if ((to == from - 7 && board[to+8] == CV_WPAWN)
|| (to == from - 9 && board[to+8] == CV_WPAWN)) {
smith[bi++] = 'E';
}
}
else if ((from == 4 && to == G1Tag && frompiece == CV_WKING) //short castling
|| (from == 60 && to == G8Tag && frompiece == CV_BKING)) {
smith[bi++] = 'c';
}
else if ((from == 4 && to == C1Tag && frompiece == CV_WKING) //long castling
|| (from == 60 && to == 58 && frompiece == CV_BKING)) {
smith[bi++] = 'C';
}
break;
default:
break;
}

// promotion spot
if (promote != ' ') {
smith[bi++] = promote;
}

smith[bi] = 0;
}


/**
* NB: We need to pass in some kind of data structure with the current board
* status.
*/
int cl_smith2san(const char *smith, char *san)
{
if (strlen(smith) > 4 && smith[4] == 'c') {
strncpy(san, "O-O", 4);
} else if (strlen(smith) > 4 && smith[4] == 'C') {
strncpy(san, "O-O-O", 6);
} else {
strncpy(san, smith+2, 8);
}

return 0;
}

54 changes: 53 additions & 1 deletion CLChessUtils/cl_chess_utils.h
Expand Up @@ -2,14 +2,66 @@
* cl_chess_utils.h
* CLChessUtils
* Created by Ettore Pasquini on 4/15/10.
* Created by Ettore Pasquini on 9/2/09.
* Copyright 2010 Cubelogic. All rights reserved.
* Copyright 2010 Ettore Pasquini. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Cubelogic nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef cl_chess_utils_h_
#define cl_chess_utils_h_

#include "cl_chess_defs.h"

void fen2board(CHESSVIEW_PIECES board[64], const char *fen);
/*!
@abstract
Populate board matrix with position from FEN string.
@discussion
This function populates a pre-allocated array with pieces from a FEN
string. The output array describes a 8x8 board from bottom left to top right.
For more info about Forsyth–Edwards Notation (FEN) see
https://en.wikipedia.org/wiki/FEN
@param fen The input board position
@param board The output board. Memory should be allocated by client.
*/
void cl_fen2board(const char *fen, CHESSVIEW_PIECES board[64]);

/*!
* Generates move in Smith format.<br>
* <br>
* @param smith Return string. Assume length of 8 characters as in char s[8]
* @param from Monotone tag (0-63) representing a square
* @param to Monotone tag (0-63) representing a square
* @param promote 'Q','R','B','N'
* @param board Current board. Not to be confused with struct Board in board.h
*/
void cl_gen_smith(char *smith, int from, int to,
char promote, CHESSVIEW_PIECES board[64]);

#endif

0 comments on commit 9ace924

Please sign in to comment.