Thaumcraft4 - Golem Core "Harvest" - Bug with magic beans [closed] - java

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 months ago.
Improve this question
I've got a mana bean farm with different segments according of bean type each. There are golems with "Harvest" core and Ordo upgrade are harvesting them. They cannot reach the segments they are not bellongs. But sometimes I saw that in a neighbour segment is growing bean(s) with wrong aspect. In my case there are Vitium and Spiritus, but that is not important. Later I had an investigation of code and found something in it.
`
void harvest() {
this.count = 200;
final int md = this.blockMd;
final FakePlayer fp = FakePlayerFactory.get((WorldServer)this.theWorld, new GameProfile((UUID)null, "FakeThaumcraftGolem"));
fp.func_70107_b(this.theGolem.field_70165_t, this.theGolem.field_70163_u, this.theGolem.field_70161_v);
if (CropUtils.clickableCrops.contains(this.block.func_149739_a() + md)) {
this.block.func_149727_a(this.theWorld, this.xx, this.yy, this.zz, (EntityPlayer)fp, 0, 0.0f, 0.0f, 0.0f);
}
else {
this.theWorld.func_147480_a(this.xx, this.yy, this.zz, true);
if (this.theGolem.getUpgradeAmount(4) > 0) {
final ArrayList<ItemStack> items = new ArrayList<ItemStack>();
final ArrayList<Entity> drops = (ArrayList<Entity>)EntityUtils.getEntitiesInRange(this.theWorld, this.theGolem.field_70165_t, this.theGolem.field_70163_u, this.theGolem.field_70161_v, (Entity)this.theGolem, (Class)EntityItem.class, 6.0);
if (drops.size() > 0) {
for (final Entity e : drops) {
if (e instanceof EntityItem) {
if (e.field_70173_aa < 2) {
Vec3 v = Vec3.func_72443_a(e.field_70165_t - this.theGolem.field_70165_t, e.field_70163_u - this.theGolem.field_70163_u, e.field_70161_v - this.theGolem.field_70161_v);
v = v.func_72432_b();
e.field_70159_w = -v.field_72450_a / 4.0;
e.field_70181_x = 0.075;
e.field_70179_y = -v.field_72449_c / 4.0;
}
boolean done = false;
final EntityItem item = (EntityItem)e;
final ItemStack st = item.func_92059_d();
if (st.func_77973_b() != null && st.func_77973_b() == Items.field_151100_aR && st.func_77960_j() == 3) {
final int var5 = BlockDirectional.func_149895_l(this.blockMd);
final int par2 = this.xx + Direction.field_71583_a[var5];
final int par3 = this.zz + Direction.field_71581_b[var5];
final Block var6 = this.theWorld.func_147439_a(par2, this.yy, par3);
if (var6 == Blocks.field_150364_r && BlockLog.func_150165_c(this.theWorld.func_72805_g(par2, this.yy, par3)) == 3) {
final ItemStack itemStack = st;
--itemStack.field_77994_a;
this.theWorld.func_147465_d(this.xx, this.yy, this.zz, Blocks.field_150375_by, BlockDirectional.func_149895_l(this.blockMd), 3);
}
done = true;
}
else if (st.func_77973_b() != null && st.func_77973_b() == ConfigItems.itemManaBean) {
if (this.block.func_149707_d(this.theWorld, this.xx, this.yy, this.zz, 0)) {
final ItemStack itemStack2 = st;
--itemStack2.field_77994_a;
if (!st.func_77973_b().func_77648_a(st.func_77946_l(), (EntityPlayer)fp, this.theWorld, this.xx, this.yy + 1, this.zz, 0, 0.5f, 0.5f, 0.5f)) {
this.theWorld.func_147465_d(this.xx, this.yy, this.zz, ConfigBlocks.blockManaPod, 0, 3);
}
}
done = true;
}
else {
final int[] xm = { 0, 0, 1, 1, -1, 0, -1, -1, 1 };
final int[] zm = { 0, 1, 0, 1, 0, -1, -1, 1, -1 };
for (int count = 0; st != null && st.field_77994_a > 0 && count < 9; ++count) {
if (st.func_77973_b() != null && (st.func_77973_b() instanceof IPlantable || st.func_77973_b() instanceof ItemSeedFood) && st.func_77973_b().func_77648_a(st.func_77946_l(), (EntityPlayer)fp, this.theWorld, this.xx + xm[count], this.yy - 1, this.zz + zm[count], ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) {
final ItemStack itemStack3 = st;
--itemStack3.field_77994_a;
}
}
}
if (st.field_77994_a <= 0) {
item.func_70106_y();
}
else {
item.func_92058_a(st);
}
if (done) {
break;
}
continue;
}
}
}
}
}
fp.func_70106_y();
this.theGolem.startActionTimer();
}
`
The key is in first 'else' is starts with condition "this.theGolem.getUpgradeAmount(4) > 0". I've seen in the different file that upgrade with 4 ID is exactly an Ordo upgrade, but I'm not familiar with Java and I can't see what's going on here and how to fix my problem with "beans shuffle". Is anybody have any clue how to override this logic or where actually in code is caused a problem? Preventively thanks for any answer

