Archief - [PROG][JAVA] Array out of bounds

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

presario

Legacy Member
Hi,

Zit met een vraagske. Voor men project moet ik doolhof maken met daarin een "held" die naar een "wezen" moet bewegen en verslaan. Het tekenen van de doolhof doe ik op deze manier
Code:
private static final long serialVersionUID = 1L;

	private JLabel[][] label = new JLabel[10][10];

	public int[][] doolhof = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
								{ 0, 3, 1, 1, 1, 1, 1, 1, 1, 0 }, 
								{ 0, 0, 0, 0, 0, 0, 1, 3, 1, 0 },
								{ 0, 1, 1, 1, 1, 1, 1, 2, 1, 0 },
								{ 0, 1, 1, 1, 3, 1, 1, 1, 1, 0 },
								{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
								{ 0, 1, 3, 1, 1, 1, 1, 1, 1, 0 },
								{ 0, 0, 0, 0, 0, 0, 1, 3, 1, 0 },
								{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
								{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };

	public Doolhofveld() {

		GridLayout thisLayout = new GridLayout(10, 10);
		thisLayout.setHgap(0);
		thisLayout.setVgap(0);
		thisLayout.setColumns(10);
		thisLayout.setRows(10);
		setLayout(thisLayout);
		dool(doolhof);

	}

	public void dool(int b[][]) {
		for (int i = 0; i < b.length; i++)
			for (int j = 0; j < b[i].length; j++) {
				if (b[i][j] == 0) {

					label[i][j] = new JLabel();
					label[i][j].setIcon(new ImageIcon(getClass()
							.getClassLoader().getResource("W.png")));
					label[i][j].setBounds(i * 100, j * 100, 250, 500);
					add(label[i][j]);
				}
				if (b[i][j] == 1) {

					label[i][j] = new JLabel();
					label[i][j].setIcon(new ImageIcon(getClass()
							.getClassLoader().getResource("G.png")));
					label[i][j].setBounds(i * 100, j * 100, 250, 500);
					add(label[i][j]);
				}
				if (b[i][j] == 2) {

					label[i][j] = new JLabel();
					label[i][j].setIcon(new ImageIcon(getClass()
							.getClassLoader().getResource("P.png")));
					label[i][j].setBounds(i * 100, j * 100, 250, 500);
					add(label[i][j]);
				}
				if (b[i][j] == 3) {

					label[i][j] = new JLabel();
					label[i][j].setIcon(new ImageIcon(getClass()
							.getClassLoader().getResource("D.png")));
					label[i][j].setBounds(i * 100, j * 100, 250, 500);
					add(label[i][j]);

				}

			}
	}
Nu, dat zorgt voor geen problemen, het is nl. het bewegen. Ik laat mijn "held" bewegen dmv buttons in men frame. Ik gebruik van elke button zijn actionlistener om methode aan te roepen.
Code:
public boolean boven() {
		boolean controle = false;

		for (int i = 0; i < doolhof.length; i++)
			for (int j = 0; j < doolhof[i].length; j++) {

				if (doolhof[i][j] == 2) {
					if (doolhof[i - 1][j] == 0) {

						return controle = false;
					} else {
						return controle = true;
					}
				}
			}

		return controle;

	}

	public void beweegBoven() {

		if (boven() == true) {

			for (int i = 0; i < doolhof.length; i++)
				for (int j = 0; j < doolhof[i].length; j++) {
					
					if (doolhof[i][j] == 2) {
						if(doolhof[i-1][j]==3)
						{
							Gevecht g=new Gevecht();
							g.setVisible(true);
						}
						
						doolhof[i][j] = doolhof[i - 1][j];
						doolhof[i - 1][j] = 2;
						
						label[i][j].setIcon(new ImageIcon(getClass()
								.getClassLoader().getResource("G.png")));
						label[i - 1][j].setIcon(new ImageIcon(getClass()
								.getClassLoader().getResource("P.png")));
					}
					

				}
		}
	
		
	}

	public boolean onder() {
		boolean controle = false;
		for (int i = 0; i < doolhof.length; i++)
			for (int j = 0; j < doolhof[i].length; j++) {

				if (doolhof[i][j] == 2) {
					if (doolhof[i + 1][j] == 0)
						controle = false;
					else
						controle = true;

				}
			}
		return controle;
	}

	public void beweegOnder() {
		
				if (onder() == true) {
					for (int i = 0; i < doolhof.length; i++)
						for (int j = 0; j < doolhof[i].length; j++) {
							
							if (doolhof[i][j] == 2) {
								/*if(doolhof[i+1][j]==3)
								{
									Gevecht g=new Gevecht();
									g.setVisible(true);
								}*/
								doolhof[i][j] = doolhof[i + 1][j];
								doolhof[i + 1][j] = 2;
								label[i][j].setIcon(new ImageIcon(getClass()
										.getClassLoader().getResource("G.png")));
								label[i + 1][j].setIcon(new ImageIcon(getClass()
										.getClassLoader().getResource("P.png")));
							}

						}
			}
	}

	public boolean links() {
		boolean controle = false;
		for (int i = 0; i < doolhof.length; i++)
			for (int j = 0; j < doolhof[i].length; j++) {

				if (doolhof[i][j] == 2) {
					if (doolhof[i][j-1] == 0)
						controle = false;
					else
						controle = true;

				}
			}
		return controle;
	}

	public void beweegLinks() {
		
				if (links() == true) {
					for (int i = 0; i < doolhof.length; i++)
						for (int j = 0; j < doolhof[i].length; j++) {
							
							if (doolhof[i][j] == 2) {
								if(doolhof[i][j-1]==3)
								{
									Gevecht g=new Gevecht();
									g.setVisible(true);
								}
								doolhof[i][j] = doolhof[i][j - 1];
								doolhof[i][j - 1] = 2;
								label[i][j].setIcon(new ImageIcon(getClass()
										.getClassLoader().getResource("G.png")));
								label[i][j - 1].setIcon(new ImageIcon(getClass()
										.getClassLoader().getResource("P.png")));
							}
			}
		}
	}

	public boolean rechts() {
		boolean controle = false;
		
		for (int i = 1; i < doolhof.length; i++)
			for (int j = 1; j < doolhof[i].length; j++) {

				if (doolhof[i][j] == 2) 
				{
					if (doolhof[i][j + 1] == 0)
						controle = false;
					else
						controle = true;

				}
			}
		return controle;
	}

	public void beweegRechts() {
		
		if (rechts() == true) {
			
					
					try
					{
						
						for (int i = 1; i <= doolhof.length; i++)
							
							for (int j = 1; j <= doolhof[i].length; j++) {
								if (doolhof[i][j] == 2) 
								{
									if(doolhof[i][j+1]==3)
									{
											Gevecht g=new Gevecht();
											g.setVisible(true);
									}
						doolhof[i][j] = doolhof[i][j + 1];
						doolhof[i][j + 1] = 2;
						label[i][j].setIcon(new ImageIcon(getClass()
								.getClassLoader().getResource("G.png")));
						label[i][j + 1].setIcon(new ImageIcon(getClass()
								.getClassLoader().getResource("P.png")));
						
						}
							}
						}
						catch(ArrayIndexOutOfBoundsException e)
						{
							
							JOptionPane.showMessageDialog(null,e.getMessage());
						}
		}
			
				
	}
Dus ik controleer of er al dan niet een muur staat, staat er geen dan mag hij bewegen. Ik roep dus telkens de methode "beweeg.." maar het loopt fout bij het bewegen. Naar boven en naar links gaat zonder probleem maar als ik naar onder of naar rechts klik krijg ik een "array out of bounds exeption". Iemand die hier ziet waar de fout zit? Zou er mij een serieus plezier mee doen :)!

mvg

Pres.

Timmos

Legacy Member
presario zei:
Code:
    public boolean onder() {
        boolean controle = false;
        for (int i = 0; i < doolhof.length; i++)
            for (int j = 0; j < doolhof[i].length; j++) {

                if (doolhof[i][j] == 2) {
                    if (doolhof[[B][COLOR=Red]i + 1[/COLOR][/B]][j] == 0)
                        controle = false;
                    else
                        controle = true;

                }
            }
        return controle;
    }

    public void beweegOnder() {
        
                if (onder() == true) {
                    for (int i = 0; i < doolhof.length; i++)
                        for (int j = 0; j < doolhof[i].length; j++) {
                            
                            if (doolhof[i][j] == 2) {
                                /*if(doolhof[[B][COLOR=Red]i+1[/COLOR][/B]][j]==3)
                                {
                                    Gevecht g=new Gevecht();
                                    g.setVisible(true);
                                }*/
                                doolhof[i][j] = doolhof[[B][COLOR=Red]i + 1[/COLOR][/B]][j];
                                doolhof[[B][COLOR=Red]i + 1[/COLOR][/B]][j] = 2;
                                label[i][j].setIcon(new ImageIcon(getClass()
                                        .getClassLoader().getResource("G.png")));
                                label[[B][COLOR=Red]i + 1[/COLOR][/B]][j].setIcon(new ImageIcon(getClass()
                                        .getClassLoader().getResource("P.png")));
                            }

                        }
            }
    }

    public boolean rechts() {
        boolean controle = false;
        
        for (int i = 1; i < doolhof.length; i++)
            for (int j = 1; j < doolhof[i].length; j++) {

                if (doolhof[i][j] == 2) 
                {
                    if (doolhof[i][[B][COLOR=Red]j + 1[/COLOR][/B]] == 0)
                        controle = false;
                    else
                        controle = true;

                }
            }
        return controle;
    }

    public void beweegRechts() {
        
        if (rechts() == true) {
            
                    
                    try
                    {
                        
                        for (int i = 1; i [B][COLOR=Red]<=[/COLOR][/B] doolhof.length; i++)
                            
                            for (int j = 1; j [B][COLOR=Red]<=[/COLOR][/B] doolhof[i].length; j++) {
                                if (doolhof[i][j] == 2) 
                                {
                                    if(doolhof[i][[B][COLOR=Red]j+1[/COLOR][/B]]==3) [B][COLOR=Red]// 2 indexen te hoog![/COLOR][/B]
                                    {
                                            Gevecht g=new Gevecht();
                                            g.setVisible(true);
                                    }
                        doolhof[i][j] = doolhof[i][[B][COLOR=Red]j + 1[/COLOR][/B]];
                        doolhof[i][[B][COLOR=Red]j + 1[/COLOR][/B]] = 2;
                        label[i][j].setIcon(new ImageIcon(getClass()
                                .getClassLoader().getResource("G.png")));
                        label[i][[B][COLOR=Red]j + 1[/COLOR][/B]].setIcon(new ImageIcon(getClass()
                                .getClassLoader().getResource("P.png")));
                        
                        }
                            }
                        }
                        catch(ArrayIndexOutOfBoundsException e)
                        {
                            
                            JOptionPane.showMessageDialog(null,e.getMessage());
                        }
        }
            
                
    }
msg too short

Timmos

Legacy Member
presario zei:
Dat zijn de fouten?
Nee, alles wat in het wit staat is fout :lol:

:unsure:

Hetgeen wat rood gemarkeerd staat is de oorzaak van de Exception. Alle indexen zijn één te hoog, vanaf de comment "// 2 indexen te hoog" zijn ze 2 te hoog (op de laatste resp. voorlaatste iteraties van je for-lus), maar dat komt omdat je "<=" gebruikt in je for-header.

presario

Legacy Member
Timmos zei:
Nee, alles wat in het wit staat is fout :lol:

:unsure:

Hetgeen wat rood gemarkeerd staat is de oorzaak van de Exception. Alle indexen zijn één te hoog, vanaf de comment "// 2 indexen te hoog" zijn ze 2 te hoog (op de laatste resp. voorlaatste iteraties van je for-lus), maar dat komt omdat je "<=" gebruikt in je for-header.

En hoe kan ik dat oplossen? :)

