I am writing a custom Rock in GridWorld. However when, I run the following code:
for(int i = 0;i<7;i++){
Grid<Actor> g = getGrid();
Location l = getLocation();
int x = l.getCol();
int y = l.getRow();
switch(i){
case 0:
Location l1 = new Location(x-1,y-1);
Actor a = g.get(l1);
if((a.toString()).equals("Infectious Rock")){
}else if((a.toString()).equals("Infectious Bug")){
}else{
a.removeSelfFromGrid();
}
break;
(This is repeated 7 more times with different variables and different coordinates)
Here is the NPE:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at infectiousRock.act(infectiousRock.java:18)
Does anyone know what is causing this?
You first have to check if the Actor you get from calling g.get(1l) exists or not. There is a simple fix to this, change your current if statement to:
if(a != null) {
if((a.toString()).equals("Infectious Rock")){
}else if((a.toString()).equals("Infectious Bug")){
}else{
a.removeSelfFromGrid();
}
} else
break;
Adding the extra !=null check should do the trick, and if not leave a comment and I'll do my best to update the answer.
Related
I get a Null Pointer Exception, and the trace tells me it is inside a function that I have. This function runs every frame and does some calculations and stuff. Anyway, the problem is that when I go to debug, stepping through each line, the function runs fine, and the error only comes up at the end of the draw loop.
This error only recently came up, and the changes I made don't have much to do with the function in question so...
The function mentioned in the trace detects if the object touches something, and acts on it.
Also, the trace gives a line number that does not exist, I'm guessing that's because of the Processing compiling.
I am using Processing 4 if that matters.
Here's the trace:
java.lang.NullPointerException
at ants$Ant.sense(ants.java:190)
at ants$Ant.go(ants.java:220)
at ants.draw(ants.java:44)
at processing.core.PApplet.handleDraw(PApplet.java:2201)
at processing.awt.PSurfaceAWT$10.callDraw(PSurfaceAWT.java:1422)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:354)
Thanks!
Edit:
More info: This is an ant simulator, and it crashes at food pickup. This used to work and broke while adding (seemingly) unrelated stuff. It crashes at food pickup, which is managed by the sense() function. The Food class only has a position and a render function.
Here is some code:
void sense() { // The problematic function
if (!detectFood && !carryFood) {
float closest = viewRadius;
Food selected = null;
for (Food fd : foods){
float foodDist = position.dist(fd.position);
if(foodDist <= viewRadius) {
if(foodDist < closest) {
selected = fd;
closest = foodDist;
}
}
}
if (selected != null){
detectFood = true;
foodFocused = selected;
}
} else {
if(position.dist(foodFocused.position) < 2*r) {
takeFood();
detectFood = false;
}
}
}
void draw() { // draw loop
background(51);
for (Food food : foods) {
food.render();
}
for (Ant ant : ants) {
ant.go();
}
for (int i=0; i < trails.size(); i++) {
Trail trail = trails.get(i);
if (trail.strenght <= 0)
trails.remove(trail);
else
trail.go();
}
}
The problem is not the trail, as it still crashes without it,
I'm trying to use join_facet() iteratively to grow a single facet starting from a given facet_handle. However, I'm running into trouble when using the Halfedge_around_facet_circulator in combination with join_facet(). My while-loop does not become false anymore which works fine if I don't use join_facet() and the circulator seems to point to something else.
I assume that the join operation is somehow changing that Halfedge_around_facet_circulator. But why and how to solve this?
Polyhedron P_out; // is a valid pure triangle Polyhedron
bool merge_next = true;
while (merge_next == true) {
Polyhedron::Halfedge_around_facet_circulator hit = facet_handle->facet_begin(); // facet_handle pointing to facet of P_out
merge_next = false;
do {
if(!(hit->is_border_edge())) {
if (coplanar(hit->facet(), hit->opposite()->facet())) {
if (CGAL::circulator_size(hit->opposite()->vertex_begin()) >= 3 && CGAL::circulator_size(hit->vertex_begin()) >= 3
&& hit->facet()->id() != hit->opposite()->facet()->id()) {
Polyhedron::Halfedge_handle hit2 = hit;
P_out->join_facet(hit2);
merge_next = true;
}
}
}
} while (++hit != facet_handle->facet_begin());
}
What this code should do:
Given the facet_handle, iterate over the corresponding halfedges of facet and merge if possible. Then taking facet_handle of created new facet again and doing the same until no neighboring facets are left to merge.
Edit:
There are areas on which the code runs fine and others where it crashes at hit->is_border_edge() after the first join_facet().
In the sample below, the function should return a non-null data.
Since the data could be changed in the process, it needs to be var, and can only be nullable to start with.
I can't use lateinit because the first call of if (d == null) will throw.
After the process it will be assigned a non-null data, but the return has to use the !! (double bang or non-null assertion operator).
What is the best approach to avoid the !!?
fun testGetLowest (dataArray: List<Data>) : Data {
var d: Data? = null
for (i in dataArray.indecs) {
if (d == null) {// first run
d = dataArray[i]
} else if {
d.level < dataArray[i].level
d = dataArray[i]
}
}
return d!!
}
If you don't like !! then supply a default value for it. You'll realize you can only supply the default value if the list is not empty, but, as you said, the list is already known to be non-empty. The good part of this story is that the type system doesn't track list size so when you say dataArray[0], it will take your word for it.
fun testGetLowest(dataArray: List<Data>) : Data {
var d: Data = dataArray[0]
for (i in 1 until dataArray.size) {
if (d.level < dataArray[i].level) {
d = dataArray[i]
}
}
return d
}
Normally, you can and should lean on the compiler to infer nullability. This is not always possible, and in the contrived example if the inner loop runs but once d is non-null. This is guaranteed to happen if dataArray has at least one member.
Using this knowledge you could refactor the code slightly using require to check the arguments (for at least one member of the array) and checkNotNull to assert the state of the dataArray as a post-condition.
fun testGetLowest (dataArray: List<Data>) : Data {
require(dataArray.size > 0, { "Expected dataArray to have size of at least 1: $dataArray")
var d: Data? = null
for (i in dataArray.indecs) {
if (d == null) {// first run
d = dataArray[i]
} else if {
d.level < dataArray[i].level
d = dataArray[i]
}
}
return checkNotNull(d, { "Expected d to be non-null through dataArray having at least one element and d being assigned in first iteration of loop" })
}
Remember you can return the result of a checkNotNull (and similar operators):
val checkedD = checkNotNull(d)
See Google Guava's Preconditions for something similar.
Even if you were to convert it to an Option, you would still have to deal with the case when dataArray is empty and so the value returned is undefined.
If you wanted to make this a complete function instead of throwing an exception, you can return an Option<Data> instead of a Data so that the case of an empty dataArray would return a None and leave it up to the caller to deal with how to handle the sad path.
How to do the same check, and cover the empty case
fun testGetLowest(dataArray: List<Data>)
= dataArray.minBy { it.level } ?: throw AssertionError("List was empty")
This uses the ?: operator to either get the minimum, or if the minimum is null (the list is empty) throws an error instead.
The accepted answer is completly fine but just to mentioned another way to solve your problem by changing one line in your code: return d ?: dataArray[0]
I a writing a program using RobotC for the Lego NXT to imitate the behaviour of a puppy. This section of code is supposed to rotate the head which is connected to motor port 3 and read the value on the ultra sonic sensor. If while the head is turned, the dog is called, it will turn in the direction it was already facing. The following function is called when the ultrasonic sensor reads a value (meaning the robot has come close to a wall):
visible
void SonarSensor()
{
int sensorValleft;
int sensorValright;
bool alreadyTurned = false;
int i,j;
i = 0;
j = 0;
motor[1] = 0;
motor[2] = 0;
motor[3] = -SPEED/2;
wait10Msec(15);
motor[3] = 0;
sensorValleft = SensorValue[3];
while(i<100)
{
if(SensorValue[4] > 40)//calibrate sound sensor
{
//turn left
motor[1]=SPEED;
motor[2] = -SPEED;
wait10Msec(25);
i = 1000;
j = 1000;
alreadyTurned = true;
}
else
{
i++;
wait1Msec(5);
}
}
motor[3] = SPEED/2;
wait10Msec(30);
motor[3] = 0;
sensorValright = SensorValue[3];
while(j<100)
{
if(SensorValue[3] > 1)//calibrate sound sensor
{
//turn right
motor[1]-=SPEED;
motor[2] = SPEED;
wait10Msec(25);
j = 1000;
alreadyTurned = true;
}
else
{
j++;
wait1Msec(5);
}
}
if(alreadyTurned == false)
{
if(sensorValleft > sensorValright)
{
//turn left
motor[1]=SPEED;
motor[2] = -SPEED;
wait10Msec(25);
}
else
{
//turn right
motor[1]=-SPEED;
motor[2] = SPEED;
wait10Msec(25);
}
}
}visible
When the head (motor[3]) rotates the first time the error 0002EA Type2 appears on the NXT screen. At first we thought it was because we were over-rotating the motor causing it to be obstructed so we tried to play around with the wait times but it made no difference.
Any ideas on what causes this error or how to fix it would be appreciated.
Thanks,
Dominique
The answer as to why only motor[3] causes an error is actually quite simple. The motorA, motorB, and motorC values are defined in an enum, where motorA=0, motorB=1, and motorC=2. So, motor[1] and motor[2] are equivalent to calling motor[motorB] and motor[motorC]. However, motor[3] isn't equivalent to anything. It's trying to set the power of a motor that doesn't exist. motor[0] would be ok, however, and would correspond to motor[motorA].
While debugging, I started putting break points in to see where the error was and it alwas occurred on the line motor[3] = -SPEED/2; it turns out that with the third motor the proper syntax is to use motor[motorA]=-SPEED/2;. I am not sure why only this motor returns this error as I am using two other motors which I set new speeds using
motor[1]=SPEED;
motor[2]=SPEED;
However, this was the way to abolish the error.
I'm messing around with the PushSource sample filter shipped with the DirectShow SDK and I'm having the following problem:
When I call IMediaControl::Run(), it returns S_FALSE which means "the graph is preparing to run, but some filters have not completed the transition to a running state". MSDN suggests to then call IMediaControl::GetState() and wait for the transition to finish.
And so, I call IMediaControl::GetState(INFINITE, ...) which is supposed to solve the problem.
However, to the contrary, it returns VFW_S_STATE_INTERMEDIATE even though I've specified an infinite waiting time.
I've tried all three variations (Bitmap, Bitmap Set and Desktop) and they all behave the same way, which initially lead me to believe there is a bug in there somewhere.
However, then, I tried using IFilterGraph::AddSourceFilter to do the same and it did the same thing, which must mean it's my rendering code that is the problem:
CoInitialize(0);
IGraphBuilder *graph = 0;
assert(S_OK == CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&graph));
IBaseFilter *pushSource = 0;
graph->AddSourceFilter(L"sample.bmp", L"Source", &pushSource);
IPin *srcOut = 0;
assert(S_OK == GetPin(pushSource, PINDIR_OUTPUT, &srcOut));
graph->Render(srcOut);
IMediaControl *c = 0;
IMediaEvent *pEvent;
assert(S_OK == graph->QueryInterface(IID_IMediaControl, (void**)&c));
assert(S_OK == graph->QueryInterface(IID_IMediaEvent, (void**)&pEvent));
HRESULT hr = c->Run();
if(hr != S_OK)
{
if(hr == S_FALSE)
{
OAFilterState state;
hr = c->GetState(INFINITE, &state);
assert(hr == S_OK );
}
}
long code;
assert(S_OK == pEvent->WaitForCompletion(INFINITE, &code));
Anyone knows how to fix this?
IBaseFilter *pushSource = 0;
graph->AddSourceFilter(L"sample.bmp", L"Source", &pushSource);
AddSourceFilter adds a default source filter, I don't think it will add your pushsource samplefilter.
I would recommend to add the graph to the ROT, so you can inspect it with graphedit.
And what happens if you don't call GetState()?
hr = pMediaControl->Run();
if(FAILED(hr)) {
/// handle error
}
long evCode=0;
while (evCode == 0)
{
pEvent->WaitForCompletion(1000, &evCode);
/// other code
}
Open GraphEditPlus, add your filter, render its pin and press Run. Then you'll see states of each filter separately, so you'll see what filter didn't run and why.