Well, I didn't get an answer after searching this code, but I accidently found that golem is trying to replace bean with dropped ones. That technicaly solved my problem by half. this.theWorld.func_147465_d(this.xx, this.yy, this.zz, ConfigBlocks.blockManaPod, 0, 3); This line is telling me about this, but it has no clue about specific aspect, random only

Related

NullpointerException while Iterating through Mat

I am currently trying to iterate over every pixel of a black and white image in OpenCV 4.1.2 in Java and to store e 3x3 Matrix for every pixel, which should have a 1, if the pixel currently worked with has e neighbouring pixel there, and an 0 if there is no neighbour at this position. So the value in the center of the Mat should always be 1. Currently im working with that nested for-loops, that should iterate through the Mat.
Mat bwDrawing = new Mat(drawing.size(), CvType.CV_8UC3);
Imgproc.cvtColor(drawing, bwDrawing, Imgproc.COLOR_RGB2GRAY);
List<MatOfInt> freemanChains = new ArrayList<>();
for (double y = 2; y-2 < bwDrawing.size().height; y++) {
for (double x = 2; x-2 < bwDrawing.size().width; x++) {
MatOfInt freemanMat = new MatOfInt();
if (bwDrawing.get((int)y-1, (int)x-1)[0] != 0) {
freemanMat.put(0, 0, 1);
} else {
freemanMat.put(0,0, 0);
}
if (bwDrawing.get((int)y-1, (int)x)[0] != 0) {
freemanMat.put(0, 1, 1);
} else {
freemanMat.put(0,1, 0);
}
if (bwDrawing.get((int)y-1, (int)x+1)[0] == 0) { //right here is the NullPointer Exception
freemanMat.put(0, 2, 1);
} else {
freemanMat.put(0,2, 0);
}
if (bwDrawing.get((int)y, (int)x-1)[0] != 0) {
freemanMat.put(1, 0, 1);
} else {
freemanMat.put(1,0, 0);
}
if (bwDrawing.get((int)y, (int)x)[0] != 0) {
freemanMat.put(1, 1, 1);
} else {
freemanMat.put(1,1, 0);
}
if (bwDrawing.get((int)y, (int)x+1)[0] != 0) {
freemanMat.put(1, 2, 1);
} else {
freemanMat.put(1,2, 0);
}
if (bwDrawing.get((int)y+1, (int)x-1)[0] != 0) {
freemanMat.put(2, 0, 1);
} else {
freemanMat.put(2,0, 0);
}
if (bwDrawing.get((int)y+1, (int)x)[0] != 0) {
freemanMat.put(2, 1, 1);
} else {
freemanMat.put(2,1, 0);
}
if (bwDrawing.get((int)y+1, (int)x+1)[0] != 0) {
freemanMat.put(2, 2, 1);
} else {
freemanMat.put(2,2, 0);
}
freemanChains.add(freemanMat);
// System.out.println(freemanMat.get(2, 2)[0]);
}
}
As marked by the comment in the code, im getting an NullPointer Exception the first time im checking for a pixel at x+1. And i do not understand why.
My overall goal is tho calculate a Freeman Chain Code of some contours, and i hope to achieve it with that somehow. Are there any other options in OpenCV to get the Freeman Chain Code since they removed it from the findContours() function?
Any help to both problems is much appreciated. Thank you.

