Chess Game In Java

A fully functional chess game in Java, without an AI or disallowing moves that are considered to be illegal according to the rules of chess.
1. import java.awt.BorderLayout;
2. import java.awt.Color;
3. import java.awt.ComponentOrientation;
4. import java.awt.Cursor;
5. import java.awt.GridLayout;
6. import java.awt.event.InputEvent;
7. import java.awt.image.BufferedImage;
8. import java.io.IOException;
9. import java.io.InputStream;
10.import java.util.Map;
11.import java.util.TreeMap;
12. 
13.import javax.imageio.ImageIO;
14.import javax.swing.ImageIcon;
15.import javax.swing.JButton;
16.import javax.swing.JFrame;
17.import javax.swing.JLabel;
18.import javax.swing.JOptionPane;
19.import javax.swing.JPanel;
20.import javax.swing.JToolBar;
21.import java.awt.Dimension;
22. 
23.public class ChessGame extends JFrame {
24. 
25.        private static final long serialVersionUID = 1L;
26. 
27.        private JPanel jContentPane = null;
28. 
29.        private JPanel jPanel = null;
30. 
31.        private JToolBar tlbMain = null;
32. 
33.        private JLabel lblCells[] = new JLabel[64];
34.       
35.        private String jPieces[][] = new String[8][8];  //  @jve:decl-index=0:
36. 
37.        private JButton btnNewGame = null;
38. 
39.        private JLabel lblStatus = null;
40.       
41.        private int heldX, heldY, heldI = -1;
42.       
43.        // Map the full names of the pieces to their codenames (wRook, wQueen, etc.)
44.        private Map pieceName = new TreeMap();  //  @jve:decl-index=0:
45. 
46.        private JLabel lblCurrPlayer = null;
47.       
48.        // Stores the current player's move - we can easily match it against
49.        // the first character of the pieces array
50.        private char currPlayer = ' ';
51. 
52.        private JButton btnUndo = null;
53.       
54.        private int[][] moves = new int[10][6];
55.       
56.        private String movedPieces[] = new String[10];
57.       
58.        private int currMove = 0;
59. 
60.        /**
61.         * This is the default constructor
62.         */
63.        public ChessGame() {
64.                super();
65.                initialize();
66.                buildBoard();
67.        }
68.       
69.        /**
70.         * This method initializes btnUndo     
71.         *      
72.         * @return javax.swing.JButton 
73.         */
74.        private JButton getBtnUndo() {
75.                if (btnUndo == null) {
76.                        btnUndo = new JButton();
77.                        btnUndo.setText("Undo");
78.                        btnUndo.setEnabled(false);
79.                        btnUndo.addMouseListener(new java.awt.event.MouseAdapter() {
80.                                public void mouseReleased(java.awt.event.MouseEvent e) {
81.                                        undoMove();
82.                                }
83.                        });
84.                }
85.                return btnUndo;
86.        }
87. 
88.        public static void main( String args[] ) {
89.                new ChessGame().setVisible(true);
90.        }
91. 
92.        /**
93.         * This method initializes this
94.         *
95.         * @return void
96.         */
97.        private void initialize() {
98.                this.setSize(671, 555);
99.                this.setContentPane(getJContentPane());
100.                this.setTitle("Basic Chess");
101.                this.setExtendedState(JFrame.MAXIMIZED_BOTH);
102.        }
103. 
104.        /**
105.         * This method initializes jContentPane
106.         *
107.         * @return javax.swing.JPanel
108.         */
109.        private JPanel getJContentPane() {
110.                if (jContentPane == null) {
111.                        jContentPane = new JPanel();
112.                        jContentPane.setLayout(new BorderLayout());
113.                        jContentPane.add(getJPanel(), BorderLayout.CENTER);
114.                        jContentPane.add(getTlbMain(), BorderLayout.NORTH);
115.                }
116.                return jContentPane;
117.        }
118. 
119.        /**
120.         * This method initializes jPanel       
121.         *      
122.         * @return javax.swing.JPanel   
123.         */
124.        private JPanel getJPanel() {
125.                if (jPanel == null) {
126.                        GridLayout gridLayout = new GridLayout();
127.                        gridLayout.setRows(8);
128.                        gridLayout.setHgap(5);
129.                        gridLayout.setVgap(5);
130.                        gridLayout.setColumns(8);
131.                        jPanel = new JPanel();
132.                        jPanel.setLayout(gridLayout);
133.                        //buildBoard();
134.               }
135.                return jPanel;
136.        }
137.       
138.        private void newGame()
139.        {
140.                resetBoard();
141.                resetPieces();
142.        }
143.       
144.        private void resetPieces()
145.        {
146.                jPieces = new String[8][8];
147.                jPieces[0][0] = "bRook";
148.                jPieces[0][1] = "bKnight";
149.                jPieces[0][2] = "bBishop";
150.                jPieces[0][3] = "bKing";
151.                jPieces[0][4] = "bQueen";
152.                jPieces[0][5] = "bBishop";
153.                jPieces[0][6] = "bKnight";
154.                jPieces[0][7] = "bRook";
155.                jPieces[1][0] = "bPawn";
156.                jPieces[1][1] = "bPawn";
157.                jPieces[1][2] = "bPawn";
158.                jPieces[1][3] = "bPawn";
159.                jPieces[1][4] = "bPawn";
160.                jPieces[1][5] = "bPawn";
161.                jPieces[1][6] = "bPawn";
162.                jPieces[1][7] = "bPawn";
163.               
164.                jPieces[6][0] = "wPawn";
165.                jPieces[6][1] = "wPawn";
166.                jPieces[6][2] = "wPawn";
167.                jPieces[6][3] = "wPawn";
168.                jPieces[6][4] = "wPawn";
169.                jPieces[6][5] = "wPawn";
170.                jPieces[6][6] = "wPawn";
171.                jPieces[6][7] = "wPawn";
172.                jPieces[7][0] = "wRook";
173.                jPieces[7][1] = "wKnight";
174.                jPieces[7][2] = "wBishop";
175.                jPieces[7][3] = "wKing";
176.                jPieces[7][4] = "wQueen";
177.                jPieces[7][5] = "wBishop";
178.                jPieces[7][6] = "wKnight";
179.                jPieces[7][7] = "wRook";
180.                RepaintPieces();
181.        }
182.       
183.        private void PaintPiece(String pieceName, int i)
184.        {
185.                try
186.                {
187.                        if(pieceName != null && pieceName != "")
188.                        {
189.                                InputStream inIcon = ClassLoader.getSystemResourceAsStream("pociu/games/chess/" + pieceName + ".png");
190.                                BufferedImage imgIcon = ImageIO.read(inIcon);
191.                                lblCells[i].setIcon(new ImageIcon(imgIcon));
192.                                //System.out.println("Painted " + pieceName + " at " + i);
193.                        }
194.                        else
195.                        {
196.                                lblCells[i].setIcon(null);
197.                                //System.out.println("Cleared cell at " + i);
198.                        }
199.                }
200.                catch(IOException e)
201.                {
202.                        e.printStackTrace();
203.                }
204.        }
205.       
206.        private void RepaintPieces()
207.        {
208.                int i = 0;
209.                for(int x = 0; x < 8; x++)
210.                {
211.                        for(int y = 0; y < 8; y++)
212.                        {
213.                                if(jPieces[x][y] != null && !jPieces[x][y].equals(""))
214.                                {
215.                                        PaintPiece(jPieces[x][y], i);
216.                                }
217.                                else
218.                                {
219.                                        PaintPiece("", i);
220.                                }
221.                                i++;
222.                        }
223.                }
224.        }
225.       
226.        private void ClearHlight(int i, int rowNum)
227.        {
228.                if((i + rowNum) % 2 == 0)
229.                {
230.                        lblCells[i].setBackground(Color.WHITE);
231.                }
232.                else
233.                {
234.                        lblCells[i].setBackground(Color.GRAY);
235.                }
236.        }
237.       
238.        private void undoMove()
239.        {
240.                if(btnUndo.isEnabled() && currMove > 0)
241.                {
242.                        currMove--;
243.                        movePiece(moves[currMove][3], moves[currMove][4], moves[currMove][5], moves[currMove][0], moves[currMove][1], moves[currMove][2], true);
244.                }
245.        }
246.       
247.        private void resetBoard()
248.        {
249.                currMove = 0;
250.                pieceName.clear();
251.                pieceName.put("bRook", "Black Rook");
252.                pieceName.put("bQueen", "Black Queen");
253.                pieceName.put("bPawn", "Black Pawn");
254.                pieceName.put("bKnight", "Black Knight");
255.                pieceName.put("bBishop", "Black Bishop");
256.                pieceName.put("bKing", "Black King");
257.                pieceName.put("wRook", "White Rook");
258.                pieceName.put("wQueen", "White Queen");
259.                pieceName.put("wPawn", "White Pawn");
260.                pieceName.put("wKnight", "White Knight");
261.                pieceName.put("wBishop", "White Bishop");
262.                pieceName.put("wKing", "White King");
263.                pieceName.put("wRook", "White Rook");
264.               
265.                // If we're holding a piece, clear the hover of the cell
266.                if(heldI >= 0 && heldX >= 0)
267.                {
268.                        ClearHlight(heldI, heldX);
269.                }
270.               
271.                switchPlayer();
272.               
273.                heldX = heldY = heldI = -1;
274.        }
275.       
276.        private void buildBoard()
277.        {
278.                // First reset the variables, maps, etc.
279.                resetBoard();
280.               
281.                int rowColor = 0;
282.                int i = 0;
283.                for(int x = 0; x <= 7; x++)
284.                {
285.                        rowColor++;
286.                        for(int y = 0; y <= 7; y++)
287.                        {
288.                                lblCells[i] = new JLabel("", JLabel.CENTER);
289.                                lblCells[i].setOpaque(true);
290.                                if(rowColor % 2 == 0)
291.                                {
292.                                        lblCells[i].setBackground(Color.GRAY);
293.                                }
294.                                else
295.                                {
296.                                        lblCells[i].setBackground(Color.WHITE);
297.                                }
298.                               
299.                                final int passX = x;
300.                                final int passY = y;
301.                                final int passI = i;
302.
303.                                lblCells[i].addMouseListener(new java.awt.event.MouseAdapter() {
304.                                        public void mouseEntered(java.awt.event.MouseEvent e) {
305.                                                // If we're holding a piece show that along with the cell we're hovering
306.                                                if(heldI > 0)
307.                                                {
308.                                                        lblStatus.setText("Picked up " + pieceName.get(jPieces[heldX][heldY]) + " at " + showBoardRelative(heldX, heldY) + " | Hovering: " + showBoardRelative(passX, passY));
309.                                                }
310.                                                else // Just show what we're hovering
311.                                                {
312.                                                        lblStatus.setText("Hovering: " + showBoardRelative(passX, passY));
313.                                                }
314.                                                // Unless we hover the one we're holding...
315.                                                if(passI != heldI)
316.                                                {
317.                                                        lblCells[passI].setBackground(Color.DARK_GRAY);
318.                                                }
319.                                        }
320.                                });
321.                               
322.                                lblCells[i].addMouseListener(new java.awt.event.MouseAdapter() {
323.                                        public void mouseExited(java.awt.event.MouseEvent e) {
324.                                                lblStatus.setText("");
325.                                                // Unless we hover the one we're holding...
326.                                                if(passI != heldI)
327.                                                {
328.                                                        // Clear the hover effect
329.                                                        ClearHlight(passI, passX);
330.                                                }
331.                                        }
332.                                });
333.                               
334.                                lblCells[i].addMouseListener(new java.awt.event.MouseAdapter() {
335.                                        public void mouseReleased(java.awt.event.MouseEvent e) {
336.                                                if(e.getModifiers() == InputEvent.BUTTON3_MASK)
337.                                                {
338.                                                        showCellInfo(passX, passY, passI);
339.                                                }
340.                                                else if(e.getModifiers() == InputEvent.BUTTON1_MASK)
341.                                                {
342.                                                        clickCell(e, passX, passY, passI);
343.                                                }
344.                                        }
345.                                });
346. 
347.                                jPanel.add(lblCells[i]);
348.                                rowColor++;
349.                                i++;
350.                        }
351.                }
352.                resetPieces();
353.        }
354.       
355.        // Translates grid relative coordinates to chess board relative
356.        // For ex.: 0x0 to 8A
357.        private String showBoardRelative(int x, int y)
358.        {
359.                String chessCoord = "";
360.                chessCoord = (x - 8) * -1 + "" + (char)(y + 65);
361.                return chessCoord;
362.        }
363.       
364.        private void showCellInfo(int x, int y, int i)
365.        {
366.                if(jPieces[x][y] != null && !jPieces[x][y].equals(""))
367.                {
368.                        JOptionPane.showMessageDialog( null, pieceName.get(jPieces[x][y]) + " located at " + showBoardRelative(x, y), "Cell Information", JOptionPane.INFORMATION_MESSAGE );
369.                }
370.                else
371.                {
372.                        JOptionPane.showMessageDialog( null, "No piece located at " + showBoardRelative(x, y), "Cell Information", JOptionPane.INFORMATION_MESSAGE );
373.                }
374.        }
375.       
376.        private boolean isValidMove(int fromX, int fromY)
377.        {
378.                if(jPieces[fromX][fromY].length() > 0 && jPieces[fromX][fromY].charAt(0) == currPlayer)
379.                {
380.                        return true;                   
381.                }
382.                else
383.                {
384.                        return false;
385.                }
386.        }
387.       
388.        private void movePiece(int fromX, int fromY, int fromI, int toX, int toY, int toI, boolean isUndo)
389.        {
390.                if(fromX == toX && fromY == toY)
391.                {
392.                        ClearHlight(fromI, fromX);
393.                        lblStatus.setText("Move canceled.");
394.                }
395.                else if(isValidMove(fromX, fromY) || isUndo == true)
396.                {
397.                        PaintPiece(jPieces[fromX][fromY], toI);
398.                        PaintPiece("", fromI);
399.                        ClearHlight(fromI, fromX);
400.                        lblStatus.setText("Moved " + pieceName.get(jPieces[fromX][fromY]) + " from " + showBoardRelative(fromX, fromY) + " to " + showBoardRelative(toX, toY));
401.                        jPieces[toX][toY] = jPieces[fromX][fromY];
402.                        jPieces[fromX][fromY] = "";
403.                        if(currMove > 9)
404.                        {
405.                                pushbackUndos();
406.                        }
407.                        moves[currMove] = new int[6];
408.                        moves[currMove][0] = fromX;
409.                        moves[currMove][1] = fromY;
410.                        moves[currMove][2] = fromI;
411.                        moves[currMove][3] = toX;
412.                        moves[currMove][4] = toY;
413.                        moves[currMove][5] = toI;
414.                        movedPieces[currMove] = jPieces[fromX][fromY];
415.                        btnUndo.setEnabled(true);
416.                        if(isUndo == false)
417.                        {
418.                                currMove++;
419.                        }
420.                        switchPlayer();
421.                }
422.                else
423.                {
424.                        ClearHlight(fromI, fromX);
425.                        JOptionPane.showMessageDialog( null, "It's the " + lblCurrPlayer.getText(), "Illegal Move", JOptionPane.INFORMATION_MESSAGE );
426.                }
427.        }
428.       
429.        private void pushbackUndos()
430.        {
431.                for(int i = 0; i < 9; i++)
432.                {
433.                        moves[i] = moves[i + 1];
434.                        movedPieces[i] = movedPieces[i + 1];
435.                }
436.                currMove--;
437.        }
438.       
439.        private void switchPlayer()
440.        {
441.                //System.out.write(currPlayer);
442.                if(currPlayer == 'w')
443.                {
444.                        currPlayer = 'b';
445.                        lblCurrPlayer.setText("Black Player's Turn.");
446.                        lblCurrPlayer.setBackground(Color.BLACK);
447.                        lblCurrPlayer.setForeground(Color.WHITE);
448.                }
449.                else if(currPlayer == 'b' || currPlayer == ' ')
450.                {
451.                        currPlayer = 'w';
452.                        lblCurrPlayer.setText("White Player's Turn.");
453.                        lblCurrPlayer.setBackground(Color.WHITE);
454.                        lblCurrPlayer.setForeground(Color.BLACK);
455.                }
456.        }
457. 
458.        private void clickCell(java.awt.event.MouseEvent e, int x, int y, int i)
459.        {
460.                JLabel lblClicked = (JLabel)e.getSource();
461.                if(heldI != -1) // We're dropping a piece
462.                {
463.                        jContentPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
464.                        movePiece(heldX, heldY, heldI, x, y, i, false);
465.                        heldX = heldY = heldI = -1;
466.                }
467.                else // We're picking up a piece
468.                {
469.                        if(jPieces[x][y] == null || jPieces[x][y].equals(""))
470.                        {
471.                                lblStatus.setText("No piece to pick up.");
472.                        }
473.                        else
474.                        {
475.                                jContentPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
476.                                lblClicked.setBackground(new Color(255, 176, 70));
477.                                lblStatus.setText("Picked up " + pieceName.get(jPieces[x][y]) + " from " + showBoardRelative(x, y));
478.                                heldX = x;
479.                                heldY = y;
480.                                heldI = i;
481.                        }
482.                }
483.        }
484. 
485.        /**
486.         * This method initializes tlbMain     
487.         *      
488.         * @return javax.swing.JToolBar 
489.         */
490.        private JToolBar getTlbMain() {
491.                if (tlbMain == null) {
492.                        lblCurrPlayer = new JLabel();
493.                        lblCurrPlayer.setText("");
494.                        lblCurrPlayer.setOpaque(true);
495.                        lblStatus = new JLabel();
496.                        lblStatus.setText("");
497.                        lblStatus.setPreferredSize(new Dimension(200, 16));
498.                        lblStatus.setSize(new Dimension(200, 16));
499.                        tlbMain = new JToolBar();
500.                        tlbMain.setOrientation(JToolBar.HORIZONTAL);
501.                        tlbMain.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
502.                        tlbMain.setFloatable(false);
503.                        tlbMain.add(getBtnNewGame());
504.                        tlbMain.add(new JToolBar.Separator());
505.                        tlbMain.add(getBtnUndo());
506.                        tlbMain.add(new JToolBar.Separator());
507.                        tlbMain.add(lblCurrPlayer);
508.                        tlbMain.add(new JToolBar.Separator());
509.                        tlbMain.add(lblStatus);
510.                }
511.                return tlbMain;
512.        }
513. 
514.        /**
515.         * This method initializes btnNewGame   
516.         *      
517.         * @return javax.swing.JButton 
518.         */
519.        private JButton getBtnNewGame() {
520.                if (btnNewGame == null) {
521.                        btnNewGame = new JButton();
522.                        btnNewGame.setText("New Game");
523.                        btnNewGame.addMouseListener(new java.awt.event.MouseAdapter() {
524.                                public void  mouseReleased(java.awt.event.MouseEvent e) {
525.                                        if(JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null, "Are you sure you wish to end this game?"))
526.                                        {
527.                                                newGame();
528.                                        }
529.                                }
530.                        });
531.               }
532.                return btnNewGame;
533.        }
534. 
535.}  //  @jve:decl-index=0:visual-constraint="10,10"
Nathan Pakovskie is an esteemed senior developer and educator in the tech community, best known for his contributions to Geekpedia.com. With a passion for coding and a knack for simplifying complex tech concepts, Nathan has authored several popular tutorials on C# programming, ranging from basic operations to advanced coding techniques. His articles, often characterized by clarity and precision, serve as invaluable resources for both novice and experienced programmers. Beyond his technical expertise, Nathan is an advocate for continuous learning and enjoys exploring emerging technologies in AI and software development. When he’s not coding or writing, Nathan engages in mentoring upcoming developers, emphasizing the importance of both technical skills and creative problem-solving in the ever-evolving world of technology. Specialties: C# Programming, Technical Writing, Software Development, AI Technologies, Educational Outreach

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top