unknown run-time exception in kattis problem "marbles on a tree" - graph

I've been trying to implement this solution (https://algorithmist.com/wiki/UVa_10672_-_Marbles_on_a_tree) to this kattis problem (https://open.kattis.com/problems/marblestree). This is a graph theory problem involving a tree and a greedy algorithm similar to DFS. My code works for the sample test case, but generates a run-time exception on the second test case. The problem is, I have no idea where the exception is happening or what the exception is - Kattis gives me no hints. This isn't a memory exceeded or time exceeded deal, as kattis has a seperate notification for those errors; something somewhere is generating an explicit run-time exception and I have no idea where. My guess is that the exception is happening somewhere in the while loop with the condition "que.size() > 0", but I cant find where. Here is the code:
import java.util.*;
import java.io.*;
public class marblestree
{
public static ArrayList<ArrayList<Integer>> adjList = new ArrayList<>();
public static ArrayList<Integer> values = new ArrayList<>();
public static ArrayList<Integer> leaves = new ArrayList<>();
public static void main(String args[]) throws IOException
{
Scanner in = new Scanner(System.in);
int n = 1;
while (n > 0)
{
n = in.nextInt();
if (n == 0)
break;
for (int i = 0; i < n; i++)
{
adjList.add(new ArrayList<Integer>());
}
for (int j = 0; j < n; j++)
{
in.nextInt();
values.add(in.nextInt());
int adjNum = in.nextInt();
for (int m = 0; m < adjNum; m++)
{
adjList.get(in.nextInt() - 1).add(j);
}
if (adjNum == 0)
leaves.add(j);
}
//System.out.println("adjList: " + adjList);
//handle case
LinkedList<Integer> que = new LinkedList<>();
for (Integer y : leaves)
{
que.add(y);
}
int moves = 0;
adjList.get(0).add(0);
while (que.size() > 0)
{
//System.out.println("next, this is currently the que: " + que);
//System.out.println("and these are the values at each vertex:" + values);
int now = que.poll();
if (now != 0)
{
if (adjList.get(now).get(0) > 0 && !que.contains(adjList.get(now).get(0)))
que.add(adjList.get(now).get(0));
moves += Math.abs(values.get(now) - 1);
values.set(adjList.get(now).get(0), values.get(adjList.get(now).get(0)) + (values.get(now) - 1));
values.set(now, 1);
}
}
System.out.println(moves);
adjList = new ArrayList<>();
values = new ArrayList<>();
leaves = new ArrayList<>();
}
}
}

Related

Formatting a string in a textarea javafx using escape sequences

