Why am I getting this dynamic IndexOutOfBounds Exception? - class

I am trying to write a program where text is translated into hexadecimal, then into decimal, and then into an (R, G, B) format. However, when trying to incorporate ClickableRectangle, I get an ArrayIndexOutOfBounds exception that changes dynamically with the sign of rects.
Any thoughts on my problem/optimization?
char[] colors; //Array of characters to be translated into hexadecimal
String r = ""; //Red value of color
String g = ""; //Green value of color
String b = ""; //Blue value of color
int x = 0; //X-coordinate of rectangle
int y = 0; //Y-coordinate of rectangle
int q; //Character count
ClickableRectangle[] rects = new ClickableRectangle[400*400]; //Rectangles
void settings() {
size(displayWidth, displayHeight);
}
void setup() {
background(0);
colors = new char[3];
String s = ([INSERT TRANSCRIPT HERE]); //Too long to be in post//
for (int i = 0; i < s.length(); i+=3) {
for (int j = i; j < i+3; j++) {
colors[j-i] = s.charAt(j);
}
r = hex(colors[0], 2);
g = hex(colors[1], 2);
b = hex(colors[2], 2);
drawAPoint(r, g, b, i);
println(i);
q++;
}
save("SlachtochtFeuf.png"); //Ignore this, using for testing purposes
println("q = " + q);
println("x = " + x);
println("y = " + y);
}
void draw() {
for (int i = 0; i < rects.length; i++) {
if (rects[i].isClicked()) {
println(rects[i].getValue()); //Prints char representation of color
}
}
}
void drawAPoint(String r2, String g2, String b2, int i) {
noStroke();
fill(unhex(r2), unhex(g2), unhex(b2));
rects[i] = new ClickableRectangle(x, y, r2, g2, b2);
rects[i].display();
if (x >= width) {
x = 0;
y += 6;
} else {
x+=6;
}
}
class ClickableRectangle {
int x = 0;
int y = 0;
String r = "";
String g = "";
String b = "";
public ClickableRectangle(int x, int y, String r, String g, String b) {
this.x = x;
this.y = y;
this.r = r;
this.g = g;
this.b = b;
}
public void display() {
fill(unhex(r), unhex(g), unhex(b));
rect(x, y, 6, 6);
}
public void setRGB(String r, String g, String b) {
this.r = r;
this.g = g;
this.b = b;
}
public String getValue() {
return ""+char(unhex(r))+char(unhex(g))+char(unhex(b));
}
public boolean isClicked() {
return mouseX > x && mouseY > y && mouseX < x+6 && mouseY < y+6;
}
}

For future reference, you should tell us exactly which line throws the exception, and you should include all of the code needed to repeat the problem. If the text is too long to post, then narrow it down to a smaller MCVE.
But judging from what I can see, the problem appears to be here:
String s = "test";
for (int i = 0; i < s.length(); i+=3) {
for (int j = i; j < i+3; j++) {
colors[j-i] = s.charAt(j);
}
//other stuff
}
Just run through this in your head:
When i=0 and j=0, you access charAt 0.
When i=0 and j=1, you access charAt 1.
When i=0 and j=2, you access charAt 2.
When i=3 and j=3, you access charAt 3.
When i=3 and j=4, you access charAt 4.
You could also use println() statements to better see what's going on:
for (int i = 0; i < s.length(); i+=3) {
println("i: " + i);
for (int j = i; j < i+3; j++) {
println("j: " + j);
colors[j-i] = s.charAt(j);
}
//other stuff
}
That prints out:
i: 0
j: 0
j: 1
j: 2
0
i: 3
j: 3
j: 4
That last part is the problem- the String I'm using is "test", so it only has 4 characters: charAt(0), charAt(1), charAt(2), and charAt(3). So when you try to access charAt(4), it throws a StringIndexOutOfBoundsException!
I don't know exactly what you're trying to do here, but you'll have to rework your code so that it doesn't try to access characters outside the bounds of the String.
As a side note: it looks like you're trying to code your whole project all at once. Don't do that. Instead, develop this in small increments- try to get smaller pieces working by themselves before you combine them into your whole project. Can you write a separate sketch that simply loops over a String and prints out the characters you're trying to extract? Then if you get stuck, you can use that smaller sketch as your MCVE, and it'll be easier for us to help you.

Related

When running a method of a class I get a 'unexpected token: (' error message

