mirror of
https://github.com/TwoFX/Morris.git
synced 2025-12-13 08:22:51 +00:00
Add RandomBot, fix a bug in the game logic
This commit is contained in:
@@ -19,5 +19,15 @@ namespace Morris
|
||||
// der .Opponent verwendet, ist einfacher zu erkennen (Kapselung).
|
||||
return ~p;
|
||||
}
|
||||
|
||||
private static Random rng = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// Gibt ein zufälliges Element der IList zurück
|
||||
/// </summary>
|
||||
public static T ChooseRandom<T>(this IList<T> it)
|
||||
{
|
||||
return it[rng.Next(it.Count)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<Compile Include="Game.cs" />
|
||||
<Compile Include="GameResult.cs" />
|
||||
<Compile Include="GameState.cs" />
|
||||
<Compile Include="RandomBot.cs" />
|
||||
<None Include="LICENSE" />
|
||||
<Compile Include="IGameStateObserver.cs" />
|
||||
<Compile Include="IMoveProvider.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();
|
||||
|
||||
39
Morris/RandomBot.cs
Normal file
39
Morris/RandomBot.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Ein extrem einfacher KI-Spieler, der einen zufälligen gültigen Spielzug auswählt
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user