我目前正在尝试用Java编写井字游戏,该游戏可以在网络上玩。我正在使用Java中的套接字编程,而对于UI,我正在使用JavaFX。启动服务器和2个客户端后,客户端将连接到服务器,将玩家配对并创建游戏。尝试执行实际的Tic Tac Toe游戏时,GUI卡住了。我相信这可能与线程有关,但是经过无数小时尝试不同的解决方案后,我仍无法弄清楚。
以下是该问题的视频 https://www.youtube.com/watch?v=dCIxRkGJlCI&t=2s
我的GitHub存储库: https://github.com/Stinny/Tic-Tac-Toe
我认为该问题存在于TicTacToeController.java类中
任何信息将不胜感激!
这是我的TicTacToeController类
public class TicTacToeController implements Initializable {
private static Socket socket;
private static PrintWriter out;
private static BufferedReader in;
private static Image Circle = new Image("./Circle.png");
private static Image Cross = new Image("./Cross.png");
private static ImageView icon, opponentIcon;
@FXML
Button topLeft, topRight, topCenter,
midLeft, midCenter, midRight,
botLeft, botMid, botRight;
@FXML
Button play;
public void initialize(URL url, ResourceBundle rb) {
}
public void buttonClickHandler(ActionEvent evt) throws Exception{
Button clickedButton = (Button) evt.getTarget();
evt.getEventType();
String button =((Control)evt.getSource()).getId();
System.out.println(button);
if(button.equals("play")){
clickedButton.setDisable(true);
play();
}
else if (button.equals("topLeft")) {
out.print("MOVE0");
//do something
} else if (button.equals("topRight")) {
//do something
out.print("MOVE2");
} else if (button.equals("topCenter")) {
//do something
out.print("MOVE1");
} else if (button.equals("midLeft")) {
//do something
out.print("MOVE3");
} else if (button.equals("midCenter")) {
//do something
out.print("MOVE4");
} else if (button.equals("midRight")) {
//do something
out.print("MOVE5");
} else if (button.equals("botLeft")) {
//do something
out.print("MOVE6");
} else if (button.equals("botMid")) {
//do something
out.print("MOVE7");
} else if (button.equals("botRight")) {
//do something
out.print("MOVE8");
}
}
public void play() throws IOException {
String response;
try {
connectToServer();
response = in.readLine();
System.out.println("Send to server" + in);
char mark = response.charAt(7);
System.out.println("You are " + mark);
if (mark == 'X') {
icon = new ImageView(Circle);
opponentIcon = new ImageView(Cross);
} else {
icon = new ImageView(Cross);
opponentIcon = new ImageView(Circle);
}
//frame.setTitle("Tic Tac Toe - Player " + mark);
while (true) {
response = in.readLine();
if (response != null) {
System.out.println(response);
if (response.startsWith("VALID_MOVE")) {
int location = Integer.parseInt(response.substring(5));
if (location == 0) {
handleButtonClick(topLeft, icon);
} else if (location == 1) {
handleButtonClick(topLeft, icon);
} else if (location == 2) {
handleButtonClick(topLeft, icon);
} else if (location == 3) {
handleButtonClick(topLeft, icon);
} else if (location == 4) {
handleButtonClick(topLeft, icon);
} else if (location == 5) {
handleButtonClick(topLeft, icon);
} else if (location == 6) {
handleButtonClick(topLeft, icon);
} else if (location == 7) {
handleButtonClick(topLeft, icon);
} else if (location == 7) {
handleButtonClick(topLeft, icon);
} else if (location == 8) {
handleButtonClick(topLeft, icon);
}
} else if (response.startsWith("OPPONENT_MOVED")) {
int location = Integer.parseInt(response.substring(15));
if (location == 0) {
handleButtonClick(topLeft, opponentIcon);
} else if (location == 1) {
handleButtonClick(topCenter, opponentIcon);
} else if (location == 2) {
handleButtonClick(topRight, opponentIcon);
} else if (location == 3) {
handleButtonClick(midLeft, opponentIcon);
} else if (location == 4) {
handleButtonClick(midCenter, opponentIcon);
} else if (location == 5) {
handleButtonClick(midRight, opponentIcon);
} else if (location == 6) {
handleButtonClick(botLeft, opponentIcon);
} else if (location == 7) {
handleButtonClick(botMid, opponentIcon);
} else if (location == 8) {
handleButtonClick(botRight, opponentIcon);
}
} 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;
}
}
}
out.println("QUIT");
}
finally {
socket.close();
}
}
public void handleButtonClick(Button button, ImageView mark){
button.setGraphic(mark);
}
public static void connectToServer(){
try {
socket = new Socket("localhost", 7777);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println(e + " fuck");
}
}
}
这是我的服务器类:
public class Server {
private static ServerSocket serverSocket;
private static ArrayList<Socket> sockets;
private static Socket socket;
public static void main(String[] args) throws Exception {
try {
serverSocket = new ServerSocket(7777);
sockets = new ArrayList<>();
for(int i = 1; i < 3; i++){
socket = serverSocket.accept();
System.out.println("Player " + i + " connected");
sockets.add(socket);
}
Game game = new Game();
System.out.println("Created game, waiting for players to connect");
Game.PlayerHandler playerX = game.new PlayerHandler(sockets.remove(sockets.size()-1), 'X');
Game.PlayerHandler playerO = game.new PlayerHandler(sockets.remove(sockets.size()-1), 'O');
game.currentPlayer = playerX;
playerX.start();
playerO.start();
System.out.println("Game started");
}catch(IOException e)
{
e.printStackTrace();
}
}
}
class Game{
private PlayerHandler[] board = {
null, null, null,
null, null, null,
null, null, null
};
PlayerHandler currentPlayer;
public boolean isFull(){
for(int i = 0; i < board.length; i++) {
if(board[i] == null){
return false;
}
}
return true;
}
public boolean hasWinner() {
if (checkHorizontalWin() || checkVerticalWin() || checkDiagonalWin()) {
return true;
} else {
return false;
}
}
public boolean checkHorizontalWin() {
if (board[0] != null && board[0] == board[1] && board[0] == board[2]) {
return true;
} else if(board[3] != null && board[3] == board[4] && board[3] == board[5]) {
return true;
} else if(board[6] != null && board[6] == board[7] && board[6] == board[8]) {
return true;
} else {
return false;
}
}
public boolean checkVerticalWin() {
if (board[0] != null && board[0] == board[3] && board[0] == board[6]) {
return true;
} else if(board[1] != null && board[1] == board[4] && board[1] == board[7]) {
return true;
} else if(board[2] != null && board[2] == board[5] && board[2] == board[8]) {
return true;
} else {
return false;
}
}
public boolean checkDiagonalWin() {
if (board[0] != null && board[0] == board[4] && board[0] == board[8]) {
return true;
} else if (board[2] != null && board[2] == board[4] && board[2] == board[6]) {
return true;
} else {
return false;
}
}
public synchronized boolean move(PlayerHandler player, int location) { //A player moves based on their assigned Piece
System.out.println("Player moved at location " + location);
if(board[location]==null){
board[location] = player;
currentPlayer = currentPlayer.opponent;
currentPlayer.opponentMoved(location);
return true;
}
return false;
}
class PlayerHandler extends Thread{
char mark;
private String name;
private Socket socket;
PlayerHandler opponent;
BufferedReader in;
PrintWriter out;
public PlayerHandler(Socket socket, char mark) {
this.socket = socket;
this.mark = mark;
try{
// initialize input and output streams
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
out.println("WELCOME" + mark);
} catch(IOException e){
}
}
public void setOpponent(PlayerHandler opponent){
this.opponent = opponent;
}
public void opponentMoved(int location){
out.println("OPPONENT_MOVED" + location);
out.println(
hasWinner() ? "DEFEAT" : isFull() ? "TIE" : "");
}
public void run() {
try {
if (mark == 'X') {
out.println("MESSAGE Your move");
}
while (true) {
String command = in.readLine();
if (command != null) {
if (command.startsWith("MOVE")) {
int location = Integer.parseInt(command.substring(5));
System.out.println(location);
if (move(this, location)) {
out.println("VALID_MOVE" + "location");
out.println(hasWinner() ? "VICTORY"
: isFull() ? "TIE"
: "");
} else {
out.println("MESSAGE ?");
}
}
}
}
}catch(IOException e) {
System.out.println("Player died: " + e);
} finally {
try {socket.close();} catch(IOException e){}
}
}
}
}