• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

Mühle Spiel inklusive KI

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Bevor wir alles mit Websocket ausstatten, lohnt sich die Wahl der "Server"sprache, ja irgendwo sehr. :p
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Moment.. In welcher Sprache der Server geschrieben ist sollte eigentlich irrelevant für den Client sein oder meinst du das Kommunikationsprotokoll zwischen Client und Server?
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
Ich habe die Plätze intern mit Nummern versehen, 1-24, von links nach rechts, von unten nach oben.
Das wäre ne einfache Möglichkeit, Züge anzugeben.... (so muss ich auch nix ändern.. :-P)

Aber: meine KI ist schlecht und des Namens unwürdig, so richtig witzig würde das mit der nicht werden...
Wenn jetzt aber 5, 6 Leute eine haben, würde ich meine weiter entwickeln... Sonst aber lohnt sich das nicht
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
@MingsPing:

Meine ist auch nicht gut, sieh überlegt nur ein wenig, es ist nicht komplett reiner Zufall.

Aber mir geht es ähnlich. Und groß an dem Code Erweitern möchte ich auch vermeiden. Bin gerade in Askese was das Coding angeht... und muß mich erstmal wieder sammeln.

Aber es gibt bei meiner Lösung noch Probleme, das ist fern von fertig. Aber die kann man, wenn man intensiver darüber nachdenkt und Zeit besitzt auch fixen.
Also komplett doof ist sie nicht.

Hier haben sich aber nicht viele gemeldet... leider :o
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Über eine KI habe ich mir selbst noch keine Gedanken gemacht.
Ich bin leider auch kein Mühle-Profi. Eine KI sollte aber im Vergleich zu anderen Spielen nicht allzu schwer sein.
Im Moment schreibe ich mit theSplit ja bereits wegen eines Servers, auf dem die KIs gegeneinander spielen können, wenn ausreichendes Interesse besteht.

Daher wäre es toll, wenn sich noch ein paar Leute melden. Auch wenn die KIs aktuell noch nicht fertig sind, kann ja jeder weiter entwickeln.
Ggf. würde ich dann auch eine eigene KI beisteuern.
 

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
  • Thread Starter Thread Starter
  • #68
In ca. 2 Wochen habe ich auch wieder ein paar Tage Zeit, da könnte ich meine KI etwas weiterentwickeln.
Wenn ihr aber meint, dass die 4 KIs zu wenige sind (sind doch 4 oder?) dann könnte man ja auch an die Veranstalter des Wettbewerbs schreiben und mal fragen, ob die ne Mail rumschicken wollen, damit sich hier vielleicht noch welche anschließen.

Ich würde das mit dem KIs gegeneinander antreten lassen übrigens auch sehr interessant finden, wenn wir das mit Go machen. Da denke ich, ist es deutlich komplizierter eine KI zu entwerfen, die nicht nur per Zufall spielt, da das "Potentielle Gebiet" zu erkennen eher anspruchsvoll sein dürfte.
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Aktuell unterhalte ich mich per PN mit theSplit bezüglich eines möglichen Client-Server Protokolls.

Ich denke, dass das Erkennen einer Mühle ein wesentlicher, wenn gleich fast trivialer Bestandteil der KI sein sollte.
Führt die KI einen Zug aus, muss sie selbst erkennen, wenn sie dadurch eine Mühle gebaut hat und sollte dies selbstständig dem Server mitteilen.
Der Server validiert nur die Angaben des Clients, hilft ihm jedoch nicht bei der Analyse des Feldes.


Ohne eine konkrete Implementierung darzustellen, will ich den wesentlichen Gedanken bei der Erkennung einer Mühle vorführen.



Zur Illustration:

Nehmen wir an, die Felder des Mühlefelds seien wie folgt durchnummeriert.
[src=text]Feld-Ids:
[ 1 ] ----------- [ 2] --------- [ 3]
| | |
| [ 4] ---- [ 5] ---- [ 6] |
| | | | |
| | [ 7][ 8][ 9] | |
[ 10]-[ 11]-[ 12] [ 13]-[ 14]-[ 15]
| | [ 16][ 17][ 18] | |
| | | | |
| [ 19] ---- [ 20] ---- [ 21] |
| | |
[ 22] ---------- [ 23] ---------- [ 24][/src]

Es gibt eine Ausgangssituation, bevor die KI ihren Zug ausführt.
[src=text]Ausgangsposition:
[ x ] ----------- [ ] --------- [ o ]
| | |
| [ o ] ---- [ ] ---- [ o ] |
| | | | |
| | [ o ][ ][ ] | |
[ x ]-[ ]-[ ] [ ]-[ ]-[ ]
| | [ ][ ][ ] | |
| | | | |
| [ ] ---- [ ] ---- [ ] |
| | |
[ ] ---------- [ x ] ---------- [ x ][/src]