I am new to java and I am using processing. I am just learning to how use classes is java and I am getting confusing error messages when I run a method. the error message is 'unexpected token: (' the error as at the p.setPieces(pawn, white); line
here is my code:
int ranks = 8;
int files = 8;
int spacing;
// set the values for all the pieces and colors
int empty = 0;
int pawn = 1;
int knight = 2;
int bishop = 3;
int rook = 4;
int queen = 5;
int king = 6;
int white = 8;
int black = 16;
Piece p = new Piece();
p.setPiece(pawn, white);
void setup() {
size(600, 600);
spacing = width / ranks;
}
void draw() {
background(0);
// draw the board
for (int i = 0; i < ranks; i++) {
for (int j = 0; j < files; j++) {
if ((i + j) % 2 == 0) {
noStroke();
fill(255);
rect(i * spacing, j * spacing, spacing, spacing);
} else {
noStroke();
fill(0);
rect(i * spacing, j * spacing, spacing, spacing);
}
}
}
}
and then in a different file I have:
class Piece {
// make variables for color and type of a piece
int pieceType;
int pieceColor;
// set up type and color
void setPiece(int Type, int Color) {
pieceType = Type;
pieceColor = Color;
}
}
As khelwood and luk2302 mentioned, simply move p.setPiece(pawn, white); in setup() (preferably after size()):
int ranks = 8;
int files = 8;
int spacing;
// set the values for all the pieces and colors
int empty = 0;
int pawn = 1;
int knight = 2;
int bishop = 3;
int rook = 4;
int queen = 5;
int king = 6;
int white = 8;
int black = 16;
Piece p = new Piece();
void setup() {
size(600, 600);
spacing = width / ranks;
p.setPiece(pawn, white);
}
void draw() {
background(0);
// draw the board
for (int i = 0; i < ranks; i++) {
for (int j = 0; j < files; j++) {
if ((i + j) % 2 == 0) {
noStroke();
fill(255);
rect(i * spacing, j * spacing, spacing, spacing);
} else {
noStroke();
fill(0);
rect(i * spacing, j * spacing, spacing, spacing);
}
}
}
}
class Piece {
// make variables for color and type of a piece
int pieceType;
int pieceColor;
// set up type and color
void setPiece(int Type, int Color) {
pieceType = Type;
pieceColor = Color;
}
}
When using "active" mode (e.g. setup()/draw()) you can only declare variables (at the top), but not use them directly in the main block of code. You need to reference them within a function.

While/if Loop is not working in class

I'm learning java and I'm having an issue with my if code not running.
In the following code I'm trying to determine if a number (variable num) is a triangle number (1,3, 6, 10 etc). The code should run through and give the "Is Triangle". However it keeps spitting out Null.
I understand this is not the most effective way to do this code, but I am trying to learn how to use Classes.
public class HelloWorld {
public static void main(String[] args) {
class NumberShape {
int num = 45;
int tri = 0;
int triplus = 0;
String triresult;
public String triangle() {
while (tri < num) {
if (tri == num) {
triresult = "Is a Triangle";
System.out.println("Is a Triangle");
} else if (tri + (triplus + 1) > num){
triresult = "Is Not a Triangle";
} else {
triplus++;
tri = tri + triplus;
}
}
return triresult;
}
}
NumberShape result = new NumberShape();
System.out.println(result.triangle());
}
}
Thanks for any help provided.
Try this code :
public class HelloWorld {
public static void main(String[] args) {
class NumberShape {
int num = 10;//Try other numbers
int tri = 0;
int triplus = 0;
int res = 0;
String triresult = "Is Not a Triangle";
int[] tab= new int[num];
public String triangle() {
//to calculate the triangle numbers
for(int i = 0; i<num; i++){
res = res + i;
tab[i]=res;
}
//To check if num is a triangle or not
for(int i = 0; i<tab.length; i++){
System.out.println(">> " + i + " : " + tab[i]);
if(tab[i]== num){
triresult = num + " Is a Triangle";
break;//Quit if the condition is checked
}else{
triresult = num + " Is Not a Triangle";
}
}
return triresult;
}
}
NumberShape result = new NumberShape();
System.out.println(result.triangle());
}
}
Hope this Helps.
Step through the loop carefully. You'll probably see that there is a case where
(tri < num)
fails, and thus you fall out of the loop, while
(tri == num)
and
(tri + (triplus + 1) > num)
both fail too, so no text gets set before you fall out.
You probably want to do your if-tests within the method on just tri, not a modification of tri, so as to reduce your own confusion about how the code is working.

Dynamically adding tiles to a grid based map

