// This function accepts a queue of intended moves for the specified program. It first performs error // checking to ensure that the moves are possible, then updates the associated AINodeData to reflect // game changes as a result of these moves, and finally submits the moves to the turnActions queue for // sending during subsequent calls to HandleAITurn. private MoveCode PerformMoves(Haxxit.Maps.ProgramHeadNode program, Queue<Haxxit.Maps.Point> path) { if (path == null) { return MoveCode.NoMovesSpecified; } else if (!path.Any()) { return MoveCode.NoMovesSpecified; } // Will hold all nodes touched by program both before and after move List<Haxxit.Maps.Point> programPoints = new List<Haxxit.Maps.Point>(); // Get all the nodes currently associated with the program foreach (Haxxit.Maps.MapNode node in program.GetAllNodes()) { programPoints.Insert(0, node.coordinate); } int movesLeft = program.Program.Moves.MovesLeft; Haxxit.Maps.Point currentHead = program.coordinate; foreach (Haxxit.Maps.Point destination in path) { Haxxit.Maps.Point direction = destination - currentHead; if (!IsInBounds(destination)) { return MoveCode.MoveWasOutOfBounds; } else if (Math.Abs(direction.X) == 1 && Math.Abs(direction.Y) != 0) { return MoveCode.MoveWasNotAdjacent; } else if (Math.Abs(direction.Y) == 1 && Math.Abs(direction.X) != 0) { return MoveCode.MoveWasNotAdjacent; } else if (Math.Abs(direction.X) != 1 && Math.Abs(direction.Y) != 1) { return MoveCode.MoveWasNotAdjacent; } else if (!mapData[destination.X, destination.Y].canHoldCurrentProgram(program)) { return MoveCode.MoveWasBlocked; } else if (movesLeft <= 0) { return MoveCode.InsufficientMoves; } movesLeft--; programPoints.Add(destination); Haxxit.Maps.MoveEventArgs nextMove = new Haxxit.Maps.MoveEventArgs(currentHead, direction); turnActions.Enqueue(new NotifyArgs("haxxit.map.move", this, nextMove, NotifyArgs.ArgType.Move)); currentHead = destination; } int index = 0; foreach (Haxxit.Maps.Point point in programPoints) { if (index < programPoints.Count - program.Program.Size.MaxSize) { mapData[point.X, point.Y].IsAvailable = true; mapData[point.X, point.Y].OccupiedBy = null; } else { mapData[point.X, point.Y].IsAvailable = false; mapData[point.X, point.Y].OccupiedBy = program; } index++; } return MoveCode.Success; }
// Moves the program directly left if possible. This was implemented as a proof of concept. // May be useful for future testing. private void BehaviorMoveLeft(Haxxit.Maps.ProgramHeadNode program) { Haxxit.Maps.Point head = program.coordinate; Haxxit.Maps.Point moveLeft = new Haxxit.Maps.Point(-1, 0); for (int moves = 0; program.Program.Moves.MovesLeft > moves; moves++) { Haxxit.Maps.Point movedHead = new Haxxit.Maps.Point(head.X - moves, head.Y); if (movedHead.X - 1 < 0) // Can't move off edge of Map { break; } if (mapData[movedHead.X - 1, head.Y].canHoldCurrentProgram(program)) { Haxxit.Maps.MoveEventArgs moveHeadLeft = new Haxxit.Maps.MoveEventArgs(movedHead, moveLeft); turnActions.Enqueue(new NotifyArgs("haxxit.map.move", this, moveHeadLeft, NotifyArgs.ArgType.Move)); } } }