diff --git a/Morris/ExtensionMethods.cs b/Morris/ExtensionMethods.cs
index 1d32fe4..961def8 100644
--- a/Morris/ExtensionMethods.cs
+++ b/Morris/ExtensionMethods.cs
@@ -19,5 +19,15 @@ namespace Morris
// der .Opponent verwendet, ist einfacher zu erkennen (Kapselung).
return ~p;
}
+
+ private static Random rng = new Random();
+
+ ///
+ /// Gibt ein zufälliges Element der IList zurück
+ ///
+ public static T ChooseRandom(this IList it)
+ {
+ return it[rng.Next(it.Count)];
+ }
}
}
diff --git a/Morris/GameState.cs b/Morris/GameState.cs
index 497052b..cf2ca97 100644
--- a/Morris/GameState.cs
+++ b/Morris/GameState.cs
@@ -244,7 +244,11 @@ namespace Morris
return MoveValidity.Invalid; // Darf keinen Stein mehr platzieren
// 3.: Wurde eine Mühle geschlossen?
- bool millClosed = Mills.Any(mill => mill.Contains(move.To) && mill.All(point => (int)Board[point] == (int)NextToMove || point == move.To));
+ bool millClosed = Mills.Any(mill => // Es muss eine potentielle Mühle geben, die
+ mill.Contains(move.To) && // den neu gesetzten Stein enthält und
+ mill.All(point => // bei der alle Punkte
+ (!move.From.HasValue || point != move.From) && // nicht der Ursprungspunkt der aktuellen Steinbewegung sind und
+ (int)Board[point] == (int)NextToMove || point == move.To)); // entweder schon vom Spieler bestzt sind oder Ziel der aktuellen Steinbewegung sind.
// 4.: Verifikation des Mühlenparameters
if (millClosed)
diff --git a/Morris/Morris.csproj b/Morris/Morris.csproj
index b865345..a5a8f20 100644
--- a/Morris/Morris.csproj
+++ b/Morris/Morris.csproj
@@ -49,6 +49,7 @@
+
diff --git a/Morris/Program.cs b/Morris/Program.cs
index ae35359..d2243c3 100644
--- a/Morris/Program.cs
+++ b/Morris/Program.cs
@@ -11,7 +11,8 @@ namespace Morris
static void Main(string[] args)
{
var a = new ConsoleInteraction();
- var g = new Game(a, a);
+ var b = new RandomBot();
+ var g = new Game(b, b);
g.AddObserver(a);
g.Run();
Console.ReadKey();
diff --git a/Morris/RandomBot.cs b/Morris/RandomBot.cs
new file mode 100644
index 0000000..6f195a7
--- /dev/null
+++ b/Morris/RandomBot.cs
@@ -0,0 +1,39 @@
+/*
+ * RandomBot.cs
+ * Copyright (c) 2016 Markus Himmel
+ * This fileis distributed under the terms of the MIT license
+ */
+
+using System;
+using System.Linq;
+
+namespace Morris
+{
+ ///
+ /// Ein extrem einfacher KI-Spieler, der einen zufälligen gültigen Spielzug auswählt
+ ///
+ class RandomBot : IMoveProvider
+ {
+ // Anhand dieser Klasse können wir sehen, wie einfach es ist, einen Computerspieler zu implementieren.
+ // Es muss lediglich eine einzige, einfache Methode implementiert werden. Der Spielzustandparameter stellt
+ // Methoden wie BasicMoves und IsValidMove bereit, mit denen viele verschiedene Strategien sehr einfach
+ // implementiert werden können.
+
+ private Random rng = new Random();
+
+ public GameMove GetNextMove(IReadOnlyGameState state)
+ {
+ // Ein zufälliger Spielzug
+ GameMove chosen = state.BasicMoves().ToList().ChooseRandom();
+
+ // Wenn wir einen Stein entfernen dürfen, wählen wir einen zufälligen Punkt aus, auf dem sich ein gegnerischer Stein befindet
+ if (state.IsValidMove(chosen) == MoveValidity.ClosesMill)
+ return chosen.WithRemove(Enumerable
+ .Range(0, GameState.FIELD_SIZE)
+ .Where(d => (int)state.Board[d] == (int)state.NextToMove.Opponent())
+ .ToList().ChooseRandom());
+
+ return chosen;
+ }
+ }
+}