org/homelinux/largo/games/board/checkersboard/CheckersBoard.java
author Markus Bröker <mbroeker@largo.homelinux.org>
Fri, 17 Dec 2010 22:33:17 +0100
changeset 14 f12f77aa13b2
parent 13 f83884cc7d2f
child 15 d4b2b9a87d80
permissions -rw-r--r--
serialVersionUID starts with 1L...

/**
 *   $Id: CheckersBoard.java 152 2008-04-27 02:04:31Z mbroeker $
 *  $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/checkersboard/CheckersBoard.java $
 */

package org.homelinux.largo.games.board.checkersboard;

import java.awt.Image;

import org.homelinux.largo.games.board.Board;
import org.homelinux.largo.games.board.History;
import org.homelinux.largo.games.board.Piece;
import org.homelinux.largo.utils.ImgComponent;

public class CheckersBoard extends Board {
    static final long serialVersionUID = 1L;

    static final int PIECE = 1;
    static final int QUEEN = 2;

    final Piece white_super_sun = new Piece(new ImgComponent("images/white_super_sun.png").getImage(), "white", QUEEN,
            50);

    final Piece black_super_sun = new Piece(new ImgComponent("images/black_super_sun.png").getImage(), "black", QUEEN,
            50);

    void initBoard() {
        for (int i = 1; i < 8; i += 2)
            add(new ImgComponent("images/black_sun.png").getImage(), i, "black", PIECE);
        for (int i = 8; i < 15; i += 2)
            add(new ImgComponent("images/black_sun.png").getImage(), i, "black", PIECE);
        for (int i = 17; i <= 23; i += 2)
            add(new ImgComponent("images/black_sun.png").getImage(), i, "black", PIECE);

        for (int i = 40; i < 47; i += 2)
            add(new ImgComponent("images/white_sun.png").getImage(), i, "white", PIECE);
        for (int i = 49; i <= 55; i += 2)
            add(new ImgComponent("images/white_sun.png").getImage(), i, "white", PIECE);
        for (int i = 56; i < 63; i += 2)
            add(new ImgComponent("images/white_sun.png").getImage(), i, "white", PIECE);
    }

    /**
     * The init method initializes a complete checkers board with figures and a
     * history.
     */
    public void init() {
        super.init();
        initBoard();
        board_pieces = getPieces();
        repaint();
    }

    public CheckersBoard(int w, int h) {
        super(w, h);
    }

    void add(Image img, int i, String c, int t) {
        int v = 0;

        switch (t) {
        case PIECE:
            v = 10;
        }

        setPiece(i, new Piece(img, c, t, v));
    }

    /**
     * Checks, wether this move is possible or not.
     */
    public boolean validMove(int t, int o) {
        int steps;
        int rows;

        if (t == o)
            return false;

        if (isSamePiece(t, o))
            return false;

        if (getType(o) == EMPTY)
            return false;

        /*
         * 00 01 02 03 04 05 06 07
         * 08 09 10 11 12 13 14 15
         * 16 17 18 19 20 21 22 23
         * 24 25 26 27 28 29 30 31
         * 32 33 34 35 36 37 38 39
         * 40 41 42 43 44 45 46 47
         * 48 49 50 51 52 53 54 55
         * 56 57 58 59 60 61 62 63
         */

        steps = Math.abs(t - o);
        rows = Math.abs(t / 8 - o / 8);

        switch (getType(o)) {
        case PIECE:
            if (steps % 7 == 0) {
                if (steps == 7 && rows == 1 && isEmpty(t)) {
                    if (isBlack(o) && (t > o))
                        return true;
                    if (isWhite(o) && (t < o))
                        return true;
                }

                if (steps == 14 && rows == 2 && isEmpty(t)) {
                    if (isBlack(o) && (t > o) && isEnemy(o + 7, o))
                        return true;
                    if (isWhite(o) && (t < o) && isEnemy(o - 7, o))
                        return true;
                }
            }

            if (steps % 9 == 0) {
                if (steps == 9 && rows == 1 && isEmpty(t)) {
                    if (isBlack(o) && (t > o))
                        return true;
                    if (isWhite(o) && (t < o))
                        return true;
                }

                if (steps == 18 && rows == 2 && isEmpty(t)) {
                    if (isBlack(o) && (t > o) && isEnemy(o + 9, o))
                        return true;
                    if (isWhite(o) && (t < o) && isEnemy(o - 9, o))
                        return true;
                }
            }
            break;
        case QUEEN:
            if (steps % 7 == 0 && isEmpty(t)) {
                if (steps == 7 && rows == 1)
                    return true;
                if (steps == 14 && rows == 2)
                    return true;
                if (steps == 21 && rows == 3)
                    return true;
                if (steps == 28 && rows == 4)
                    return true;
                if (steps == 35 && rows == 5)
                    return true;
                if (steps == 42 && rows == 6)
                    return true;
                if (steps == 49 && rows == 7)
                    return true;
            }

            if (steps % 9 == 0 && isEmpty(t)) {
                if (steps == 9 && rows == 1)
                    return true;
                if (steps == 18 && rows == 2)
                    return true;
                if (steps == 27 && rows == 3)
                    return true;
                if (steps == 36 && rows == 4)
                    return true;
                if (steps == 45 && rows == 5)
                    return true;
                if (steps == 54 && rows == 6)
                    return true;
                if (steps == 63 && rows == 7)
                    return true;
            }
            break;
        }
        return false;
    }

