0
package gamework;
import java.awt. Color;
import java.awt. GridLayout;
import java.awt. event.MouseAdapter;
import java.awt. event.MouseEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net. Socket;
import javax. swing.Icon;
import javax. swing.ImageIcon;
import javax. swing.JFrame;
import javax. swing.JLabel;
import javax. swing.JOptionPane;
import javax. swing.JPanel;
/**
* A client for the TicTacToe game, modified and extended from the
* class presented in Deitel and Deitel "Java How to Program" book.
* I made a bunch of enhancements and rewrote large sections of the
* code. In particular I created the TTTP (Tic Tac Toe Protocol)
* which is entirely text based. Here are the strings that are sent:
*
* Client -> Server Server -> Client
* --- ---
* MOVE <n> (0 <= n <= 8) WELCOME <char> (char in {X, O})
* QUIT VALID_MOVE
* OTHER_PLAYER_MOVED <n>
* VICTORY
* DEFEAT
* TIE
* MESSAGE <text>
*
*/
public class GameClient {
private JFrame frame = new JFrame("Tic Tac Toe");
private JLabel messageLabel = new JLabel("");
private ImageIcon icon;
private ImageIcon opponentIcon;
private Square[] board = new Square[9];
private Square currentSquare;
private static int PORT = 8901;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
/**
* Constructs the client by connecting to a server, laying out the
* GUI and registering GUI listeners.
*/
public GameClient(String serverAddress) throws Exception {
// Setup networking
socket = new Socket(serverAddress, PORT);
in = new BufferedReader(new InputStreamReader(
socket. getInputStream()));
out = new PrintWriter(socket. getOutputStream(), true);
// Layout GUI
messageLabel. setBackground(Color. lightGray);
frame. getContentPane().add(messageLabel, "South");
JPanel boardPanel = new JPanel();
boardPanel. setBackground(Color. black);
boardPanel. setLayout(new GridLayout(3, 3, 2, 2));
for (int i = 0; i < board. length; i++) {
final int j = i;
board[i] = new Square();
board[i].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
currentSquare = board[j];
out. println("MOVE " + j);}});
boardPanel.add(board[i]);
}
frame. getContentPane().add(boardPanel, "Center");
}
/**
* The main thread of the client will listen for messages
* from the server. The first message will be a "WELCOME"
* message in which we receive our mark. Then we go into a
* loop listening for "VALID_MOVE", "OPPONENT_MOVED", "VICTORY",
* "DEFEAT", "TIE", "OPPONENT_QUIT or "MESSAGE" messages,
* and handling each message appropriately. The "VICTORY",
* "DEFEAT" and "TIE" ask the user whether or not to play
* another game. If the answer is no, the loop is exited and
* the server is sent a "QUIT" message. If an OPPONENT_QUIT
* message is recevied then the loop will exit and the server
* will be sent a "QUIT" message also.
*/
public void play() throws Exception {
String response;
try {
response = in.readLine();
if (response. startsWith("WELCOME")) {
char mark = response. charAt(8);
icon = new ImageIcon(mark == 'X' ? "x.gif" : "o.gif");
opponentIcon = new ImageIcon(mark == 'X' ? "o.gif" : "x.gif");
frame. setTitle("Tic Tac Toe - Player " + mark);
}
while (true) {
response = in.readLine();
if (response. startsWith("VALID_MOVE")) {
messageLabel. setText("Valid move, please wait");
currentSquare. setIcon(icon);
currentSquare. repaint();
} else if (response. startsWith("OPPONENT_MOVED")) {
int loc = Integer. parseInt(response. substring(15));
board[loc].setIcon(opponentIcon);
board[loc].repaint();
messageLabel. setText("Opponent moved, your turn");
} else if (response. startsWith("VICTORY")) {
messageLabel. setText("You win");
break;
} else if (response. startsWith("DEFEAT")) {
messageLabel. setText("You lose");
break;
} else if (response. startsWith("TIE")) {
messageLabel. setText("You tied");
break;
} else if (response. startsWith("MESSAGE")) {
messageLabel. setText(response. substring(8));
}
}
out. println("QUIT");
}
finally {
socket. close();
}
}
private boolean wantsToPlayAgain() {
int response = JOptionPane. showConfirmDialog(frame,
"Want to play again?",
"Tic Tac Toe is Fun Fun Fun",
JOptionPane.YES_NO_OPTION);
frame. dispose();
return response == JOptionPane.YES_OPTION;
}
/**
* Graphical square in the client window. Each square is
* a white panel containing. A client calls setIcon() to fill
* it with an Icon, presumably an X or O.
*/
static class Square extends JPanel {
JLabel label = new JLabel((Icon)null);
public Square() {
setBackground(Color. white);
add(label);
}
public void setIcon(Icon icon) {
label. setIcon(icon);
}
}
/**
* Runs the client as an application.
*/
public static void main(String[] args) throws Exception {
while (true) {
String serverAddress = (args. length == 0) ? "localhost" : args[1];
GameClient client = new GameClient(serverAddress);
client. frame.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);
client. frame.setSize(240, 160);
client. frame.setVisible(true);
client. frame.setResizable(false);
client. play();
if (!client. wantsToPlayAgain()) {
break;
}
}
}
}
Tümünü Göster