我该如何为游戏实施等待通知方法? [关闭]

问题描述 投票:1回答:1

我必须与三名球员一起实施一场比赛。我有课程:玩家,游戏,棋盘和边缘。棋盘是一个完整的图表,每个玩家必须提取优势。当图形成为生成树时,玩家获胜。我用线程实现游戏,但我无法弄明白我应该如何实现等待通知方法。在互联网上找到的例子只显示两个线程。等待应该是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");
        }
    }
}

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

java java-threads
1个回答
-1
投票

简化任务,

  • 我们有一个董事会和一队球员,和
  • 我们必须按照某个给定的顺序让一个玩家一个接一个地进入这个棋盘:一个进入,移动,离开,然后只有下面才能开始。

Board看起来非常像共享资源,因此我们必须在其上同步进程。

董事会什么都不做,但球员做了。所以玩家将等待并通知。一个玩家

  • 可以定义是否轮到你了
  • 等等(如果不是)(字面意思) - 另一个不等待的玩家可以尝试
  • 然后在董事会上离开并离开(id 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();
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.