Swapping position of objects by Polymorphism - java

I am trying to solve an instance of Blockworld Problem. Basically an NxN Grid contains Blocks A, B, C and an Agent. Only the Agent can move, if on the way it encounter a Block, then their positions will be switched. For example, Agent(1, 0) goes left encounter a Block B(0, 0) then the new positions of the two would be Agent(0, 0) and B(1, 0).
Both my Agent and Block classes are subclass of Entity.
Here is my function swap(). It checks if after a move, the Agent is on the a Block, then the new Position of Block would be the previous position of the Agent.
I tried with (Block block : blockList) and it works, but not with the (Entity en : entityList) when I tried to use Polymorphism.
Can anyone spot the mistake I made please?
public void swap() {
for (Entity en : entityList) {
if (agent.position.equals(block.position) && (en instanceof Block)) {
System.out.print("Agent overlap block: " + en);
en.previousPosition = new Dimension(block.position.width, block.position.height);
en.setPosition(agent.previousPosition);
}
}
}

First Of All, you haven't told where did the "block" in the if statement came from.
What you may need to do, is:
public void swap(){
for(Entity en:entityList){
if((en instanceof Block)&&(en.position.equals(agent.position)){
// ^here is "en" instead of block
System.out.println("Agent overlab block: "+en);
en.previousPosition=new Dimension(
en.position.width,
en.position.height);
en.setPosition(agent.previousPosition);
}
}
}
At last, you may use java.awt.Point instead of Dimension.
Also, you should use setter method for the field "previousPosition".

Your problem is that your code does stuff if agent.position and block.position are equal; but in the example you talk about, agent.position and block.position are different. So your code is never actually making any changes.

Everywhere you use the block variable in the function, you need to change it with en since your for loop no longer creates a variable named block.
When you move entities around in this function, be careful that you don't accidentally try to swap the agent with itself!

Related

Moving all statements from one method to another

So I have a Method
public modifiers Foo foo(Bar bar){
blah;
blah;
veryInterestingStmt;
moreBlah();
return XYZ;
}
I now want to split this method s.t. everything in its body is extracted into a separate method (programmatically).
I.e.
public modifiers Foo foo(Bar bar){
return trulyFoo(bar);
}
public modifiers Foo trulyFoo(Bar bar){
blah;
blah;
veryInterestingStmt;
moreBlah();
return XYZ;
}
How do I do that, though?
The naive
private void fracture(SootMethod sm) {
SootClass sc = sm.getDeclaringClass();
String auxMethodName = sm.getName() + FRACTURE_SUFFIX;
Type auxReturnType = sm.getReturnType();
List<Type>auxParamTypes = new LinkedList<>(sm.getParameterTypes());
int auxModifiers = sm.getModifiers();
SootMethod auxMethod = sc.addMethod(new SootMethod(auxMethodName,auxParamTypes,auxReturnType,auxModifiers));
Body body = sm.getActiveBody();
Body auxBody = Jimple.v().newBody(auxMethod);
auxMethod.setActiveBody(auxBody);
for(Local l : body.getLocals()){
auxBody.getLocals().add(l);
}
PatchingChain<Unit> units = body.getUnits();
PatchingChain<Unit> auxUnits = auxBody.getUnits();
Iterator<Unit> it = body.getUnits().snapshotIterator();
boolean passedFirstNonidentity = false;
while(it.hasNext()){
Stmt stmt = (Stmt) it.next();
if(!passedFirstNonidentity && !(stmt instanceof IdentityStmt)) {
passedFirstNonidentity = true;
//TODO: if added more parameters than original method had, add their identity stmts here
}
auxUnits.add(stmt);
// if(passedFirstNonidentity) units.remove(stmt); //TODO: uncomment this and later add call to {#code auxMethod}
}
}
}
Doesn't work. If I run, say
DirectedGraph dg = new ExceptionalUnitGraph(auxMethod.getActiveBody());
I get a
java.lang.RuntimeException: Unit graph contains jump to non-existing target
at soot.toolkits.graph.UnitGraph.buildUnexceptionalEdges(UnitGraph.java:128)
at soot.toolkits.graph.ExceptionalUnitGraph.initialize(ExceptionalUnitGraph.java:258)
at soot.toolkits.graph.ExceptionalUnitGraph.<init>(ExceptionalUnitGraph.java:159)
at soot.toolkits.graph.ExceptionalUnitGraph.<init>(ExceptionalUnitGraph.java:192)
The technique of moving code without altering the behavior of the code is called Refactoring and is nicely covered in a book by Martin Fowler.
In your case, I would take the following multi-step approach:
Stand up a "do nothing" function in the function you wish to split, just above the lines of code you wish to move.
Move one or two of those lines of code from the surrounding function int the "do nothing" function, splitting the function, but having the split be a nested call.
Move the split function up (or down) to the edge of the block in the surronding function.
Move teh slpit function out of the block, placing new calls to it either prior to every call of the original function, or after every call of the original function. Note that you may have to rework the handling of return parameters, depending on the details.
It is strongly suggested that you write a set of tests to validate some, if not most, of the overall functionality of this block first. Then, after each change run your tests to verify that you didn't change behavior.
What you are seeing now is a change in behavior which came about by modifying the text of the code in such a manner that it did change behavior. The set of safe transformations of source code is likely smaller than you previously believed, or maybe you just made a simple error. However, the work you are attempting requires more knowledge than can be expressed in a StackOverflow style, question / answer, format. That's why I made the book reference.
If you can narrow the scope, you might get a better response in a future resubmission.
It seems that moving stmts just doesn't work. In contrast, completely replacing the body
Body originalBody = sm.getActiveBody();
originalBody.setMethod(auxMethod);
auxMethod.setActiveBody(originalBody);
Body newBody = Jimple.v().newBody(sm);
sm.setActiveBody(newBody);
and then regenerating the locals, identity stmts (and other stmts you may need) in the newBody looks like a sensible way to go.

