public void DoAIMove(Larva Larva, Bird[] Birds, Board Board) { BoardConfig nextConfig = AILarvaMove(Larva, Birds, Board); try { _larva.Move(new Move(_larva.Pos, nextConfig.LarvaPos)); } catch (InvalidMoveException) { } }
private int getBirdToMove(BoardConfig nextConfig, BoardConfig origBC) { for (int i = 0; i < nextConfig.BirdsPos.Length; ++i) { if (!(origBC.BirdsPos[i].Equals(nextConfig.BirdsPos[i]))) { return(i); } } return(-1); }
public static void calculateLevelHeuristics(ref List <BCTree <BoardConfig> > lNodes) { for (int i = 0; i < lNodes.Count; ++i) { if ((lNodes[i].Level % 2) == 0) // Calculate heuristics of level 2 or level 0, so MAX of children { if (lNodes[i].isLeaf) { BoardConfig tempBC = new BoardConfig(lNodes[i].data); int tempHeuristic = lNodes[i].data.EvaluateBCHeuristic(); tempBC.heuristic = tempHeuristic; lNodes[i].data = tempBC; } else { BoardConfig tempBC = new BoardConfig(lNodes[i].data); int MAXHeuristic = lNodes[i].children[0].data.heuristic; for (int j = 1; j < lNodes[i].children.Count; ++j) { if (lNodes[i].children[j].data.heuristic > MAXHeuristic) { MAXHeuristic = lNodes[i].children[j].data.heuristic; } } tempBC.heuristic = MAXHeuristic; lNodes[i].data = tempBC; } } else if ((lNodes[i].Level % 2) == 1) // Calculate heuristics of level 3 or level 1, so MIN of children (or just calculate heuristic for level 3) { if (lNodes[i].isLeaf) { BoardConfig tempBC = new BoardConfig(lNodes[i].data); int tempHeuristic = lNodes[i].data.EvaluateBCHeuristic(); tempBC.heuristic = tempHeuristic; lNodes[i].data = tempBC; } else { BoardConfig tempBC = new BoardConfig(lNodes[i].data); int MINHeuristic = lNodes[i].children[0].data.heuristic; for (int j = 1; j < lNodes[i].children.Count; ++j) { if (lNodes[i].children[j].data.heuristic < MINHeuristic) { MINHeuristic = lNodes[i].children[j].data.heuristic; } } tempBC.heuristic = MINHeuristic; lNodes[i].data = tempBC; } } } }
public BoardConfig(BoardConfig bc) : this() { Level = bc.Level; LarvaPos = bc.LarvaPos; BirdsPos = new Position[bc.BirdsPos.Length]; for (int i = 0; i < bc.BirdsPos.Length; ++i) { BirdsPos[i] = bc.BirdsPos[i]; } }
// TODO make method less repetitive public static void generateLarvaChildren(ref BCTree <BoardConfig> parentNode, int lvl, Board Board) { //Console.Write("ParentNode Larva = " + GetScoreForPos(parentNode.data.LarvaPos)); for (int i = 0; i < parentNode.data.BirdsPos.Length; ++i) { //Console.Write(", Bird " + (i + 1) + " = " + GetScoreForPos(parentNode.data.BirdsPos[i])); } //Console.WriteLine(); Position topLeftPosition = new Position(parentNode.data.LarvaPos.Row - 1, parentNode.data.LarvaPos.Col - 1); if (Board.IsValidPosition(topLeftPosition) && parentNode.data.IsCellEmpty(topLeftPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.LarvaPos = topLeftPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Top left position = " + GetScoreForPos(topLeftPosition)); } Position topRightPosition = new Position(parentNode.data.LarvaPos.Row - 1, parentNode.data.LarvaPos.Col + 1); if (Board.IsValidPosition(topRightPosition) && parentNode.data.IsCellEmpty(topRightPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.LarvaPos = topRightPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Top right position = " + GetScoreForPos(topRightPosition)); } Position bottomLeftPosition = new Position(parentNode.data.LarvaPos.Row + 1, parentNode.data.LarvaPos.Col - 1); if (Board.IsValidPosition(bottomLeftPosition) && parentNode.data.IsCellEmpty(bottomLeftPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.LarvaPos = bottomLeftPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bottom left position = " + GetScoreForPos(bottomLeftPosition)); } Position bottomRightPosition = new Position(parentNode.data.LarvaPos.Row + 1, parentNode.data.LarvaPos.Col + 1); if (Board.IsValidPosition(bottomRightPosition) && parentNode.data.IsCellEmpty(bottomRightPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.LarvaPos = bottomRightPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bottom right position = " + GetScoreForPos(bottomRightPosition)); } }
public static BoardConfig getBestMove(List <BCTree <BoardConfig> > level1Nodes, ref BCTree <BoardConfig> rootNode, bool larva) { // Calculate MAX of children and place it in root, as well as return Board Configuration of MAX child if (rootNode.isLeaf) { BoardConfig tempBC = new BoardConfig(rootNode.data); int tempHeuristic = rootNode.data.EvaluateBCHeuristic(); tempBC.heuristic = tempHeuristic; rootNode.data = tempBC; //Console.WriteLine("Root is a leaf"); return(rootNode.data); } else { BoardConfig tempBC = new BoardConfig(rootNode.data); int MAXHeuristic = rootNode.children[0].data.heuristic; BoardConfig MAXConfig = rootNode.children[0].data; for (int i = 1; i < rootNode.children.Count; ++i) { if (larva) { if (rootNode.children[i].data.heuristic > MAXHeuristic) { MAXHeuristic = rootNode.children[i].data.heuristic; MAXConfig = rootNode.children[i].data; } } else { if (rootNode.children[i].data.heuristic < MAXHeuristic) { MAXHeuristic = rootNode.children[i].data.heuristic; MAXConfig = rootNode.children[i].data; } } } rootNode.data = MAXConfig; return(MAXConfig); } }
public void DoAIMove(Larva Larva, Bird[] Birds, Board Board) { int birdIndex = 4; var to = new Position(); BoardConfig nextConfig = AIBirdsMove(Larva, Birds, Board); for (int i = 0; i < _birds.Length; ++i) { if (!(nextConfig.BirdsPos[i].Equals(_birds[i].Pos))) { birdIndex = i; to = nextConfig.BirdsPos[i]; } } try { _birds[birdIndex].Move(new Move(_birds[birdIndex].Pos, to)); } catch (InvalidMoveException) { } }
public BoardConfig AIBirdsMove(Larva Larva, Bird[] Birds, Board Board) { // Get original positions Position origLarvaPosition = Larva.Pos; Position[] origBirdsPosition = new Position[Birds.Length]; for (int i = 0; i < Birds.Length; ++i) { origBirdsPosition[i] = Birds[i].Pos; } BoardConfig origBC = new BoardConfig(0, origLarvaPosition, origBirdsPosition); BCTree <BoardConfig> MiniMaxTree = new BCTree <BoardConfig>(origBC); // Get level 1 kids for the Birds Utilities.generateBirdsChildren(ref MiniMaxTree, 1, Board); List <BCTree <BoardConfig> > level1Nodes = new List <BCTree <BoardConfig> >(); Utilities.drill(MiniMaxTree, 0, 1, ref level1Nodes); //Console.WriteLine("Count of nodes at Level 1 given by drill method = " + level1Nodes.Count); // Get level 2 kids for the Larva for (int i = 0; i < level1Nodes.Count; ++i) { var temp = level1Nodes[i]; Utilities.generateLarvaChildren(ref temp, 2, Board); } List <BCTree <BoardConfig> > level2Nodes = new List <BCTree <BoardConfig> >(); Utilities.drill(MiniMaxTree, 0, 2, ref level2Nodes); //Console.WriteLine("Count of nodes at Level 2 given by drill method = " + level2Nodes.Count); // Get level 3 kids for the Birds for (int i = 0; i < level2Nodes.Count; ++i) { var temp = level2Nodes[i]; Utilities.generateBirdsChildren(ref temp, 3, Board); } List <BCTree <BoardConfig> > level3Nodes = new List <BCTree <BoardConfig> >(); Utilities.drill(MiniMaxTree, 0, 3, ref level3Nodes); //Console.WriteLine("Count of nodes at Level 3 given by drill method = " + level3Nodes.Count); //Console.WriteLine("Calculating level 3 heuristics..."); Utilities.calculateLevelHeuristics(ref level3Nodes); for (int i = 0; i < level3Nodes.Count; i++) { //Console.WriteLine(i + " " + level3Nodes[i].data.heuristic); } //Console.WriteLine("Calculating level 2 heuristics..."); Utilities.calculateLevelHeuristics(ref level2Nodes); for (int i = 0; i < level2Nodes.Count; i++) { //Console.WriteLine(i + " " + level2Nodes[i].data.heuristic); } //Console.WriteLine("Calculating level 1 heuristics..."); Utilities.calculateLevelHeuristics(ref level1Nodes); for (int i = 0; i < level1Nodes.Count; i++) { //Console.WriteLine(i + " " + level1Nodes[i].data.heuristic); } Console.WriteLine(); Console.Write("Current Positions - Larva = " + Utilities.GetScoreForPos(MiniMaxTree.data.LarvaPos)); for (int i = 0; i < MiniMaxTree.data.BirdsPos.Length; ++i) { Console.Write(", Bird " + (i + 1) + " = " + Utilities.GetScoreForPos(MiniMaxTree.data.BirdsPos[i])); } Console.WriteLine(); Console.WriteLine("Calculating best move for Birds..."); BoardConfig nextConfig = Utilities.getBestMove(level1Nodes, ref MiniMaxTree, false); int birdToMove = getBirdToMove(nextConfig, origBC); Position nextBirdPosition = nextConfig.BirdsPos[birdToMove]; Utilities.PreOrderPrintBirds(MiniMaxTree); Console.WriteLine("The best next move for the Birds is for Bird " + (birdToMove + 1) + " to go to position " + Utilities.GetScoreForPos(nextBirdPosition)); Console.WriteLine(); return(nextConfig); }
// TODO make method less repetitive public static void generateBirdsChildren(ref BCTree <BoardConfig> parentNode, int lvl, Board Board) { //Console.Write("ParentNode Larva = " + GetScoreForPos(parentNode.data.LarvaPos)); for (int i = 0; i < parentNode.data.BirdsPos.Length; ++i) { //Console.Write(", Bird " + (i + 1) + " = " + GetScoreForPos(parentNode.data.BirdsPos[i])); } //Console.WriteLine(); Position bird1LeftPosition = new Position(parentNode.data.BirdsPos[0].Row - 1, parentNode.data.BirdsPos[0].Col - 1); if (Board.IsValidPosition(bird1LeftPosition) && parentNode.data.IsCellEmpty(bird1LeftPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[0] = bird1LeftPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 1 left position = " + GetScoreForPos(bird1LeftPosition)); } Position bird1RightPosition = new Position(parentNode.data.BirdsPos[0].Row - 1, parentNode.data.BirdsPos[0].Col + 1); if (Board.IsValidPosition(bird1RightPosition) && parentNode.data.IsCellEmpty(bird1RightPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[0] = bird1RightPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 1 right position = " + GetScoreForPos(bird1RightPosition)); } Position bird2LeftPosition = new Position(parentNode.data.BirdsPos[1].Row - 1, parentNode.data.BirdsPos[1].Col - 1); if (Board.IsValidPosition(bird2LeftPosition) && parentNode.data.IsCellEmpty(bird2LeftPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[1] = bird2LeftPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 2 left position = " + GetScoreForPos(bird2LeftPosition)); } Position bird2RightPosition = new Position(parentNode.data.BirdsPos[1].Row - 1, parentNode.data.BirdsPos[1].Col + 1); if (Board.IsValidPosition(bird2RightPosition) && parentNode.data.IsCellEmpty(bird2RightPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[1] = bird2RightPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 2 right position = " + GetScoreForPos(bird2RightPosition)); } Position bird3LeftPosition = new Position(parentNode.data.BirdsPos[2].Row - 1, parentNode.data.BirdsPos[2].Col - 1); if (Board.IsValidPosition(bird3LeftPosition) && parentNode.data.IsCellEmpty(bird3LeftPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[2] = bird3LeftPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 3 left position = " + GetScoreForPos(bird3LeftPosition)); } Position bird3RightPosition = new Position(parentNode.data.BirdsPos[2].Row - 1, parentNode.data.BirdsPos[2].Col + 1); if (Board.IsValidPosition(bird3RightPosition) && parentNode.data.IsCellEmpty(bird3RightPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[2] = bird3RightPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 3 right position = " + GetScoreForPos(bird3RightPosition)); } Position bird4LeftPosition = new Position(parentNode.data.BirdsPos[3].Row - 1, parentNode.data.BirdsPos[3].Col - 1); if (Board.IsValidPosition(bird4LeftPosition) && parentNode.data.IsCellEmpty(bird4LeftPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[3] = bird4LeftPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 4 left position = " + GetScoreForPos(bird4LeftPosition)); } Position bird4RightPosition = new Position(parentNode.data.BirdsPos[3].Row - 1, parentNode.data.BirdsPos[3].Col + 1); if (Board.IsValidPosition(bird4RightPosition) && parentNode.data.IsCellEmpty(bird4RightPosition)) { BoardConfig tempBC = new BoardConfig(parentNode.data); tempBC.Level = lvl; tempBC.BirdsPos[3] = bird4RightPosition; parentNode.AddChild(tempBC); //Console.WriteLine("Bird 4 right position = " + GetScoreForPos(bird4RightPosition)); } }