//3ICE: A draughts.Man.canStepTo() funkció elkészítése jó bonyolult volt. Éjféltől hajnali ötig debuggoltam. De most kész. Végül a helyes megoldás: && g.get(q) == null volt. (n == null helyett.) Egy hiba, majd 2 hiba, majd 0 hiba.
package draughts;

import grid.Grid;
import position.Direction;
import position.Position;

/**
 * A draughts csomagon belül hozzuk létre a nyilvános Man osztályt, mely
 * kiterjeszti az előbbi Piece osztályt. Új adattag bevezetésére nincs szükség,
 * az absztrakt metódusok konkréttá tételére szorítkozunk.
 */
public class Man extends Piece {

	/**
	 * Egy konstruktor, mely meghívja a szülőosztály konstruktorát. Paraméterül
	 * várja a
	 * @param p pozíciót (Position)
	 * @param c színt (Color)
	 * @param g és a játéktáblát (Piece-szel paraméterezett Grid)
	 */
	public Man(Position p, Color c, Grid<Piece> g) {
		super(p, c, g);
	}

	/**
	 * canStepTo: Egy egyszerű bábu egyet léphet átlósan le (ha a színe fekete)
	 * vagy fel (ha a színe fehér). Előfordulhat hogy kettőt lépünk, ha át
	 * tudjunk ugrani az ellenfél egy bábuját.
	 * @param q paraméterül vár egy pozíciót
	 * @return csak akkor ad vissza igaz értéket, ha lehet oda lépni
	 */
	@Override
	public boolean canStepTo(Position q) {
		//System.out.println(p + "->" + q);
		if ("(2,2)->(0,0)".equals(p + "->" + q)) {
			//System.out.println("Break now!");
			//return true;
		}
		/**
		 * Vizsgáljuk meg, hogy a megadott pozíció a táblán van-e (isValid), egy
		 * átlón helyezkedik-e el bábu eredeti pozíciója és a paraméter pozíció
		 * (isDiagonal), és a paraméterül kapott pozíció különbözik-e a bábu
		 * jelenlegi pozíciójától (equals). A kérdés eldöntésére egy lehetséges
		 * megoldás az alábbi lépéssorozat:
		 */
		//System.out.println(g.isValid(q));
		//System.out.println(Position.isDiagonal(p, q));
		//System.out.println(!p.equals(q));
		if (g.isValid(q) && Position.isDiagonal(p, q) && !p.equals(q)) {
			/**
			 * Számítsuk ki a távolságot a bábu eredeti helye és a paraméter
			 * között (distance)! Váltsuk át a távolságot irányra
			 * (fromDistance).
			 */
			final int[] t = p.distance(q);
			final Direction d = Direction.fromDistance(t);
			//System.out.println(d);

			/**
			 * Egy változóban tároljuk el, hogy a szomszédos mezőn (next) milyen
			 * bábu található (get).
			 */
			final Piece n = (Piece) g.get(p.next(d));
			//System.out.println(n);

			/**
			 * 3ICE: Refactor bonus: Do not calculate steps twice.
			 */
			final int steps = Math.abs(t[0]) + Math.abs(t[1]);
			//System.out.println((c == Color.BLACK && d == Direction.DOWN_LEFT || d == Direction.DOWN_RIGHT));
			//System.out.println((c == Color.WHITE && d == Direction.UP_LEFT || d == Direction.UP_RIGHT));
			//System.out.println(n == null);
			//System.out.println(steps == 2 || (steps == 4 && n != null && c != n.c));
			//System.out.println(steps == 4 && n != null && c == n.c);
			//System.out.println(((c == Color.BLACK && d == Direction.DOWN_LEFT || d == Direction.DOWN_RIGHT) || (c == Color.WHITE && d == Direction.UP_LEFT || d == Direction.UP_RIGHT)) && n == null && steps == 2 || (steps == 4 && n != null && c != n.c));
			/**
			 * jó irányba léptünk, és a paraméterül kapott hely üres, és vagy
			 * csak egyet léptünk vagy kettőt, az utóbbi esetben egy ellenséges
			 * bábu áll a közbülső mezőn.
			 */
			if (/**
					 * Jó irányba lépnénk-e! Ha a bábu színe fekete, akkor az
					 * iránynak DOWN_LEFT vagy DOWN_RIGHT-nak kell lennie. Ha a
					 * szín fehér, akkor UP_LEFT vagy UP_RIGHT-nak kell lennie.
					 */
					((c == Color.BLACK && d == Direction.DOWN_LEFT || d == Direction.DOWN_RIGHT)
					|| (c == Color.WHITE && d == Direction.UP_LEFT || d == Direction.UP_RIGHT))
					/**
					 * A paraméterül kapott hely üres-e (a get null-t ad
					 * vissza).
					 */
					&& g.get(q) == null) {
				return /**
						 * Csak egy lépést tettünk-e meg. Ez akkor igaz, ha a
						 * függőleges és vízszintes távolság abszolút értékének
						 * összege pontosan 2.
						 */
						steps == 2
						/**
						 * Két lépést tettünk-e meg! Ez akkor igaz, ha a
						 * függőleges és vízszintes távolság abszolút értékének
						 * összege pontosan 4.
						 */
						|| steps == 4
						/**
						 * Ellenséges-e a szomszédos mezőn lévő bábu. Ez akkor
						 * igaz, ha a szomszédos bábu nem null és a színe eltér
						 * az aktuális bábu színétől.
						 */
						&& n != null && c != n.c;//3ICE: UGly code: !(n.c.equals(c))
			}
		}
		/**
		 * Ha nem, adjunk vissza hamis értéket.
		 */
		return false;
	}

	/**
	 * toString: Például egy egyszerű fekete bábu esetén ez BM lesz.
	 * @return visszaadja a bábu színének első betűjét (charAt), mellette egy
	 * "M" betűt.
	 * @note No thanks. My one liner beats calling charAt on some obscure
	 * class.getName and a string concatenation.
	 */
	@Override
	public String toString() {
		//c.toString().charAt(0) + this.getClass().getName()
		return c == Color.WHITE ? "WM" : "BM";
	}
}
