2014-04-08 01:26:54 +00:00
|
|
|
/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
2016-03-15 17:12:58 +00:00
|
|
|
* Copyright (C) 2010-2016 Robert Ancell
|
2014-04-08 01:26:54 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify it under
|
|
|
|
* the terms of the GNU General Public License as published by the Free Software
|
2016-02-15 20:53:54 +00:00
|
|
|
* Foundation, either version 3 of the License, or (at your option) any later
|
2014-04-08 01:26:54 +00:00
|
|
|
* version. See http://www.gnu.org/copyleft/gpl.html the full text of the
|
|
|
|
* license.
|
|
|
|
*/
|
|
|
|
|
2014-06-24 13:14:59 +00:00
|
|
|
public class ChessMove : Object
|
2014-04-08 01:26:54 +00:00
|
|
|
{
|
|
|
|
public int number;
|
|
|
|
public ChessPiece piece;
|
|
|
|
public ChessPiece? promotion_piece;
|
2018-04-24 14:54:55 +00:00
|
|
|
public ChessPiece? castling_rook;
|
2014-04-08 01:26:54 +00:00
|
|
|
public ChessPiece? victim;
|
|
|
|
public int r0;
|
|
|
|
public int f0;
|
|
|
|
public int r1;
|
|
|
|
public int f1;
|
|
|
|
public bool ambiguous_rank;
|
|
|
|
public bool ambiguous_file;
|
2018-04-24 15:47:46 +00:00
|
|
|
public bool en_passant;
|
2014-04-08 01:26:54 +00:00
|
|
|
public CheckState check_state;
|
|
|
|
|
|
|
|
public string get_lan ()
|
|
|
|
{
|
2018-04-24 14:54:55 +00:00
|
|
|
if (castling_rook != null)
|
2014-04-08 01:26:54 +00:00
|
|
|
{
|
|
|
|
if (f1 > f0)
|
|
|
|
return "O-O";
|
|
|
|
else
|
|
|
|
return "O-O-O";
|
|
|
|
}
|
|
|
|
|
|
|
|
var builder = new StringBuilder ();
|
|
|
|
if (victim != null)
|
|
|
|
builder.append_printf ("%c%dx%c%d", 'a' + f0, r0 + 1, 'a' + f1, r1 + 1);
|
|
|
|
else
|
|
|
|
builder.append_printf ("%c%d-%c%d", 'a' + f0, r0 + 1, 'a' + f1, r1 + 1);
|
|
|
|
|
|
|
|
const char promotion_symbols[] = {' ', 'R', 'N', 'B', 'Q', 'K'};
|
|
|
|
if (promotion_piece != null)
|
|
|
|
builder.append_printf ("=%c", promotion_symbols[promotion_piece.type]);
|
|
|
|
|
|
|
|
switch (check_state)
|
|
|
|
{
|
|
|
|
case CheckState.CHECK:
|
|
|
|
builder.append_c ('+');
|
|
|
|
break;
|
|
|
|
case CheckState.CHECKMATE:
|
|
|
|
builder.append_c ('#');
|
|
|
|
break;
|
2020-12-05 15:59:08 +00:00
|
|
|
default:
|
|
|
|
break;
|
2014-04-08 01:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return builder.str;
|
|
|
|
}
|
|
|
|
|
|
|
|
public string get_san ()
|
|
|
|
{
|
|
|
|
const string piece_names[] = {"", "R", "N", "B", "Q", "K"};
|
|
|
|
return make_san ((string[]) piece_names);
|
|
|
|
}
|
|
|
|
|
|
|
|
public string get_fan ()
|
|
|
|
{
|
|
|
|
const string white_piece_names[] = {"", "♖", "♘", "♗", "♕", "♔"};
|
|
|
|
const string black_piece_names[] = {"", "♜", "♞", "♝", "♛", "♚"};
|
|
|
|
if (piece.color == Color.WHITE)
|
|
|
|
return make_san ((string[]) white_piece_names);
|
|
|
|
else
|
|
|
|
return make_san ((string[]) black_piece_names);
|
|
|
|
}
|
|
|
|
|
|
|
|
private string make_san (string[] piece_names)
|
|
|
|
{
|
2018-04-24 14:54:55 +00:00
|
|
|
if (castling_rook != null)
|
2014-04-08 01:26:54 +00:00
|
|
|
{
|
|
|
|
if (f1 > f0)
|
|
|
|
return "O-O";
|
|
|
|
else
|
|
|
|
return "O-O-O";
|
|
|
|
}
|
|
|
|
|
|
|
|
var builder = new StringBuilder ();
|
|
|
|
builder.append (piece_names[piece.type]);
|
|
|
|
if (ambiguous_file)
|
|
|
|
builder.append_printf ("%c", 'a' + f0);
|
|
|
|
if (ambiguous_rank)
|
|
|
|
builder.append_printf ("%d", r0 + 1);
|
|
|
|
if (victim != null)
|
|
|
|
builder.append ("x");
|
|
|
|
builder.append_printf ("%c%d", 'a' + f1, r1 + 1);
|
|
|
|
|
|
|
|
if (promotion_piece != null)
|
|
|
|
builder.append_printf ("=%s", piece_names[promotion_piece.type]);
|
|
|
|
|
|
|
|
switch (check_state)
|
|
|
|
{
|
|
|
|
case CheckState.CHECK:
|
|
|
|
builder.append_c ('+');
|
|
|
|
break;
|
|
|
|
case CheckState.CHECKMATE:
|
|
|
|
builder.append_c ('#');
|
|
|
|
break;
|
2020-12-05 15:59:08 +00:00
|
|
|
default:
|
|
|
|
break;
|
2014-04-08 01:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return builder.str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move suitable for a chess engine (CECP/UCI) */
|
|
|
|
public string get_engine ()
|
|
|
|
{
|
|
|
|
var builder = new StringBuilder ();
|
|
|
|
const char promotion_symbols[] = {' ', 'r', 'n', 'b', 'q', ' '};
|
|
|
|
if (promotion_piece != null)
|
|
|
|
builder.append_printf ("%c%d%c%d%c", 'a' + f0, r0 + 1, 'a' + f1, r1 + 1, promotion_symbols[promotion_piece.type]);
|
|
|
|
else
|
|
|
|
builder.append_printf ("%c%d%c%d", 'a' + f0, r0 + 1, 'a' + f1, r1 + 1);
|
|
|
|
return builder.str;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ChessMove copy ()
|
|
|
|
{
|
|
|
|
var move = new ChessMove ();
|
|
|
|
move.number = number;
|
|
|
|
move.piece = piece;
|
|
|
|
move.promotion_piece = promotion_piece;
|
2018-04-24 14:54:55 +00:00
|
|
|
move.castling_rook = castling_rook;
|
2014-04-08 01:26:54 +00:00
|
|
|
move.victim = victim;
|
|
|
|
move.r0 = r0;
|
|
|
|
move.f0 = f0;
|
|
|
|
move.r1 = r1;
|
|
|
|
move.f1 = f1;
|
|
|
|
move.ambiguous_rank = ambiguous_rank;
|
|
|
|
move.ambiguous_file = ambiguous_file;
|
2018-04-24 15:47:46 +00:00
|
|
|
move.en_passant = en_passant;
|
2014-04-08 01:26:54 +00:00
|
|
|
move.check_state = check_state;
|
|
|
|
return move;
|
|
|
|
}
|
|
|
|
}
|