我必须与三名球员一起实施一场比赛。我有课程:玩家,游戏,棋盘和边缘。棋盘是一个完整的图表,每个玩家必须提取优势。当图形成为生成树时,玩家获胜。我用线程实现游戏,但我无法弄明白我应该如何实现等待通知方法。在互联网上找到的例子只显示两个线程。等待应该是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");
}
}
}
我只包括了这个问题的相关课程
简化任务,
Board看起来非常像共享资源,因此我们必须在其上同步进程。
董事会什么都不做,但球员做了。所以玩家将等待并通知。一个玩家
这是一个简短的例子,董事会自己管理队列。它可以运行,但不能解决您的确切任务。只是说明了这个想法。
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();
}
}
}