Wie verweise ich auf eine Kartenposition im Code?

8

Ich codiere eine digitale Version des Brettspiels von Macao, die eine flache Karte ähnlich der folgenden hat. Spieler haben ein "Schiff", das in der blauen Box beginnt und den gestrichelten Linien in jede Richtung / Ausrichtung folgen kann. Die größeren Rechtecke repräsentieren die Standorte der Stadt.

Ich stecke in den folgenden Fragen fest.

  1. Wie zeichne ich die Position jedes Schiffes auf? Ich denke an Koordinaten wie X, Y, aber das sagt mir nicht, dass das Segment aktiviert ist

  2. Wie konstruiere ich die Routenpfade als Objekte? Platziere ich sie in einem Array?

  3. Schließlich; Um den Abstand zwischen einem Rechteck und einem anderen zu messen, muss gezählt werden, wie viele Segmente vorhanden sind, um den kürzesten Abstand zu ermitteln. Ich glaube, dass dies über einen einfachen Pfadalgorithmus gelöst werden kann.

Ich habe noch nie zuvor eine solche Karte in einem Projekt erstellt, würde mich aber über jede Hilfe freuen, um dies voranzutreiben.

Kartenkonzept

Atilla Jax
quelle
Angesichts der Verwirrung, die meine Antwort mit sich bringt, können Sie Ihre Frage bearbeiten und angeben, ob die Leerzeichen zwischen den Strichen Stellen sind, an denen Schiffe anhalten und bleiben können, oder ob es sich nur um Routen handelt und Schiffe nur in Städten anhalten und bleiben dürfen :)
Vaillancourt
Die Striche stellen die einzigen legalen Stellen dar, an denen Schiffe anhalten / bleiben können. Sie fungieren auch als legale Routen. Die Städte zählen auch. Ein Segelschiff muss physisch in der gewünschten Stadt landen. Ignoriere die Leerzeichen.
Atilla Jax

Antworten:

8

Ich würde vorschlagen, dass Sie zunächst ein Knotendiagramm erstellen (eine Reihe von Knoten und Bögen (manchmal auch Kanten genannt)).

  • Die Knoten sind die Städte und die "Strich" -Kreuzung
  • Die Bögen verbinden Städte und "Strich" -Kreuzungen

Dann haben alle diese Knoten Informationen wie ihren 'physischen' Standort (x / y-Koordinaten auf der Karte).

So lösen Sie Ihre Probleme:

  1. Sie verwenden die Position, die in den Knoten festgelegt ist, um den Standort und die Ausrichtung abzuleiten.
  2. Dies hängt von der Implementierung Ihres Knotendiagramms ab.
  3. Verwenden Sie einen Pfadfindungsalgorithmus wie A *, um die beste Route zwischen Ihrem aktuellen Standort und dem Ziel zu finden. Ihr Diagramm wird wiederum dafür verwendet.

Dies sollte Ihnen den Einstieg erleichtern.

Bearbeiten

Das erzeugte Knotendiagramm könnte folgendermaßen aussehen:

Das erzeugte Knotendiagramm

Natürlich wären die im Bild dargestellten Bögen die Bögen, die die Knoten im Diagramm verbinden.

Aus der Frage geht nicht hervor, ob die Kreuzungsknoten Stellen sind, an denen die Schiffe bleiben könnten , aber da es sich um ein Brettspiel handelt, habe ich angenommen, dass mehr als ein Strich zwischen zwei Städten liegt, weil es kostet mehr, um von einer Stadt in eine andere zu reisen (zum Beispiel benötigen Sie eine 2 auf einem Würfel anstelle von nur 1). Vor diesem Hintergrund nahm ich an, dass ein Schiff an diesen Stellen bleiben könnte (aber nicht auf Bögen).

Ist dies jedoch nicht der Fall, können die Kreuzungsknoten weiterhin für Navigationszwecke zwischen Städten verwendet werden. Dies würde jedoch quadratische Schiffsspuren ergeben, weshalb möglicherweise ein anderer Ansatz gewählt werden sollte. Beispiel: Kanten können Daten enthalten, die beschreiben, wie sie zurückgelegt werden sollen (Spline, Punktserien usw.).