How to project an image using a reference image in java?

I am doing a project and would like to recreate a version of the image without noise. For example, this is the original image and I would like to produce an image that only displays the badminton court lines and net. This is the code that I wrote for it: `
public SimplePicture findBC()
{
Pixel[][] pixels = img_.getPixels2D();
SimplePicture result = new SimplePicture(img_.getWidth(), img_.getHeight());
int w = img_.getWidth();
int h = img_.getHeight();
boolean bird = false;
boolean line = false;
for(int r = 0; r < h; r++)
{
for(int c = 0; c < w; c++)
{
int ori = (pixels[r][c].getRed() + pixels[r][c].getGreen() + pixels[r][c].getBlue())/3;
if(pixels[r][c].getRed() >= 200 && pixels[r][c].getGreen() >= 200 && pixels[r][c].getBlue() <= 100)
bird = true;
else
bird = false;
if(ori > 195 || ori < 30)
line = true;
else
line = false;
if(line == true)
{
Color black = new Color(0, 0, 0, 0);
result.setBasicPixel(c, r, black.getRGB());
}
else if(bird==true)
{
Color birdie = new Color(255, 255, 0);
result.setBasicPixel(c, r, birdie.getRGB());
}
else if(!bird && !line)
{
Color grey = new Color(240, 240, 240, 0);
result.setBasicPixel(c, r, grey.getRGB());
}
}
}
return result;
}`
However, when I tested the code, it results in image that is noisy from glares and the lines further away are faded. If I know what the court should look like, how do I code that to let the computer know to look for key parts and recreate a cleaner version of the image? Please and thank you :)

Negamax-search implementation not working when player can move twice in a row

