我正在尝试编写扑克服务器和客户端程序,我在服务器类中创建游戏,我的客户端类获取输出并显示它们。但是,当我这样做时,似乎创建了两个游戏对象,第一个玩家得到的输入与控制台中显示的对象一致,第二个玩家总是显示未在sysout方法中显示的卡片,我似乎无法找到我创建第二个游戏对象的位置。
服务器类:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
public class PokerServer {
/**
* The port that the server listens on.
*/
private static final int PORT = 9050;
// keeps track of all the names
private static ArrayList<String> names = new ArrayList<String>();
// broadcast messages
private static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
private boolean bothPlayersConnected = false;
/**
* The appplication main method, which just listens on a port and spawns
* handler threads.
*/
public static void main(String[] args) throws Exception {
System.out.println("The poker server is running.");
ServerSocket listener = new ServerSocket(PORT);
try {
while (true) {
new GameThread(listener.accept()).start();
}
} finally {
listener.close();
}
}
private static class GameThread extends Thread {
private String name;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private Game game;
public GameThread(Socket socket) {
this.socket = socket;
}
/**
* Services this thread's client by repeatedly requesting a screen name
* until a unique one has been submitted, then acknowledges the name and
* registers the output stream for the client in a global set, then
* repeatedly gets inputs and broadcasts them.
*/
public void run() {
try {
System.out.println("get to this part");
// Create character streams for the socket.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// get the name of the player
out.println("SUBMITNAME");
name = in.readLine();
names.add(name);
while(names.size()<2){
out.println("MESSAGE waiting for opponent to connect");
}
// Now that a successful name has been chosen, add the
// socket's print writer to the set of all writers so
// this client can receive broadcast messages.
// out.println("NAMEACCEPTED");
// writers.add(out);
game = new Game(names.get(0), names.get(1), 1000);
game.dealToPlayers();
out.println(names.get(0) + game.getPlayer1().getHand()[0].transferStr());
out.println(names.get(0) + game.getPlayer1().getHand()[1].transferStr());
out.println(names.get(1) + game.getPlayer2().getHand()[0].transferStr());
out.println(names.get(1) + game.getPlayer2().getHand()[1].transferStr());
// Accept messages from this client and broadcast them.
// Ignore other clients that cannot be broadcasted to.
while (true) {
String input = in.readLine();
if (input == null) {
return;
} else if (input.startsWith(names.get(0))) {
}
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + name + ": " + input);
}
}
} catch (IOException e) {
System.out.println(e);
} finally {
// This client is going down! Remove its name and its print
// writer from the sets, and close its socket.
if (name != null) {
names.remove(name);
}
if (out != null) {
writers.remove(out);
}
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}
客户端类
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class PokerClient {
BufferedReader in;
PrintWriter out;
String playerName = "Poker";
JFrame frame = new JFrame(playerName);
JPanel playerHandPanel, controlPanel, bottomPanel, topPanel, messageBoard;
JButton check, fold;
JTextField textField = new JTextField(10);
JLabel firstLine = new JLabel("");
String serverAddress = "localhost";
Card playerHand1, playerHand2;
public PokerClient() {
// Layout GUI
frame.setSize(1100, 700);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
playerHandPanel = new JPanel(new GridLayout(1, 0));
playerHandPanel.setPreferredSize(new Dimension(600, 300));
playerHandPanel.setVisible(true);
topPanel = new JPanel(new GridLayout(1, 0));
topPanel.setPreferredSize(new Dimension(900, 300));
topPanel.setVisible(true);
messageBoard = new JPanel(new GridLayout(0, 1));
messageBoard.add(firstLine);
controlPanel = new JPanel();
controlPanel.setPreferredSize(new Dimension(600, 40));
controlPanel.setVisible(true);
topPanel.add(messageBoard);
check = new JButton("Check");
check.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(playerName+"CHECK");
}
});
fold = new JButton("fold");
fold.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(playerName+"FOLD");
}
});
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(isInt(textField.getText())){
out.println(textField.getText());
textField.setText("");
} else{
JFrame frame = new JFrame("Not a number");
frame.setSize(600, 70);
frame.setLocation(400, 250);
frame.setResizable(false);
JLabel label = new JLabel("You must enter a number in order to raise");
frame.add(label);
frame.setVisible(true);
frame.toFront();
frame.repaint();
textField.setText("");
}
}
});
controlPanel.add(check);
controlPanel.add(fold);
controlPanel.add(new JLabel(" Raise:"));
controlPanel.add(textField);
bottomPanel = new JPanel();
bottomPanel.add(controlPanel, BorderLayout.SOUTH);
bottomPanel.add(playerHandPanel, BorderLayout.NORTH);
frame.add(topPanel, BorderLayout.NORTH);
frame.add(bottomPanel, BorderLayout.SOUTH);
//frame.add(firstLine, "SOUTH");
frame.setVisible(true);
}
private static boolean isInt(String s)
{
try
{ int i = Integer.parseInt(s); return true; }
catch(NumberFormatException er)
{ return false; }
}
/**
* Prompt for and return the desired screen name.
*/
private String getName() {
return JOptionPane.showInputDialog(
frame,
"Choose a screen name:",
"Screen name selection",
JOptionPane.PLAIN_MESSAGE);
}
private Card constructCard(String line){
int seperator = line.indexOf('/');
int cardNum = Integer.parseInt(line.substring(0, seperator));
Card card;
if(line.substring(seperator+1).startsWith("S")){
card = new Card(cardNum, Suit.SPADE);
} else if(line.substring(seperator+1).startsWith("C")){
card = new Card(cardNum, Suit.CLUB);
} else if(line.substring(seperator+1).startsWith("D")){
card = new Card(cardNum, Suit.DIAMOND);
} else{
card = new Card(cardNum, Suit.HEART);
}
System.out.println(card.toString());
return card;
}
/**
* Connects to the server then enters the processing loop.
*/
private void run() throws IOException {
Socket socket = new Socket(serverAddress, 9050);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Process all messages from server, according to the protocol.
while (true) {
String line = in.readLine();
System.out.println(line);
if (line.startsWith("SUBMITNAME")) {
String name = getName();
playerName = name;
out.println(name);
frame.setTitle(playerName);
} else if (line.startsWith(playerName)) {
playerHandPanel.add(new CardComponent(constructCard(line.substring(playerName.length()))));
playerHandPanel.revalidate();
playerHandPanel.repaint();
} else if(line.startsWith("CARD")){
topPanel.add(new CardComponent(constructCard(line.substring(4))));
topPanel.revalidate();
topPanel.repaint();
} else if(line.startsWith("MESSAGE")){
firstLine.setText(line.substring(7));
}
}
}
public static void main(String[] args) throws Exception {
PokerClient client = new PokerClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}