Data Structures in 2D-Games with Multiplayer (Java)

I have following problem:
I've programmed a 2D Game with a multiplayer function. Right now i store others Player Data and GameObjects in two ArrayList (The world is stored otherwise). Sometimes the Network-Thread sends Updates, which can not be applied, because the Game draws the Players/Game Objects (java.util.ConcurrentModificationException). Because this drawing process happens every Second around 60 times (because of animations) the problem apeers often (every 2 seconds). This is the code for the players ArrayList:
Draw the Players:
for (Player p : oPlayer) {
if (p != null) {
int x = (int) ((width / 2) + (p.x - getPlayerX()) * BLOCK_SIZE);
int y = (int) ((height / 2) + (p.y - getPlayerY()) * BLOCK_SIZE);
g.drawImage(onlinePlayer, x, y, BLOCK_SIZE, BLOCK_SIZE, null);
FontMetrics fm = g.getFontMetrics();
g.setColor(Color.DARK_GRAY);
g.drawString(p.getName(), x + (BLOCK_SIZE / 2) - (fm.stringWidth(p.getName()) / 2), y - 5);
}
}
Edit Information in Network-Thread:
case "ADP": //add Player
Game.oPlayer.add(new Player(message, id));
sendX();
sendY();
break;
case "SPX": // set X
for (Player p : Game.oPlayer) {
if (p.getId() == id) {
p.setX(Short.parseShort(message));
break;
}
}
break;
case "SPY": // set Y
for (Player p : Game.oPlayer) {
if (p.getId() == id) {
p.setY(Short.parseShort(message));
break;
}
}
break;
case "PDI": // remove Player
for (Player p : Game.oPlayer) {
if (p.getId() == id) {
Game.oPlayer.remove(p);
break;
}
}
break;
Thank you in advance :)
What happens here is, that 2 Threads are working on the same list.
The first one is reading the List (for (Player p : oPlayer) {) and the second one is modifying it (Game.oPlayer.add(new Player(message, id));). This brings the oPlayer list into an (sort of) "inconsistent" state. Java sees that you modified something that you are reading and throws this exception to let you know, that something is not kosher.
More information about ConcurrentModificationExceptions can be found here
To clarify, you dipped into the so called Readers-writer problem. You have an reader (Thread), that reads the Data of Game.oPlayer and a writer (Thread) that writes data to Game.oPlayer.
Solutions
Synchronized-Keyword
The synchronized keyword is explained here. You would use it like this:
private final List<Player> players = ...;
public void addPlayer(Player player) {
synchronized(players) {
players.add(player);
}
}
public void removePlayer(Player player) {
synchronized(players) {
players.remove(player);
}
}
Note that the List has to bee final. Furhter i am using a local attribute instead of your static one. Remove players with Game.oPlayer to get a suited solution.
This allows only 1 thread to access players.add() and players.remove().
Lock
Informations about how to use Locks can be found here.
Easy said, you create a block like this:
try {
lock.lock();
// work ..
} finally {
lock.unlock();
}
so that only one thread can access the work part by saying lock.lock(). If any other thread locked the work part using lock.lock() and not unlocked it, the current thread will wait until lock.unlock() is called. The try-finall block is used, to assure, that the lock is unlocked, even if your work part is throwing an throwable.
Furhter i would recommend itterating over a "copy" of the player-list like this:
List<Player> toIterate;
synchronized(players) {
toIterate = new ArrayList<>(getPlayerList());
}
for(Player player : toIterate) {
// work
}
Or synchronizing this part completly like this:
synchronized(players) {
for(Player player : players) {
// work
}
}
The first one provides you with an copy of that instance, which basically means, it contains the same Objects as the original List, but it isn't the same List. It helps you by letting more threads work on there own "list" and finish theire jobs, regardless of updates at the current time, becaus the second example will block if:
Any thread wants to read the list.
Any thread modifies the list.
So you only have to synchronize the coppy part in the first example.
Even furhter (not particually part of your question, but still something that would make it easyer) i would recommend not using static, as you stated in Game.oPlayer.[...] and taking a look at Dependency Injection.
You could modify your Game-class to provide the methods addPlayer(Player player);, removePlayer(Player player); and getPlayerList(); to realy code in an Object Oriented fashion.
With that design, you could easyly modify your code, to handle the new concurrency issue.
If a list is iterated or modified in one thread and also in another thread you will get a ConcurrentModficationException. In general user interface applications restrict modifying model data to a single thread, usually the user interface thread, such as the event dispatch thread of Swing, or the platform thread in JavaFX.
As an aside, for JavaFX there exists a game library providing out of the box techniques for game development. JavaFX in general is much better suited for graphics intensive work than AWT or Swing.
Have you tried using Vector instead? It is part of Collection and is synchronized.

How do I resolve a NullPointerException on a JUNG graph?

So, basically this is what I have so far.
public List<String> cycleSearch(Graph<String,String> g) throws Exception{
List<String> list = null;
Graph<String,String> auxG = g;
for(String aux : g.getVertices()){
String aux2 = aux;
if(g.degree(aux)>1){
if(auxG.removeVertex(aux2)){
for(String d : g.getSuccessors(aux2)){
for(String a : g.getSuccessors(aux)){
if(a!=d){
list = findPath(auxG,d,a);
if(list!=null){
list.add(0,aux);
list.add(aux);
return list;
}
}
}
}
}
}
auxG = g;
}
return null;
}
What the method does is basically to search for a cycle in a hypergraph based on JUNG.
The idea it's to recieve a graph on the parameters and then create a variable (as the same type) to later remove a vertex from it without making any changes on the original graph, just in case a cycle isn't found. That way I can use a method called findPath(,,), once the vertex is removed. The method will 'create' another path without walking through the removed vertex.
My compiler says there is problem right here:
for(String d : g.getSuccessors(aux2))
I've been programming graphs in Java(JUNG) for only 1 month.
HELP
There is a bug in JUNG that this code has turned--getSuccessors() should be returning an empty collection if the graph does not have the vertex, rather than returning null, which is what SetHypergraph's implementation does. Sorry about that. (In general, you can avoid this by wrapping the getSuccessors(x) inside a containsVertex(x) if statement.)
However, the reason why you're encountering this bug is that you're doing at least a couple of things that do not make sense:
(1) you're assigning auxG to g (so they're referencing the same object); this is misleading and not helpful.
Similarly, you're assigning aux2 to aux, which is also misleading.
(2) you're removing aux[2] from auxG and then asking for aux2's successors in auxG. aux2 will not have any successors in auxG once it's removed.
(3) Since aux2 and aux are the same vertex, your innermost loop will also not do anything useful for the same reason; there will be no successors.
You need to rethink your entire algorithm, because this simply is not correct as designed.
Instead of using null to represnt no successors, you could just use an empty list, and thus avoid the NullPointerException. Replace return null; with return new LinkedList<>();.

