001 /**
002 * BoardPanel is a GUI component for displaying a chessboard.
003 */
004
005 package ui;
006
007 import java.awt.Color;
008 import java.awt.ComponentOrientation;
009 import java.awt.GridLayout;
010 import java.util.Collection;
011 import java.util.HashMap;
012 import java.util.Map;
013
014 import javax.swing.JPanel;
015
016 import rules.GameState;
017 import core.Move;
018 import core.Piece;
019 import core.Position;
020
021
022 public class BoardPanel extends JPanel {
023 private static final long serialVersionUID = 144;
024
025 private Map<Position, SquarePanel> map;
026 private Collection<Move> moves;
027
028 // One square of the board may be selected at a given time
029 private SquarePanel selectedPanel = null;
030
031 /**
032 * Constructor
033 */
034 public BoardPanel() {
035 this.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
036 this.setLayout(new GridLayout(8, 8));
037
038 map = new HashMap<Position, SquarePanel>();
039
040 // For each square on the board
041 for (int i = 63; i >= 0; i--) {
042 int x = i % 8;
043 int y = i / 8;
044 Position pos = Position.get(x, y);
045 Color color;
046 if ((x + y) % 2 == 0) {
047 color = Color.BLACK;
048 }
049 else {
050 color = Color.WHITE;
051 }
052 SquarePanel panel = new SquarePanel(color);
053 this.add(panel);
054 map.put(pos, panel);
055 }
056 }
057
058 /**
059 * Updates this component to reflect the board in the argument
060 */
061 public void updateBoard(GameState state) {
062
063 // For each position/piece pair
064 for (Map.Entry<Position, ? extends Piece> e : state.getPieceMap().entrySet()) {
065 // Set the piece field of the appropriate SquarePanel
066 SquarePanel s = map.get(e.getKey());
067 s.setPiece(e.getValue());
068 s.setCanMove(false);
069 s.setCanBeTaken(false);
070 }
071
072 moves = state.legalMoves();
073 for(Move m : moves) {
074 if (!m.isPass()) {
075 map.get(m.getFrom()).setCanMove(true);
076 }
077 }
078 reselectCapture();
079 }
080 /**
081 * Corrects the canBeTaken flag for all SquarePanels in the map
082 */
083 private void reselectCapture(){
084 for(Move m: moves) {
085 if (!m.isPass()) {
086 map.get(m.getTo()).setCanBeTaken(false);
087 }
088 }
089 for(Move m: moves) {
090 if (!m.isPass() &&
091 selectedPanel != null &&
092 selectedPanel == map.get(m.getFrom())) {
093 map.get(m.getTo()).setCanBeTaken(true);
094 }
095 }
096 }
097
098 /**
099 * Sets the selected panel to the one at the position in the argument.
100 * If the argument is null, or if the suggested square cannot move,
101 * then no panel is selected.
102 * Returns whether a panel has been selected.
103 */
104 public boolean setSelectedPanel(Position p) {
105 // Deselect the old panel
106 if (selectedPanel != null) {
107 selectedPanel.setSelected(false);
108 this.update(this.getGraphics());
109 }
110
111 // Select the new panel and change the state variable
112 if (p != null) {
113 SquarePanel panel = map.get(p);
114 if (!panel.getCanMove()) {
115 return false;
116 }
117 panel.setSelected(true);
118 selectedPanel = panel;
119
120 this.update(this.getGraphics());
121 reselectCapture();
122 return true;
123 } else {
124 selectedPanel = null;
125 }
126 reselectCapture();
127 return false;
128 }
129 }