如何为游戏实施等待通知方法?

时间:2019-04-13 15:39:29

标签: java java-threads

我必须实现一个由三个玩家组成的游戏。我有以下课程:玩家,游戏,棋盘和优势。棋盘是完整的图形,每个玩家都必须提取一条优势。当图表变成一棵生成树时,玩家将获胜。我使用线程来实现游戏,但我不知道该如何实现等待通知方法。互联网上的示例仅显示了两个线程。等待应该在run方法中,或者我应该为wait()和notify()创建一个新方法?我应该在游戏类中拥有run方法吗?还是只是在球员班上?

游戏类:

public class Game {

    private Board board;
    private Player winner;
    private Edge edges;
    private final List<Player> players = new ArrayList<>();

    public void addPlayer(Player player) {
        players.add(player);
        player.setGame(this);
    }

    public void setWinner(Player winningPlayer) {
        int maxPoints = 0;
        this.winner = winningPlayer;
        for (Player p : players) {
            maxPoints += p.getPoints();
            p.setPoints(0);
        }
        winningPlayer.setPoints(maxPoints);
    } 

    public Board getBoard() {
        return board;
    }

    public void setBoard(Board board) {
        this.board = board;
    }

    public List<Player> getPlayers() {
        return players;
    }

    public void start () {
        int i;
        for (i = 0; i < getPlayers().size(); i++) {
            new Thread(getPlayers().get(i)).start();
        }
    }
}

董事会课程:

public class Board {
    private final Graph complete;

    public Board() {
        complete = new Graph();
    }

    public Board(int size) {
        // create the complete graph
        this.complete = new Graph(size);
        // shuffle its edges
        Collections.shuffle(complete.getEdges());
    }

    public synchronized Edge extract() {
        Edge edge = complete.getEdges().getFirst();
        complete.getEdges().removeFirst();
        return edge;
    }

    public boolean isEmpty(){
        return complete.getEdges().isEmpty();
    }
}

玩家职业:

public class Player implements Runnable{

    private String name;
    private Game game;
    private Graph graph = new Graph();
    private int points;
    private static final int THINKING_TIME = 20;

    public Player(String name) {
        this.name = name;
    }

    private boolean play() throws InterruptedException {
        Board board = game.getBoard();
        if (board.isEmpty()) {
            return false;
        }
        graph.add( board.extract() );
        System.out.println(name + ": " + graph);
        Thread.sleep(THINKING_TIME);

        if (graph.isSpanningTree()) { 
            game.setWinner(this);
        }

        return true;
    }

    public void setPoints(int points) {
        this.points = points;
    }

    public int getPoints() {
        return points;
    }

    public Game getGame() {
        return game;
    }

    public void setGame(Game game) {
        this.game = game;
    }

    public void run(){
        try {
            play();
        } catch (InterruptedException e){
            System.out.println("error: " + this.name + "'s turn was interrupted");
        }
    }
}

我只包括了该问题的相关课程

1 个答案:

答案 0 :(得分:-1)

简化任务,

  • 我们有一个董事会和一群玩家,并且

  • 我们只需要按照给定的顺序逐个让该板上的玩家: 一个人进入,移动,离开,然后只有下一个人才能出发。

面板看起来很像共享资源,因此我们绝对必须在其上同步过程。

董事会什么都不做,但是玩家却做。因此,玩家将等待通知。  玩家

  • 可以定义是否轮到自己了

  • 等待,如果不是(按字面意思)-其他一些等待玩家可以尝试

  • 然后在董事会上采取行动,离开(同情est 通知所有感兴趣的各方以继续尝试)

这是一个简短的示例,其中董事会自行管理队列。它可运行,但不能解决您的精确任务。只是说明这个想法。

    public class Game {

    private static class PlayBoard {

        private int movesLeft;
        private List<Player> players;
        private int playerToMove;

        PlayBoard(int movesLeft) {
            this.movesLeft = movesLeft;
        }

        void setParties(Player... players) {
            this.players = Arrays.asList(players);
            this.players.forEach((Player player) -> player.prepareForGame(this));
            playerToMove = 0;
        }

        boolean isActive() {
            return movesLeft > 0;
        }

        boolean canIMove(Player player) {
            return players.get(playerToMove) == player;
        }

        void takeMove(Player player) {
            playerToMove = players.indexOf(player);
            movesLeft--;
            System.out.printf("%s's making move. %d moves left\n", player.name, movesLeft);
            playerToMove = (playerToMove + 1) % players.size();
        }
    }

    private static class Player {

        private final String name;
        private PlayBoard playBoard;

        Player(String name) {
            this.name = name;
        }

        void prepareForGame(PlayBoard playBoard) {
            this.playBoard = playBoard;
        }

        void play() {
            synchronized (playBoard) {
                while (playBoard.isActive()) {
                    if (playBoard.canIMove(this)) {
                        playBoard.takeMove(this);
                        playBoard.notifyAll();
                    } else {
                        try {
                            playBoard.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        PlayBoard playBoard = new PlayBoard(12);
        playBoard.setParties(new Player("Lea"),
                             new Player("Susan"),
                             new Player("Daria"));

        List<Thread> threads = playBoard.players.stream()
            .map(player -> new Thread(player::play))
            .collect(Collectors.toList());

        threads.forEach(Thread::start);
        for (Thread thread : threads) {
            thread.join();
        }
    }
}