public ListMap(int size) { Size = size; CreateNewBoard(); LastBlueMove = null; LastRedMove = null; }
public ListMap() { LastBlueMove = null; LastRedMove = null; //Size = 11; //CreateNewBoard(); }
public void DetachFrom(ListHex node) { if (node != null) { Attached[node.Row, node.Column] = 0; SetEdgeAttachedStatuses(); } }
public void ClearPathingVariables() { G = 0; H = 0; Parent = null; Status = Status.Untested; Priority = 0; }
public void AttachTo(ListHex node) { if (node != null && node.Owner == Owner) { Attached = Attached.Add(node.Attached).PointwiseMinimum(1.0); } SetEdgeAttachedStatuses(); }
public List <ListHex> GetNeighboursFrom(ListHex hex, PlayerType player) { var opponent = player == PlayerType.Blue ? PlayerType.Red : PlayerType.Blue; var neighbourHexes = hex.Neighbours.ToList(); var neighbours = neighbourHexes.Select(x => HexAt(x.ToTuple())).ToList(); neighbours.RemoveAll(x => x.Owner == opponent); return(neighbours.ToList()); }
public bool IsAttachedTo(ListHex node) { if (node != null) { return(IsAttachedTo(node.Row, node.Column)); } return(false); }
private void CreateNewBoard() { Board = new List <ListHex>(Size * Size); for (var row = 0; row < Size; row++) { for (var column = 0; column < Size; column++) { var hex = new ListHex(Size, row, column); Board.Add(hex); } } }
public bool TakeHex(PlayerType player, int row, int column) { if (!IsInBounds(row, column)) { return(false); } var hexToTake = Board.FirstOrDefault(x => x.Row == row && x.Column == column); if (hexToTake == null) { return(false); } if (hexToTake.Owner != PlayerType.White) { return(false); } hexToTake.Owner = player; var neighbours = GetNeighboursFor(hexToTake).Where(x => x.Owner == player).ToList(); neighbours.Add(hexToTake); var newAttachedMatrix = Matrix <double> .Build.Dense(Size, Size, 0); foreach (var hex in neighbours) { newAttachedMatrix = newAttachedMatrix + hex.Attached; } // This is the new attached matrix newAttachedMatrix = newAttachedMatrix.PointwiseMinimum(1.0); // Every item marked 1 in the new attached matrix must be given the new // matrix, not just the neighbours var hexesToUpdate = newAttachedMatrix.EnumerateIndexed(Zeros.AllowSkip); foreach (var hex in hexesToUpdate) { var myHex = HexAt(hex.Item1, hex.Item2); myHex.Attached = newAttachedMatrix; myHex.SetEdgeAttachedStatuses(); } if (player == PlayerType.Blue) { LastBlueMove = hexToTake; } else { LastRedMove = hexToTake; } return(true); }
private List <ListHex> GetNeighboursFor(ListHex source) { var neighbours = new List <ListHex>(); foreach (var neighbour in source.Neighbours) { var neighbourOnBoard = HexAt(neighbour.Row, neighbour.Column); if (neighbourOnBoard != null) { neighbours.Add(neighbourOnBoard); } } return(neighbours.ToList()); }
public ListHex(int size, int row, int column) : base(size, row, column) { Parent = null; RandomValue = Guid.NewGuid(); Status = Status.Untested; Attached = Matrix <double> .Build.Dense(size, size, 0); G = 0; H = 0; Attached.At(row, column, 1.0); Owner = PlayerType.White; GetNeighbours(); SetEdgeAttachedStatuses(); }
private bool IsInBounds(ListHex hex) { return(IsInBounds(hex.ToTuple())); }
public ListHex HexAt(ListHex hex) { return(HexAt(hex.ToTuple())); }
public List <ListHex> PathBetween(ListHex start, ListHex end, int currentBest) { // Get the best looking node var bestLookingHex = _searchSpace.Board .OrderBy(x => x.F()) .ThenBy(x => x.RandomValue) .FirstOrDefault(z => z.Status == Status.Open); if (bestLookingHex == null) { if (start.Status == Status.Untested || start.Status == Status.Open) { bestLookingHex = start; } else { return(new List <ListHex>()); } } if (bestLookingHex.Equals(end)) { AddLogLine(bestLookingHex + " is at end."); var preferredPath = new List <ListHex>(); var parent = bestLookingHex; while (parent != null) { if (!preferredPath.Contains(parent)) { preferredPath.Add(parent); parent = parent.Parent; } else { parent = null; } } return(preferredPath); } bestLookingHex.Status = Status.Closed; var neighbours = _searchSpace.GetNeighboursFrom(bestLookingHex, _playerSearchingFor); AddLog(neighbours.Count + " neighbours to examine."); foreach (var node in neighbours) { if (node.Owner != opponent) { if (node.Status == Status.Open) { if (node.G > bestLookingHex.G + (node.Owner == _playerSearchingFor ? costPerFriendlyNode : costPerOpenNode)) { node.Parent = bestLookingHex; node.G = bestLookingHex.G + (node.Owner == _playerSearchingFor ? costPerFriendlyNode : costPerOpenNode); node.H = (_playerSearchingFor == PlayerType.Blue ? _searchSpace.Size - 1 - node.Row : _searchSpace.Size - 1 - node.Column) * costPerNodeLeft; } } else if (node.Status == Status.Untested) { node.Status = Status.Open; node.Parent = bestLookingHex; node.G = bestLookingHex.G + (node.Owner == _playerSearchingFor ? costPerFriendlyNode : costPerOpenNode); node.H = (_playerSearchingFor == PlayerType.Blue ? _searchSpace.Size - 1 - node.Row : _searchSpace.Size - 1 - node.Column) * costPerNodeLeft; } } } return(PathBetween(start, end, currentBest)); }
private int ThinkAboutTheNextMove( ListPlayer player, ListMap map, List <ListHex> path, ListHex currentMove, int depth, int alpha, int beta, bool isMaximizing) { var judge = new Appraiser(); var scout = new Pathfinder(map, isMaximizing ? player.Me : player.Opponent()); var myPath = scout.GetPathForPlayer(); if (depth == 0 || map.Board.All(x => x.Owner != PlayerType.White)) { return(judge.ScoreFromBoard(player, myPath, path)); } var possibleMoves = GetPossibleMoves(path, myPath, isMaximizing ? player.Me : player.Opponent(), map); if (isMaximizing) { foreach (var move in possibleMoves) { var bestScore = -9999; var newMap = map.GetCopyOf(); newMap.TakeHex(player.Me, move.Row, move.Column); bestScore = Math.Max(bestScore, ThinkAboutTheNextMove( player, newMap, myPath, move, depth - 1, alpha, beta, false)); if (bestScore > alpha) { _finalChoice = move.ToTuple(); alpha = bestScore; } if (beta <= alpha) { break; } } return(alpha); } else { foreach (var move in possibleMoves) { var worstScore = 9999; var newMap = map.GetCopyOf(); newMap.TakeHex(player.Opponent(), move.Row, move.Column); worstScore = Math.Min(worstScore, ThinkAboutTheNextMove( player, newMap, myPath, move, depth - 1, alpha, beta, true)); beta = Math.Min(worstScore, beta); if (beta <= alpha) { break; } } return(beta); } }