Timmos

Legacy Member
presario zei:
En hoe kan ik dat oplossen? :)
Tja ik ga niet gans uw programma analyseren. Het komt er op neer dat ge een tabel hebt met een breedte van k kolommen en een lengte van r rijen.

Wat gij doet is de waarde opvragen van kolom k die niet bestaat (kolom 0 tot en met (k - 1) bestaan wél). Of zelfs van kolom (k + 1), maar daar komt je programma nooit omdat je dan al een Exception hebt gekregen van kolom k.

Je analyseert het probleem van de doolhof verkeerd. Denk eens goed na hoe je jouw probleem omzet in code, want nu is het duidelijk niet goed, zoals je ziet.

jodeman

Legacy Member
Simpel, omdat ge ELK element afloopt, neemt dat er nu 5 elementen in uw array zitten op plaatsen 0,1,2,3,4. De maximum waarde voor geen array out of bounds te krijgen is dus 4. Als je elk element afloopt en elke keer +1 doet krijg je op een keer 4+1 = 5 -> out of bounds. Gewoon checken dat de waarde niet groter of gelijk aan de lengte van de array is vooraleer je +1 doet en je zit goed.

presario

Legacy Member
Al merci voor de respons!
@jodeman
Misschien voelde mijn vraag al aankomen maar hoe moet ik dat checken :unsure:? Of moet ik mijn for-lus veranderen?