Die KI, die x spielt, ist am Zug und entscheidet von Feld 10 auf Feld 22 zu ziehen:
[src=text]Feld nach Zug (10, 22):
[ x ] ----------- [ ] --------- [ o ]
| | |
| [ o ] ---- [ ] ---- [ o ] |
| | | | |
| | [ o ][ ][ ] | |
[ _ ]-[ ]-[ ] [ ]-[ ]-[ ]
| | [ ][ ][ ] | |
| | | | |
| [ ] ---- [ ] ---- [ ] |
| | |
[ x ] ---------- [ x ] ---------- [ x ][/src]

Die KI muss an dieser Stelle erkennen, dass durch den Zug eine Mühle mit 22, 23, 24 entstanden ist und muss selbst entscheiden, welchen Stein sie entfernt.



Man kann sich nun überlegen, dass es für das Auftreten/ Entstehen einer Mühle keine Rolle spielt ob ein Stein nach links oder nach rechts (also horizontal) bzw. nach oben oder nach unten (also vertikal) bewegt wird. Wird ein Stein horizontal bewegt, sind die vertikalen Nachbarn des Steins zu untersuchen. Wird er vertikal bewegt, so sind die horizontalen Nachbarn zu untersuchen.

Das kann man sich anhand des Beispielfeldes recht schnell klar machen: Wird ein Stein von 10 nach 22 bewegt, so entsteht auf 10 ein leeres Feld, in der Vertikalen kann folglich keine neue Mühle entstehen. Nur in der Horizontalen und natürlich nur dort, wo ein Stein hinzugekommen ist, kann eine neue Mühle entstehen. Dazu muss man überlegen, welche Horizontalen Nachbarn eines Feldes existieren. Im Fall der 22 existiert ein Nachbar (23) rechts von der 22 und ein Nachbar (24) rechts vom Rechten Nachbarn (23).

Allgemein können nur 3 Nachbarschaftsfälle auftreten:
[src=text]Fall 1: Es existieren 2 linke Nachbarn
[_]
|
[?]-[?]-[x]

Fall 2: Es existiert ein linker und ein rechter Nachbar:
[_]
|
[?]-[x]-[?]

Fall 3: Es existieren zwei ein rechte Nachbarn:
[_]
|
[x]-[?]-[?][/src]

Analog lässt sich die Situation analysieren, wenn eine horizontale Bewegung durchgeführt wurde.


Wer bisher Probleme mit der Erkennung von Mühlen gehabt hat, sollte damit hoffentlich weiter kommen.
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
Nur eine Anmerkung, bitte die Nummerierung von unten nach oben, sprich links unten beginnt die 1... :-)
Sonst mit allem einverstanden.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Ich habs bei mir so gelöst gehabt:
Spielfelder im Uhrzeigersinn von 0 - 8 und vermerkt auf welchem Quadrat diese liegen.
Die Felder lagen alle in einem Array.

Um auf ein Feld zu kommen rechnet man also "feldNummer + (8 * feldQuadrat)" - war so ziemlich einfach, wenn man will könnte man in dieser Form sogar noch Quadrate hinzufügen ;)

Einziges kleines Manko, der Sprung von Feld 8 auf 0 bzw. 0 auf 8. Sonst kann man die Nachbarn ganz einfach bestimmen. mit theoretisch +1 +2 -1 -2 vom FeldIndex wobei natürlich noch überprüft werden muß das Feld 1 nicht einen -2 Nachbarn hat weil dies 8 wäre...

Und die Nachbarn werden dann auf eigene Steine überprüft. Horizontale und Vertikale Verbindung werden dann nochmal extra erfasst, lässt sich aber leicht rechnen in welchem Quadrat das Feld liegt.
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
@MingsPing: Die Benennung der Felder sollte das kleinste Problem darstellen. Das ist, wie schon gesagt nur eine Sache der Benennung und ist im Prinzip völlig willkürlich.
Sollte sie dir gar nicht zusagen, kannst du auch eine Methode implementieren, die eine Übersetzung der FeldIds, wie ich sie nun angegeben habe und wie du sie bei dir intern verwendest, durchführen:


[src=text]
Feld-Ids von mir
[ 1 ] ----------- [ 2] --------- [ 3]
| | |
| [ 4] ---- [ 5] ---- [ 6] |
| | | | |
| | [ 7][ 8][ 9] | |
[ 10]-[ 11]-[ 12] [ 13]-[ 14]-[ 15]
| | [ 16][ 17][ 18] | |
| | | | |
| [ 19] ---- [ 20] ---- [ 21] |
| | |
[ 22] ---------- [ 23] ---------- [ 24]
[/src]

