| 

.NET C# Java Javascript Exception

3
Ich möchte Spielfiguren verschiendener Typen auf einem Spielfeld platzieren. Als Beispiel kann man sich ein Schachbrett mit Schachfiguren vorstellen.

Die Idee ist, die Spielfiguren als Objekte zu modellieren. Verschiedene Spielfiguren sind dabei Instanzen verschiedener Klassen. Das Spielfeld ist ein rechteckiges Feld. Auf jedem Feld kann maximal eine Spielfigur stehen.

Folgender Ansatz zur Modellierung würde mir gefallen. Es gibt Objekte der Klassen A, B, C usw. Instanzen der Klassen sollen in einem Array ar (edit) mit numerischen Indizes (/edit) gespeichert werden.

Wie kann man den obigen Ansatz in CSharp darstellen? Die Elemente eines Arrays in CSharp haben meines Wissens immer genau einen Typ. Sowas wie
ar(0,0) = new(A); /* eckige Klammern sind im BB-Code nicht erlaubt */
ar(1,1) = new(B);
...
geht wohl nicht.
Gibt es hier einen (eleganten) Lösungsansatz? Wenn ja, welcher Typ hat das Array, und wie erkenne ich ob
a) ein Objekt auf den ar(x,y) steht und
b) aus welcher Klasse das Objekt stammt

Ich hoffe ich konnte die Idee klar darstellen. Wenn nicht bitte fragen :-)
News:
08.09.2009
peri 51 1 2
peri 51 1 2
3 Antworten
5
Du hast (mindestens) zwei Möglichkeiten:
1) Listen vom Typ object
2) Generische Listen

Beispiel Typ object:
class Spielfeld
{
ArrayList _map = new ArrayList();
public Spielfeld()
{
for (int y = 0; y < 8; y++)
{
_map.Add(new ArrayList());
for (int x = 0; x < 8; x++)
((ArrayList)_map[y]).Add(null);
}
}

public object GetAt(int x, int y)
{
return ((ArrayList)_map[y])[x];
}

public void Test()
{
object t = GetAt(10, 10);
if (t is Figur1) // Mach was mit ((Figur1)t)
;
}
}
class Figur1 { }
class Figur2 { }
class Figur3 { }


Beispiel für Generische Listen:
class Spielfeld
{
List<List<Figur>> _map = new List<List<Figur>>();
public Spielfeld()
{
for (int y = 0; y < 8; y++)
{
_map.Add(new List<Figur>());
for (int x = 0; x < 8; x++)
_map[y].Add(null);
}
}

public Figur GetAt(int x, int y)
{
return _map[y][x];
}

public void Test()
{
Figur t = GetAt(10, 10);
if (t is Figur1) // Mach was mit ((Figur1)t)
;
}
}
class Figur1 : Figur { }
class Figur2 : Figur { }
class Figur { }
08.09.2009
DaSpors 4,2k 2 8
Das „t is Figur1“ würde ich vermeiden und stattdessen in der Basisklasse von den Subklassen zu implementierende abstrakte Methoden definieren, welche eine solche Unterscheidung unnötig machen.
reima 08.09.2009
Jup, auch ne Möglichkeit. Ich bin immer eher dafür den Code klein zu halten und lasse deswegen gern mal geschwindigkeit ausser Acht ;)
DaSpors 08.09.2009
@DaSpors: Dankesehr schonmal. Mit gefällt in Variante 1 die Idee mit Arraylists gut, und der Hinweis auf den Zugriff in der Funktion GetAt() ist prima, ich hätte an dieser Stelle wohl länger geknobelt. Dafür gibts eine positive Bewertung :-)
peri 08.09.2009
Kann mich da meinem Vorredner nur anschließen! Hast zwei super Beispiele beschrieben.
Dustin Klein 08.09.2009
1
Die Klasse Figur sollte abstract sein.
Statt GetAt kann ein Indexer (this[x,y]) verwendet werden.
Wenn die Größe des Spielfeldes konstant und bekannt ist (wie beim Schach) wäre ein jagged Array eine effiziente Alternative zur List<List<T>>.
gfoidl 08.09.2009
"Mit gefällt in Variante 1 die Idee mit Arraylists gut". Das ist aber die Steinzeitvariante die mit Objekt Orientierung nur wenig am Hut hat. Variante 2 (mit der Basisklasse) ist aufgrund von Polymorphie die enzig zu verwendende. Vergiss die ArrayList (außer du arbeitest mit .net 1.0 ;)
gfoidl 08.09.2009
2
Was spricht in diesem einfachen Fall gegen normale Arrays?
abstract class Figur { }
class Figur1 : Figur { }
class Figur2 : Figur { }
class Spielfeld
{
Figur[,] _spielfeld = new Figur[8, 10];
// ...
}
08.09.2009
stj 326 1 2
0
In Java würde ich ein Interface "Figur" definieren und alle Spielfiguren müßten das Interface implementieren. In Java kann man Collections von Interfaces bauen.

interface Figur {...}

public class Dame implements Figur {}

public class Bauer implements Figur {}

List<? extends Figur> feld = new ArrayList<? extends Figur> ();


Da C# stark von Java übernommen hat, würde ich davon ausgehen, dass C# das auch kann.
Ich kann es nur gerade nicht prüfen.
11.09.2009
stefan.bachert 395 4
Ja C# kann das. In den bisherigen Antworten wurde statt dem Interface eine abstrakte Klasse verwendet. Dies hat den Vorteil dass darin bereits ein "Template" definiert werden kann das für alle Spielfiguren gleich ist.

Aber warum eine Java-Antwort zu einer C#-Frage?
gfoidl 11.09.2009

Stelle deine .net-Frage jetzt!