OK so I have this HashMap
private Map<String, Player> players = new HashMap<String, Player>();
Here is what I use to remove:
public void destroy() {
players.remove("Red");
os.println(me.getUsername() + "|1|has left|yes|chat");
}
I say Red because it's just a TEST right now. I will get the eventual correct one later. Anyways...
I use THIS to check.
if (e.getKeyCode() == KeyEvent.VK_Q) {
for (Player playert : players.values()) {
c.append("\n < "+playert.getUsername() + " > ");
}
}
When I'm all by myself.. I press Q and I get:
< Dan >
then my friend Red logs in and I Press Q... I get:
< Dan >
< Red >
then he leaves I press Q and I get:
< Dan >
< Red >
So.. how come this isn't working?
Also, here is the code that gets called in init() when a player logs in the game (starts the applet)
public void playerLogin() throws IOException {
Random roll = new Random();
int newNo = roll.nextInt(200);
// me.getUsername() = "Guest #" + roll.nextInt(110);
// String me.getUsername() = getParameter("name");
me = new Player();
me.setUsername(getParameter("name"));
me.setPlayerImage(ImageIO.read(getClass().getResource("me.gif")));
me.setX(256);
me.setY(256);
me.setMap(1);
me.setCommand("move");
players.put(me.getUsername(), me);
repaint();
System.out.println(me.getUsername() + " was added. player: " + me);
os.println(me.getUsername() + "|" + me.getX() + "|" + me.getY() + "|"
+ me.getMap() + "|" + me.getCommand());
attack = 4;
defense = 5;
gold = 542;
level = 1;
exp = 53;
}
In other words, your Applet#destroy() method is not called at the moment you expect it is called? You should use Applet#stop(). The destroy() is only called when the object in question is eligible for GC and/or when the whole browser instance is been closed (and thus not only the current page/tab). JVM may namely keep running as long as the browser instance runs.
When you hit Q... you are checking the contents of players but where is your call to destroy()? Do you explicitly call destroy() anywhere in your code?
Related
I am trying to add a header to the beginning of each page in Java. I am printing my console output to a file as well. All of the examples I can find are for PDF files but I need to print to a text file for later data transfer and use iText which I cannot use. Any suggestions would be awesome. Here is how I am printing so far:
PrintStream out = new PrintStream(new FileOutputStream("example.txt"));
System.setOut(out);
I'm assuming you're going to use fixed-width characters (anything else would be significantly more complicated..)
Here is a naive implementation, you can tweak it from here. I think it works pretty decently but you should test it thoroughly, also handle the case when a word is longer than a line and maybe a better exception for when a header is longer than the page:
public class PagePrinter {
private final PrintStream printer;
private final int pageWidth;
private final int pageLength;
private int currWidth = 0;
private int currLine = 0;
private int currPage = 1;
private boolean inPageHeader = false;
/**
* #param printer
* - print stream to print to
* #param pageWidth
* - in characters
* #param pageLength
* - in lines, includes the length of the header
*/
public PagePrinter(PrintStream printer, int pageWidth, int pageLength) {
this.printer = printer;
this.pageLength = pageLength;
this.pageWidth = pageWidth;
}
public void print(String str) {
// replace tabs with spaces
// may need to replace other chars that don't translate to 1 char when printed
str = str.replace("\t", " ");
// split would drop a trailing delimiter so concat extra
String[] lines = str.concat("\r\n#").split("\\r?\\n");
// print first
printWords(lines[0]);
// print rest excluding the extra
for (int i = 1; i < lines.length - 1; i++) {
// re-add delimiter (but keeping track of its affect on the page)
newline();
printWords(lines[i]);
}
}
private void printWords(String str) {
// split would drop a trailing delimiter so concat extra
String[] words = str.concat(" #").split(" ");
printWord(words[0]);
for (int i = 1; i < words.length - 1; i++) {
// re-add delimiter (but keeping track of its affect on the page)
if (currWidth < pageWidth) {
printer.print(" ");
currWidth++;
}
printWord(words[i]);
}
}
/** The smallest unit of appending to the document, */
private void printWord(String word) {
// determines when to print a header
if (currLine == 0 && !inPageHeader) {
printPageHeader();
}
int remainingSpaceOnLine = pageWidth - currWidth;
if (word.length() < remainingSpaceOnLine) {
printer.print(word);
currWidth += word.length();
} else if (word.length() < pageWidth) {
newline();
printWord(word);
} else {
// FIXME word is longer than the page width
// maybe split it with a hyphen and addWord() the parts
throw new RuntimeException("Word '" + word + "' is longer than line!");
}
}
public void newline() {
currLine++;
if (currLine >= pageLength) {
newPage();
} else {
currWidth = 0;
printer.println();
}
}
public void newPage() {
if (inPageHeader) {
throw new RuntimeException("Page header is longer than the page!!!");
}
currWidth = 0;
currLine = 0;
currPage++;
printer.println();
}
private void printPageHeader() {
inPageHeader = true;
myPageHeader();
inPageHeader = false;
}
protected void myPageHeader() {
print("----- Page " + currPage + " -----\n");
}
public static void main(String[] args) {
PagePrinter test = new PagePrinter(System.out, 40, 10);
test.print("\tThis is the song that never ends. Yes, it goes on and on my friend. "
+ "Some people started singing it not knowing what it was "
+ "and they'll continue singing it forever just because..."
+ "\n\tThis is the song that never ends. Yes, it goes on and on my friend. "
+ "Some people started singing it not knowing what it was "
+ "and they'll continue singing it forever just because..."
+ "\n\tThis is the song that never ends. Yes, it goes on and on my friend. "
+ "Some people started singing it not knowing what it was "
+ "and they'll continue singing it forever just because.."
+ "\n\tThis is the song that never ends. Yes, it goes on and on my friend. "
+ "Some people started singing it not knowing what it was "
+ "and they'll continue singing it forever just because...");
test.newPage();
test.print("This is a new page!");
test.newline();
test.print("This is a newline even though part would've fit on the previous!");
}
}
I have a problem with the execution of the methods in a for loop. I want my program to execute the programmedMoving() method 5 times.
This programmedMoving() method consists of two methods:
the first one ( chooseTheDirection() ) executes some algorithm and returns the Point2D towards which the object should move;
the second one ( moveToThePoint() ) should get this point and move the object.
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_H) {
for(int i=0; i<5; i++{
programmedMoving();
}
}
}
//////////////////////////////////////////////////////////////////
private void programmedMoving(){
chooseTheDirection(); //returns the Point2D
moveToThePoint();//according to the direction starts moving the point
}
The problem is that it executes chooseTheDirection() method 5 times without waiting for the moveToThePoint() method to finish it's execution. So, by the time the object on the JPanel starts actually moving, the chooseTheDirection() method already provides 5 Point2D points, whereas I need it to provide only one, and wait for the end of the next method.
Could anyone tell me what am I doing wrong? Thank you.
ADDITIONALLY:
private Direction chooseDirection(){
final List<Direction> directionList = Collections.unmodifiableList(Arrays.asList(Direction.values()));
int pick = random.nextInt(directionList.size());
dir = directionList.get(pick);
directionsArchive.add(dir);
System.out.println("dir " + dir + " " + directionsArchive);
if(directionsArchive.size() == 1){
dir = directionsArchive.get(0);
System.out.println("equal to one taken " + dir + " size of dir " + directionsArchive.size());
directionsArchive.add(dir);
}
if(directionsArchive.size() > 1){
int last = directionsArchive.size()-1;
System.out.println("index of last " + last);
if(directionsArchive.get(last).equals(dir)){
pick = random.nextInt(directionList.size());
dir = directionList.get(pick);
directionsArchive.add(dir);
}
System.out.println("more than one taken " + dir + " size of dir " + directionsArchive.size());
directionsArchive.add(dir);
}
else{
directionsArchive.add(dir);
System.out.println(" size of dir " + directionsArchive.size());}
return dir;
}
private void moveToThePoint(){
if(dir.equals(Direction.NORTH)){
this.robot.turnUp();
this.robot.go();
}
if(dir.equals(Direction.SOUTH)){
this.robot.turnDown();
this.robot.go();
}
if(dir.equals(Direction.EAST)){
this.robot.turnRight();
this.robot.go();
}
if(dir.equals(Direction.WEST)){
this.robot.turnLeft();
this.robot.go();
}
}
// SOME EXAMPLES TO THE MOVING METHODS. I PROVIDED ONLY ONE, CAUSE THEY ARE PRETTY SIMILAR
public void turnDown()
{
//System.out.println("Robot - Turn Down!");
this.m_nXDir = 0;
this.m_nYDir = 1;
}
public void go()
{
this.m_nStep = 1;
//System.out.println("Robot - Go!");
}
public void move(int d, int e)
{
//from start to finish
int x = d + this.m_nStep * this.m_nXDir;
int y = e + this.m_nStep * this.m_nYDir;
int w = getWidth();
int h = getHeight();
setBounds(x, y, w, h);
}
moveToThePoint doesn't actually move the object, it merely sets the step size to 1. I assume the actual move() function is called on a timer.
Here are 2 suggestions on how to fix it:
Re-run the decision algorithm (programmedMoving) for every step.
or
Queue up future moves. You store a queue of future moves for the object, and each times it is scheduled to move() you remove the next move from the queue and execute it.
I have for the past few days been trying to get an example of the state pattern working. The task has been set as part of the module for the master course ive been doing. I did find a thread on here that used the same example however, in my opinion doesnt do it correctly, as the program should work with any sort of test criteria which i am trying to do. Thread here: state design pattern . I have narrowed it down to, i believe the if-statement in the normal state class, so ive cut out the set/getters for the state and ammo, however i can add it in later if they are needed
At the moment it is completing the first assertEquals perfectly fine, however one it goes to the second it throws a nullpointexception. SO my question is, what have i done wrong, or missed out, with the if-statement to return a nullpointexception for the second part of the if-statement? and the sarky reply i got wasn't helpful, as all i want is a fresh pair of eyes to look over what I have done to find the mistake, not to do my entire assignment as i just need a little bit of help to fix this small problem. Also I already knew what a NPE and in this case its happening because the 2nd part of the statement is not being initialised with the criteria specified.
Thank You in advance
public class Railgun {
static int MAX_AMMO = 10;
public String fire(Point p, int round){
System.out.println(p + " " + round);
// System.out.println("ASA W " + state.fire(p, round));
return state.fire(p, round);
}
}
Fire method in the normal state:
public String fire(Point p, int round) {
// NormalState normal = new NormalState();
NeedAmmoState needAmmo = new NeedAmmoState();
System.out.println("akhdka " + round);
ammo-= round;
int round1 = round;
int result1 = 0 + round1;
if(ammo >= 0 && result1 == round1)
{
System.out.println(result1);
return "Fire order: Success "+ result1 + "/" + round1;
}
else if((ammo < 0) && (ammo != -result1))
{
railgun.ammo = 0;
return "Fire order: Partial success " + result1 + "/" + round1;
}else
{ System.out.println("Fail: " + ammo);
railgun.setState(needAmmo);
return "Fire order: Failure "+ result1 + "/" + round1;
}
}
Junit Test:
public void testFire() {
final Railgun railgun = new Railgun();
final int numRounds = 6;
final int x = 100;
final int y = 340;
// This fire mission should be completely successful
String actualResult = railgun.fire(new Point(x, y), numRounds);
String expectedResult = "Fire order: Success 6/6";
System.out.println("ASAS " + actualResult);
assertEquals(expectedResult, actualResult);
// This fire mission should be partially successful
actualResult = railgun.fire(new Point(x, y), numRounds);
//System.out.println(actualResult);
expectedResult = "Fire order: Partial success 4/6";
assertEquals(expectedResult, actualResult);
// This fire mission should fail
actualResult = railgun.fire(new Point(x, y), numRounds); expectedResult = "Fire order: Failure 0/6";
assertEquals(expectedResult, actualResult);
// Check state change to NeedAmmo state
assertEquals(railgun.getState().getClass(), NeedAmmoState.class);
}
Is it possible to convert the function go into the non-recursive function? Some hints or a start-up sketch would be very helpful
public static TSPSolution solve(CostMatrix _cm, TSPPoint start, TSPPoint[] points, long seed) {
TSPSolution sol = TSPSolution.randomSolution(start, points, seed, _cm);
double t = initialTemperature(sol, 1000);
int frozen = 0;
System.out.println("-- Simulated annealing started with initial temperature " + t + " --");
return go(_cm, sol, t, frozen);
}
private static TSPSolution go(CostMatrix _cm, TSPSolution solution, double t, int frozen) {
if (frozen >= 3) {
return solution;
}
i++;
TSPSolution bestSol = solution;
System.out.println(i + ": " + solution.fitness() + " " + solution.time() + " "
+ solution.penalty() + " " + t);
ArrayList<TSPSolution> nHood = solution.nHood();
int attempts = 0;
int accepted = 0;
while (!(attempts == 2 * nHood.size() || accepted == nHood.size()) && attempts < 500) {
TSPSolution sol = nHood.get(rand.nextInt(nHood.size()));
attempts++;
double deltaF = sol.fitness() - bestSol.fitness();
if (deltaF < 0 || Math.exp(-deltaF / t) > Math.random()) {
accepted++;
bestSol = sol;
nHood = sol.nHood();
}
}
frozen = accepted == 0 ? frozen + 1 : 0;
double newT = coolingSchedule(t);
return go(_cm, bestSol, newT, frozen);
}
This is an easy one, because it is tail-recursive: there is no code between the recursive call & what the function returns. Thus, you can wrap the body of go in a loop while (frozen<3), and return solution once the loop ends. And replace the recursive call with assignments to the parameters: solution=bestSol; t=newT;.
You need to thinkg about two things:
What changes on each step?
When does the algorithm end?
Ans the answer should be
bestSol (solution), newT (t), frozen (frozen)
When frozen >= 3 is true
So, the easiest way is just to enclose the whole function in something like
while (frozen < 3) {
...
...
...
frozen = accepted == 0 ? frozen + 1 : 0;
//double newT = coolingSchedule(t);
t = coolingSchedule(t);
solution = bestSol;
}
As a rule of thumb, the simplest way to make a recursive function iterative is to load the first element onto a Stack, and instead of calling the recursion, add the result to the Stack.
For instance:
public Item recursive(Item myItem)
{
if(myItem.GetExitCondition().IsMet()
{
return myItem;
}
... do stuff ...
return recursive(myItem);
}
Would become:
public Item iterative(Item myItem)
{
Stack<Item> workStack = new Stack<>();
while (!workStack.isEmpty())
{
Item workItem = workStack.pop()
if(myItem.GetExitCondition().IsMet()
{
return workItem;
}
... do stuff ...
workStack.put(workItem)
}
// No solution was found (!).
return myItem;
}
This code is untested and may (read: does) contain errors. It may not even compile, but should give you a general idea.
I am writing the code in Java as a plugin to a Minecraft server, but the logical principles are general in nature.
public void doReviewMember(CommandSender playerSent) {
if (!reviewsMember.isEmpty()) {
Review doThis = null;
ArrayList<Review> players = new ArrayList<Review>();
ArrayList<Review> playersVIP = new ArrayList<Review>();
ArrayList<Review> playersVIPplus = new ArrayList<Review>();
for (int c1 = 0; c1 < reviewsMember.size(); c1++) {
if (Bukkit.getPlayer(reviewsMember.get(c1).getName()).hasPermission("reviewplugin.vipplus"))
playersVIPplus.add(reviewsMember.get(c1));
else if (Bukkit.getPlayer(reviewsMember.get(c1).getName()).hasPermission("reviewplugin.vip"))
playersVIP.add(reviewsMember.get(c1));
else players.add(reviewsMember.get(c1));
}
if (playersVIPplus.size() > 0)
doThis = playersVIPplus.get(0);
else if (playersVIP.size() > 0)
doThis = playersVIP.get(0);
else doThis = players.get(0);
Bukkit.getPlayer(playerSent.getName()).sendMessage("§4[§6ReviewPlugin§4] §eThis review is for §b" + doThis.getName());
Bukkit.getPlayer(playerSent.getName()).teleport(doThis.getLocation());
reviewsMember.remove(doThis);
if (reviewsMember.size() > 1)
Bukkit.getPlayer(playerSent.getName()).sendMessage("§4[§6ReviewPlugin§4] §eThere are " + reviewsMember.size() + " member reviews left to do.");
else if (reviewsMember.size() == 1)
Bukkit.getPlayer(playerSent.getName()).sendMessage("§4[§6ReviewPlugin§4] §eThere is " + reviewsMember.size() + " member review left to do.");
else
Bukkit.getPlayer(playerSent.getName()).sendMessage("§4[§6ReviewPlugin§4] §eThere are no more Member reviews to do at this time!");
}
else {
Bukkit.getPlayer(playerSent.getName()).sendMessage("§4[§6ReviewPlugin§4] §eThere are no more Member reviews to do at this time!");
}
}
The index out of bounds error was occurring in the for loop, so I have no idea where I am going wrong. This was tested w/o error on a Windows 8 machine but when implemented into a Linux it failed every time with the index out of bounds error.
The above code cannot fail unless some background thread modifies the array in the middle of the loop. Which is most likely the reason for your problem.