This problem concerns the fourth requirement:
The run methods of all players who did not win (those who were interrupted) should display [getName() + ":lost"]. For example: [Gates:lost]
Validation seems to be broken - the requirement is listed as failed even though the output is correct. Here's the complete output (via println):
Gates:Start game Smith:Start game Gates:Gather resources Gates:Grow economy Smith:Gather resources Gates:Kill enemies Gates:won! Smith:lost Jones:lostThis is exactly what the requirement says. I also tried several obvious variations (blank after the colon, exclamation mark at the end and so on) but to no avail. Can anyone help? Side note: Jones never gets to make a move because Gates's rate is five times as high and so Gates makes the final move before Jones even starts. If l let everyone make a move before the first delay then first requirement is listed as failed (even though it says 'at regular intervals', not 'after regular delays' - which looks like a classical fence post error). P.S: I had the sneaking suspicion that the issue might be breaking the loop on isWinnerFound instead of waiting for interruption; however, removing the break condition and adding gamer.interrupt() to the post-game loop did not change anything. P.P.S.: my intuition regarding the missing interrupt was correct insofar as the interruption is necessary for the timely ending of the game (i.e. for pulling the losers out of Thread.sleep(). However, this doesn't change anything with regard to the fourth requirement failing.
package com.codegym.task.task16.task1627;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
public static void main(String[] args) throws InterruptedException {
OnlineGame onlineGame = new OnlineGame();
onlineGame.start();
}
public static class OnlineGame extends Thread {
public static volatile boolean isWinnerFound = false;
public static List<String> actions = new ArrayList<>();
static {
actions.add("Start game");
actions.add("Gather resources");
actions.add("Grow economy");
actions.add("Kill enemies");
}
protected Gamer gamer1 = new Gamer("Smith", 3);
protected Gamer gamer2 = new Gamer("Jones", 1);
protected Gamer gamer3 = new Gamer("Gates", 5);
public void run() {
gamer1.start();
gamer2.start();
gamer3.start();
while (!isWinnerFound) {
}
for (Gamer gamer : Arrays.asList(gamer1, gamer2, gamer3)) {
try {
gamer.interrupt();
gamer.join();
}
catch (InterruptedException ignored) {
}
}
}
}
public static class Gamer extends Thread {
private int rating;
public Gamer(String name, int rating) {
super(name);
this.rating = rating;
}
@Override
public void run() {
int delay = 1000 / rating;
for (String action : OnlineGame.actions) {
try {
Thread.sleep(delay);
}
catch (InterruptedException ignored) {
break;
}
if (OnlineGame.isWinnerFound) {
break;
}
synchronized (Solution.class) {
System.out.println(getName() + ":" + action);
}
}
synchronized (Solution.class) {
// synchronised for concurrent state manipulation
boolean playerLost = OnlineGame.isWinnerFound;
if (!playerLost) {
OnlineGame.isWinnerFound = true;
}
// synchronised for concurrent output
System.out.println(getName() + (playerLost ? ":lost" : ":won!"));
}
}
}
}