Super simple question, but I can't figure it out for the life of me. I'm connecting to a database and selecting a table and outputting the tables contents into a text area. It works, but the output gets all bunched up if one of the table's contents is longer/shorter.
How can I make my current output more formatted preferably using escape sequences?
Here's my current code:
ta.appendText(rsMetaData.getColumnName(i)+ " \t"); //outputs the table column names
while (rSet.next()) { // this outputs the tables contents
for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
ta.appendText(rSet.getObject(i) + " \t");
}
ta.appendText("\n");
}
The current output looks like this
deptName chairID collegeID deptID
Biology 111221118 SC BIOL
Chemistry 111221119 SC CHEM
Computer Science 111221115 SC CS
Mathematics 111221116 SC MATH
It might not look bad on here, but in table form it looks kinda crap. I imagine it's because of the tabs. I tried to use a few escape sequences, but it doesn't work with text areas or something.
I suggest you use a TableView. If you don't want to use a TableView, then it is a matter of simple math and making sure you use a Monospace font. In this example app I find the longest word for each column. Then I determine how many spaces needed to be added to words that are shorter than the longest word. Then I add four more spaces to create a complete column.
Used to set the TextArea font to a monospaced font
textArea.setStyle("-fx-font-family: monospace");
Used to find the longest String in each column.
List<Integer> longestDataLengths = new ArrayList();//This variable is global
void findLongestDataLengthsForColumns(List<List<String>> fakeData)
{
for (int i = 0; i < fakeData.size(); i++) {
for (int ii = 0; ii < fakeData.get(i).size(); ii++) {
if (i == 0) {
longestDataLengths.add(fakeData.get(i).get(ii).length());
//System.out.println("added: " + fakeData.get(i).get(ii));
}
else {
//System.out.println("adding: " + i);;//+ fakeData.get(i).get(ii));
if (fakeData.get(i).get(ii).length() > longestDataLengths.get(ii)) {
longestDataLengths.set(ii, fakeData.get(i).get(ii).length());
}
}
}
}
}
Used to find the number of spaces needed to complete a column's length
int numberOfSpacesNeeded(int longestLength, String entry)
{
int numberOfSpaceAfterLongestLength = 4;
System.out.println("space needed: " + (longestLength - entry.length() + numberOfSpaceAfterLongestLength));
return longestLength - entry.length() + numberOfSpaceAfterLongestLength;
}
Used to create the extra spaces/spaces needed
String createSpace(int numberOfSpaces)
{
StringBuilder spaces = new StringBuilder();
for (int i = 0; i < numberOfSpaces; i++) {
spaces.append(" ");
}
return spaces.toString();
}
Complete Example
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication261 extends Application
{
List<Integer> longestDataLengths = new ArrayList();
#Override
public void start(Stage primaryStage)
{
// for (List<String> line : getFakeDBData()) {
// System.out.println(line);
// }
List<List<String>> fakeData = getFakeDBData();
findLongestDataLengthsForColumns(fakeData);
// for (Integer entry : longestDataLengths) {
// System.out.println(entry);
// }
TextArea textArea = new TextArea();
textArea.setStyle("-fx-font-family: monospace");
for (List<String> line : fakeData) {
for (int i = 0; i < line.size(); i++) {
textArea.appendText(line.get(i) + createSpace(numberOfSpacesNeeded(longestDataLengths.get(i), line.get(i))));
}
textArea.appendText("\n");
}
StackPane root = new StackPane(textArea);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
List<List<String>> getFakeDBData()
{
List<List<String>> fakeData = new ArrayList();
String data = "deptName chairID collegeID deptID\n"
+ "Biology 111221118 SC BIOL\n"
+ "Chemistry 111221119 SC CHEM\n"
+ "Computer_Science 111221115 SC CS\n"
+ "Mathematics 111221116 SC MATH";
for (String line : Arrays.asList(data.split("\n"))) {
fakeData.add(Arrays.asList(line.split(" ")));
}
return fakeData;
}
//
void findLongestDataLengthsForColumns(List<List<String>> fakeData)
{
for (int i = 0; i < fakeData.size(); i++) {
for (int ii = 0; ii < fakeData.get(i).size(); ii++) {
if (i == 0) {
longestDataLengths.add(fakeData.get(i).get(ii).length());
//System.out.println("added: " + fakeData.get(i).get(ii));
}
else {
//System.out.println("adding: " + i);;//+ fakeData.get(i).get(ii));
if (fakeData.get(i).get(ii).length() > longestDataLengths.get(ii)) {
longestDataLengths.set(ii, fakeData.get(i).get(ii).length());
}
}
}
}
}
String createSpace(int numberOfSpaces)
{
StringBuilder spaces = new StringBuilder();
for (int i = 0; i < numberOfSpaces; i++) {
spaces.append(" ");
}
return spaces.toString();
}
int numberOfSpacesNeeded(int longestLength, String entry)
{
int numberOfSpaceAfterLongestLength = 4;
System.out.println("space needed: " + (longestLength - entry.length() + numberOfSpaceAfterLongestLength));
return longestLength - entry.length() + numberOfSpaceAfterLongestLength;
}
}
Results

C# Threading, My static variable not getting locked

I have many static variables in my application and methods which modify those variables. Please find an example code below. Can somebody tell me how to lock my static variable in the following example. It's not getting locked
using System.Threading;
using System;
namespace ThreadTest
{
public class Program
{
public static void Main(string[] args)
{
MyTest.TestVar = 0;
Thread th = new Thread(ThreadB);
Thread th1 = new Thread(ThreadC);
th1.Start();
Console.WriteLine("Thread B started:");
th.Start();
Console.WriteLine("Thread C started :");
for (int i = 0; i < 10; i++)
{
MyTest.TestVar = Convert.ToInt32(MyTest.TestVar) + 1;
Console.WriteLine("A " + MyTest.TestVar);
Thread.Sleep(100);
}
Console.WriteLine("Threads completed");
}
public static void ThreadB()
{
lock (MyTest.TestVar)
{
for (int i = 0; i < 10; i++)
{
MyTest.TestVar = Convert.ToInt32(MyTest.TestVar) + 1;
Console.WriteLine("B " + MyTest.TestVar);
Thread.Sleep(10);
}
}
}
public static void ThreadC()
{
for (int i = 0; i < 10; i++)
{
MyTest.TestVar = Convert.ToInt32(MyTest.TestVar) + 1;
Console.WriteLine("C " + MyTest.TestVar);
//Thread.Sleep(100);
}
}
}
public class MyTest
{
public static Object TestVar;
}
}
Fiddle here https://dotnetfiddle.net/dBJpo2
Use lock statement for your issue. Use sample code like below.
Declare and instantiate a private object variable in your console app that will be used to lock access to TestVar.
//declare a private variable for locking
private Object obj = new Object() ;
Then, enclose the statement where TestVar is being incremeted by 1 within a lock statement.
//use lock to synchronize access to
//property TestVar
lock (obj)
{
MyTest.TestVar = Convert.ToInt32(MyTest.TestVar) + 1;
}
After above steps, C# runtime will only allow one thread at a time to execute the line of code that changes the value of TestVar.

NullPointer for list within map

This is a homework assignment, so explanations and pointers are preferred to solutions. Our previous assignment was to create a Graph template using an adjacency-matrix. This homework assignment was to modify the previous one using an adjacency-list instead. I have the previous matrix based code commented out for reference.
import java.util.*;
public class Graph {
public Node rootNode;
public List<Node> nodes = new ArrayList<Node>();
Map<Integer, List<Integer>> adjList;
//public int[][] adjMatrix;
int size;
public void setRootNode(Node n) {
rootNode = n;
}
public Node getRootNode() {
return rootNode;
}
public void addNode(Node n) {
nodes.add(n);
}
// This method will be called to make connect two nodes
public void connectNode(Node src, Node dst) {
// if (adjMatrix == null)
// {
// size = nodes.size();
// adjMatrix = new int[size][size];
// }
int srcIndex = nodes.indexOf(src);
int dstIndex = nodes.indexOf(dst);
// adjMatrix[srcIndex][dstIndex] = 1;
// adjMatrix[dstIndex][srcIndex] = 1;
if (!adjList.containsKey(srcIndex))
adjList.put(srcIndex, new ArrayList<Integer>());
adjList.get(srcIndex).add(dstIndex);
if (!adjList.containsKey(dstIndex))
adjList.put(dstIndex, new ArrayList<Integer>());
adjList.get(dstIndex).add(srcIndex);
}
private Node getUnvisitedChildNode(Node n) {
int index = nodes.indexOf(n);
for (int j = 0; j < size; j++)
//if (adjMatrix[index][j] == 1 && ((Node) nodes.get(j)).visited == false)
if (adjList.containsKey(index) && ((Node) nodes.get(j)).visited == false)
return nodes.get(j);
return null;
}
// BFS traversal: iterative version
public void bfs() {
// BFS uses a Queue data structure
Queue<Node> q = new LinkedList<Node>();
q.add(rootNode);
printNode(rootNode);
rootNode.visited = true;
while (!q.isEmpty()) {
Node n = q.remove();
Node child = null;
while ((child = getUnvisitedChildNode(n)) != null) {
child.visited = true;
printNode(child);
q.add(child);
}
}
}
// DFS traversal: iterative version
public void dfs() {
// DFS uses a Stack data structure
Stack<Node> s = new Stack<Node>();
s.push(rootNode);
rootNode.visited = true;
printNode(rootNode);
while (!s.isEmpty()) {
Node n = s.peek();
Node child = getUnvisitedChildNode(n);
if (child != null) {
child.visited = true;
printNode(child);
s.push(child);
} else
s.pop();
}
}
// Utility methods for clearing visited property of node
private void reset() {
for (Node n : nodes)
n.visited = false;
}
// Utility methods for printing the node's label
private void printNode(Node n) {
System.out.print(n.label + " ");
}
// get all neighboring nodes of node n.
public List<Node> getNeighbors(Node n) {
int srcIndex = nodes.indexOf(n);
List<Node> neighbors = new ArrayList<Node>();
// for (int j = 0; j < adjMatrix[srcIndex].length; j++)
// if (adjMatrix[srcIndex][j] == 1)
for (int j = 0; j < adjList.get(srcIndex).size(); j++)
if (adjList.get(srcIndex).contains(j))
neighbors.add(nodes.get(j));
return neighbors;
}
// implement recursive version of dfs
public void dfs(Node n) {
printNode(n); // visit the node
n.visited = true;
for (Node node : getNeighbors(n))
if (!node.visited)
dfs(node);
}
static class Node {
public char label;
public boolean visited = false;
public Node(char label) {
this.label = label;
}
}
public static void main(String[] args) {
// Lets create nodes as given as an example in the article
Node n0 = new Node('0');
Node n1 = new Node('1');
Node n2 = new Node('2');
Node n3 = new Node('3');
Node n4 = new Node('4');
Node n5 = new Node('5');
Node n6 = new Node('6');
Node n7 = new Node('7');
Node n8 = new Node('8');
// Create the graph, add nodes, create edges between nodes
Graph g = new Graph();
g.addNode(n0);
g.addNode(n1);
g.addNode(n2);
g.addNode(n3);
g.addNode(n4);
g.addNode(n5);
g.addNode(n6);
g.addNode(n7);
g.addNode(n8);
g.setRootNode(n8);
g.connectNode(n0, n1);
g.connectNode(n0, n3);
g.connectNode(n0, n8);
g.connectNode(n1, n7);
g.connectNode(n3, n2);
g.connectNode(n3, n4);
g.connectNode(n3, n4);
g.connectNode(n4, n8);
g.connectNode(n2, n7);
g.connectNode(n2, n5);
g.connectNode(n5, n6);
// Perform the DFS and BFS traversal of the graph
// System.out.print("DFS Traversal (Iterative): ");
// g.dfs();
// g.reset();
System.out.print("\nDFS Traversal (Recursive): ");
g.dfs(g.getRootNode());
g.reset();
System.out.print("\nBFS Traversal (Iterative): ");
g.bfs();
g.reset();
}
}
I'm getting a Null pointer in the connectNode method where I bring in the ArrayList. Again please keep in mind this is homework. Thank you in advance for all your help.
edit: How do you get line numbers to appear within stackoverflow?
if (!adjList.containsKey(srcIndex)) your adjList is null. You never set this List in your object.

Java Game Application Working in Eclipse, but not as a .jar (Slick2D + LWJGL)

Today I was going to pack my game into a Jar to provide to a friend who codes and wanted to see a nice glitch I managed to create. When I went to make it a Runnable jar it would load up in the Command Prompt but throw Resource Not Found errors for Sounds (.ogg's), which was fine because they werent going to be used in the Debug mode it was set to. Then it threw a NullPointerException in TileHanlder.class at initTileMap() line 137.
I am at a loss so I came to StackOverflow because I have spent nearly my entire day on getting a working Jar. I have also tried JarSplice.
My main question is if there is any anomalies you notice or something I didnt do that is leading to resources not being found in the .jar.
ALL CODE AND RESOURCES WERE IN THE SAME JAR, ONE JAR FOR EVERYTHING there were not multiple jars
For ALL my code (it is OpenSource after all: Game Source Code)
Level.java (The class calling AssetHandler and TileHandler)
public class Level extends BasicGameState {
public MapHandler map = new MapHandler();
public AssetHandler asset = new AssetHandler();
static OutputHandler out = new OutputHandler();
public GameContainer container;
public StateBasedGame game;
public static float MouseX = 0;
public static float MouseY = 0;
public float RectX = 0;
public float RectY = 0;
public int tileAmount = 0;
public static int mapID = 1;
public static int delta;
public static int score = 0;
private static int EntityAmount = 0;
private static int ActiveEntityAmount = 0;
private int FPS = 0;
public static Image mapImage;
public static TileHandler Tile = new TileHandler();
public Point mousePoint;
public Circle mouseCirc;
public static Player p;
public static Enemy Blinky, Pinky, Inky, Clyde;
public static EntityAI AGGRESSIVE, AMBUSH, HIT_RUN, SORTOFRANDOM;
public Level(int id) {
}
#Override
public void init(GameContainer container, StateBasedGame game) throws SlickException {
MapHandler.mapRect();
mapID = MapHandler.getMapID();
MapHandler.deployMap(mapID);
try {
asset.initAssets();
OutputHandler.initFont();
} catch (AssetException e) {
e.printStackTrace();
}
TileHandler.initTileMap();
container.setUpdateOnlyWhenVisible(true);
container.setShowFPS(false);
container.setSmoothDeltas(false);
container.setVerbose(true);
this.container = container;
this.game = game;
AGGRESSIVE = new RedAI();
AMBUSH = new PinkAI();
HIT_RUN = new BlueAI();
SORTOFRANDOM = new OrangeAI();
p = new Player("Player1");
Blinky = new Enemy("Shadow", AGGRESSIVE);
Pinky = new Enemy("Speedy", AMBUSH);
Inky = new Enemy("Bashful", HIT_RUN);
Clyde = new Enemy("Pokey", SORTOFRANDOM);
}
#Override
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
Tile.drawTileMap(TileHandler.tileLayer, TileHandler.tMapTiles, g);
if (Reference.debug) {
displayTileBounds(TileHandler.tileLayer, g);
}
drawEntities();
drawStrings(g);
}
#Override
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
Input in = container.getInput();
MouseX = in.getMouseX();
MouseY = in.getMouseY();
RectX = MapHandler.Map32.getX();
RectY = MapHandler.Map32.getY();
EntityAmount = Entity.entityList.size();
ActiveEntityAmount = Enemy.enemyList.size() + Projectile.activeProjectiles.size() + 1;
Level.delta = delta;
Reference.defProjectileVelocity = .13f * Level.delta;
p.update(in);
updateNonPlayerEntities();
FPS = container.getFPS();
}
#Override
public int getID() {
return 2;
}
/** #deprecated **/
#Deprecated
protected void drawMap(Graphics g) {
g.drawImage(mapImage, Reference.MAP_X, Reference.MAP_Y);
}
protected void drawStrings(Graphics g) {
if (Reference.debug) {
OutputHandler.write("FPS: " + Integer.toString(FPS), 11, 10);
OutputHandler.write(String.format("Mouse X: %s, Mouse Y: %s", MouseX, MouseY), 11, 30);
OutputHandler.write(String.format("Rect X: %s, Y: %s", RectX, RectY), 11, 50);
OutputHandler.write("Amount of Tiles: " + (TileHandler.tileLayer.length * TileHandler.tileLayer[0].length), 11, 70);
OutputHandler.write(String.format("Amount of Entities = %s", Integer.toString(EntityAmount)), 11, 90);
OutputHandler.write(String.format("Active Entities = %s", Integer.toString(ActiveEntityAmount)), 11, 110);
out.write("Currently Loaded: " + p.isReloaded(), 11, 130);
OutputHandler.write("Amount of Entities is Accumulative", 11, 666);
} else {
String curTime = Reference.getTime();
String scoreStr = Reference.convertScore(score);
OutputHandler.write("Time: " + curTime, 11, 10);
OutputHandler.write("Score: " + scoreStr, 550, 10);
}
}
protected void displayTileBounds(Rectangle[][] tileLayer, Graphics g) {
g.setColor(Color.white);
for (int x = 0; x < tileLayer.length; x++) {
for (int y = 0; y < tileLayer[0].length; y++) {
g.fill(tileLayer[x][y]);
}
}
g.setColor(Color.magenta);
for (int s = 0; s < TileHandler.collisionTiles.size(); s++) {
Rectangle r = TileHandler.collisionTiles.get(s);
g.fill(r);
}
g.setColor(Color.orange);
g.fill(p.boundingBox);
for (int z = 0; z < Entity.teleportingTiles.length; z++) {
Rectangle r = Entity.teleportingTiles[z];
g.fill(r);
}
}
protected void drawEntities() {
ArrayList<Entity> list = Entity.entityList;
for (int i = 0; i < list.size(); i++) {
list.get(i).drawEntity(list.get(i));
}
}
protected void updateNonPlayerEntities() {
ArrayList<Enemy> list = Enemy.enemyList;
for (int i = 0; i < list.size(); i++) {
list.get(i).update();
}
ArrayList<Projectile> pList = Projectile.activeProjectiles;
for (int p = 0; p < pList.size(); p++) {
pList.get(p).update();
}
}
}
The AssetHandler (Game-Handlers-AssetHandler.java) Sounds are the THIRD TO LAST METHOD
public class AssetHandler {
public static boolean isComplete = false;
private static String musPath = "res/Sounds/";
static TileHandler tile;
private static int tsize = 32;
private static String spritesPath = "res/GameSprites/Maze Game/sprites.png";
private static String terrainPath = "res/GameSprites/Maze Game/terrain.png";
private static String twPath = "res/GameSprites/Maze Game/animation/tankToWest.png";
private static String tePath = "res/GameSprites/Maze Game/animation/tankToEast.png";
private static String tnPath = "res/GameSprites/Maze Game/animation/tankToNorth.png";
private static String tsPath = "res/GameSprites/Maze Game/animation/tankToSouth.png";
private static String bwPath = "res/GameSprites/Maze Game/animation/blueToWest.png";
private static String bePath = "res/GameSprites/Maze Game/animation/blueToEast.png";
private static String bnPath = "res/GameSprites/Maze Game/animation/blueToNorth.png";
private static String bsPath = "res/GameSprites/Maze Game/animation/blueToSouth.png";
private static String rePath, rwPath, rsPath, rnPath;
private static String pePath, pwPath, psPath, pnPath;
private static String oePath, owPath, osPath, onPath;
public static Music titleMus1, titleMus2, titleMus3, loadingScreenMus1, loadingScreenMus2, loadingScreenMus3;
public static Sound tankMove, tankFire, tankExplode, tankSurrender, tankRetreat;
public static void initSounds() {
System.out.println("Initializing Main Menu Music...");
try {
titleMus1 = new Music(musPath + "title/titlefirst.ogg");
titleMus2 = new Music(musPath + "title/titlesecond.ogg");
titleMus3 = new Music(musPath + "title/titlethird.ogg");
System.out.println("Initialized Main Menu Music!...");
} catch (SlickException e) {
e.printStackTrace();
System.out.println("ERROR: Initializing Main Menu Sounds at " + "com.treehouseelite.tank.game.handlers.AssetHandler" + " : initSounds() Method, First Try/Catch");
}
System.out.println("Initializing Loading Screen Music...");
try {
loadingScreenMus1 = new Music(musPath + "levels or loading screens/ActionBuilder.ogg");
loadingScreenMus2 = new Music(musPath + "levels or loading screens/StruggleforSurvival.ogg");
loadingScreenMus3 = new Music(musPath + "levels or loading screens/SurrealSomber.ogg");
} catch (SlickException e) {
e.printStackTrace();
System.out.println("ERROR: Initializing Loading Screen Sounds at " + "com.treehouseelite.tank.game.handlers.AssetHandler" + " : initSounds() Method, Second Try/Catch");
}
initSFX();
initsComplete();
}
private static void initsComplete() {
System.out.println("========================ALL ASSETS INITIALIZED========================");
}
public static void initSFX() {
try {
tankMove = new Sound("res/Sounds/SFX/tankMove.wav");
} catch (SlickException e) {
e.printStackTrace();
} finally {
System.out.println("All Sound Effects Initialized...");
}
}
}
TileHandler.java (Game-Handlers-TileHandler.java)
public class TileHandler {
public static String mapPath = "res/World/level_";
public static int bg, paths, collision;
public static Image[][] tMapTiles = new Image[25][20];
public static boolean[][] collidableTile = new boolean[25][20];
static Graphics g = new Graphics();
static AssetHandler asset = new AssetHandler();
// The Amount of Image is too damn high!
static TiledMap tMap;
public static int wFrame = 0;
private static int id;
public static Rectangle[][] tileLayer = new Rectangle[25][20];
public static ArrayList<Rectangle> collisionTiles = new ArrayList<Rectangle>(500);
public TileHandler() {
}
public TileHandler(int id, Rectangle rect) {
TileHandler.id = id;
try {
createTiles(id, rect);
} catch (SlickException e) {
e.printStackTrace();
}
}
protected void createTiles(int id, Rectangle layer) throws SlickException {
// Scans 0,0 to 0,20 of the tiles and then moves down the x line
// gettings tiles
// 0,0 = tileLayer[0][0]
mapPath = String.format("res/World/level_%s.tmx", id);
tMap = new TiledMap(mapPath);
bg = tMap.getLayerIndex("background");
paths = tMap.getLayerIndex("paths");
collision = tMap.getLayerIndex("collision");
// Constructs a Grid of Rectangles based on the Map's Top Left point
for (int i = 0; i < tileLayer.length; i++) {
for (int y = 0; y < tileLayer[0].length; y++) {
Rectangle tile = new Rectangle((i + Reference.MAP_X) + (i * Reference.TILE_SIZE), (y + Reference.MAP_Y) + (y * Reference.TILE_SIZE), 32, 32);
tileLayer[i][y] = tile;
}
}
/*
* for(int x = 0; x<collisionTiles.length; x++){ for(int y = 0;
* y<collisionTiles[0].length; y++){ Rectangle tile = new
* Rectangle((x+Reference.MAP_X) + (x*31),
* (y+Reference.MAP_Y+14)+(y*31),32,32); collisionTiles[x][y] = tile; }
* }
*/
}
/** #deprecated */
#Deprecated
public static void initSprites(Rectangle[][] layer) {
bg = tMap.getLayerIndex("background");
paths = tMap.getLayerIndex("paths");
collision = tMap.getLayerIndex("collision");
System.out.println("Initialized Sprites!");
}
// Initializes all tiles and put them into Image and Boolean Arrays
// Boolean Array for later use with determining whether the player or entity
// can be there. (collidableTile)
// Image array holds the tiles (tMapTiles)
public static void initTileMap() {
new Graphics();
// Getting Tiles based off Tile ID's
/** DIRT PATH MAPS (Dev Map, Level 1) **/
if ((id == 0) || (id == 1)) {
for (int x = 0; x < tileLayer.length; x++) {
for (int y = 0; y < tileLayer[0].length; y++) {
Rectangle r = new Rectangle(tileLayer[x][y].getX(), tileLayer[x][y].getY(), 32, 32);
if (tMap.getTileId(x, y, bg) == 1) {
tMapTiles[x][y] = AssetHandler.sparseGrass;
}
if (tMap.getTileId(x, y, collision) == 2) {
tMapTiles[x][y] = AssetHandler.water11;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 57) {
tMapTiles[x][y] = AssetHandler.concrete1;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 71) {
tMapTiles[x][y] = AssetHandler.concrete2;
// collisionTiles.add(new
// Rectangle(tileLayer[x][y].getX(),
// tileLayer[x][y].getY()+14, 32, 32)) ;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 85) {
tMapTiles[x][y] = AssetHandler.concrete3;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 72) {
tMapTiles[x][y] = AssetHandler.metal1;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 58) {
tMapTiles[x][y] = AssetHandler.metal2;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, paths) == 50) {
tMapTiles[x][y] = AssetHandler.hDirtPath;
}
if (tMap.getTileId(x, y, paths) == 60) {
tMapTiles[x][y] = AssetHandler.dirtPath;
}
if (tMap.getTileId(x, y, paths) == 59) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn4;
}
if (tMap.getTileId(x, y, paths) == 73) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn3;
}
if (tMap.getTileId(x, y, paths) == 79) {
tMapTiles[x][y] = AssetHandler.dirtThreewayRight;
}
if (tMap.getTileId(x, y, paths) == 46) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn1;
}
if (tMap.getTileId(x, y, paths) == 37) {
tMapTiles[x][y] = AssetHandler.hDirtCrossing1;
}
if ((tMap.getTileId(x, y, paths) == 80) || (tMap.getTileId(x, y, paths) == 88)) {
tMapTiles[x][y] = AssetHandler.dirtThreewayLeft;
}
if (tMap.getTileId(x, y, paths) == 102) {
tMapTiles[x][y] = AssetHandler.dirtThreewayDown;
}
if (tMap.getTileId(x, y, paths) == 74) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn2;
}
if (tMap.getTileId(x, y, paths) == 107) {
tMapTiles[x][y] = AssetHandler.dirtThreewayUp;
}
if (tMap.getTileId(x, y, paths) == 88) {
tMapTiles[x][y] = AssetHandler.dirtCrossroads;
}
}
}
}
}
public void drawTileMap(Rectangle[][] layer, Image[][] tiles, Graphics g) {
// Loops through the Image array and places tile based on the Top Left
// corner of the Rectangle in the rectangle array
// Rectangle Array = layer (tileLayer was passed)
// Image Array = tiles (tMapTiles was passed)
// Asset Refers to Asset Handler
for (int x = 0; x < layer.length; x++) {
for (int y = 0; y < layer[0].length; y++) {
g.drawImage(tiles[x][y], layer[x][y].getX(), layer[x][y].getY());
// Below here is image detection for the placement of Animations
if (tiles[x][y] == AssetHandler.water11) {
AssetHandler.vRiver1.draw(layer[x][y].getX(), layer[x][y].getY());
AssetHandler.vRiver1.start();
AssetHandler.vRiver1.update(Level.delta);
} else if (tiles[x][y] == AssetHandler.hDirtCrossing1) {
AssetHandler.hDirtCrossing.draw(layer[x][y].getX(), layer[x][y].getY());
AssetHandler.hDirtCrossing.start();
AssetHandler.hDirtCrossing.update(Level.delta);
}
}
}
}
}
Finally, MapHandler.java -- Very Sparsely used, Main goal is to intialize a TileHandler object to construct the tile grid for constructing the TiledMap.
public class MapHandler {
public static AssetHandler asset = new AssetHandler();
static Image devMap;
Image map_1;
Image map_2;
Image map_3;
public static Rectangle Map32;
public MapHandler() {
}
// Sends a Rectangle set Around the Map Image to TileHandler
// to construct a grid of 32x32 Rectangles inside the Map's Rectangle
public static void deployMap(int id) {
if (id == 0) {
new TileHandler(id, Map32);
}
}
// Randomly Generates a Map ID corresponding to a Level_X.tmx
// Currently set to 0 for development purposes
public static int getMapID() {
new Random();
return 0;
// return id;
}
/* Create the Rectangle and Grid */
public static void mapRect() throws SlickException {
System.out.println("Initializing Rectangular Plane...");
Map32 = new Rectangle(Reference.GUI_WIDTH / 24, Reference.GUI_HEIGHT / 24, 800, 640);
System.out.println("Map32 Initialized!...");
}
}
If You need ANY other resources or information than please let me know and I will be happy to provide so I can get over this. I will also be thinking of other ways, Thank you for any responses!
THINGS WERE CUT OUT DUE TO THE 30k Char Limit on the question text box. Mostly in the insanely crowded AssetHandler.java, it is still there in the git repository though.
I had the very same problem. After searching for a while, I came across this neat solution. See this LWJGL forum post.
public static void main(String[] args) throws SlickException {
/* Set lwjgl library path so that LWJGL finds the natives depending on the OS. */
String osName = System.getProperty("os.name");
// Get .jar dir. new File(".") and property "user.dir" will not work if .jar is called from
// a different directory, e.g. java -jar /someOtherDirectory/myApp.jar
String nativeDir = "";
try {
nativeDir = new File(GameMain.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
} catch (URISyntaxException uriEx) {
try {
// Try to resort to current dir. May still fail later due to bad start dir.
uriEx.printStackTrace();
nativeDir = new File(".").getCanonicalPath();
} catch (IOException ioEx) {
// Completely failed
ioEx.printStackTrace();
JOptionPane.showMessageDialog(new JFrame(), "Failed to locate native library directory. " +
"Error:\n" + ioEx.toString(), "Error", JOptionPane.ERROR_MESSAGE);
System.exit(-1);
}
}
// Append library subdir
nativeDir += File.separator + "lib" + File.separator + "native" + File.separator;
if (osName.startsWith("Windows")) {
nativeDir += "windows";
} else if (osName.startsWith("Linux") || osName.startsWith("FreeBSD")) {
nativeDir += "linux";
} else if (osName.startsWith("Mac OS X")) {
nativeDir += "macosx";
} else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
nativeDir += "solaris";
} else {
JOptionPane.showMessageDialog(new JFrame(), "Unsupported OS: " + osName + ". Exiting.",
"Error", JOptionPane.ERROR_MESSAGE);
System.exit(-1);
}
System.setProperty("org.lwjgl.librarypath", nativeDir);
}
Bear in mind that you need a lib folder in the same directory. I have mine stored outside of the .jar, but it may be possible to have it inside as well. Also note that it needs to happen before you do any LWJGL stuff, so the main method is a good place.