Kiddy

Legacy Member
Bij het controleren naar onder moet ge uw laatste rij niet checken, want daar kunt ge niet lager. Dus in uw for lus gewoon de arraylength - 1 nemen als max counter.

Timmos

Legacy Member
Als je niet weet hoe de lengte op te vragen van een array:
Code:
array.length
De maximale index wordt dan
Code:
array.length - 1

presario

Legacy Member
Timmos zei:
Als je niet weet hoe de lengte op te vragen van een array:
Code:
array.length
De maximale index wordt dan
Code:
array.length - 1

Dit had ik al geporbeerd maar krijg nog altijd dezelfde array out of bounds exception :/

MilM

Legacy Member
presario zei:
Dit had ik al geporbeerd maar krijg nog altijd dezelfde array out of bounds exception :/

Indien je dit rechtreeks aanspreekt, zal je een fout krijgen indien length = 0.
(in een for lus met conditie i < x.length zal dat niet gebeuren)

En wanneer uw i 0 is, kan dit ook niet hé -> doolhof[i - 1][j]

Ga gewoon uw code af en kijkt of elke index in wel in het interval [0,array.length-1] ligt.

presario

Legacy Member
MilM zei:
Indien je dit rechtreeks aanspreekt, zal je een fout krijgen indien length = 0.
(in een for lus met conditie i < x.length zal dat niet gebeuren)

