push c27c10883ccfaebf4e1c1f914a08dcbdb348c941
[tagua/yd.git] / src / variants / chess / pawn.cpp
blobe0c845bf77158303cc9672a99ec9d4439ae0fd0b
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "pawn.h"
12 #include "queen.h"
13 #include <core/behaviour.h>
14 #include <core/move.h>
15 #include <core/pathinfo.h>
16 #include <core/state.h>
17 #include <core/board.h>
18 #include <core/taguacast.h>
20 namespace Chess {
22 Pawn::Pawn() { }
24 QString Pawn::name() const { return "pawn"; }
26 bool Pawn::canMove(const Piece& piece, const Piece& target,
27 Move& move, const IState* state) const {
28 const IBehaviour* behaviour = state->behaviour();
29 if (!behaviour) return false;
30 bool enPassant = state->flags()->get("en_passant_square").value<Point>() == move.dst();
32 // moving
33 if (target == Piece() && !enPassant) {
34 if (move.delta() == behaviour->direction(piece.color())) {
35 if (move.dst().y == state->rank(state->board()->size().y - 1, piece.color())) {
36 setPromotion(move, Queen::self());
38 return true;
41 if (move.src().y == state->rank(1, piece.color()) &&
42 move.delta() == behaviour->direction(piece.color()) * 2 &&
43 state->board()->get(move.src() + behaviour->direction(piece.color())) == Piece()) {
44 move.setType("en_passant_trigger");
45 return true;
47 else
48 return false;
51 // capturing
52 else if (enPassant || target.color() != piece.color()) {
53 if (move.delta().y == behaviour->direction(piece.color()).y &&
54 abs(move.delta().x) == 1) {
55 if (enPassant)
56 move.setType("en_passant_capture");
57 else if (move.dst().y == state->rank(state->board()->size().y - 1, piece.color())) {
58 setPromotion(move, Queen::self());
61 return true;
65 return false;
68 void Pawn::setPromotion(Move& move, const IType* type) const {
69 move.setType("promotion");
70 // FIXME use variant data to set promotion type, like e.g.:
71 // move.setPromotion(m_data.get("promotion-type").value<QObject*>())
72 if (!move.promotion()) move.setPromotion(type);
75 int Pawn::index() const { return 10; }
77 Pawn* Pawn::self() {
78 static Pawn s_instance;
79 return &s_instance;