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"