[src=text]
Feld-Ids von dir
[ 1] ----------- [ 10] --------- [ 22]
| | |
| [ 4] ---- [ 11] ---- [ 19] |
| | | | |
| | [ 7][ 12][ 16] | |
[ 2]-[ 5]-[ 8] [ 17]-[ 20]-[ 23]
| | [ 9][ 13][ 18] | |
| | | | |
| [ 6] ---- [ 14] ---- [ 21] |
| | |
[ 3] ---------- [ 15] ---------- [ 24]
[/src]

[src=java]
public static mineToYours (int fieldId)
{
switch (fieldId)
{
case 1 : return 1;
case 2 : return 10;
case 3 : return 22;
case 4 : return 4;
case 5 : return 11;
case 6 : return 19;
case 7 : return 7;
case 8 : return 12;
case 9 : return 16;
case 10 : return 2;
case 11 : return 5;
case 12 : return 8;
case 13 : return 17;
case 14 : return 20;
case 15 : return 23;
case 16 : return 9;
case 17 : return 13;
case 18 : return 18;
case 19 : return 6;
case 20 : return 14;
case 21 : return 21;
case 22 : return 3;
case 23 : return 15;
case 24 : return 24;
default: throw new IllegalArgumentException("Dieses Feld existiert nicht.");
}
}

public static yoursToMine (int fieldId)
{

return mineToYours(mineToYours(fieldId));

}

[/src]



Das Ganze befindet sich auch bei mir noch in der Planungsphase - ich mache das ja nur nebenher - und daher brauchst du dir über sowas noch keine großen Gedanken zu machen. Im Moment ist die Energie noch in einer KI besser aufgehoben.


@theSplit Müsstest du dann nicht mit Modul-Rechnung hin kommen?
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
@theSplit Müsstest du dann nicht mit Modul-Rechnung hin kommen?

Schau dir mal deinen Aufbau an:
[src=text]Feld-Ids von mir
[ 1 ] ---------- [ 2] --------- [ 3]
| | |
| [ 4] ---- [ 5] ---- [ 6] |
| | | | |
| | [ 7][ 8][ 9] | |
[ 10]-[ 11]-[ 12] [ 13]-[ 14]-[ 15]
| | [ 16][ 17][ 18] | |
| | | | |
| [ 19] ---- [ 20] ---- [ 21] |
| | |
[ 22] ---------- [ 23] ---------- [ 24][/src]


Gegenüber:
[src=text]
[ 0 ] ---------- [ 1 ] ---------- [ 2 ]
| | |
| [ 0 ] ---- [ 1 ] ---- [ 2 ] |
| | | | |
| | [ 0 ][ 1 ][ 2 ] | |
[ 7 ]-[ 7 ]-[ 7 ] [ 3 ]-[ 3 ]-[ 3 ]
| | [ 6 ][ 5 ][ 4 ] | |
| | | | |
| [ 6 ] ---- [ 5 ] ---- [ 4 ] |
| | |
[ 6 ] ---------- [ 5 ] ---------- [ 4 ][/src]

bzw: mit durchlaufender Nummerierung

[src=text]
[ 0 ] ---------- [ 1 ] ---------- [ 2 ]
| | |
| [ 8 ] ---- [ 9 ] ---- [ 10] |
| | | | |
| | [ 16][ 17][ 18] | |
[ 7 ]-[ 15]-[ 23] [ 19]-[ 11]-[ 3 ]
| | [ 22][ 21][ 20] | |
| | | | |
| [ 14] ---- [ 13] ---- [ 12] |
| | |
[ 6 ] ---------- [ 5 ] ---------- [ 4 ][/src]

Bei welchem ist mathematisch leichter zu erfassen, Sprung von Feld zu Feld in einer Zahl ausgedrückt, was Nachbarn sind bzw. ob wir uns von einem Quadrat in andere Bewegen müssen?

Beispiele was ich damit meine:
Von deiner Lösung zu Feld 1 und Feld 10 ist der Schritt 9, von Feld 4 zu 11 ist es 7 von Feld 7 zu 12 ist es 5...
Von Feld 22 zu 10 sind 12, von Feld 19 zu 11 sind es 8 von Feld 16 zu 12 sind es 4...

Gegenüber:
Von Feld 0 zu 7 sind es 8 immer (Array Index).
Bei durchlaufender Nummerierung:
Von Feld 0 zu 7, 8 - von Feld 8 zu 15, 8 - von Feld 16 zu 23 - 8er Sprung im Array immer.

