Arraylist java

Olá bom dia!

Gostaria de uma ajuda.

Estou fazendo um labirinto em java, a ideia principal é que um explorador está nesse labirinto e ele pode se movimentar em 4 direções(cima,baixo,direita e esquerda), até chegar no seu destino.

Preciso implementar 4 caminhos para o meu labirinto, segue abaixo:

  1. Caminho mais curto. Isto é, que passe pelo menor número possível de casas.

  2. Caminho mais longo. Isto é, que passe pelo maior número possível de casas (ok, este é um
    critério estranho, mas pense que o explorador possui motivos para visitar o maior número de casas
    possível sem passar mais de uma vez por uma mesma casa).

  3. Caminho mais valioso. Isto é, que maximiza o valor dos itens coletados.

  4. Caminho mais rápido. Ou seja, aquele minimiza o tempo que se leva para chegar no
    destino (note que não necessariamente equivale ao mais curto, pois depende dos itens que são coletados
    no caminho, o que por sua vez afeta o tempo necessário para percorrê-lo).

Para fazer esses caminhos eu fiz um método movimentar, retornarMovimento (caso não dê as 4 direções ele retorna uma casa).

private void aumentarDirecoes() { 
		this.direcoes += 1;
	}


public void movimentar() { 

		//Parar caso não de as 4 direções.
		if(this.direcoes >= 4) return;
    
		
		Posicao retornarMovimento = retornarMovimento(); 
		
		//saber o local que ele está.
		String valor = this.game.retornarValorPosicaoLabirinto(retornarMovimento);
		
		//Caso o valor retornado seja o do próprio explorador ou a passagem esteja bloqueada não faça nada ou entrou um item. 
		if(valor.equals("X")) {
			proximoMovimento();
			aumentarDirecoes();
			//Se não de certo tente novamente.
			movimentar(); 
			
		} else { 
			
			this.posInicial = retornarMovimento; 
		}
	}

	
	private void proximoMovimento() { 
		switch(this.movimento) { 
			case CIMA:
			this.movimento = MovimentoExplorador.BAIXO; 
			break;
			case BAIXO:
			this.movimento = MovimentoExplorador.ESQUERDA; 
			break;
			case ESQUERDA:
			this.movimento = MovimentoExplorador.DIREITA; 
			break;
			case DIREITA:
			this.movimento = MovimentoExplorador.CIMA; 
			break;
		}
}

	//Em um algoritmo de tentativa e erro, sempre tem a possibilidade de retornar o movimento que não dá certo.
	public Posicao retornarMovimento() { 

		int retornoPosX = this.posInicial.getPosX();
		int retornoPosY = this.posInicial.getPosY();
		//Caso o explorador for para cima, para retornar uma posição ele precisa ser maior que 0. 
		switch(movimento) { 
			case CIMA:
					if(retornoPosX > 0) { 
					retornoPosX -= 1; 
				}
					break; 

			case BAIXO: 
					if(retornoPosX < this.game.getLines() -1){
						retornoPosX +=1; 
					}
					break; 
					
				case ESQUERDA: 
					if(retornoPosY > 0) { 
					retornoPosY -= 1;
				}
					break; 
				
				case DIREITA:
					if(retornoPosY < this.game.getColumn() -1){ 
					retornoPosY += 1; 
				}
					break;
		}
		return new Posicao(retornoPosX, retornoPosY); 
} 

Esse método movimento ele faz apenas 1 movimento, logo na implementação do primeiro caminho para encontrar o menor número de casas eu pensei em criar uma classe que adicione as coordenadas desse movimento, mas é claro vou precisar mudar esse método movimentar para retornar as coordenadas que ele foi, então toda vez que ele fizer um movimento ele adiciona as coordenadas na outra classe e depois eu só comparo os tamanhos das listas para encontrar a menor, porém para fazer isso pensei em usar um arraylist, mas não sei como utilizar perfeitamente com matrizes etc., Alguém poderia ajudar ?

Calma… O buraco é mais embaixo. Você está lidando com problemas em grafos. A sua primeira tarefa é codificar seu labirinto em um grafo, dependendo das restrições você pode ter um grafo (grafo não direcionado), um digrafo (grafo direcionado) ou um grafo ou digrafo ponderados, onde há pesos ou custos associados às arestas, que no seu caso, são os caminhos entre as interseções dos corredores. Tendo isso em mente, ai vc parte para a solução dos seus problemas:

  1. Se seus caminhos entre interseções não possuem peso/custo associado, basta usar o algoritmo de Busca em Largura (Breadth-First Search). Se houver pesos, vc pode usar o algoritmo clássico de menor caminho que é o algoritmo de Dijkstra. Se houver pesos negativos, esse algoritmo não resolve, aí vc tem que usar o algoritmo de Bellman-Ford;
  2. Busca em Profundidade (Depth-First Search) para grafo/digrafo ou adaptação dos algoritmos acima para levarem em conta o maior peso/custo ao invés do menor;
  3. É uma adaptação do item 1;
  4. É uma adaptação do item 1 também.

Ata ok, acho que era isso mesmo que eu estava procurando.