У меня проблема с Pathfinding для моей консольной игрыC#

Место общения программистов C#
Ответить
Anonymous
 У меня проблема с Pathfinding для моей консольной игры

Сообщение Anonymous »

Я работаю над консольной игрой, где вы строите железные дороги между городами и проезжаете поезда между ними. Строительная часть до сих пор работает безупречно, но у меня проблемы с той частью, которая находит самый короткий путь между станциями. < /p>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Terminal_Railways
{
internal class Train
{
public int Capacity { get; set; }
public int CurrentLoad { get; set; }
public List Stations { get; set; }
public int row { get; set; }
public int col { get; set; }
public List directions { get; set; }
public int currentDirection { get; set; }
public string nextStation { get; set; }

public void isConnected(Map map, int startCol, int startRow, int endCol, int endRow)
{
bool foundPath = false;
Console.WriteLine("Checking path...");
List noPath = new List { 5 };

if (map.grid[startCol][startRow].Type != "H" || map.grid[endCol][endRow].Type != "H")
{
/*return noPath;*/
}

Dictionary visitedTiles =
new Dictionary();

List visitedPreviousCycle = new List();

if (map.grid[startCol][startRow].Connections.Contains(0) && map.grid[startCol][startRow - 1].Connections.Contains(2) && !visitedTiles.ContainsKey((startCol, startRow - 1)))
{
visitedPreviousCycle.Add((startCol, startRow - 1));
visitedTiles.Add((startCol, startRow - 1), (startCol, startRow, 0));
}

if (map.grid[startCol][startRow].Connections.Contains(1) && map.grid[startCol + 1][startRow].Connections.Contains(3) && !visitedTiles.ContainsKey((startCol + 1, startRow)))
{
visitedPreviousCycle.Add((startCol + 1, startRow));
visitedTiles.Add((startCol + 1, startRow), (startCol, startRow, 1));
}

if (map.grid[startCol][startRow].Connections.Contains(2) && map.grid[startCol][startRow + 1].Connections.Contains(0) && !visitedTiles.ContainsKey((startCol, startRow + 1)))
{
visitedPreviousCycle.Add((startCol, startRow + 1));
visitedTiles.Add((startCol, startRow + 1), (startCol, startRow, 2));
}

if (map.grid[startCol][startRow].Connections.Contains(3) && map.grid[startCol - 1][startRow].Connections.Contains(1) && !visitedTiles.ContainsKey((startCol - 1, startRow)))
{
visitedPreviousCycle.Add((startCol - 1, startRow));
visitedTiles.Add((startCol - 1, startRow), (startCol, startRow, 3));
}

Console.WriteLine($"Starting at {startCol}, {startRow}");
int cycles = 0;

while (cycles < 2000)
{
cycles++;
List temp = visitedPreviousCycle;
visitedPreviousCycle = new List();

foreach (var tile in temp)
{
if (map.grid[tile.Col][tile.Row].Connections.Contains(0) && map.grid[tile.Col][tile.Row - 1].Connections.Contains(2) && !visitedTiles.ContainsKey((tile.Col, tile.Row - 1)))
{
visitedPreviousCycle.Add((tile.Col, tile.Row - 1));
visitedTiles.Add((tile.Col, tile.Row - 1), (tile.Col, tile.Row, 0));
if ((tile.Col, tile.Row - 1) == (endCol, endRow))
{
foundPath = true;
}
}

if (map.grid[tile.Col][tile.Row].Connections.Contains(1) && map.grid[tile.Col + 1][tile.Row].Connections.Contains(3) && !visitedTiles.ContainsKey((tile.Col + 1, tile.Row)))
{
visitedPreviousCycle.Add((tile.Col + 1, tile.Row));
visitedTiles.Add((tile.Col + 1, tile.Row), (tile.Col, tile.Row, 1));
if ((tile.Col + 1, tile.Row) == (endCol, endRow))
{
foundPath = true;
}
}

if (map.grid[tile.Col][tile.Row].Connections.Contains(2) && map.grid[tile.Col][tile.Row + 1].Connections.Contains(0) && !visitedTiles.ContainsKey((tile.Col, tile.Row + 1)))
{
visitedPreviousCycle.Add((tile.Col, tile.Row + 1));
visitedTiles.Add((tile.Col, tile.Row + 1), (tile.Col, tile.Row, 2));
if ((tile.Col, tile.Row + 1) == (endCol, endRow))
{
foundPath = true;
}
}

if (map.grid[tile.Col][tile.Row].Connections.Contains(3) && map.grid[tile.Col - 1][tile.Row].Connections.Contains(1) && !visitedTiles.ContainsKey((tile.Col - 1, tile.Row)))
{
visitedPreviousCycle.Add((tile.Col - 1, tile.Row));
visitedTiles.Add((tile.Col - 1, tile.Row), (tile.Col, tile.Row, 3));
if ((tile.Col - 1, tile.Row) == (endCol, endRow))
{
foundPath = true;
}
}

if (foundPath)
{
List path = new List();
(int currentCol, int currentRow, int direction) newTile = visitedTiles[(endCol, endRow)];
path.Add(visitedTiles[(endCol, endRow)].direction);
Console.WriteLine($"Path found in {cycles} cycles!");

while (newTile.currentCol != startCol || newTile.currentRow != startRow)
{
path.Add((newTile.direction + 2) % 4);
newTile = visitedTiles[(newTile.currentCol, newTile.currentRow)];
}

List reversePath = new List(path);
reversePath.Reverse();

foreach (int dir in reversePath)
{
path.Add((dir + 2) % 4);
}

foreach (int dir in path)
{
Console.WriteLine(dir);
}
}
}
}
}
}
}
< /code>
Это мой код для части, которая находит путь. Это относится к классу карт, который выглядит так < /p>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Terminal_Railways
{
internal class Map
{
public Map(List grid)
{
this.grid = grid;
}

public List grid { get; set; }
public string[] cityNames = {
"Riverton","Stonehaven","Eagleford","Ironpeak","Lakeshore","Windmere","Ashford","Silverbrook","Hillcrest","Northgate","Oakridge","Westvale","Kingsport","Brighton","Cedarfall",
"Highspire","Stormreach","Frostford","Maplewood","Greenwich", "Duskport","Harborview","Meadowvale","Brookhaven","Cliffside","Fairmont","Eastwatch","Shadowfen","Goldvale","Wolfden"
};

public void GenerateMap()
{
for (int i = 0; i < 30; i++)
{
grid.Add(new List());
}

foreach (List row in grid)
{
for (int j = 0; j < grid.Count; j++)
{
row.Add(new Tile { Type = "." });
}

foreach (Tile tile in row)
{
Random rand = new Random();
int randomNum = rand.Next(0, 100);

if (randomNum < 1)
{
tile.Type = "C";
}
else if (randomNum < 3)
{
tile.Type = "#";
}
}
}

List mountains = FindAllMountains();

foreach (var mountain in mountains)
{
int r = mountain.Row;
int c = mountain.Col;

if (r > 0)
{
grid[r - 1][c].Type = "#";
}

if (r < grid.Count - 1)
{
grid[r + 1][c].Type = "#";
}

if (c > 0)
{
grid[r][c - 1].Type = "#";
}

if (c < grid[r].Count - 1)
{
grid[r][c + 1].Type = "#";
}
}

List cities = FindAllCities();

foreach (var city in cities)
{
Random rand = new Random();
int nameIndex = rand.Next(0, cityNames.Length);
grid[city.Row][city.Col].CityName = cityNames[nameIndex];
grid[city.Row][city.Col].CityPopulation = new Random().Next(200, 2000);
}
}

public List FindAllMountains()
{
var mountains = new List();

for (int r = 0; r < grid.Count; r++)
{
for (int c = 0; c < grid[r].Count; c++)
{
if (grid[r][c].Type == "#")
{
mountains.Add((r, c));
}
}
}

return mountains;
}

public List FindAllCities()
{
var cities = new List();

for (int r = 0; r < grid.Count; r++)
{
for (int c = 0; c < grid[r].Count; c++)
{
if (grid[r][c].Type == "C")
{
cities.Add((r, c, grid[r][c].CityName));
}
}
}

return cities;
}

public void AddPassengers()
{
List cities = FindAllCities();

foreach (var city in cities)
{
int r = city.Row;
int c = city.Col;

if (grid[r + 1][c].Type == "H")
{
grid[r - 1][c].PassengersWaiting += grid[r][c].CityPopulation / 100;
}
else if (grid[r - 1][c].Type == "H")
{
grid[r - 1][c].PassengersWaiting += grid[r][c].CityPopulation / 100;
}
else if (grid[r][c + 1].Type == "H")
{
grid[r - 1][c].PassengersWaiting += grid[r][c].CityPopulation / 100;
}
else if (grid[r][c - 1].Type == "H")
{
grid[r - 1][c].PassengersWaiting += grid[r][c].CityPopulation / 100;
}
}
}
}
}
< /code>
, который также ссылается на класс плитки, который является этим < /p>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Terminal_Railways
{
internal class Tile
{
public string Type { get; set; } //mountain, empty, city, rail horizontal & vertical, rail turn up left right down, rail intersection 3-way 4-way, station.

// city properties
public string CityName { get; set; }
public int CityPopulation { get; set; }

// station properties
public int PassengersWaiting { get; set; }

// rail properties
public bool HasTrainLeftTrack { get; set; }
public bool HasTrainRightTrack { get; set; }
public List Connections { get; set; } = new List { }; // 0 = up, 1 = right, 2 = down, 3 = left
}
}
< /code>
Нахождение пути попадает в путь проверки и начинается с Writelines, но никогда не попадает в путь. Все, что ему нужно, правильно, все подключения верны (0 = up, 1 = справа, 2 = вниз, 3 = справа). Я не получаю бесконечных петлей, не исключения (за исключением случаев, когда станция находится на краю карты, но я решил это позже). < /p>
Странная вещь - это на самом деле сработало в первый раз. Он вернул неправильно расположенный путь, но он попал в эту часть, но с тех пор я не смог воспроизвести его, даже с относительно той же настройкой.

Подробнее здесь: https://stackoverflow.com/questions/797 ... nsole-game
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»