Dein Aufbau ist also für Menschen eventuell intuitiver - aber um die Frage zu klären ob wir horizonalte oder vertikale Nachbarn haben:
Wenn die Nummeriung bei 0 anfängt:

(Feldnummer + 1) % 2 == 0 ? Achse : sonst Eckpunkt;
wenn Achse:
ist (Feldnummer + 1) % 8 == 0 ? > (links Horizontal)
sonst ist (Feldnummer + 1) % 6 == 0 ? > (unten Vertikal)
sonst ist (Feldnummer + 1) % 4 == 0 ? > (rechts Horizontal)
sonst (oben Vertikal)

Dies ist bei deinem Aufbau nicht ganz gegeben:
So hat man bei "oben Vertikal" folgenden Sprung:
2, 5, 8 (3)
Unter Vertikal ist die Regelung ganz anders:
21, 13, 5 (8)

Links Horizontal:
10, 11, 12 (1)

Rechts Horizontal:
13, 14, 15 (1)

Bei meiner Lösung hast du auf jeder Achse einen Sprung von 8 zu machen, egal ob du von Quadrat 3 auf 2 wechselst oder von 2 zu 1 oder 1 zu 2.... usw. horizontal + vertikal.

Rechne mal durch wie du deine Verknüpfung "mathematisch" beweisen würdest! Bzw. welche Muster sich ergeben bzw. nicht im Vergleich zu meinem Schema.

-----

Zu deiner Frage, Modulo Rechnung würde ich so nicht verwenden, sondern ganz normal teilen und das Ergebnis abrunden auf die vorherige volle Zahl:
Feld 19 liegt auf Quadrat?
floor(19 / 8) = floor(2,375) = 2;

Mit Modulo:
19 % 8 = 3
17 % 8 = 1
...

Wobei bei einer Durchnummerierung auch diese Berechnung herausfällt.

Ich fand es per se nur "schöner" zu wissen, das Feld 0 links oben ist und Feld 7 das genau darunter liegende usw...
Genauso wie ich einmal für alle Felder die gleichen Regeln haben was wo und wie Nachbarn sind.
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
@virtus,
die Benennung des Feldes ist auch das kleinste Problem, das würde ich schon hinbekommen :-P (aber, lieber "nix" tun, als "ein bisschen", oder? :-) )

Die Quadrat-Benennung kann Vorteile haben, klar. Bei mir geht das ganze über Kanten und Ecken, in einem Graph, sodass die Benennung hier nicht so wichtig ist.

BTW virtus, meine Anordnung ist so:
[src=bash]
[ 22] ---------- [ 23] --------- [ 24]
| | |
| [ 19] ---- [ 20] ---- [ 21] |
| | | | |
| | [ 16][ 17][ 18] | |
[ 10]-[ 11]-[ 12] [ 13]-[ 14]-[ 15]
| | [ 7][ 8][ 9] | |
| | | | |
| [ 4] ---- [ 5] ---- [ 6] |
| | |
[ 1 ] ---------- [ 2 ] ---------- [ 3 ]
[/src]
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Die Benennung der Felder verwende ich intern nicht. Die verwende ich nur für den Informationsaustausch.
Ein Feld hält bei mir jeweils selbst die Information mit welchen Feldern es wie verknüpft ist.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Also hast du das ganze aufgebaut wie Knoten die untereinander verlinkt sind?

Und du wanderst dann nur in eine Richtung um eine Mühle zu erkennen?
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
Ja genau.
Jede Kante hat noch die Information, ob sie horizontal oder vertikal verläuft. Damit prüfe ich dann nur, ob die zum Knoten benachbarten Knoten (und deren Nachbarn) horizontal/vertikal gleich besetzt sind.

Die Knoten selbst liegen bei mir in einer Liste,die Kanten auch.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
@MingsPing

Nur zum besseren Verständnis, die Information ob "Norden", "Osten", "Süden" oder "Westen" Nachbarn angrenzen - also für die Suche in eine "Himmelsrichtung", wird dann aber in jedem Knoten/Feld benötigt oder?
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Also hast du das ganze aufgebaut wie Knoten die untereinander verlinkt sind?
Ja.

Und du wanderst dann nur in eine Richtung um eine Mühle zu erkennen?
Nein, in eine Richtung zu wandern reicht nicht aus. Bei "mittleren" Knoten musst du in beide Richtungen prüfen.

[]<-- prüft BOTTOM und BOTTOM.BOTTOM
[]<-- prüft TOP und BOTTOM
[]<-- prüft TOP und TOP.TOP

bzw entsprechend für horizontale Felder


Ja, jeder Knoten hat bei mir 4 Nachbarknoten gespeichert, wobei Nachbarknoten auch NULL sein können (z.B. oben links hat natürlich weder TOP noch LEFT)
 
Oben