org/homelinux/largo/games/board/Board.java
author Markus Bröker <mbroeker@largo.homelinux.org>
Fri, 17 Dec 2010 22:44:27 +0100
changeset 15 d4b2b9a87d80
parent 14 f12f77aa13b2
child 16 55b0d5006e7b
permissions -rw-r--r--
ArrayList replaces Vector

/**
 *   $Id: Board.java 148 2008-04-25 22:05:48Z mbroeker $
 *  $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/Board.java $
 */

package org.homelinux.largo.games.board;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;

import javax.swing.JPanel;

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

    protected boolean UNDO_DEBUG = false;

    protected Piece board_pieces[];
    private Piece pieces[];

    protected ArrayList<History> stack;
    protected int moveNr;

    protected static final int EMPTY = 0;

    Color color_black;
    Color color_white;

    int iHeight;
    int iWidth;
    int xPos;
    int yPos;

    boolean black;
    boolean blacksTurn;

    MouseListener listener;

    /**
     * The init method initializes an empty board with a history.
     */
    public void init() {
        int i;
        pieces = new Piece[64];

        for (i = 0; i < 64; i++) {
            pieces[i] = new Piece(null, null, EMPTY, 0);
        }

        xPos = 0;
        yPos = 0;

        black = false;
        blacksTurn = false;
        board_pieces = getPieces(pieces);
        stack = new ArrayList<History>();
        moveNr = 0;
    }

    public Board(int w, int h) {
        iWidth = w;
        iHeight = h;
        color_white = new Color(255, 255, 255);
        color_black = new Color(50, 100, 200);
        setPreferredSize(new Dimension(8 * iWidth, 8 * iHeight));

        init();
        listener = new MouseListener(iWidth, iHeight);
        addMouseListener(listener);
    }

    /**
     * getPiece returns a Piece-Object from the Board Cache. It might not be
     * visible on the current board.
     */
    public Piece getPiece(int t) {
        return pieces[t];
    }

    /**
     * setPiece sets a Piece-Object into the Board Cache and will not be
     * visible.
     */
    protected void setPiece(int t, Piece p) {
        pieces[t] = p;
    }

    protected Piece[] getPieces() {
        return getPieces(pieces);
    }

    private Piece[] getPieces(Piece[] which_pieces) {
        Piece[] p = new Piece[64];
        int i;

        for (i = 0; i < 64; i++)
            p[i] = new Piece(which_pieces[i]);

        return p;
    }

    protected void setPieces(Piece[] p) {
        pieces = p;
    }

    /**
     * needed in paint(Graphics g)
     */
    private Image getBoardImage(int i) {
        return board_pieces[i].image;
    }

    /**
     * getMouseListener returns a valid MouseListener for this Board.
     */
    public MouseListener getMouseListener() {
        return listener;
    }

    /**
     * currentMove returns the current stack.size().
     */
    public int currentMove() {
        return stack.size();
    }

    /**
     * returns the color of piece[i].
     */
    public String getColor(int i) {
        return pieces[i].color;
    }

    /**
     * returns the current Value of a particular piece.
     */
    public int getValue(int i) {
        return pieces[i].value;
    }

    /**
     * Defined Integer Constants: EMTPY = 0
     */
    public int getType(int i) {
        return pieces[i].type;
    }

    public boolean isEmpty(int i) {
        if (pieces[i].type == EMPTY)
            return true;
        return false;
    }

    boolean BoardisEmpty(int i) {
        if (board_pieces[i].type == EMPTY)
            return true;
        return false;
    }

    /**
     * blacksTurn = true -> Black moves blacksTurn = false -> White moves
     */
    public boolean isBlacksTurn() {
        return blacksTurn;
    }

    public void setBlacksTurn(boolean b) {
        blacksTurn = b;
    }

    /**
     * returns true, when piece[i] is white
     */
    public boolean isWhite(int i) {
        if (isEmpty(i))
            return false;

        if (pieces[i].color.equals("white"))
            return true;
        return false;
    }

    /**
     * returns true, when piece[i] is black
     */
    public boolean isBlack(int i) {
        if (isEmpty(i))
            return false;

        if (pieces[i].color.equals("black"))
            return true;
        return false;
    }

    /**
     * returns true, when both pieces have opposite colors
     */
    public boolean isEnemy(int t, int o) {
        if (isEmpty(t))
            return false;

        if (!pieces[t].color.equals(pieces[o].color))
            return true;
        return false;
    }

    /**
     * returns true, when both pieces have the same color
     */
    public boolean isSamePiece(int t, int o) {
        if (isEmpty(t))
            return false;

        if (pieces[t].color.equals(pieces[o].color))
            return true;
        return false;
    }

    /**
     * This function checks for the color of the piece at piece[i] and returns
     * true, if the color matches the current Turn.
     */
    public boolean validTurn(int i) {
        if (isEmpty(i))
            return false;

        if (getColor(i).equals("white") && isBlacksTurn())
            return false;
        if (getColor(i).equals("black") && !isBlacksTurn())
            return false;
        return true;
    }

    /**
     * simulates a "valid" move or returns false. all changes are relative to
     * pieces and will not be painted. This method sets internal variables for
     * the rochade() method, which will be overidden.
     */
    public boolean simulateMove(int t, int o) {
        if (!validMove(t, o)) {
            return false;
        }

        push(pieces[t], t, pieces[o], o);

        pieces[t] = new Piece(pieces[o]);
        pieces[o] = new Piece(null, null, EMPTY, 0);

        return true;
    }

    /**
     * Moves a Piece on the Board at Point p
     */
    public boolean move(Point p) {
        int t;
        int o;

        t = (p.endy * 8) + p.endx;
        o = (p.starty * 8) + p.startx;

        if (t < 0 || t > 63)
            return false;
        if (o < 0 || o > 63)
            return false;

        if (validTurn(o))
            return doMove(t, o);

        System.out.println("It's not your turn!");
        return false;
    }

    /**
     * Moves one half-move backward.
     */
    public void backwards() {
        History h1;
        History h2;

        if (moveNr < 2)
            return;

        moveNr -= 2;

        h1 = stack.get(moveNr);
        h2 = stack.get(moveNr + 1);

        board_pieces[h1.pos] = h1.piece;
        board_pieces[h2.pos] = h2.piece;

        repaint();
    }

    /**
     * Moves one half-move forward.
     */
    public void forward() {
        History h1;
        History h2;

        if (moveNr > stack.size() - 2)
            return;

        h1 = stack.get(moveNr);
        h2 = stack.get(moveNr + 1);

        board_pieces[h1.pos] = h2.piece;
        board_pieces[h2.pos] = new Piece(null, null, EMPTY, 0);

        moveNr += 2;
        repaint();
    }

    /**
     * pushes 2 pieces onto the stack.
     */
    public void push(Piece p1, int t, Piece p2, int o) {
        stack.add(new History(p1, t, isBlacksTurn()));
        stack.add(new History(p2, o, isBlacksTurn()));
    }

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

        if (size < 2)
            return;

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

        pieces[h1.pos] = h1.piece;
        pieces[h2.pos] = h2.piece;

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

    /**
     * This method must be implemented in your "GameBoard" Return value: TRUE:
     * the move IS possible Return value: FALSE: the move IS NOT possible
     */
    public boolean validMove(int t, int o) {
        System.out.println("public boolean validMove(int t, int o): Implement me");
        return false;
    }

    /**
     * This method must be implemented in your "GameBoard" Return value: TRUE:
     * the move was performed Return value: FALSE: the move was not performed
     */
    public boolean doMove(int t, int o) {
        System.out.println("public boolean doMove(int t, int o): Implement me");
        return false;
    }

    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics g) {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (black == true) {
                    g.setColor(color_black);
                    g.fillRect(xPos, yPos, iWidth, iHeight);
                    black = false;
                } else {
                    g.setColor(color_white);
                    g.fillRect(xPos, yPos, iWidth, iHeight);
                    black = true;
                }
                if (!BoardisEmpty((i * 8) + j))
                    g.drawImage(getBoardImage((i * 8) + j), xPos + 5, yPos, this);
                xPos += iWidth;
            }
            xPos = 0;
            yPos += iHeight;
            black = !black;
        }
        xPos = 0;
        yPos = 0;
    }
}