How to signal waithandle.waitany when doing async requests?

I'm using the following sample code to fetch some HTML Pages using async requests.
I don't want to wait until every request is completed that is using WaitHandle.WaitAll, just until the correct value is found. I'm currently doing it this way, but it feels wrong to send ManualResetEvents to the thread. Is it how it should be done? Is there a better way?
public static void runprogram()
{
System.Net.ServicePointManager.DefaultConnectionLimit = 20;
FetchPageDelegate del = new FetchPageDelegate(FetchPage);
List<HtmlDocument> htmllist = new List<HtmlDocument>();
List<IAsyncResult> results = new List<IAsyncResult>();
List<WaitHandle> waitHandles = new List<WaitHandle>();
List<ManualResetEvent> handles = new List<ManualResetEvent>();
for (int i = 0; i < 20; i++)
{
ManualResetEvent e = new ManualResetEvent(false);
handles.Add(e);
}
for(int i = 0; i < 200; i += 10)
{
int y = 0;
string url = #"URLTOPARSE" + i;
IAsyncResult result = del.BeginInvoke(url, handles[y], null, null);
results.Add(result);
waitHandles.Add(result.AsyncWaitHandle);
y++;
}
//Here i check for a signal
WaitHandle.WaitAny(handles.ToArray());
//WaitHandle.WaitAll(waitHandles.ToArray());
foreach (IAsyncResult async in results)
{
FetchPageDelegate delle = (async as AsyncResult).AsyncDelegate as FetchPageDelegate;
HtmlDocument htm = delle.EndInvoke(async);
if(htm.DocumentNode.InnerHtml.Contains("ANYTHING TO CHECK FOR(ONLY A TEST"))
{
return;
}
}
}

Resources