En wanneer uw i 0 is, kan dit ook niet hé -> doolhof[i - 1][j]

Ga gewoon uw code af en kijkt of elke index in wel in het interval [0,array.length-1] ligt.

Had blijkbaar paar details niet gezien zoals een "1" of "<=". Merci voor de hulp. Maar het werkt nog niet helemaal voor 100%.

Met deze code beweegt men wezen zonder probleem elke keer als ik op links druk
Code:
public boolean links() {
		boolean controle = false;
		for (int i = 0; i < doolhof.length; i++)
			for (int j = 0; j < doolhof[i].length; j++) {

				if (doolhof[i][j] == 2) {
					if (doolhof[i][j-1] == 0)
						controle = false;
					else
						controle = true;

				}
			}
		return controle;
	}

	public void beweegLinks() {
		
				if (links() == true) {
					for (int i = 0; i < doolhof.length; i++)
						for (int j = 0; j < doolhof[i].length; j++) {
							
							if (doolhof[i][j] == 2) {
								if(doolhof[i][j-1]==3)
								{
									Gevecht g=new Gevecht();
									g.setVisible(true);
								}
								doolhof[i][j] = doolhof[i][j - 1];
								doolhof[i][j - 1] = 2;
								label[i][j].setIcon(new ImageIcon(getClass()
										.getClassLoader().getResource("G.png")));
								label[i][j - 1].setIcon(new ImageIcon(getClass()
										.getClassLoader().getResource("P.png")));
							}
			}
		}
	}

maar met deze, als ik op rechts duw gaat hij automatisch helemaal naar door mijn muren heen en kan ik niets meer doen (dus infeite helemaal tot aan het einde van men array).
Code:
public boolean rechts() {
		boolean controle = false;
		
		for (int i = 0; i < doolhof.length; i++)
			for (int j = 0; j < doolhof[i].length; j++) {

				if (doolhof[i][j] == 2) 
				{
					if (doolhof[i][j + 1] == 0)
						controle = false;
					else
						controle = true;

				}
			}
		return controle;
	}

	public void beweegRechts()
	{
		
				if (rechts() == true) 
				{				
						for (int i = 0; i < doolhof.length-1; i++)
							
							for (int j = 0; j < doolhof[i].length-1; j++)
							{
								if (doolhof[i][j] == 2) 
								{
									if(doolhof[i][j+1]==3)
									{
											Gevecht g=new Gevecht();
											g.setVisible(true);
									}
									doolhof[i][j] = doolhof[i][j + 1];
									doolhof[i][j + 1] = 2;
									label[i][j].setIcon(new ImageIcon(getClass()
									.getClassLoader().getResource("G.png")));
									label[i][j + 1].setIcon(new ImageIcon(getClass()
											.getClassLoader().getResource("P.png")));
						
								}
							}
						
						
		}
			
				
	}

Iemand die het ziet? Ge zou mij er een serieus plezier mee doen :)

killgore

Legacy Member
imho is je hele structuur verkeerd. Als je zo lang moet nadenken over lussen, controles, ..., dan is je codedesign fucked up.

Je zou eerder iets moeten hebben als:

Doolhof->isBlocked(i,j)

die isBlocked checkt dan intern wel of hij out of bounds is of niet.

edit: en een andere oplossing is rond heel je doolhof muren te zetten, waardoor je zeker bent dat je mannetje nooit op een positie staat waar er out of bounds of zo gebeuren. Maar de properste vind ik die hierboven.

edit2: vreemd dat ik nog niet eerder geantwoord heb :p.

eniac

Legacy Member
MilM zei:
Ga gewoon uw code af en kijkt of elke index in wel in het interval [0,array.length-1] ligt.

for(int i = 0; i < array.length; i++){}

Werkt altijd, gewoon zonder nadenken dit intypen elke keer je een array wil aflopen.

Timmos

Legacy Member
eniac zei:
for(int i = 0; i < array.length; i++){}

Werkt altijd, gewoon zonder nadenken dit intypen elke keer je een array wil aflopen.
Het probleem is dat hij te pas en te onpas dan in zijn for-lus gaat checken op plaats j + 1...

Een vraagje, moet je doolhof circulair zijn? Dus langs de bovenkant eruitkomen en dan langs de onderkant er weer in?

Zo ja dan kunt ge gemakkelijk met modulo rekening werken om die out of bounds weg te krijgen.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan