Getting indexOutOfBoundsException and I don't know why - arraylist

I have been having this problem for a few hours. I don't know what it is, but I am having a hard time thinking clearly at the moment. This method displays a set of images. The first part of the method is just setting the gridbag constraints, whereas the next part in the if statement is creating jlabels and adding them to an arraylist of jlabels. The exception is being thrown when I try and add mouselisteners to the jlabels after they have been added to the arraylist (this is on line 112, and i have commented this on the code).
public void displayComplexStimulus(BufferedImage[] complexStimulus){
for(int i = 0; i < numberOfElements; i++){
if (i == 0 || i == 1 || i == 2){
c.gridx = i;
c.gridy = 0;
}
else if(i == 3 || i == 4 || i == 5){
c.gridx = i - 3;
c.gridy = 1;
}
else {
c.gridx = i - 6;
c.gridy = 2;
}
if(counter == 1){
if (phase1Trial.getPositionOfCorrectImage()!= i){
phase1IncorrectLabels.add(new JLabel(new ImageIcon(complexStimulus[i])));
phase1IncorrectLabels.get(i).addMouseListener(this); //line 112
add(phase1IncorrectLabels.get(i),c);
}
else if(phase1Trial.getPositionOfCorrectImage() == i){
correctLabel = new JLabel(new ImageIcon(complexStimulus[i]));
add(correctLabel, c);
correctLabel.addMouseListener(this);
}
}
}
}

If i==phase1Trial.getPositionOfCorrectImage() you're not adding an element to phase1IncorrectLabels. So in the next iteration after adding one element to the array it's at position i-1 and not i. You should replace your get(i) by get(phase1IncorrectLabels.size() - 1).

Related

find and remove element from array (solidity)

I've tackled a task: find a specific address in a sheet, move it to the end of the sheet, and remove it via a function pop! here is the code:
function removeAccount(address _account) external{
uint counter = arrayOfAccounts.length;
uint index;
for(uint i; i < counter; i++) {
if(arrayOfAccounts[i] == _account){
index = i;
break;
}
for(uint i = index; i < counter-1; i++){
arrayOfAccounts[i] = arrayOfAccounts[i + 1];
}
arrayOfAccounts.pop();
}
}
}
}
transact to Wote.removeAccount errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
In case you dont care about addresses order
function removeAccount(address _account) external {
if(arrayOfAccounts.length == 1) {
arrayOfAccounts.pop();
}
else if(arrayOfAccounts[arrayOfAccounts.length - 1] == _account) {
arrayOfAccounts.pop();
}
else {
for (uint i = 0; i < arrayOfAccounts.length - 1; i++) {
if(_account == arrayOfAccounts[i]) {
arrayOfAccounts[i] = arrayOfAccounts[arrayOfAccounts.length - 1];
arrayOfAccounts.pop();
}
}
}
}
If order matters
function removeAccount(address _account) external{
uint counter = arrayOfAccounts.length;
for(uint i; i < counter; i++) {
if(arrayOfAccounts[i] == _account){
for(uint j = i; j < counter-1; j++){
arrayOfAccounts[j] = arrayOfAccounts[j + 1];
}
arrayOfAccounts.pop();
break;
}
}
}
}
Else if order doesn't matter
function removeAccount(address _account) external{
uint numAccounts = arrayOfAccounts.length;
for(uint i = 0; i < numAccounts; i++) {
if(arrayOfAccounts[i] == _account){ // if _account is in the array
arrayOfAccounts[i] = arrayOfAccounts[numAccounts - 1]; // move the last account to _account's index
arrayOfAccounts.pop(); // remove the last account
break;
}
}
}
The reason is just simple.
You used the second for loop inside the first for loop.
And also please initialize the index with counter;
uint256 index = counter;
And pop only when index is less than counter

Variable interator in for cycle

This is my example
for (i in array.indices)
{
if (array[i] == 10)
{
i -= 2//have error here
}
}
How can i make 'i' variable mutable?
You can't. Use while loop instead:
var i = 0
while (i < array.size) {
if (array[i] == 10) {
i -= 2
}
...
i++
}

Needing help on printing mode in java

I am given a task to make a method that takes a parameter of an ArrayList of Integer obj and print out the sum, average, and mode.
I can't seem to figure out how to find the mode. It should print out the number if there is only one mode, and it should print out "no single mode" if there is more than one (or none) mode. My method only prints out "no single mode". How can I fix my code to have the mode printed out?
This is what I have for my code:
public static void printStatistics(ArrayList<Integer> arr){
int sum = 0;
for(int i : arr){
sum += i;
}
System.out.println("Sum: "+sum);
System.out.println("Average: "+(double)sum/arr.size());
int temp = 0, counter = 0, max = 0;
for(int j = 0; j < arr.size() - 1; j++){
for(int k = j+1; k < arr.size(); k++){
if(arr.get(j) == arr.get(k)){
counter++;
if(counter > max){
max = counter;
temp = arr.get(j);
}
if(counter == max){
temp = -1;
}
}
}
}
if(temp > 0){
System.out.println("Mode: "+temp);
}
else if(temp < 0){
System.out.println("Mode: no single mode");
}
}
The problem lies here
if(counter > max){
max = counter;
temp = arr.get(j);
}
if(counter == max){
temp = -1;
}
You are assigning the value of counter to max in the first condition so the second if condition i.e., if(counter == max) will always be true, which results in temp having the value -1 which fulfills else if(temp < 0). This is why you are getting Mode: no single mode as the output every time.
Changing the condition should give you the desired output
if(counter < max){
temp = -1;
}

GMS2 - Why am I getting this syntax error?

I made an inventory system(other is the drop) and here is the pickup code
// pickup
found_in_inv = false;
for(var i = 0; i < ds_list_size(global.inv); i++){
if(global.inv[| i][| 0] == other.object_index){ // error line
global.inv[| i][| 1]++;
found_in_inv = true;
break;
}
}
if(found_in_inv){
instance_destroy(other);
}else{
for(var i = 0; i < ds_list_size(global.inv); i++){
if(global.inv[| i][| 0] == noone){
global.inv[| i][| 0] = other.object_index;
global.inv[| i][| 1] = 1;
break;
instance_destroy(other);
}
}
}
I am getting a syntax error where "[|" found, ")" expected. I don't know how to fix this, please help.
Chained accessors (a[i][k], or a[|i][|k] in your case) are only supported in version >= 2.3 (as of writing this, is in beta).
Assign the first retrieved item into a variable to get around the fact.
Perhaps also take an opportunity to not do more reads than you need.
for(var i = 0; i < ds_list_size(global.inv); i++){
var item = global.inv[| i];
if(item[| 0] == other.object_index){ // error line
item[| 1]++;
found_in_inv = true;
break;
}
}

Programming Chess Rook Movement

I am trying to create a board game where all the pieces are able to move the same as a rook in chess. (i.e. Horizontally or vertically as many spaces as they wish)
My board is a simple 2d integer array, with values of 0,1,2 depending on whether the space is empty, has a red piece or a black piece.
My code for the movement so far is shown below, it creates a true or false value if the move is allowed or not:
int[][] board;
public boolean validMove(int fromRow, int fromCol, int toRow, int toCol) {
if (pieceAt(toRow, toCol) != EMPTY) {
return false;
} else if (fromRow - toRow == 0 && fromCol - toCol != 0) {
return true;
} else if (fromCol - toCol == 0 && fromRow - toRow != 0) {
// Trying to add piece collision code
for (int i = fromRow; i < toRow; i++) {
if (pieceAt(toCol, i) != EMPTY)
return false;
}
return true;
} else {
return false;
}
}
My problem is trying to create collision detection, if another piece is in the way it should not be able to move past it, however with my code currently it can. Can anyone help me do this?
Try code below. It's quite naive (and also not tested), but I think it should work just as is. And also I think it illustrates the idea pretty well (see comments). It's in C, but I'm sure you can transform it easily to Java (or whatever language you use).
bool validMove(int fromRow, int fromCol, int toRow, int toCol)
{
int i;
// Attempt to move to the same cell
if (fromRow == toRow && fromCol == toCol)
return false;
// Collision detection
if (fromRow == toRow) {
// Horizontal move
if (fromCol < toCol) {
// Move right
for (i = fromCol + 1; i <= toCol; ++i)
if (pieceAt(fromRow, i) != EMPTY)
return false;
} else {
// Move left
for (i = fromCol - 1; i >= toCol; --i)
if (pieceAt(fromRow, i) != EMPTY)
return false;
}
} else if (fromCol == toCol) {
// Vertical move
if (fromRow < toRow) {
// Move down
for (i = fromRow + 1; i <= toRow; ++i)
if (pieceAt(i, fromCol) != EMPTY)
return false;
} else {
// Move up
for (i = fromRow - 1; i >= toRow; --i)
if (pieceAt(i, fromCol) != EMPTY)
return false;
}
} else {
// Not a valid rook move (neither horizontal nor vertical)
return false;
}
return true;
}
EDIT
You can also optimize your code by reducing conditional statement count, using the method proposed by Toon Krijthe. The main idea is to use "delta" values (dx/dy) for incrementing or decrementing cell indexes. In that case the destination cell should be checked explicitly.
Code:
bool validMove(int fromRow, int fromCol, int toRow, int toCol)
{
int i;
// Attempt to move to the same cell
if (fromRow == toRow && fromCol == toCol)
return false;
// Collision detection
if (fromRow == toRow) { // Horizontal move
int dx = (fromCol < toCol) ? 1 : -1;
for (i = fromCol + dx; i != toCol; i += dx)
if (pieceAt(fromRow, i) != EMPTY)
return false;
} else if (fromCol == toCol) { // Vertical move
int dy = (fromRow < toRow) ? 1 : -1;
for (i = fromRow + dy; i != toRow; i += dy)
if (pieceAt(i, fromCol) != EMPTY)
return false;
} else { // Not a valid rook move
return false;
}
// Return true if destination cell is free
return pieceAt(toRow, toCell) == EMPTY;
}
you could have a 2D char array with each cell representing the position on the board. there you can have a char for the three states of the position (white/red/empty).
The other way i can think of is before each move to check from the startPosition till the endPosition positions their states. but performance wise i think the some kind of array will be much better
You can simply "walk" each field in order to check if it is empty.
For example:
int[][] board;
public boolean validMove(int fromRow, int fromCol, int toRow, int toCol)
{
if (pieceAt(toRow, toCol) != EMPTY) return false;
else if (fromRow == toRow)
{
// horizontal move
if (fromCol == toCol) return false; // same position
int dx, x;
if (fromCol < toCol)
dx = 1;
else
dx = -1;
for (x = fromCol + dx; x != toCol; x += dx)
{
if (pieceAt(toRow, x) != EMPTY) return false; // occupied
}
}
else if (fromCol == toCol)
{
// vertical move
int dy, y;
if (fromRow < toRow)
dy = 1;
else
dy = -1;
for (y = fromRow + dy; y != toRow; y += dy)
{
if (pieceAt(y, toCol) != EMPTY) return false; // occupied
return true; // free path
}
}
else return false; // no horizontal or vertical move
}