Vaillancourt
quelle
Das veröffentlichte Bild-OP wird durch ein Knotendiagramm nicht gut dargestellt. Da gibt es einen Schnittpunkt von Kanten ohne Knoten (rechts).
MichaelHouse
Sie können zwei Arten von Knoten haben: Stadtknoten und Kreuzungsknoten. Ich gehe davon aus, dass es sich um Stellen handelt, an denen das Schiff bleiben kann, nachdem sich die Spieler gewendet haben, und dass ein Schiff nur durch Bögen fahren und nicht auf ihnen bleiben kann. Mal sehen, ob ich ein Bild hinzufügen kann.
Vaillancourt
@ Byte56 Ich habe ein bisschen mehr Details zu dem hinzugefügt, was ich dachte, vielleicht ist es jetzt klarer!
Vaillancourt
2
Ah, diese Lösung ist mit dem Bild viel klarer. +1 für die verrückten Photoshop-Fähigkeiten (und für die gute Antwort).
Alexandre Desbiens
Ja, das ist meine Schuld, ich wollte aus urheberrechtlichen Gründen kein aktuelles Bild veröffentlichen, also habe ich es sehr schnell interpretiert.
Atilla Jax
1

Alexandre gab eine gute Antwort. Ich dachte, ich würde ein konkretes Beispiel ausprobieren.

Das Beispiel ist C #, aber hoffentlich ist es allgemein genug, um in jeder Sprache implementiert zu werden, die Sie verwenden möchten.

using System;
using System.Collections.Generic;

public class SimpleGraph
{
    private int _numberOfCities;
    private int[] _paths;


    public SimpleGraph()
    {
        _numberOfCities = 9;
        _paths = new int[_numberOfCities * (_numberOfCities + 1) / 2];

        AddPath(0, 2, 1);
        AddPath(0, 3, 2);
        AddPath(3, 4, 2);
        AddPath(3, 5, 1);
        AddPath(3, 2, 1);
        AddPath(2, 1, 1);
        AddPath(2, 6, 1);
        AddPath(5, 6, 1);
        AddPath(6, 7, 1);
        AddPath(5, 7, 1);
        AddPath(6, 8, 5);
        AddPath(7, 8, 5);
        AddPath(1, 8, 6);
    }


    public void AddPath(int cityA, int cityB, int distance)
    {
        int pathIndex = getPathIndex(cityA, cityB);
        if (pathIndex < 0 || _paths.Length <= pathIndex) return;

        _paths[pathIndex] = distance;
    }


    public void RemovePath(int cityA, int cityB)
    {
        AddPath(cityA, cityB, 0);
    }


    public int GetPathDistance(int cityA, int cityB)
    {
        int pathIndex = getPathIndex(cityA, cityB);
        if (pathIndex < 0 || _paths.Length <= pathIndex) return 0;

        return _paths[pathIndex];
    }


    public bool HasPath(int cityA, int cityB)
    {
        return GetPathDistance(cityA, cityB) > 0;
    }


    public List<int> GetAvailableCities(int currentCity)
    {
        var result = new List<int>();

        for (int i = 0; i < _numberOfCities; i++)
        {
            if (HasPath(currentCity, i)) result.Add(i);
        }

        return result;
    }


    private int getPathIndex(int cityA, int cityB)
    {
        if (cityA == cityB) return -1;

        int small, big;

        if (cityA < cityB)
        {
            small = cityA;
            big = cityB;
        }
        else
        {
            small = cityB;
            big = cityA;
        }

        return (big * (big - 1) / 2) + small;
    }
}

Dies ist eine grafische Darstellung Ihrer Karte, wenn Sie die Städte folgendermaßen nummerieren: Nummerierte Städte

Dann müssen Sie nur noch eine Ganzzahl von 0 bis 9 verfolgen, die den aktuellen Standort Ihres Schiffes darstellt, und sich mit den Methoden zurechtfinden.

PatrickSharbaugh
quelle
Die Segmente sind jedoch Schritte. Obwohl ich die Hilfe schätze. Ein Schiff kann nicht von 8-7 springen, ohne die 5 segmentierten Stufen (schwarze Linien) zu
betreten
In diesem Fall können Sie die angegebene Klasse weiterhin verwenden, es gibt jedoch Knoten, die keine Städte sind, und Knoten, die es sind.
PatrickSharbaugh