|
Two players alternate making moves. The player who places five
pieces in a row wins.
The source program consists of three files: a short main program, a graphical user interface, and a logic class. The logic class knows nothing about the GUI, and could just as easily be used with a text interface or by a web interface. There's a lot of room for improvement. Some possible exercises:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Five.java - main program for Five-In-A-Row Program
import javax.swing.JFrame;
////////////////////////////////////////////////////// class Five
/** Five.java - Winner is able to put 5 pieces in a row.
The Five program consists of three files:
Five.java - this file with main to create window.
FiveGUI.java - implements the GUI interface.
FiveLogic.java - the logical functioning.
@author Fred Swartz
@version 2004-05-02
*/
class Five {
//================================================ method main
public static void main(String[] args) {
JFrame window = new JFrame("Five In A Row");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setContentPane(new FiveGUI());
window.pack(); // finalize layout
window.setResizable(false);
window.show(); // make window visible
}//end main
}//endclass Five
|
1 2 3 4 5 6 7 8 9 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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
// FiveGUI.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/////////////////////////////////////////////////// class FiveGUI
/** A Graphical User Interface for a Five-In-A-Row game.
This implements the user interface (view and controller),
but the logic (model) is implemented in a separate class that
knows nothing about the user interface.
<p>This subclasses JPanel and puts the some buttons in the north,
a graphical display of the board in the center, and
a status field in the south.
</p>
<p>Exercise: This game probably originated on a Go board where
the pieces are placed on the intersections, not in the
empty spaces. Change the program to put all pieces on the
intersections.
</p>
<p>Exercise: The Undo button doesn't do anything. Fix it here
in the GUI and in the logic.
</p>
<p>Exercise: Create a machine player.</p>
@author Fred Swartz
@version 2004-05-02 Rodenbach
*/
class FiveGUI extends JPanel {
//=============================================== instance variables
private GraphicsPanel boardDisplay_;
private JTextField statusField_ = new JTextField();
private FiveLogic gameLogic_ = new FiveLogic(9, 9);
private boolean gameOver_ = false;
private static final Color[] PLAYER_COLOR = {null, Color.BLACK, Color.WHITE};
private static final String[] PLAYER_NAME = {null, "BLACK", "WHITE"};
//====================================================== constructor
public FiveGUI() {
//--- Create some buttons
JButton newGameButton = new JButton("New Game");
JButton undoButton = new JButton("Undo");
//--- Create control panel
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
controlPanel.add(newGameButton);
controlPanel.add(undoButton);
//--- Create graphics panel
boardDisplay_ = new GraphicsPanel();
//--- Set the layout and add the components
this.setLayout(new BorderLayout());
this.add(controlPanel , BorderLayout.NORTH);
this.add(boardDisplay_, BorderLayout.CENTER);
this.add(statusField_ , BorderLayout.SOUTH);
//-- Add action listeners
newGameButton.addActionListener(new NewGameAction());
}//end constructor
//////////////////////////////////////////////// class GraphicsPanel
// This is defined inside the outer class so that
// it can use the game logic variable.
class GraphicsPanel extends JPanel implements MouseListener {
private static final int ROWS = 9;
private static final int COLS = 9;
private static final int CELL_SIZE = 30; // Pixels
private static final int WIDTH = COLS * CELL_SIZE;
private static final int HEIGHT = ROWS * CELL_SIZE;
//================================================== constructor
public GraphicsPanel() {
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setBackground(Color.GRAY);
this.addMouseListener(this); // Listen own mouse events.
}//end constructor
//============================================== paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g);
//-- Paint grid (could be done once and saved).
for (int r=1; r<ROWS; r++) { // Horizontal lines
g.drawLine(0, r*CELL_SIZE, WIDTH, r*CELL_SIZE);
}
for (int c=1; c<COLS; c++) {
g.drawLine(c*CELL_SIZE, 0, c*CELL_SIZE, HEIGHT);
}
//-- Draw players pieces.
for (int r=0; r<ROWS; r++) {
for (int c=0; c<COLS; c++) {
int x = c * CELL_SIZE;
int y = r * CELL_SIZE;
int who = gameLogic_.getPlayerAt(r, c);
if (who != gameLogic_.EMPTY) {
g.setColor(PLAYER_COLOR[who]);
g.fillOval(x+2, y+2, CELL_SIZE-4, CELL_SIZE-4);
}
}
}
}//end paintComponent
//======================================== listener mousePressed
public void mousePressed(MouseEvent e) {
//--- map x,y coordinates into a row and col.
int col = e.getX()/CELL_SIZE;
int row = e.getY()/CELL_SIZE;
int currentOccupant = gameLogic_.getPlayerAt(row, col);
if (!gameOver_ && currentOccupant == gameLogic_.EMPTY) {
gameLogic_.move(row, col);
switch (gameLogic_.getGameStatus()) {
case 1: // Player one wins. Game over.
gameOver_ = true;
statusField_.setText("BLACK WINS");
break;
case 2: // Player two wins. Game over.
gameOver_ = true;
statusField_.setText("WHITE WINS");
break;
case FiveLogic.TIE: // Tie game. Game over.
gameOver_ = true;
statusField_.setText("TIE GAME");
break;
default: showNextPlayer();
}
} else { // Not legal
Toolkit.getDefaultToolkit().beep();
}
this.repaint(); // Show any updates to game.
}//end mousePressed
//========================================== ignore these events
public void mouseClicked (MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered (MouseEvent e) {}
public void mouseExited (MouseEvent e) {}
}//end inner class GraphicsPanel
//======================================= untility method showNextPlayer
private void showNextPlayer() {
statusField_.setText(PLAYER_NAME[gameLogic_.getNextPlayer()] + " to play");
}//end showNextPlayer
///////////////////////////////////////// inner class NewGameAction
private class NewGameAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
gameLogic_.reset();
gameOver_ = false;
showNextPlayer();
boardDisplay_.repaint();
}
}//end inner class NewGameAction
}//end class FiveGUI
|
1 2 |