I want to have an infinitely explorable map. The plan is to create categories of game tiles (roads, obstacles, buildings), and randomly choose a category of game tile to be added when the player approaches the edge of the existing set of tiles. Tiles will also be destroyed once the player is 2 grid squares away from that tile. Currently I am using a multidimensional array that requires a size initializer.
What I have so far:
public class GameManager : MonoBehaviour
{
private GameObject[,] tileArray;
public GameObject groundTile;
public GameObject player;
private int tileSize = 80;
private int nextFarX = 1;
private int nextFarZ = 1;
private int nextNearX = -1;
private int nextNearZ = -1;
private float padding = .1f;
private int arrayOffset;
private int arrayDimension;
// Use this for initialization
void Start ()
{
arrayDimension = 200;
arrayOffset = arrayDimension / 2;
tileArray = new GameObject[,];
this.AddCubeAt(0, 0);
}
// Update is called once per frame
void Update () {
var x = Convert.ToInt32(player.transform.position.x / tileSize);
var z = Convert.ToInt32(player.transform.position.z / tileSize);
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
var checkX = x + i;
var checkZ = z + j;
if (tileArray[checkX + arrayOffset, checkZ + arrayOffset] == null)
{
//player is less than 2 tiles away from this grid, add a tile
this.AddCubeAt(checkX, checkZ);
}
}
}
// feels like a hack, but it will remove tiles that are not touching the tile that the player occupies
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
if (i == 0 | i == 5 | j == 0 | j == 5)
{
if (tileArray[x + (i-2) + arrayOffset, z + (j-2) + arrayOffset] != null)
{
Destroy(tileArray[x + (i - 2) + arrayOffset, z + (j - 2) + arrayOffset]);
tileArray[x + (i - 2) + arrayOffset, z + (j - 2) + arrayOffset] = null;
}
}
}
}
}
private void AddCubeAt(int x, int z)
{
var pos = new Vector3(x * tileSize, 0, z * tileSize);
var rot = Quaternion.identity;
GameObject newCube = (GameObject)Instantiate(groundTile, pos, rot);
tileArray[x + arrayOffset, z + arrayOffset] = newCube;
}
}
What is a better way to approach this?
You should familiarize yourself with Graph Data Structure (not adjacency matrix implementation). It's much more appropriate for this task. And, I would solve this
Tiles will also be destroyed once the player is 2 grid squares away from that tile
in another way: Every time player changed his position I would start DFS on target depth (in your case it's 2) and remove found tiles.
Decided to go with a simple Dictionary and methods to query/update it:
private GameObject RetrieveTileAt(int x, int z)
{
string key = string.Format("{0}.{1}", x, z);
if (tileDictionary.ContainsKey(key))
{
return tileDictionary[key];
}
else
{
return null;
}
}
private void InsertTileAt(int x, int z, GameObject tile)
{
string key = string.Format("{0}.{1}", x, z);
tileDictionary[key] = tile;
}
It is not an infinitely sized grid, (int min + int max)squared, but it should be far more than I need.

issue in my if statement to make comparison in my java program

any help please, so i already wrote the prog but my if statement in my for loop is not working. the prog need to generate 6 random nos,then apply bubble sort which i already did.then the user must enter 6 numbers and these numbers must be compared against the random numbers and must say whether numbers are found in the random numbers or not. here's the code. something is wrong with the if statement ` public static void main(String[] args) {
try {
int numbers[] = new int[6]; //random numbers will be stored in new array
//2 loop will be created to avoid duplication of numbers
System.out.println("Array before Bubble sort");
for (int i = 0; i < 6; i++) {
numbers[i] = (int) (Math.random() * 40);
if (i > 0) {
for (int b = 0; b < i; b++) { //
if (numbers[b] == numbers[i]) {
i--; //decrement to continue the for loop if the integer has been repeated
}
}
}
System.out.print(numbers[i] + ","); //random numbers will be printed before using sorting bubble sort
}
//sort an array using bubble sort
bubbleSort(numbers);
System.out.println(" \nArray after bubble sort");
for (int i = 0; i < 6; i++) {
System.out.print(numbers[i] + ",");
}
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("\ninput 6 number between 1 and 40");
int inputNumber = Integer.parseInt(input.readLine());
for (int b = 0; b < 6; b++) {
System.out.println("number:");
int outcome=Integer.parseInt(input.readLine());
if(outcome==numbers){
System.out.println("found in random numbers");
}else{
System.out.println("not found in random numbers");
}
}
} catch (Exception e) {
System.out.println("error");
}
}
public static void bubbleSort(int[] numbers) {
int n = numbers.length;
int temp = 0;
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n - i); j++) {
if (numbers[j - 1] > numbers[j]) { //swap the element
temp = numbers[j - 1];
numbers[j - 1] = numbers[j];
numbers[j] = temp;
}
}
}
}
}`
System.out.println("\ninput 6 number between 1 and 40");
//Scanner is specifically designed for getting an input purpose and introduced in Java 5,so better use it
Scanner s = new Scanner(System.in);
//you need to have nested loop here
//But the best way to search is use binary search,as you have already sorted the array
while (s.hasNextInt()) {
//one at a time from the input is put to outcome
int outcome = s.nextInt();
boolean found = false;
for (int b = 0; b < 6; b++) {
found = false;
if (outcome == numbers[b]) {
found = true;
//remember to break the inner loop if a match is found
break;
} else {
found = false;
}
}
if (found == true) {
System.out.println("found in random numbers");
} else {
System.out.println("not found in random numbers");
}

Creating a Linked list with Structs - C++

I was writing a program which could read an input file and store the read data in nodes linked by a "link list". However, I was getting a few errors:
In constructor List::List(), no match for 'operator =' in *((List*)this)->List::list[0] = 0
In constructor Polynomial::Polynomial(): no match for 'operator =' in *((Polynomial*)this)->Polynomial::poly = (operator new(400u), (<statement>), ...)
I have a feeling where I do: I try to access a certain node through an array is where I go wrong, however, I can't figure it out much.
Here is the code:
#include <iostream>
#include <fstream>
using namespace std;
enum result{success, failure};
struct Node
{
double coefficient;
int power;
Node();
Node(double coef, int pwr);
};
struct List
{
Node *list[100];
//Default constructor
List();
};
Node::Node()
{
coefficient = 0;
power = 0;
}
List::List()
{
*list[0] = NULL;
}
Node::Node(double coef, int pwr)
{
coefficient = coef;
power = pwr;
}
class Polynomial
{
public:
Polynomial();
result multiply(Polynomial &p, Polynomial &q);
result add(Polynomial p, Polynomial &q);
void initialize(ifstream &file);
void simplify(Polynomial &var);
void print_poly();
~Polynomial();
private:
List *poly; //Store the pointer links in an array
Node first_node;
int val;
};
Polynomial::Polynomial()
{
*poly = new List();
}
Polynomial::void initialize(ifstream &file)
{
int y[20];
double x[20];
int i = 0, j = 0;
//Read from the file
file >> x[j];
file >> y[j];
first_node(x[j], y[j++]); //Create the first node with coef, and pwr
*poly->list[i] = &first_node; //Link to the fist node
//Creat a linked list
while(y[j] != 0)
{
file >> x[j];
file >> y[j];
*poly->list[++i] = new Node(x[j], y[j++]);
}
val = i+1; //Keeps track of the number of nodes
}
Polynomail::result multiply(Polynomial &p, Polynomial &q)
{
int i, j, k = 0;
for(i = 0; i < p.val; i++)
{
for(j = 0; j < q.val; j++)
{
*poly->list[k] = new Node(0, 0);
*poly->list[k].coefficient = (p.poly->list[i].coefficient)*(q.poly->list[j].coefficient);
*poly->list[k++].power = (p.poly->list[i].power)+(q.poly->list[j].power);
}
}
val = k+1; //Store the nunber of nodes
return success;
}
Polynomial::void simplify(Polynomial &var)
{
int i, j, k = 0;
//Create a copy of the polynomial
for(j = 0; j < var.val; j++)
{
*poly->list[j] = new Node(0, 0);
*poly->list[j].coefficient = var.poly->list[j].coefficient;
*poly->list[j].power = var.poly->list[j].power;
}
//Iterate through the nodes to find entries which have the same power and add them, otherwise do nothing
for(k = 0; k < var.val; k++)
{
for(i = k; i < var.val;)
{
if(*poly->list[k].power == var.poly->list[++i].power)
{
if(*poly->list.power[0] == 0)
{
NULL;
}
else
{
*poly->list[k].coefficient = *poly->list[k].coefficient + var.poly->list[i].ceofficient;
var.poly->list[i] = Node(0, 0);
}
}
}
}
}
Polynomial::void print_pol()
{
int i = 0;
for(i = 0; i < temp.val; i++)
{
cout << "Coefficient: " << temp.poly->list[i].coefficient << ", and " << "Power: " << temp.poly->list[i].power << endl;
}
}
The problem is a wrong dereference. Line 34 should probably be
list[0] = NULL; // remove the *
You try to assign the value NULL to a variable of the type Node, but you probably mean a pointer to Node.
The very same is true in line 63.
In addition, line 66 sould probably b:
void Polynomial::initialize(ifstream &file) // start with return type