How does recursion work here?

Recursion is a new practice for me and I am trying to get better at it and understand how the methods return. I have the following program but am unfailiar with how to use the this keyword. Can you please review the code and walk me through the program showing the values held by the variables as the methods execute?
I have tried numerous things to determine how the value answer in the compute method holds 14 after execution can anyone walk me through the first few recursive calls so I can try and figure out the rest?
public class Recurs1 {
public static void main (String [] arg) {
Recurs1 r = new Recurs1();
r.compute();
}
public void compute() {
int [] stuff = {1, 2, 3, 4};
int answer = this.go(stuff, 0);
System.out.println("The answer is " + answer);
}
private int go(int[] numbers, int spot) {
if (numbers.length == spot) return spot;
int value = this.go(numbers, spot + 1 );
return value + numbers[spot];
}
}
Ok so a few things I notice here:
The purpose of go() seems to be calculating the sum of the numbers in the array. If this is the case, your method should look like this:
private int go(int[] numbers, int spot) {
if (numbers.length - 1 == spot) return numbers[spot];
int value = this.go(numbers, spot + 1 );
return value + numbers[spot];
}
This is because numbers.length in this case will return 4, but the last element in this array is at index 3 (arrays are 0-indexed).
This way, when the function is called with the second parameter set to 3, it will return the value of the last element in the array and then the code will "bubble up" (as I like to call it) and calculate the sum of the elements by subsequently returning the current summed value + the value of the current call.
As for your problem with the this keyword, it's actually very simple. this always refers to the current class instance your code is in. In this case, you create a Recurs1 instance called r in your main function so whenever you call a method on that particular object, the this keyword used in those methods will refer to r. If you created multiple Recurs1 objects (each with potential different internal states) in your program, their respective this references would always point to themselves allowing you to access their member variables and methods.
Hope that helps and good luck, recursion is usually what most people have trouble getting their heads around at first but once you get used to it it's pretty cool!
OK so this is not an answer to your question per se, more like a lesson in recursion.
Keep in mind I have never tried to to do this with a java class.
Recursion means a function that calls itself repeatedly until a answer has been reached, or your function detects you are running out of stack space.
You first step into the function determines if you will call yourself.
When you call yourself you will push a new copy of the data onto the stack and begin executing. I think in the case of java you will allocate a new object into the heap ( don't quote me on this ) and each invocation will have a new set of variables that get populated with new values.
As you recurse deeper and deeper you simply allocate new copies of the object until you find the answer or run out of memory.
If you find the answer you then return the result to the previous level in the stack of objects eg:
int foo(int i ){
if(some condition){
return foo(i);
} else
return i
}
as You can see if the condition tests true the foo() keeps getting called. Now at each call, the variables of foo() are saved for as many levels deep as you go. If the condition tests false then each instance of foo() returns to the previous until you are at the original invocation of foo() which then returns to the caller of foo().
Clear as Mud?

Not using an if statement in Java

This is a very odd, and quite specific question.
Ultimately I am trying to write a program convert that takes in java source, and transforms it such that it does not use (Among other things)
Arrays
Loops
User defined methods
If statements
This is a challenge that I set for myself, after my teacher told me that it was impossible to write a program without using these things.
I have most of these worked out, including function inlining and array substitution, however I cannot work out how to manage an if statement.
In C++ I'd use labels and gotos and maybe ?:, however Java does not support GOTO statements.
My question is this:
Given a section of code,
if(CONDITION)
{
//More code in here
}
How can transform it such that it is functionally the same, however does not use the if keyword. Note that loop structures are also out of the question.
Given this, it would be easy to create else and else if statements.
However I am also unsure of how to create loops using this, as there is no GOTO statement and methods are out of the question.
Edit:
Please note that switches are also not allowed, nor is recursion (Ruled out by the fact that you cannot define user methods, and a recursive main function wouldn't work with every program)
The ?: operator does not work for all situations. AFAIK you cannot call a void function with ?: as it wants to assign a value as part of its operation.
These conditions come from the IB Computer Science SL requires course, I am taking HL and as a class we were laughing at the 'mastery' factors for SL which include 'if' statements (And if fact 3/15 of them are 'User defined methods with params and return types) The challenge is effectively to FAIL a mastery test in SL while still producing a program that functions correctly.
Answer: (By bdares)
String result = (CONDITION)?"0":"A";
try{
Integer.parseInt(result);
//Condition is true
} catch(NumberFormatException e){
//Condition is false
}
if(A) {
X();
}
else{
Y();
}
can be converted to:
A?X():Y();
You can nest these all you want, or simply remove one side of the : and get a simple if. The conditionals are easy.
If you want it to work for void methods, here's a way:
String result = A?"0":"A";
try{
Integer.parseInt(result);
X();
} catch(NumberFormatException e){
Y();
}
I'm not sure it's possible to write an entire useful program without using an if statement. However, I think what your teacher may be getting at is that you can write code to follow the same "logical" path by using a more object-oriented approach in place of an if statement. For example:
public interface Moveable {
void move(int x, int y);
}
public class Ball implements Moveable {
private int x;
private int y;
public void move(int x, int y) {
this.x = x;
this.y = y;
}
}
public class NullMoveable {
public void move(int x, int y) {
// Do nothing.
}
}
... and then in your main application code:
Moveable mv = new NullMoveable();
// Move object; don't care if it's a Ball or a NullMoveable
// so no need to explicitly check with an if-statement.
mv.move(10, 50);
The principle here is that the fewer possible paths there are in your code (due to if statements) the easier it is to test and maintain.
You can use the conditional operator and a switch:
switch( CONDITION ? 1 : 0 )
{
case 1:
//... true code
break;
case 0:
//... false code
break;
}
For the loops you can unroll your code to some predefined maximum and use labeled breaks to jump out of the unrolled code early based on some condition. You can use break to end any code block in Java not just loops.
The Java language has no goto but the Virtual Machine has it, so you could of course also generate JVM instructions directly although this would be not much different from a regular Java compiler which also translates all ifs an loops into jump instructions.
In some cases, you can use bit manipulation. For example:
if(x > 0) // positive number
{
isPositive = true;
}
else // negative number
{
isPositive = flase;
}
is equivalent to:
isPositive = (x >> 31) == 0;
EDIT:
This is just an example, of course you can do much more complex bit manipulation with one statement instead of doing it using bunch of if statements.
If you were allowed to use anonymous inner classes (these probably classify as user-defined methods, but I'll let you be the judge):
if(COND) {
X();
} else {
Y();
}
becomes:
ifReplacement(COND,
new Runnable() { public void run() { X();}},
new Runnable() { public void run() { Y();}});
with signature:
public static void ifReplacement(boolean condition,
Runnable ifBranch,
Runnable elseBranch)
Of course, JDK8 lambdas would make this much nicer:
ifReplacement(COND, ()->X(), ()->Y());

Categories

Resources