遊戲線程問題 (Issues with threads in game)


問題描述

遊戲線程問題 (Issues with threads in game)

我一直在嘗試使用一些基本的多線程來製作一個基本的井字遊戲,但不知何故,兩個線程都可以訪問同步語句,這讓我很困惑。

這是代碼:

import java.util.*;
public class TicTacToe extends Thread {
static  char[][] map = new char[3][3];
static char notsCrosses;
static volatile boolean gameFinish = false;


public TicTacToe(String n){
    super(n);
}
public TicTacToe(){

}
public synchronized String pickPosition(int x){

    switch (x){
        case 1: map[0][0] = notsCrosses; return "00";
        case 2: map[0][1] = notsCrosses; return "01";
        case 3: map[0][2] = notsCrosses; return "02";
        case 4: map[1][0] = notsCrosses; return "10";
        case 5: map[1][1] = notsCrosses; return "11";
        case 6: map[1][2] = notsCrosses; return "12";
        case 7: map[2][0] = notsCrosses; return "20";
        case 8: map[2][1] = notsCrosses; return "21";
        case 9: map[2][2] = notsCrosses; return "22";
    }
    return null;
}

public void run() {
    if (this.getName() == "player1") {
        notsCrosses = 'X';
    } else {
        notsCrosses = 'O';
    }
    Scanner input = new Scanner(System.in);
    synchronized (this) {
        while (!gameFinish) {
            try {
                System.out.print(this.getName() + " Enter the position (1‑9): ");
                int position = input.nextInt();
                pickPosition(position);

                System.out.print("h");
                printMaze();
                int yCood = Integer.parseInt(pickPosition(position).substring(0, 1));
                int xCood = Integer.parseInt(pickPosition(position).substring(1, 2));

                if (hasWon(map, xCood, yCood)) {
                    System.out.println("You win! " + this.getName());
                    gameFinish = true;
                }

                notify();
                wait();
            } catch (InterruptedException i) {

            }
        }
    }
}


public static void main(String[] args) {
    for(int i=0; i<map.length; i++){
        for(int j=0; j<map[i].length; j++){
            map[i][j] = '‑';
        }

    }
    new TicTacToe().printMaze();

    TicTacToe player1 = new TicTacToe("player1");
    TicTacToe player2 = new TicTacToe("player2");

    player1.start();
    player2.start();

}
public synchronized void printMaze(){
        for(int i=0; i<map.length; i++){
            if(i==0) {
                for (int x = 0; x < 3; x++) {
                    System.out.print("‑‑‑");
                }
                System.out.println();
            }
            for(int j=0; j<map[i].length; j++) {
                System.out.print("|");
                System.out.print(map[i][j]);
                System.out.print("|");
            }
            System.out.println();
            for(int x=0; x<3; x++) {
                System.out.print("‑‑‑");
            }
            System.out.println();

        }

}


public synchronized boolean hasWon(char[][] m,int xCood, int yCood){
    if(checkRow(m,yCood) || checkColumn(m,xCood) || checkDiagonal(m,xCood,yCood)){
        return true;
    }
    return false;


}

public synchronized boolean checkRow(char[][] m,int yCood){
    for(int i=0; i<3; i++){
        if(map[yCood][i] != notsCrosses){
            return false;
        }
    }
    return true;
}

public synchronized boolean checkColumn(char[][] m,int xCood){
    for(int i=0; i<3; i++){
        if(map[i][xCood] != notsCrosses){
            return false;
        }
    }
    return true;
}
public synchronized boolean checkDiagonal(char[][] m,int xCood, int yCood){
    if(map[0][0]==notsCrosses && map[1][1]==notsCrosses && map[2][2]==notsCrosses){
            return true;
    }
    else if(map[2][0]==notsCrosses && map[1][1]==notsCrosses && map[0][2]==notsCrosses){
            return true;
    }
    return false;


}
}

我在 run 方法中使用 synchronize 語句,我想做的只是一次只允許一個線程(播放器)訪問該代碼並檢查 volatile 變量“遊戲完成”。


參考解法

方法 1:

You have two bugs:

  1. You have two players, each of which synchronize on themselves. That won't work. You need to synchronize on some single thing that is shared.

  2. Nowhere does your code keep track of which player's turn it is. So your code has no idea when to stop waiting. It just guesses and may guess wrong.

(by Mohammad RizwaanDavid Schwartz)

參考文件

  1. Issues with threads in game (CC BY‑SA 2.5/3.0/4.0)

#java #tic-tac-toe #multithreading






相關問題

電子郵件地址中帶有 + 字符的 Java 郵件 (Java mail with + character in email address)

如何快速原型化 Java 代碼? (How to quickly prototype Java code?)

如何使用 Maven 在目標(SVN-)服務器上創建 Javadoc? (How to create Javadoc on the target (SVN-) server using Maven?)

為什麼檢查二叉樹有效性的解決方案不起作用? (Why the solution for checking the validity of binary tree is not working?)

Selenium webdriver通過第一個數字找到texy (Selenium webdriver find texy by first digits)

setOnClickListener 沒有在圖像視圖上被調用 (setOnClickListener is not getting called on image view)

繪製多邊形:找不到錯誤 (Drawing Polygon : unable to find error)

半透明 JButton:對像出現在背景中 (Semi-Transparent JButton: Objects appear in Background)

比較同一數組的元素 (Compare elements of the same array)

Java 屏幕截圖小程序 (Java screen capture applet)

Minecraft 1.8.9 Forge Modding 的Java 開發工具包,需要什麼JDK/JRE,代碼是否正確? (Java Development Kit with Minecraft 1.8.9 Forge Modding, What JDK/JRE Is Needed, Is Code Correct?)

java while (resultset.next()) 不返回同一列中的所有數據 (java while (resultset.next()) does not return all data in the same column)







留言討論