I'm trying to implement Negamax search for a game called Nine Men's Morris in Java.
If a player has three pieces in a row (here called a mill), he removes a opponent's piece (the 'additional' move) before switching turns.
Additionally, there is a set piece phase and a move piece phase, after all initial pieces have been placed.
My implementation looks like this:
public int[] negamaxSet(int depth, int alpha, int beta, int color) {
if (depth == 0 || board.isGameOver()) {
return new int[] { color * evaluateBoard(color};
}
int stonesSet = color == -1 ? board.blackStonesSet : board.whiteStonesSet;
// set piece phase
if (stonesSet < Game.initialPieces) {
List<Piece> moves = board.getEmpty();
int bestValue = Integer.MIN_VALUE;
int bestMoveX = -1;
int bestMoveY = -1;
for (Piece piece : moves) {
Piece move = new Piece(color, piece.x, piece.y);
board.setPiece(move);
int value[] = null;
//Player made Mill, move again
if(board.checkMill(move)){
value = negamaxRemove(depth - 1, alpha, beta, color);
}
//normal move, switch turn
else {
value = negamaxSet(depth - 1, -beta, -alpha, -color);
value[0] = -value[0];
}
if (value[0] > bestValue) {
bestValue = value[0];
bestMoveX = move.x;
bestMoveY = move.y;
}
if (value[0] > alpha) {
alpha = value[0];
}
board.revertLastMove();
// if (alpha >= beta)
// break;
}
return new int[] { bestValue, bestMoveX, bestMoveY };
} else {
//move phase
List<Piece> moves = board.getPiecesByColor(color);
int bestValue = Integer.MIN_VALUE;
int bestMoveX = -1;
int bestMoveY = -1;
int bestMoveX2 = -1;
int bestMoveY2 = -1;
for (Piece piece : moves) {
List<Piece> adjPieces = board.getAdjacentEmtpy(piece);
for(Piece adjPiece : adjPieces){
Piece newFrom = new Piece(color, piece.x, piece.y);
Piece newTo = new Piece(color, adjPiece.x, adjPiece.y);
board.movePiece(newFrom, newTo);
int[] value = null;
//Player made Mill, move again
if(board.checkMill(newTo, false)){
value = negamaxRemove(depth - 1, alpha, beta, color);
} else {
value = negamaxSet(depth - 1, -beta, -alpha, -color);
value[0] = -value[0];
}
if (value[0] > bestValue) {
bestValue = value[0];
bestMoveX = newFrom.x;
bestMoveY = newFrom.y;
bestMoveX2 = newTo.x;
bestMoveY2 = newTo.y;
}
if (value[0] > alpha) {
alpha = value[0];
}
board.revertLastMove();
// if (alpha >= beta)
// break;
}
}
return new int[] { bestValue, bestMoveX, bestMoveY, bestMoveX2, bestMoveY2 };
}
}
It is probably advisable to not change the basic Negamax algorithm and encapsulate setting a stone and moving a stone in one operation to not distinguish between the two in the algorithm itself, but from my understanding it should still work like this.
The function negamaxRemove is basically the same as negamaxSet but without checking for a mill (not possible) and looking for a piece to remove.
Is it correct to call negamaxRemove with the same parameters as the calling function and not switching the sign (thereby maximizing again)?
Somehow the AI player does not prevent the opponent from forming a mill (but forms one himself if possible).
Is the algorithm correct like this and I should look for the error elsewhere in the code?
Or did I misinterpreted how Negamax should work?
(I commented out alpha-beta pruning so setting alpha or beta wrongly wouldn't make a difference here)
I would really appreciate some pointers!
I've implemented this game. Change your definition of a move from "performs action, awarded another move" to "performs multipart action". Then instead of having to make 2 "moves", you just end up with moves looking like from: 3, to: 0, remove: 17, from: 3, to: 0, remove 19, etc. For moves that do not remove a piece, you simply set remove to -1.

Ice Sliding Puzzle Path Finding

I apologize for the somewhat vague title, I'm unsure what you would call this puzzle.
I'm making a path finding method to find the route with the least moves, not the distance traveled.
The rules of the game are simple, you must traverse from the orange square to the green square, but you can only move in a straight line, and cannot stop moving in that direction until you hit a boundary (either the wall of the arena or an obstacle), as if they were sliding across ice.
Example map, and unless I'm mistaken, the desired path (8 moves)
Arena.java: https://gist.github.com/CalebWhiting/3a6680d40610829b1b6d
ArenaTest.java: https://gist.github.com/CalebWhiting/9a4767508831ea5dc0da
I'm assuming this would be best handled with a Dijkstras or A* path finding algorithm, however I'm not only not very experienced with these algorithms, but also don't know how I would go about defining the path rules.
Thank you for any help in advance.
Here's my solution (Java) in case someone is still interested. As #tobias_k suggested in his comment above, indeed BFS is the way to go:
import java.util.LinkedList;
public class PokemonIceCave {
public static void main(String[] args) {
int[][] iceCave1 = {
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1},
{0, 1, 1, 0, 0},
{0, 1, 0, 0, 1},
{0, 0, 0, 1, 0}
};
System.out.println(solve(iceCave1, 0, 0, 2, 4));
System.out.println();
int[][] iceCave2 = {
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1},
{0, 1, 1, 0, 0},
{0, 1, 0, 0, 1},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 0}
};
System.out.println(solve(iceCave2, 0, 0, 2, 5));
}
public static int solve(int[][] iceCave, int startX, int startY, int endX, int endY) {
Point startPoint = new Point(startX, startY);
LinkedList<Point> queue = new LinkedList<>();
Point[][] iceCaveColors = new Point[iceCave.length][iceCave[0].length];
queue.addLast(new Point(0, 0));
iceCaveColors[startY][startX] = startPoint;
while (queue.size() != 0) {
Point currPos = queue.pollFirst();
System.out.println(currPos);
// traverse adjacent nodes while sliding on the ice
for (Direction dir : Direction.values()) {
Point nextPos = move(iceCave, iceCaveColors, currPos, dir);
System.out.println("\t" + nextPos);
if (nextPos != null) {
queue.addLast(nextPos);
iceCaveColors[nextPos.getY()][nextPos.getX()] = new Point(currPos.getX(), currPos.getY());
if (nextPos.getY() == endY && nextPos.getX() == endX) {
// we found the end point
Point tmp = currPos; // if we start from nextPos we will count one too many edges
int count = 0;
while (tmp != startPoint) {
count++;
tmp = iceCaveColors[tmp.getY()][tmp.getX()];
}
return count;
}
}
}
System.out.println();
}
return -1;
}
public static Point move(int[][] iceCave, Point[][] iceCaveColors, Point currPos, Direction dir) {
int x = currPos.getX();
int y = currPos.getY();
int diffX = (dir == Direction.LEFT ? -1 : (dir == Direction.RIGHT ? 1 : 0));
int diffY = (dir == Direction.UP ? -1 : (dir == Direction.DOWN ? 1 : 0));
int i = 1;
while (x + i * diffX >= 0
&& x + i * diffX < iceCave[0].length
&& y + i * diffY >= 0
&& y + i * diffY < iceCave.length
&& iceCave[y + i * diffY][x + i * diffX] != 1) {
i++;
}
i--; // reverse the last step
if (iceCaveColors[y + i * diffY][x + i * diffX] != null) {
// we've already seen this point
return null;
}
return new Point(x + i * diffX, y + i * diffY);
}
public static class Point {
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
public enum Direction {
LEFT,
RIGHT,
UP,
DOWN
}
}
I think the best solution would probably be the BFS, where you represent the state of the board with a "State" object with the following parameters: number of moves made so far, and coordinates. It should also have a method to find the next states attainable (which should be fairly easy to code, just go N, S, E, W and return an array of the first blocking spots).
Create initial state (0 moves with initial coordinates)
Put in a priority queue (sorting by number moves)
while(priority queue has more states):
Remove node
if it is a goal state:
return the state
Find all neighbors of current state
Add them to priority queue (remembering to increment number of moves by 1)
This uses an implicit graph representation. Optimality is guaranteed because of the priority queue; when the goal state is found, it will have been reached with the fewest moves. If the whole priority queue is exhausted and no state is returned, then no solution exists. This solution takes O(V^2logV) time because of the priority queue, but I think this is the simplest to code. A straight up O(V) BFS solution is possible but you'll have to keep track of what states you have or have not visited yet and the fewest number of moves to reach them, which would take O(V) memory.