    /**
     * pop: undo the push operation.
     */
    public void undo() {
        History h1 = null;
        History h2 = null;
        int size = stack.size();
        int pos;

        if (size < 2)
            return;

        h1 = stack.elementAt(size - 1);
        h2 = stack.elementAt(size - 2);

        setPiece(h1.pos(), h1.piece());
        setPiece(h2.pos(), h2.piece());

        if (getType(h2.pos()) != EMPTY) {
            pos = 2 * h2.pos() - h1.pos();
            if (pos >= 0 && pos < 64)
                setPiece(pos, new Piece(null, null, EMPTY, 0));
        }

        stack.setSize(size - 2);

        /* Reset the current player */
        setBlacksTurn(h2.turn());
    }

    /**
     * simulates a "valid" move or returns false. all changes are relative to
     * pieces and will not be painted.
     */
    public boolean simulateMove(int t, int o) {
        int rows = Math.abs(t / 8 - o / 8);
        int pos;

        if (!validMove(t, o)) {
            return false;
        }

        if (rows == 2 && getType(o) == PIECE) {
            pos = (t - o) / 2 + o;
            push(getPiece(pos), pos, getPiece(o), o);
            setPiece(pos, new Piece(null, null, EMPTY, 0));
        } else
            push(getPiece(t), t, getPiece(o), o);

        setPiece(t, new Piece(getPiece(o)));
        setPiece(o, new Piece(null, null, EMPTY, 0));

        return true;
    }

    /**
     * performs a "valid" move or returns false. all changes are relative to
     * board_pieces and will be painted.
     */
    public boolean doMove(int t, int o) {
        int steps = Math.abs(t - o);
        int rows = Math.abs(t / 8 - o / 8);
        int pos;

        if (!validMove(t, o)) {
            return false;
        }

        if (rows == 2 && getType(o) == PIECE) {
            pos = (t - o) / 2 + o;
            push(getPiece(pos), pos, getPiece(o), o);
            setPiece(pos, new Piece(null, null, EMPTY, 0));
        } else if (rows >= 2 && getType(o) == QUEEN) {
            if (steps % 7 == 0) {
                if (t > o)
                    for (pos = o + 7; pos <= t - 7; pos += 7) {
                        if (isEnemy(pos, o)) {
                            push(getPiece(pos), pos, getPiece(o), o);
                            setPiece(pos, new Piece(null, null, EMPTY, 0));
                        }
                    }
                else {
                    for (pos = o - 7; pos >= t + 7; pos -= 7) {
                        if (isEnemy(pos, o)) {
                            push(getPiece(pos), pos, getPiece(o), o);
                            setPiece(pos, new Piece(null, null, EMPTY, 0));
                        }
                    }
                }
            }

            if (steps % 9 == 0) {
                if (t > o)
                    for (pos = o + 9; pos <= t - 9; pos += 9) {
                        if (isEnemy(pos, o)) {
                            push(getPiece(pos), pos, getPiece(o), o);
                            setPiece(pos, new Piece(null, null, EMPTY, 0));
                        }
                    }
                else {
                    for (pos = o - 9; pos >= t + 9; pos -= 9) {
                        if (isEnemy(pos, o)) {
                            push(getPiece(pos), pos, getPiece(o), o);
                            setPiece(pos, new Piece(null, null, EMPTY, 0));
                        }
                    }
                }
            }
        }

        if (t <= 7 && getType(o) == PIECE)
            setPiece(t, new Piece(white_super_sun));
        else if (t >= 56 && getType(o) == PIECE)
            setPiece(t, new Piece(black_super_sun));
        else
            setPiece(t, new Piece(getPiece(o)));

        setPiece(o, new Piece(null, null, EMPTY, 0));

        board_pieces = getPieces();
        repaint();

        moveNr = stack.size();

        return true;
    }
}