No więc kod wygląda tak (tylko te najistotniejsze fragmenty):
public List<Wierzcholek> ZnajdzDroge(Point start, Point goal)
{
czasRozpoczecia = proces.UserProcessorTime;
Wierzcholek rodzic;
bool znaleziono = false;
kolejkaOpen.Clear();
kolejkaClose.Clear();
int[,] kierunek;
if (przekatne)
kierunek = new int[8, 2] { { 0*siatka, -1*siatka }, { 1*siatka, 0*siatka }, { 0*siatka, 1*siatka }, { -1*siatka, 0*siatka }, { 1*siatka, -1*siatka }, { 1*siatka, 1*siatka }, { -1*siatka, 1*siatka }, { -1*siatka, -1*siatka } };
else
kierunek = new int[4, 2] { { 0*siatka, -1*siatka }, { 1*siatka, 0*siatka }, { 0*siatka, 1*siatka }, { -1*siatka, 0*siatka } };
rodzic.G = 0;
rodzic.H = 1;
rodzic.F = rodzic.G + rodzic.H;
rodzic.WierzcholekDrogi = start;
rodzic.Rodzic = rodzic.WierzcholekDrogi;
kolejkaOpen.Push(rodzic);
while (kolejkaOpen.Count > 0 && !stop)
{
rodzic = kolejkaOpen.Pop();
if(rodzic.WierzcholekDrogi == goal)
{
kolejkaClose.Add(rodzic);
znaleziono = true;
break;
}
if (kolejkaClose.Count > (800 / siatka) * (600 / siatka))
{
stop = true;
return null;
}
for(int i=0; i<(przekatne ? 8 : 4); i++)
{
Wierzcholek nowyWierzcholek = new Wierzcholek();
nowyWierzcholek.WierzcholekDrogi.X = rodzic.WierzcholekDrogi.X + kierunek[i, 0];
nowyWierzcholek.WierzcholekDrogi.Y = rodzic.WierzcholekDrogi.Y + kierunek[i, 1];
if (nowyWierzcholek.WierzcholekDrogi.X < 0 || nowyWierzcholek.WierzcholekDrogi.Y < 0 || nowyWierzcholek.WierzcholekDrogi.X >= 800 || nowyWierzcholek.WierzcholekDrogi.Y >= 600 || mapa.GetPixel(nowyWierzcholek.WierzcholekDrogi.X, nowyWierzcholek.WierzcholekDrogi.Y).Name == "ff000000")
continue;
int noweG=0;
switch (mapa.GetPixel(nowyWierzcholek.WierzcholekDrogi.X, nowyWierzcholek.WierzcholekDrogi.Y).Name)
{
case "ffffffff":
noweG = rodzic.G + 1;
break;
case "ff22b14c":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga1.Text);
break;
case "ffb5e61d":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga2.Text);
break;
case "fffff200":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga3.Text);
break;
case "ffffc90e":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga4.Text);
break;
case "ffff7f27":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga5.Text);
break;
case "ffed1c24":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga6.Text);
break;
case "ff00a2e8":
noweG = rodzic.G + int.Parse(oknoGlowne.textBoxWaga7.Text);
break;
}
if (noweG == rodzic.G)
{
continue;
}
int znalezionoWOtwartejKolejce = -1;
for (int j = 0; j < kolejkaOpen.Count; j++)
{
if (kolejkaOpen[j].WierzcholekDrogi == nowyWierzcholek.WierzcholekDrogi)
{
znalezionoWOtwartejKolejce = j;
break;
}
}
if (znalezionoWOtwartejKolejce != -1 && kolejkaOpen[znalezionoWOtwartejKolejce].G <= noweG)
continue;
int znalezionoWZamknietejKolejce = -1;
for (int j = 0; j < kolejkaClose.Count; j++)
{
if (kolejkaClose[j].WierzcholekDrogi == nowyWierzcholek.WierzcholekDrogi)
{
znalezionoWZamknietejKolejce = j;
break;
}
}
if (znalezionoWZamknietejKolejce != -1 && kolejkaClose[znalezionoWZamknietejKolejce].G <= noweG)
continue;
nowyWierzcholek.Rodzic = rodzic.WierzcholekDrogi;
nowyWierzcholek.G = noweG;
nowyWierzcholek.H = Math.Abs(nowyWierzcholek.WierzcholekDrogi.X - goal.X) + Math.Abs(nowyWierzcholek.WierzcholekDrogi.Y - goal.Y);
nowyWierzcholek.F = nowyWierzcholek.G + nowyWierzcholek.H;
kolejkaOpen.Push(nowyWierzcholek);
oknoGlowne.UpdateMap(nowyWierzcholek.WierzcholekDrogi, mapa, Color.White);
}
kolejkaClose.Add(rodzic);
}
czasWyszukiwania = proces.UserProcessorTime - czasRozpoczecia;
if (znaleziono)
{
Wierzcholek znalezionyWierzcholek = kolejkaClose[kolejkaClose.Count - 1];
for (int i = kolejkaClose.Count - 1; i >= 0; i--)
{
if (znalezionyWierzcholek.Rodzic == kolejkaClose[i].WierzcholekDrogi || i == kolejkaClose.Count - 1)
{
znalezionyWierzcholek = kolejkaClose[i];
oknoGlowne.UpdateMap(kolejkaClose[i].WierzcholekDrogi, mapa, Color.Violet);
oknoGlowne.pictureBoxMapa.Refresh();
}
else
{
kolejkaClose.RemoveAt(i);
}
}
stop = true;
return kolejkaClose;
}
stop = true;
return null;
}
public void SzukajDrogi()
{
bool przekatne = false;
if (radioButtonKierunek2.Checked)
{
przekatne = true;
}
AlgorytmyAZGwiazdka AlgorytmAZGwiazdka = new AlgorytmyAZGwiazdka(mapa, siatka, przekatne);
List<Wierzcholek> odnalezionaDroga = AlgorytmAZGwiazdka.ZnajdzDroge(new Point(int.Parse(textBoxStartPosX.Text), int.Parse(textBoxStartPosY.Text)), new Point(int.Parse(textBoxGoalPosX.Text), int.Parse(textBoxGoalPosY.Text)));
if (odnalezionaDroga != null)
{
UpdateStatusLabel("Znaleziono drogę! " + AlgorytmAZGwiazdka.CalkowityCzas.Ticks);
}
}
private delegate void UpdateStatusLabelDelegate(String text);
private void UpdateStatusLabel(String text)
{
if (labelStatus.InvokeRequired)
{
Invoke(new UpdateStatusLabelDelegate(UpdateStatusLabel), new object[] { text });
return;
}
labelStatus.Text = text;
}
public delegate void UpdateMapDelegate(Point punkt, Bitmap mapka, Color kolor);
public void UpdateMap(Point punkt, Bitmap mapka, Color kolor)
{
if (pictureBoxMapa.InvokeRequired)
{
Invoke(new UpdateMapDelegate(UpdateMap), new object[] { punkt, mapka, kolor });
return;
}
mapka.SetPixel(punkt.X, punkt.Y, kolor);
pictureBoxMapa.Image = mapka;
pictureBoxMapa.Update();
}
private void buttonStart_Click(object sender, EventArgs e)
{
Thread watek = new Thread(new ThreadStart(SzukajDrogi));
watek.Start();
}
Specjalistą nie jestem, ale wydaje mi się, że to powinno działać tak jak zakładam. Po zakończeniu wyszukiwania drogi jak użyję pictureBox.Refresh() to na mapce są zaznaczone wszystkie punkty, ale w trakcie działania algorytmu to nie działa :/