Knights tour backtracking lasts too long

How long does it last to solve the knights tour problem with backtracking on an 8x8 board? Because my algorithm already computes somehow too long and it seems, like it wont finish. But when I try a 6x6, or 5x5 board, it finishes successfully.
the code:
class KnightsTour{
private boolean[][] board;
private int count, places;
private static final Point[] moves = new Point[]{
new Point(-2, -1),
new Point(-2, 1),
new Point(2, -1),
new Point(2, 1),
new Point(-1, -2),
new Point(-1, 2),
new Point(1, -2),
new Point(1, 2)
};
public KnightsTour(int n) {
board = new boolean[n][n];
places = n*n;
count = 0;
}
public boolean ride(int x, int y) {
board[x][y] = true;
count++;
if (count == places) {
return true;
}
for (Point p : moves) {
int nextX = x + p.x;
int nextY = y + p.y;
if (nextX < 0 || nextX >= board.length || nextY < 0 || nextY >= board.length || board[nextX][nextY]) {
continue;
}
if (ride(nextX, nextY)) {
return true;
}
}
board[x][y] = false;
count--;
return false;
}
}
I came across the same problem. Everything runs smoothly till n=7 and suddenly it takes forever to calculate for n=8. I hope this helps someone :)
The problem lies with the order in which you are checking for the moves. You are using :
xMove[8] = { -2, -2, 2, 2, -1, -1, 1, 1}
yMove[8] = { -1, 1, -1, 1, -2, 2, -2, 2}
If you plot these vectors in the 2D plane, they are haphazardly placed. In other words, they are not ordered in either a clockwise or an anti-clockwise manner. Consider this instead :
xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 }
yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 }
If you plot these vectors, they are neatly arranged in an anticlockwise circle.
Somehow this causes the recursion to run much quickly for large values of n. Mind you, it still takes forever to calculate for n=9 onwards.

Categories