📄 tictactoeserver.java
字号:
import java.io.*;import java.net.*;import javax.swing.*;import java.awt.*;import java.util.Date;public class TicTacToeServer extends JFrame implements TicTacToeConstants { public static void main(String[] args) { TicTacToeServer frame = new TicTacToeServer(); } public TicTacToeServer() { JTextArea jtaLog = new JTextArea(); // Create a scroll pane to hold text area JScrollPane scrollPane = new JScrollPane(jtaLog); // Add the scroll pane to the frame getContentPane().add(scrollPane, BorderLayout.CENTER); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 300); setTitle("TicTacToeServer"); setVisible(true); try { // Create a server socket ServerSocket serverSocket = new ServerSocket(8000); jtaLog.append(new Date() + ": Server started at socket 8000\n"); // Number a session int sessionNo = 1; // Ready to create a session for every two players while (true) { jtaLog.append(new Date() + ": Wait for players to join session " + sessionNo + '\n'); // Connect to player 1 Socket player1 = serverSocket.accept(); jtaLog.append(new Date() + ": Player 1 joined session " + sessionNo + '\n'); jtaLog.append("Player 1's IP address" + player1.getInetAddress().getHostAddress() + '\n'); // Notify that the player is Player 1 new DataOutputStream( player1.getOutputStream()).writeInt(PLAYER1); // Connect to player 2 Socket player2 = serverSocket.accept(); jtaLog.append(new Date() + ": Player 2 joined session " + sessionNo + '\n'); jtaLog.append("Player 2's IP address" + player2.getInetAddress().getHostAddress() + '\n'); // Notify that the player is Player 2 new DataOutputStream( player2.getOutputStream()).writeInt(PLAYER2); // Display this session and increment session number jtaLog.append(new Date() + ": Start a thread for session " + sessionNo++ + '\n'); // Create a new thread for this session of two players HandleASession thread = new HandleASession(player1, player2); // Start the new thread thread.start(); } } catch(IOException ex) { System.err.println(ex); } }}// Define the thread class for handling a new session for two playersclass HandleASession extends Thread implements TicTacToeConstants { private Socket player1; private Socket player2; // Create and initialize cells private char[][] cell = new char[3][3]; private DataInputStream fromPlayer1; private DataOutputStream toPlayer1; private DataInputStream fromPlayer2; private DataOutputStream toPlayer2; // Continue to play private boolean continueToPlay = true; /** Construct a thread */ public HandleASession(Socket player1, Socket player2) { this.player1 = player1; this.player2 = player2; // Initialize cells for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) cell[i][j] = ' '; } /** Implement the run() method for the thread */ public void run() { try { // Create data input and output streams DataInputStream fromPlayer1 = new DataInputStream( player1.getInputStream()); DataOutputStream toPlayer1 = new DataOutputStream( player1.getOutputStream()); DataInputStream fromPlayer2 = new DataInputStream( player2.getInputStream()); DataOutputStream toPlayer2 = new DataOutputStream( player2.getOutputStream()); // Write anything to notify player 1 to start // This is just to let player 1 know to start toPlayer1.writeInt(1); // Continuously serve the players and determine and report // the game status to the players while (true) { // Receive a move from player 1 int row = fromPlayer1.readInt(); int column = fromPlayer1.readInt(); cell[row][column] = 'X'; // Check if Player 1 wins if (isWon('X')) { toPlayer1.writeInt(PLAYER1_WON); toPlayer2.writeInt(PLAYER1_WON); sendMove(toPlayer2, row, column); break; // Break the loop } else if (isFull()) { // Check if all cells are filled toPlayer1.writeInt(DRAW); toPlayer2.writeInt(DRAW); sendMove(toPlayer2, row, column); break; } else { // Notify player 2 to take the turn toPlayer2.writeInt(CONTINUE); // Send player 1's selected row and column to player 2 sendMove(toPlayer2, row, column); } // Receive a move from Player 2 row = fromPlayer2.readInt(); column = fromPlayer2.readInt(); cell[row][column] = 'O'; // Check if Player 2 wins if (isWon('O')) { toPlayer1.writeInt(PLAYER2_WON); toPlayer2.writeInt(PLAYER2_WON); sendMove(toPlayer1, row, column); break; } else { // Notify player 1 to take the turn toPlayer1.writeInt(CONTINUE); // Send player 2's selected row and column to player 1 sendMove(toPlayer1, row, column); } } } catch(IOException ex) { System.err.println(ex); } } /** Send the move to other player */ private void sendMove(DataOutputStream out, int row, int column) throws IOException { out.writeInt(row); // Send row index out.writeInt(column); // Send column index } /** Determine if the cells are all occupied */ private boolean isFull() { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (cell[i][j] == ' ') return false; // At least one cell is not filled // All cells are filled return true; } /** Determine if the player with the specified token wins */ private boolean isWon(char token) { // Check all rows for (int i = 0; i < 3; i++) if ((cell[i][0] == token) && (cell[i][1] == token) && (cell[i][2] == token)) { return true; } /** Check all columns */ for (int j = 0; j < 3; j++) if ((cell[0][j] == token) && (cell[1][j] == token) && (cell[2][j] == token)) { return true; } /** Check major diagonal */ if ((cell[0][0] == token) && (cell[1][1] == token) && (cell[2][2] == token)) { return true; } /** Check subdiagonal */ if ((cell[0][2] == token) && (cell[1][1] == token) && (cell[2][0] == token)) { return true; } /** All checked, but no winner */ return false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -