我应该如何为游戏实施等待通知方法?
How should I implement a wait-notify approach for a game?
我必须实现一个三人游戏。我有 classes:玩家、游戏、棋盘和边缘。棋盘是一个完整的图,每个玩家都必须提取一条边。当图变成生成树时,玩家获胜。我用线程实现游戏,但我无法弄清楚我应该如何实现等待通知 approach.The 在互联网上找到的示例仅显示两个线程。等待应该在 运行 方法中,或者我应该为 wait() 和 notify() 创建一个新方法?我应该在游戏 class 中有一个 运行 方法?或者只是在玩家 class?
游戏Class:
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();
}
}
}
棋盘Class:
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();
}
}
玩家Class:
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");
}
}
}
我只包括了这个问题的相关 classes
简化任务,
我们有一个棋盘和一个玩家队列,并且
我们只需要让玩家按照给定的顺序一个接一个地在这个棋盘上:
一进一出,一进一出,后人方可登船。
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();
}
}
}
我必须实现一个三人游戏。我有 classes:玩家、游戏、棋盘和边缘。棋盘是一个完整的图,每个玩家都必须提取一条边。当图变成生成树时,玩家获胜。我用线程实现游戏,但我无法弄清楚我应该如何实现等待通知 approach.The 在互联网上找到的示例仅显示两个线程。等待应该在 运行 方法中,或者我应该为 wait() 和 notify() 创建一个新方法?我应该在游戏 class 中有一个 运行 方法?或者只是在玩家 class?
游戏Class:
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();
}
}
}
棋盘Class:
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();
}
}
玩家Class:
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");
}
}
}
我只包括了这个问题的相关 classes
简化任务,
我们有一个棋盘和一个玩家队列,并且
我们只需要让玩家按照给定的顺序一个接一个地在这个棋盘上: 一进一出,一进一出,后人方可登船。
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();
}
}
}