private static float AlphaBeta(GameState gs, int depth, float alpha, float beta, bool isMax) { if (depth == 0 || gs.IsEndGame()) { float val = EvaluateMove(gs); return isMax ? val : -val; } Point p = null; if (isMax) { p = new Point(gs.MyX(), gs.MyY()); } else { p = new Point(gs.OpponentX(), gs.OpponentY()); } GameState newState = null; foreach (Point child in gs.PossibleMoves(p.X, p.Y, true)) { if (isMax) { newState = gs.ApplyMoveToMeAndCreate(child.GetDirectionFromPoint(p.X, p.Y)); } else { newState = gs.ApplyMoveToOpponentAndCreate(child.GetDirectionFromPoint(p.X, p.Y)); } alpha = Math.Max (alpha, -AlphaBeta(newState, depth-1, -beta, -alpha, !isMax)); if (beta <= alpha) { break; } } return alpha; }
// do flood fill from all reachable nodes in graph and return running count private static int FloodFillDepthFirst(GameState gs, bool me) { toVisitStack.Clear(); visited.Clear(); toVisitStack.Push(gs); int score = 0; while(toVisitStack.Count != 0) { GameState v = toVisitStack.Pop(); if (!visited.Contains(v)) { visited.Add(v); if (me) { score += FloodFill(v, v.MyX(), v.MyY()); foreach (Point n in gs.PossibleMoves(v.MyX(), v.MyY())) { toVisitStack.Push(v.ApplyMoveToMeAndCreate(n.GetDirectionFromPoint(v.MyX(), v.MyY()))); } } else { score += FloodFill(v, v.OpponentX(), v.OpponentY()); foreach (Point n in gs.PossibleMoves(v.OpponentX(), v.OpponentY())) { toVisitStack.Push(v.ApplyMoveToOpponentAndCreate(n.GetDirectionFromPoint(v.OpponentX(), v.OpponentY()))); } } } } return score; }
// Modified A* search // TODO clean up this is barely legible private static Path MoveByShortestPath(GameState gs, Point goal) { List<GameState> toVisit = new List<GameState>(); List<GameState> visited = new List<GameState>(); toVisit.Add(gs); while(toVisit.Count != 0) { // determine which node in queue is closet to the goal if (toVisit.Count > 1) { float best = GetEuclideanOpponentDistance(toVisit[0].MyX(), toVisit[0].MyY()); float tmp; int bestIndex = 0; for(int i=1; i < toVisit.Count; i++) { tmp = GetEuclideanOpponentDistance(toVisit[i].MyX(), toVisit[i].MyY()); if (tmp < best) { bestIndex = i; best = tmp; } } if (bestIndex > 0) { GameState removed = toVisit[bestIndex]; toVisit.RemoveAt(bestIndex); toVisit.Insert(0, removed); } } GameState v = toVisit[0]; toVisit.RemoveAt(0); if (!visited.Contains(v)) { visited.Add(v); foreach (Point n in gs.PossibleMoves(v.MyX(), v.MyY(), true)) { // goal found if (goal != null && n.X == goal.X && n.Y == goal.Y) { //Console.Error.WriteLine("Found"); GameState found = v.ApplyMoveToMeAndCreate(n.GetDirectionFromPoint(v.MyX(), v.MyY())); found.SetParent(v); return GetPath(found); // add neighbours to queue } else if (!v.IsWall(n.X, n.Y)) { GameState next = v.ApplyMoveToMeAndCreate(n.GetDirectionFromPoint(v.MyX(), v.MyY())); if (toVisit.Contains(next)) { GameState parent = toVisit[toVisit.IndexOf(next)].GetParent(); // path back to start node is shorter from node being processed if (GetEuclideanOpponentDistance(new Point(v.MyX(), v.MyY()), new Point(Map.MyX(), Map.MyY())) < parent.GetScore()) { //Console.Error.WriteLine("betta"); toVisit[toVisit.IndexOf(next)].SetParent(v); continue; } } v.SetScore(GetEuclideanOpponentDistance(new Point(v.MyX(), v.MyY()), new Point(Map.MyX(), Map.MyY()))); next.SetParent(v); toVisit.Add(next); } } } } return null; }
private static int BreadthFirst(GameState gs, bool me) { //Queue<GameState> toVisit = new Queue<GameState>(); //List<GameState> visited = new List<GameState>(); toVisit.Clear(); visited.Clear(); toVisit.Enqueue(gs); while(toVisit.Count != 0) { GameState v = toVisit.Dequeue(); if (!visited.Contains(v)) { visited.Add(v); if (me) { foreach (Point n in gs.PossibleMoves(v.MyX(), v.MyY())) { toVisit.Enqueue(v.ApplyMoveToMeAndCreate(n.GetDirectionFromPoint(v.MyX(), v.MyY()))); } } else { foreach (Point n in gs.PossibleMoves(v.OpponentX(), v.OpponentY())) { toVisit.Enqueue(v.ApplyMoveToOpponentAndCreate(n.GetDirectionFromPoint(v.OpponentX(), v.OpponentY()))); } } } } return visited.Count; }