I am creating a new mod that has a container. The issue is that the inventory slots are offset by 7. It seems like the server thinks the first column is where the second-to-last column, and the second column is where the last column is. Here is some code. The classes should be included.
public class GuiHandler implements IGuiHandler {
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == 0) {
return new ContainerGenerator(player.inventory, (TileEntityGenerator) world.getTileEntity(x, y, z));
} else {
return null;
}
}
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == 0) {
return new GuiGenerator(player.inventory, (TileEntityGenerator) world.getTileEntity(x, y, z));
} else {
return null;
}
}
}
The container class
public class ContainerGenerator extends Container {
private TileEntityGenerator tileEntity;
private int count;
public ContainerGenerator(InventoryPlayer inventory, TileEntityGenerator tileEntity) {
this.tileEntity = tileEntity;
this.tileEntity.openInventory();
this.count = tileEntity.getCount();
this.addSlotToContainer(new Slot(tileEntity, 0, 27, 47));
this.addSlotToContainer(new Slot(tileEntity, 1, 134, 47));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlotToContainer(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (int i = 0; i < 9; i++) {
this.addSlotToContainer(new Slot(inventory, i, 8 + i * 18, 142));
}
}
// some other random code
And some relevent tile entity overrides (there is some other random code)
#Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
this.count = nbt.getInteger("count");
NBTTagList tagList = nbt.getTagList("items", 10);
this.items = new ItemStack[2];
NBTTagCompound compound = tagList.getCompoundTagAt(0);
byte slotId = compound.getByte("slot");
if (slotId >= 0 && slotId < 2) {
items[slotId] = ItemStack.loadItemStackFromNBT(compound);
}
compound = tagList.getCompoundTagAt(1);
slotId = compound.getByte("slot");
if (slotId >= 0 && slotId < 2) {
items[slotId] = ItemStack.loadItemStackFromNBT(compound);
}
}
#Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setInteger("count", count);
NBTTagList list = new NBTTagList();
if (items[0] != null) {
NBTTagCompound compound = new NBTTagCompound();
compound.setByte("slot", (byte) 0);
items[0].writeToNBT(compound);
list.appendTag(compound);
}
if (items[1] != null) {
NBTTagCompound compound = new NBTTagCompound();
compound.setByte("slot", (byte) 1);
items[1].writeToNBT(compound);
list.appendTag(compound);
}
nbt.setTag("items", list);
}
#Override
public int getSizeInventory() {
return items.length;
}
#Override
public ItemStack getStackInSlot(int slot) {
return items[slot];
}
#Override
public ItemStack decrStackSize(int slot, int amount) {
if (items[slot] == null) {
return null;
}
if (items[slot].stackSize == amount) {
ItemStack itemStack = items[slot];
items[slot] = null;
return itemStack;
} else {
ItemStack itemStack = items[slot].splitStack(amount);
if (items[slot].stackSize == 0) {
items[slot] = null;
}
markDirty();
return itemStack;
}
}
#Override
public ItemStack getStackInSlotOnClosing(int slot) {
if (items[slot] != null) {
ItemStack itemStack = items[slot];
items[slot] = null;
return itemStack;
} else {
return null;
}
}
#Override
public void setInventorySlotContents(int slot, ItemStack stack) {
items[slot] = stack;
if (stack != null && stack.stackSize > getInventoryStackLimit()) {
markDirty();
}
}
Edit: screenshots. Notice which slots are highlighted if any.
Sorry for the lengthy post. I'm new to modding, so it is hard for me to pin point the issue exactly.
Related
Can anyone make me this class 1.12.2 compatible? I tried it many times but without success. I would be happy if anyone is so nice. And don't come with learning java or whatever I am new at this learning by doing Example IContainer. this is not in 1.12.2. or world.notify();. I do not know what should I add to make this compatible? the owner of this utils is not active anymore so I cant ask.
package utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.scheduler.BukkitRunnable;
import net.minecraft.server.v1_7_R4.IContainer;
import net.minecraft.server.v1_7_R4.TileEntity;
public class BO2 {
private Arena arena;
public BO2() {
this.arena = new Arena(this);
}
public Arena getArena() {
return arena;
}
private static HashSet<Location> blocksForUpdate = new HashSet<>();
public void addBlockUpdate(Location location) {
blocksForUpdate.add(location);
}
public void startUpdate() {
new BukkitRunnable() {
#Override
public void run() {
if (!blocksForUpdate.isEmpty()) {
net.minecraft.server.v1_7_R4.World world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
for (Location location : blocksForUpdate) {
world.notify(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
blocksForUpdate.clear();
}
}
}.runTaskTimer(Utils.getPlugin(Utils.class), 1, 1);
}
/* Spawn BO2 */
public List<Block> spawn(Location location, File file) {
long time = System.currentTimeMillis();
BufferedReader reader;
ArrayList<Block> blocks = new ArrayList<>();
try {
reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
if (!line.contains(",") || !line.contains(":")) {
continue;
}
String[] parts = line.split(":");
String[] coordinates = parts[0].split(",");
String[] blockData = parts[1].split("\\.");
setBlockFast(location.getWorld(), location.getBlockX() + Integer.valueOf(coordinates[0]), location.getBlockY() + Integer.valueOf(coordinates[2]), location.getBlockZ() + Integer.valueOf(coordinates[1]), Integer.valueOf(blockData[0]), blockData.length > 1 ? Byte.valueOf(blockData[1]) : 0);
blocks.add(location.getWorld().getBlockAt(location.getBlockX() + Integer.valueOf(coordinates[0]), location.getBlockY() + Integer.valueOf(coordinates[2]), location.getBlockZ() + Integer.valueOf(coordinates[1])));
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("BO2 spawnada em " + (time - System.currentTimeMillis()) + "ms");
return blocks;
}
/* Load BO2 file */
public List<FutureBlock> load(Location location, File file) {
BufferedReader reader;
ArrayList<FutureBlock> blocks = new ArrayList<>();
try {
reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
if (!line.contains(",") || !line.contains(":")) {
continue;
}
String[] parts = line.split(":");
String[] coordinates = parts[0].split(",");
String[] blockData = parts[1].split("\\.");
blocks.add(new FutureBlock(location.clone().add(Integer.valueOf(coordinates[0]), Integer.valueOf(coordinates[2]), Integer.valueOf(coordinates[1])), Integer.valueOf(blockData[0]), blockData.length > 1 ? Byte.valueOf(blockData[1]) : 0));
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return blocks;
}
/* Set methods */
public boolean setBlockFast(World world, int x, int y, int z, int blockId, byte data) {
if (y >= 255 || y < 0) {
return false;
}
net.minecraft.server.v1_7_R4.World w = ((CraftWorld) world).getHandle();
net.minecraft.server.v1_7_R4.Chunk chunk = w.getChunkAt(x >> 4, z >> 4);
boolean b = data(chunk, x & 0x0f, y, z & 0x0f, net.minecraft.server.v1_7_R4.Block.getById(blockId), data);
addBlockUpdate(new Location(Bukkit.getWorlds().get(0), x, y, z));
return b;
}
#SuppressWarnings("deprecation")
public boolean setBlockFast(Location location, Material material, byte data) {
return setBlockFast(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), material.getId(), data);
}
private boolean data(net.minecraft.server.v1_7_R4.Chunk that, int i, int j, int k, net.minecraft.server.v1_7_R4.Block block, int l) {
int i1 = k << 4 | i;
if (j >= that.b[i1] - 1) {
that.b[i1] = -999;
}
int j1 = that.heightMap[i1];
net.minecraft.server.v1_7_R4.Block block1 = that.getType(i, j, k);
int k1 = that.getData(i, j, k);
if (block1 == block && k1 == l) {
return false;
} else {
boolean flag = false;
net.minecraft.server.v1_7_R4.ChunkSection chunksection = that.getSections()[j >> 4];
if (chunksection == null) {
if (block == net.minecraft.server.v1_7_R4.Blocks.AIR) {
return false;
}
chunksection = that.getSections()[j >> 4] = new net.minecraft.server.v1_7_R4.ChunkSection(j >> 4 << 4, !that.world.worldProvider.g);
flag = j >= j1;
}
int l1 = that.locX * 16 + i;
int i2 = that.locZ * 16 + k;
if (!that.world.isStatic) {
block1.f(that.world, l1, j, i2, k1);
}
if (!(block1 instanceof IContainer)) {
chunksection.setTypeId(i, j & 15, k, block);
}
if (!that.world.isStatic) {
block1.remove(that.world, l1, j, i2, block1, k1);
} else if (block1 instanceof IContainer && block1 != block) {
that.world.p(l1, j, i2);
}
if (block1 instanceof IContainer) {
chunksection.setTypeId(i, j & 15, k, block);
}
if (chunksection.getTypeId(i, j & 15, k) != block) {
return false;
} else {
chunksection.setData(i, j & 15, k, l);
if (flag) {
that.initLighting();
}
TileEntity tileentity;
if (block1 instanceof IContainer) {
tileentity = that.e(i, j, k);
if (tileentity != null) {
tileentity.u();
}
}
if (!that.world.isStatic && (!that.world.captureBlockStates || (block instanceof net.minecraft.server.v1_7_R4.BlockContainer))) {
block.onPlace(that.world, l1, j, i2);
}
if (block instanceof IContainer) {
if (that.getType(i, j, k) != block) {
return false;
}
tileentity = that.e(i, j, k);
if (tileentity == null) {
tileentity = ((IContainer) block).a(that.world, l);
that.world.setTileEntity(l1, j, i2, tileentity);
}
if (tileentity != null) {
tileentity.u();
}
}
that.n = true;
return true;
}
}
}
/* FutureBlock Utils */
public class FutureBlock {
private Location location;
private int id;
private byte data;
public FutureBlock(Location location, int id, byte data) {
this.location = location;
this.id = id;
this.data = data;
}
public byte getData() {
return data;
}
public Location getLocation() {
return location;
}
public int getId() {
return id;
}
#SuppressWarnings("deprecation")
public void place() {
location.getBlock().setTypeIdAndData(id, data, true);
}
}
}
I have to do an assignment at school, it's a car park simulator, calling run(); from the main gives a perfectly normal simulation where the carspots get repainted every step but when calling it from an actionListener it only paints the result and not the steps inbetween. There are 6 classes down below where the main is in the Simulator class, and SimulatorView has the repaint(); in it.
So could anyone explain to me why it simulates every step when run() is called from the main, and why it just paints the output when run() is called from an ActionListener behind a JButton?
Simulator.java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class Simulator implements ActionListener{
private CarQueue entranceCarQueue;
private CarQueue paymentCarQueue;
private CarQueue exitCarQueue;
private SimulatorView simulatorView;
private int day = 0;
private int hour = 0;
private int minute = 0;
private int tickPause = 100;
int weekDayArrivals= 50; // average number of arriving cars per hour
int weekendArrivals = 90; // average number of arriving cars per hour
int enterSpeed = 3; // number of cars that can enter per minute
int paymentSpeed = 10; // number of cars that can pay per minute
int exitSpeed = 9; // number of cars that can leave per minute
public Simulator() {
entranceCarQueue = new CarQueue();
paymentCarQueue = new CarQueue();
exitCarQueue = new CarQueue();
simulatorView = new SimulatorView(3, 6, 30, this);
}
public void run() {
for (int i = 0; i < 10000; i++) {
tick();
}
}
public void run(int steps) {
System.out.println("run " + steps + " steps");
for (int i = 0; i < steps; i++) {
tick();
}
}
private void tick() {
System.out.println("simulator-tick");
// Advance the time by one minute.
minute++;
while (minute > 59) {
minute -= 60;
hour++;
}
while (hour > 23) {
hour -= 24;
day++;
}
while (day > 6) {
day -= 7;
}
Random random = new Random();
// Get the average number of cars that arrive per hour.
int averageNumberOfCarsPerHour = day < 5
? weekDayArrivals
: weekendArrivals;
// Calculate the number of cars that arrive this minute.
double standardDeviation = averageNumberOfCarsPerHour * 0.1;
double numberOfCarsPerHour = averageNumberOfCarsPerHour + random.nextGaussian() * standardDeviation;
int numberOfCarsPerMinute = (int)Math.round(numberOfCarsPerHour / 60);
// Add the cars to the back of the queue.
for (int i = 0; i < numberOfCarsPerMinute; i++) {
Car car = new AdHocCar();
entranceCarQueue.addCar(car);
}
// Remove car from the front of the queue and assign to a parking space.
for (int i = 0; i < enterSpeed; i++) {
Car car = entranceCarQueue.removeCar();
if (car == null) {
break;
}
// Find a space for this car.
Location freeLocation = simulatorView.getFirstFreeLocation();
if (freeLocation != null) {
simulatorView.setCarAt(freeLocation, car);
int stayMinutes = (int) (15 + random.nextFloat() * 10 * 60);
car.setMinutesLeft(stayMinutes);
}
}
// Perform car park tick.
simulatorView.tick();
// Add leaving cars to the exit queue.
while (true) {
Car car = simulatorView.getFirstLeavingCar();
if (car == null) {
break;
}
car.setIsPaying(true);
paymentCarQueue.addCar(car);
}
// Let cars pay.
for (int i = 0; i < paymentSpeed; i++) {
Car car = paymentCarQueue.removeCar();
if (car == null) {
break;
}
// TODO Handle payment.
simulatorView.removeCarAt(car.getLocation());
exitCarQueue.addCar(car);
}
// Let cars leave.
for (int i = 0; i < exitSpeed; i++) {
Car car = exitCarQueue.removeCar();
if (car == null) {
break;
}
// Bye!
}
// Update the car park view.
simulatorView.updateView();
// Pause.
try {
Thread.sleep(tickPause);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e)
{
String command = e.getActionCommand();
switch (command) {
case "oneStep":
run(1);
break;
case "hundredSteps":
run(10);
break;
default:
break;
}
}
public static void main (String[] args) {
Simulator start = new Simulator();
}
}
SimulatorView.java:
import javax.swing.*;
import java.awt.*;
public class SimulatorView extends JFrame {
private CarParkView carParkView;
private int numberOfFloors;
private int numberOfRows;
private int numberOfPlaces;
private Car[][][] cars;
public SimulatorView(int numberOfFloors, int numberOfRows, int numberOfPlaces, Simulator parent) {
this.numberOfFloors = numberOfFloors;
this.numberOfRows = numberOfRows;
this.numberOfPlaces = numberOfPlaces;
cars = new Car[numberOfFloors][numberOfRows][numberOfPlaces];
carParkView = new CarParkView();
Container contentPane = getContentPane();
//contentPane.add(stepLabel, BorderLayout.NORTH);
contentPane.add(carParkView, BorderLayout.CENTER);
//contentPane.add(population, BorderLayout.SOUTH);
JButton stepForward = new JButton("oneStep");
stepForward.addActionListener(parent);
JButton stepHundredForward = new JButton("hundredSteps");
stepHundredForward.addActionListener(parent);
JMenuBar stepBar = new JMenuBar();
stepBar.add(stepForward);
stepBar.add(stepHundredForward);
contentPane.add(stepBar, BorderLayout.SOUTH);
pack();
setVisible(true);
updateView();
}
public void updateView() {
carParkView.updateView();
}
public int getNumberOfFloors() {
return numberOfFloors;
}
public int getNumberOfRows() {
return numberOfRows;
}
public int getNumberOfPlaces() {
return numberOfPlaces;
}
public Car getCarAt(Location location) {
if (!locationIsValid(location)) {
return null;
}
return cars[location.getFloor()][location.getRow()][location.getPlace()];
}
public boolean setCarAt(Location location, Car car) {
if (!locationIsValid(location)) {
return false;
}
Car oldCar = getCarAt(location);
if (oldCar == null) {
cars[location.getFloor()][location.getRow()][location.getPlace()] = car;
car.setLocation(location);
return true;
}
return false;
}
public Car removeCarAt(Location location) {
if (!locationIsValid(location)) {
return null;
}
Car car = getCarAt(location);
if (car == null) {
return null;
}
cars[location.getFloor()][location.getRow()][location.getPlace()] = null;
car.setLocation(null);
return car;
}
public Location getFirstFreeLocation() {
for (int floor = 0; floor < getNumberOfFloors(); floor++) {
for (int row = 0; row < getNumberOfRows(); row++) {
for (int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
if (getCarAt(location) == null) {
return location;
}
}
}
}
return null;
}
public Car getFirstLeavingCar() {
for (int floor = 0; floor < getNumberOfFloors(); floor++) {
for (int row = 0; row < getNumberOfRows(); row++) {
for (int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
if (car != null && car.getMinutesLeft() <= 0 && !car.getIsPaying()) {
return car;
}
}
}
}
return null;
}
public void tick() {
System.out.println("simulatorview-tick");
for (int floor = 0; floor < getNumberOfFloors(); floor++) {
for (int row = 0; row < getNumberOfRows(); row++) {
for (int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
if (car != null) {
car.tick();
}
}
}
}
}
private boolean locationIsValid(Location location) {
int floor = location.getFloor();
int row = location.getRow();
int place = location.getPlace();
if (floor < 0 || floor >= numberOfFloors || row < 0 || row > numberOfRows || place < 0 || place > numberOfPlaces) {
return false;
}
return true;
}
private class CarParkView extends JPanel {
private Dimension size;
private Image carParkImage;
/**
* Constructor for objects of class CarPark
*/
public CarParkView() {
size = new Dimension(0, 0);
}
/**
* Overridden. Tell the GUI manager how big we would like to be.
*/
public Dimension getPreferredSize() {
return new Dimension(800, 500);
}
/**
* Overriden. The car park view component needs to be redisplayed. Copy the
* internal image to screen.
*/
public void paintComponent(Graphics g) {
if (carParkImage == null) {
return;
}
Dimension currentSize = getSize();
if (size.equals(currentSize)) {
g.drawImage(carParkImage, 0, 0, null);
}
else {
// Rescale the previous image.
g.drawImage(carParkImage, 0, 0, currentSize.width, currentSize.height, null);
}
}
public void updateView() {
// Create a new car park image if the size has changed.
if (!size.equals(getSize())) {
size = getSize();
carParkImage = createImage(size.width, size.height);
}
Graphics graphics = carParkImage.getGraphics();
for(int floor = 0; floor < getNumberOfFloors(); floor++) {
for(int row = 0; row < getNumberOfRows(); row++) {
for(int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
Color color = car == null ? Color.white : Color.red;
drawPlace(graphics, location, color);
}
}
}
repaint();
}
/**
* Paint a place on this car park view in a given color.
*/
private void drawPlace(Graphics graphics, Location location, Color color) {
graphics.setColor(color);
graphics.fillRect(
location.getFloor() * 260 + (1 + (int)Math.floor(location.getRow() * 0.5)) * 75 + (location.getRow() % 2) * 20,
60 + location.getPlace() * 10,
20 - 1,
10 - 1); // TODO use dynamic size or constants
}
}
}
Car.java:
public abstract class Car {
private
Location location;
private int minutesLeft;
private boolean isPaying;
/**
* Constructor for objects of class Car
*/
public Car() {
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public int getMinutesLeft() {
return minutesLeft;
}
public void setMinutesLeft(int minutesLeft) {
this.minutesLeft = minutesLeft;
}
public boolean getIsPaying() {
return isPaying;
}
public void setIsPaying(boolean isPaying) {
this.isPaying = isPaying;
}
public void tick() {
System.out.println("car-tick");
minutesLeft--;
}
}
Location.java:
public class Location {
private int floor;
private int row;
private int place;
/**
* Constructor for objects of class Location
*/
public Location(int floor, int row, int place) {
this.floor = floor;
this.row = row;
this.place = place;
}
/**
* Implement content equality.
*/
public boolean equals(Object obj) {
if(obj instanceof Location) {
Location other = (Location) obj;
return floor == other.getFloor() && row == other.getRow() && place == other.getPlace();
}
else {
return false;
}
}
/**
* Return a string of the form floor,row,place.
* #return A string representation of the location.
*/
public String toString() {
return floor + "," + row + "," + place;
}
/**
* Use the 10 bits for each of the floor, row and place
* values. Except for very big car parks, this should give
* a unique hash code for each (floor, row, place) tupel.
* #return A hashcode for the location.
*/
public int hashCode() {
return (floor << 20) + (row << 10) + place;
}
/**
* #return The floor.
*/
public int getFloor() {
return floor;
}
/**
* #return The row.
*/
public int getRow() {
return row;
}
/**
* #return The place.
*/
public int getPlace() {
return place;
}
}
CarQueue.java:
import java.util.LinkedList;
import java.util.Queue;
public class CarQueue {
private Queue<Car> queue = new LinkedList<>();
public boolean addCar(Car car) {
return queue.add(car);
}
public Car removeCar() {
return queue.poll();
}
}
AdHocCar.java:
public class AdHocCar extends Car {
public AdHocCar() {
}
}
When you call run() from the actionListener, it is being executed on the EventDispatchTread, blocking that thread until the run() method terminates. Only after that point can the EDT act on the repaint request.
"In general Swing is not thread safe. All Swing components and related classes, unless otherwise documented, must be accessed on the event dispatching thread." see here
So when an action is performed, actionListener pick up that event and execute run() in the event dispatching thread.
At step 0, when it comes to repaint(), it doesn't draw anything because "The component will be repainted after all of the currently pending events have been dispatched." see here
The repaint() is waiting for the release of ActionListener.actionPerformed.
So it comes to step 1, the same thing happens. Only at the end, after the action event is released, the repaint() will be execute once. So that's why only results are there not steps in between.
My suggestion is put the painting logic in the main thread instead of the actionListener.
First of all there is a lot of code because i really don't know where my issue is, I do apologise!
I'm making a program that solves a varying size puzzle for eg (3x3 with 0-8) The zero represents a blank tile the objective is to move the the blank tile around until the goal state is reached. At the moment I am using Depth First Search to solve the puzzle. Netbeans returns a 'OutOfMemory' error when i run the program however if I change the goal state so it only requires one move to complete it displays the solution. Below is my code, I've only added some of the classes because I don't want this post being ridiculously long. Please let me know if you require the other classes
EDIT: Inserted wrong code for board class
Depth First Search Class
package npuzzle;
import java.util.ArrayList;
import java.util.Stack;
public class DFSearch {
public static void search(int[][] initial, int[][] goal, int rows, int columns)
{
Board board = new Board(initial, goal, rows, columns, "");
Node root = new Node(board);
Stack<Node> stack = new Stack<Node>();
stack.add(root);
performSearch(stack, board);
}
public static void performSearch(Stack<Node> s, Board board)
{
int searchCount = 1;
while (!s.isEmpty())
{
Node tNode = (Node) s.pop();
//if not goal state
if (!tNode.getCurrentState().isGoalState())
{
ArrayList<State> tChildren = tNode.getCurrentState().gChildren();
for (int i = 0; i < tChildren.size(); i++)
{
Node newNode = new Node(tNode, tChildren.get(i), tNode.getGCost() + tChildren.get(i).findCost(), 0);
if(!isRepeatedState(newNode))
{
s.add(newNode);
}
}
searchCount++;
}
else
{
tNode.getCurrentState().printState();
System.exit(0);
//PRINTING OF DIRECTIONS
}
}
System.out.println("Error! No solution found!");
}
private static boolean isRepeatedState(Node c)
{
boolean returnVal = false;
Node checkNode = c;
while(c.getParent() != null && !returnVal)
{
if (c.getParent().getCurrentState().equals(checkNode.getCurrentState()))
{
returnVal = true;
}
c = c.getParent();
}
return returnVal;
}
}
Board Class
package npuzzle;
import java.util.ArrayList;
import java.util.Arrays;
public class Board implements State
{
private int PUZZLE_SIZE = 0;
private int outOfPlace = 0;
private int rows;
private int columns;
private int[][] GOAL;
private int[][] currentBoard;
private String directions = "";
public Board(int[][] initial, int[][] goal, int N, int M, String direction)
{
currentBoard = initial;
GOAL = goal;
rows = N;
columns = M;
PUZZLE_SIZE = rows*columns;
directions = direction;
setOutOfPlace();
}
#Override
public boolean isGoalState() {
if (Arrays.deepEquals(currentBoard, GOAL))
{
return true;
}
return false;
}
#Override
public ArrayList<State> gChildren() {
ArrayList<State> children = new ArrayList<State>();
int[] blanktile = getBlankTile();
int[] newblanktile = Arrays.copyOf(blanktile, blanktile.length);
if (blanktile[0] != 0) {
newblanktile[0]--;
Swap(newblanktile, blanktile, children, "up");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != 0) {
newblanktile[1]--;
Swap(newblanktile, blanktile, children, "left");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[0] != (this.rows - 1)) {
newblanktile[0]++;
Swap(newblanktile, blanktile, children, "down");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != (this.columns - 1)) {
newblanktile[1]++;
Swap(newblanktile, blanktile, children, "right");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
return children;
}
#Override
public double findCost() {
return 1;
}
#Override
public void printState() {
System.out.println(directions);
}
#Override
public boolean equals(State s) {
if (Arrays.deepEquals(currentBoard, ((Board) s).getCurrentBoard()))
{
return true;
}
else
return false;
}
private void setOutOfPlace() {
int i = 0;
int j = -1;
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] != GOAL[i][j])
{
outOfPlace++;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
}
private int[] getBlankTile()
{
int i = 0;
int j = -1;
int[] blanktile = {0,0};
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] == 0) {
blanktile[0] = i;
blanktile[1] = j;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
return blanktile;
}
public int getOutOfPlace()
{
return outOfPlace;
}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
public int getPUZZLE_SIZE() {
return PUZZLE_SIZE;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
public int[][] getGOAL() {
return GOAL;
}
public int[][] getCurrentBoard()
{
return currentBoard;
}
public String getDirections()
{
return directions;
}
}
My source code:
import java.util.*;
public class Arvore {
public Arvore() {
root = null;
}
public void inserir(String x) {
root = insert(x, root);
}
public void remove(String x) {
root = remove(x, root);
}
private No remove(String x, No t) {
if (t == null) {
return t;
}
int comp = x.compareTo(t.str);
if (comp < 0) {
t.left = remove(x, t.left);
} else if (comp > 0) {
t.right = remove(x, t.right);
} else if (t.left != null && t.right != null) {
t.str = findMin(t.right).str;
t.right = remove(t.str, t.right);
} else {
t = (t.left != null) ? t.left : t.right;
}
return balance(t);
}
public String findMin() {
return findMin(root).str;
}
public String findMax() {
return findMax(root).str;
}
public boolean contains(String x) {
return contains(x, root);
}
public void makeEmpty() {
root = null;
}
public boolean isEmpty() {
return root == null;
}
private static final int maxBal = 1;
private No balance(No t) {
if (t == null) {
return t;
}
if (height(t.left) - height(t.right) > maxBal) {
if (height(t.left.left) >= height(t.left.right)) {
t = rotateWithLeftChild(t);
} else {
t = doubleWithLeftChild(t);
}
} else if (height(t.right) - height(t.left) > maxBal) {
if (height(t.right.right) >= height(t.right.left)) {
t = rotateWithRightChild(t);
} else {
t = doubleWithRightChild(t);
}
}
t.height = Math.max(height(t.left), height(t.right)) + 1;
return t;
}
public void checkBalance() {
checkBalance(root);
}
private int checkBalance(No t) {
if (t == null) {
return -1;
}
if (t != null) {
int hl = checkBalance(t.left);
int hr = checkBalance(t.right);
if (Math.abs(height(t.left) - height(t.right)) > 1
|| height(t.left) != hl || height(t.right) != hr) {
System.out.println("OOPS!!");
}
}
return height(t);
}
private No insert(String x, No t) {
if (t == null) {
return new No(x, null, null);
}
int comp = x.compareTo(t.str);
if (comp < 0) {
t.left = insert(x, t.left);
} else if (comp > 0) {
t.right = insert(x, t.right);
} else
;
t.occ+=1;
return balance(t);
}
private No findMin(No t) {
if (t == null) {
return t;
}
while (t.left != null) {
t = t.left;
}
return t;
}
private No findMax(No t) {
if (t == null) {
return t;
}
while (t.right != null) {
t = t.right;
}
return t;
}
private boolean contains(String x, No t) {
while (t != null) {
int comp = x.compareTo(t.str);
if (comp < 0) {
t = t.left;
} else if (comp > 0) {
t = t.right;
} else {
return true;
}
}
return false;
}
private void printTree(No t) {
if (t != null) {
printTree(t.left);
System.out.println(t.str + ": " + t.occ);
printTree(t.right);
}
}
private int height(No t) {
return t == null ? -1 : t.height;
}
private No rotateWithLeftChild(No k2) {
No k1 = k2.left;
k2.left = k1.right;
k1.right = k2;
k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
k1.height = Math.max(height(k1.left), k2.height) + 1;
return k1;
}
private No rotateWithRightChild(No k1) {
No k2 = k1.right;
k1.right = k2.left;
k2.left = k1;
k1.height = Math.max(height(k1.left), height(k1.right)) + 1;
k2.height = Math.max(height(k2.right), k1.height) + 1;
return k2;
}
private No doubleWithLeftChild(No k3) {
k3.left = rotateWithRightChild(k3.left);
return rotateWithLeftChild(k3);
}
private No doubleWithRightChild(No k1) {
k1.right = rotateWithLeftChild(k1.right);
return rotateWithRightChild(k1);
}
private class No {
No(String tStr) {
this(tStr, null, null);
}
No(String tStr, No lt, No rt) {
str = tStr;
left = lt;
right = rt;
height = 0;
occ = 1;
}
String str;
No left;
No right;
int height;
int occ = 0;
}
private No root;
public static void main(String[] args) {
Arvore t = new Arvore();
System.out.println("AVL TREE TEST\n");
String msg;
String[] inputs;
Scanner sc = new Scanner(System.in);
ArrayList palavras = new ArrayList();
int i = 0;
while (true) {
msg = sc.nextLine();
if (msg.equals("")) {
break;
}
inputs = msg.split(" ");
i = 0;
while (i < inputs.length) {
palavras.add(inputs[i]);
}
}
i = 0;
while (i < palavras.size()) {
if (palavras.get(i).equals("REMOVE")) {
palavras.remove(palavras.get(i));
palavras.remove(palavras.get(i + 1));
i += 2;
} else {
t.insert(palavras.get(i));
}
i++;
}
t.printTree();
}
}
I can't figure out why i have an error when i call insert and printTree, on the main function.
And i have a warning by adding a string to my arraylist, when i do palavras.add(inputs[i]).
Your loop:
i = 0;
while (i < inputs.length) {
palavras.add(inputs[i]);
}
is not incrementing i, so you will eventually run out of space for the array as you try to insert an infinite number of references to inputs[0].
The warning is because you are using a raw ArrayList. Try declaring palavras as:
ArrayList<String> palavras = new ArrayList<>(); // new ArrayList<String>(); if pre Java 7
Your other loop:
i = 0;
while (i < palavras.size()) {
if (palavras.get(i).equals("REMOVE")) {
palavras.remove(palavras.get(i));
palavras.remove(palavras.get(i + 1));
i += 2;
} else {
t.insert(palavras.get(i));
}
i++;
}
will generate an IndexOutOfBoundsException if the first branch of the if is taken when i == palavras.size() - 1 when it tries to remove the second element. Even if you are guaranteed that "REMOVE" is always followed by another element, you need to either reverse the order of the removals:
palavras.remove(palavras.get(i + 1));
palavras.remove(palavras.get(i));
or remove the element at i twice:
palavras.remove(palavras.get(i));
palavras.remove(palavras.get(i));
(because when you call remove() it moves all succeeding elements down one position in the array).
You are calling t.printTree() but, there is no such method defined in class Arvore; the method you did define takes a tree as an argument. Same thing with insert(): the actual method that's available takes a String and a No as arguments.
So I'm trying to run my pacman project as a jar(also tried runnable) and I just get the error message you see in the title. It runs perfectly fine in eclipse/netbeans, but whilst cleaning/building i see the warnings:
Note: C:\Users\Lucas\Documents\Eclipse\PackMan\src\game\packman\GameData.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
The main class is correct and assigned. Does anybody know what I'm doing wrong?
Here is my GameData class
public class GameData {
int mazeNo;
CopyOnWriteArrayList<Position> pills;
CopyOnWriteArrayList<Position> powerPills;
public MoverInfo packman;
public GhostInfo[] ghostInfos = new GhostInfo[4];
public int score;
Maze[] mazes;
boolean dead = false;
boolean win = false;
public GameData() {
mazes = new Maze[4];
// load mazes information
for (int m=0; m<4; m++) {
mazes[m] = new Maze(m);
}
setMaze(mazeNo);
}
private void setMaze(int m) {
packman = new MoverInfo(mazes[m].packmanPos);
for (int g=0; g<4; g++) {
ghostInfos[g] = new GhostInfo(mazes[m].ghostPos);
}
pills = new CopyOnWriteArrayList((List<Position>)(mazes[m].pills.clone()));
powerPills = new CopyOnWriteArrayList((List<Position>)(mazes[m].powerPills.clone()));
}
public void movePackMan(int reqDir) {
if (move(reqDir, packman)) {
packman.curDir = reqDir;
} else {
move(packman.curDir, packman);
}
}
private int wrap(int value, int incre, int max) {
return (value+max+incre)%max;
}
private boolean move(int reqDir, MoverInfo info) {
// current position of packman is (row, column)
int row = info.pos.row;
int column = info.pos.column;
int rows = mazes[mazeNo].rows;
int columns = mazes[mazeNo].columns;
int nrow = wrap(row, MoverInfo.DROW[reqDir], rows);
int ncol = wrap(column, MoverInfo.DCOL[reqDir], columns);
if (mazes[mazeNo].charAt(nrow, ncol) != '0') {
info.pos.row = nrow;
info.pos.column = ncol;
return true;
}
return false;
}
public void update() {
if (pills.contains(packman.pos)) {
pills.remove(packman.pos);
score += 5;
} else if (powerPills.contains(packman.pos)) {
powerPills.remove(packman.pos);
score += 50;
for (GhostInfo g:ghostInfos) {
g.edibleCountDown = 500;
}
}
for (GhostInfo g:ghostInfos) {
if (g.edibleCountDown > 0) {
if (touching(g.pos, packman.pos)) {
// eat the ghost and reset
score += 100;
g.curDir = g.reqDir = MoverInfo.LEFT;
g.pos.row = mazes[mazeNo].ghostPos.row;
g.pos.column = mazes[mazeNo].ghostPos.column;
g.edibleCountDown = 0;
}
g.edibleCountDown--;
} else {
if (touching(g.pos, packman.pos)) {
dead = true;
}
}
}
// level is cleared
if (pills.isEmpty() && powerPills.isEmpty()) {
mazeNo++;
if (mazeNo < 4) {
setMaze(mazeNo);
} else if (mazeNo == 5) {
win = true;
} else {
// game over
dead = true;
}
}
}
private boolean touching(Position a, Position b) {
return Math.abs(a.row-b.row) + Math.abs(a.column-b.column) < 3;
}
public void moveGhosts(int[] reqDirs) {
for (int i=0; i<4; i++) {
GhostInfo info = ghostInfos[i];
info.reqDir = reqDirs[i];
if (move(info.reqDir, info)) {
info.curDir = info.reqDir;
} else {
move(info.curDir, info);
}
}
}
public int getWidth() {
return mazes[mazeNo].width;
}
public int getHeight() {
return mazes[mazeNo].height;
}
public List<Integer> getPossibleDirs(Position pos) {
List<Integer> list = new ArrayList<>();
for (int d=0; d<4;d++) {
Position npos = getNextPositionInDir(pos, d);
if (mazes[mazeNo].charAt(npos.row, npos.column) != '0') {
list.add(d);
}
}
return list;
}
private Position getNextPositionInDir(Position pos, int d) {
int nrow = wrap(pos.row, MoverInfo.DROW[d], mazes[mazeNo].rows);
int ncol = wrap(pos.column, MoverInfo.DCOL[d], mazes[mazeNo].columns);
return new Position(nrow, ncol);
}
}