public void EnableGroundedCell() { var componentTrackingMatrix = new CorrectComponentTrackingMatrix(new Matrix("000|000|000", "010|000|000", "000|000|000").Voxels); componentTrackingMatrix[1, 0, 1] = true; componentTrackingMatrix.HasNonGroundedVoxels.Should().BeFalse(); }
public void TrackComponents6() { var componentTrackingMatrix = new CorrectComponentTrackingMatrix(new Matrix("000|101|001", "110|101|000", "111|011|101").Voxels); componentTrackingMatrix[0, 1, 2] = true; componentTrackingMatrix.HasNonGroundedVoxels.Should().BeFalse(); }
public void TrackComponents3() { var componentTrackingMatrix = new CorrectComponentTrackingMatrix(new Matrix("000|101|000", "000|000|000", "000|000|000").Voxels); componentTrackingMatrix.HasNonGroundedVoxels.Should().BeTrue(); componentTrackingMatrix[1, 1, 0] = true; componentTrackingMatrix.HasNonGroundedVoxels.Should().BeTrue(); componentTrackingMatrix[1, 0, 0] = true; componentTrackingMatrix.HasNonGroundedVoxels.Should().BeFalse(); componentTrackingMatrix[1, 0, 0] = false; componentTrackingMatrix.HasNonGroundedVoxels.Should().BeTrue(); }
public IEnumerable <ICommand> Solve() { buildingMatrix = new CorrectComponentTrackingMatrix(new bool[N, N, N]); var(transformedTargetMatrix, stickPositions) = TransformMatrix(targetMatrix); var(cloneCommands, initialBots) = fast ? Clone2(new Grid(grid.CountX, 2, minX, minZ, maxX, maxZ)) : Clone(2 * grid.CountX, new Grid(grid.CountX, 2, minX, minZ, maxX, maxZ)); foreach (var command in cloneCommands) { yield return(command); } var botQueues = new List <Queue <ICommand> >(); for (var i = 0; i < initialBots.Count; i++) { botQueues.Add(new Queue <ICommand>()); } var botsToGenerateCommands = initialBots.ToList(); var botCount = botsToGenerateCommands.Count; for (var y = 0; y <= maxY; y++) { for (var botId = 0; botId < botCount / 2; botId++) { var nearId = botId; var farId = botId + botCount / 2; foreach (var(nearCommand, farCommand) in FillLayer(transformedTargetMatrix, botsToGenerateCommands[nearId], botsToGenerateCommands[farId])) { var nearBeforeTransform = grid.GetCellId(botsToGenerateCommands[nearId]); var farBeforeTransform = grid.GetCellId(botsToGenerateCommands[farId]); botQueues[nearId].Enqueue(nearCommand); botQueues[farId].Enqueue(farCommand); if (nearCommand is SMove sMove) { botsToGenerateCommands[nearId] += sMove.Shift; } if (nearCommand is LMove lMove) { botsToGenerateCommands[nearId] += lMove.firstShift.Shift + lMove.secondShift.Shift; } if (farCommand is SMove sMove1) { botsToGenerateCommands[farId] += sMove1.Shift; } if (farCommand is LMove lMove1) { botsToGenerateCommands[farId] += lMove1.firstShift.Shift + lMove1.secondShift.Shift; } if (!nearBeforeTransform.Equals(grid.GetCellId(botsToGenerateCommands[nearId]))) { throw new Exception("Wrong zone"); } if (!farBeforeTransform.Equals(grid.GetCellId(botsToGenerateCommands[farId]))) { throw new Exception("Wrong zone"); } } } } for (var botId = 0; botId < botCount / 2; botId++) { foreach (var command in RemoveSticks(stickPositions, botsToGenerateCommands[botId])) { botQueues[botId].Enqueue(command); if (command is SMove sMove) { botsToGenerateCommands[botId] += sMove.Shift; } if (command is LMove lMove) { botsToGenerateCommands[botId] += lMove.firstShift.Shift + lMove.secondShift.Shift; } } } var botsToEvaluate = initialBots.ToList(); bool isHighEnergy = false; bool firstHigh = false; while (botQueues.Any(x => x.Count > 0)) { var commands = new List <ICommand>(); if (isHighEnergy && !firstHigh && !buildingMatrix.HasNonGroundedVoxels) { commands = new ICommand[] { new Flip() }.Concat(Enumerable.Repeat <ICommand>(new Wait(), botsToEvaluate.Count - 1)).ToList(); isHighEnergy = false; foreach (var command in commands) { yield return(command); } continue; } bool[] shouldWait = new bool[botCount]; firstHigh = false; for (var i = 0; i < botQueues.Count; i++) { if (botQueues[i].Count == 0) { continue; } if (botQueues[i].Peek() is Fill fillCommand) { var fillPosition = botsToEvaluate[i] + fillCommand.Shift; if (!CanFill(buildingMatrix.Voxels, fillPosition) && !isHighEnergy) { shouldWait[i] = true; shouldWait[GetPartnerId(i)] = true; } } else if (botQueues[i].Peek() is GFill gFillCommand) { var filledCells = new List <Vec>(); foreach (var cell in Cuboid.FromPoints(botsToEvaluate[i] + gFillCommand.NearShift, botsToEvaluate[i] + gFillCommand.NearShift + gFillCommand.FarShift).AllPoints()) { if (!buildingMatrix[cell]) { filledCells.Add(cell); } buildingMatrix[cell] = true; } if (buildingMatrix.HasNonGroundedVoxels && !isHighEnergy) { foreach (var filledCell in filledCells) { buildingMatrix[filledCell] = false; } shouldWait[i] = true; shouldWait[GetPartnerId(i)] = true; } } else if (botQueues[i].Peek() is Voidd voidCommand) { var voidPosition = botsToEvaluate[i] + voidCommand.Shift; if (!buildingMatrix.CanVoidCell(voidPosition) && !isHighEnergy) { shouldWait[i] = true; shouldWait[GetPartnerId(i)] = true; } } } for (var i = 0; i < botQueues.Count; i++) { if (botQueues[i].Count == 0 || shouldWait[i]) { commands.Add(new Wait()); continue; } if (botQueues[i].Peek() is Fill fillCommand) { var fillPosition = botsToEvaluate[i] + fillCommand.Shift; buildingMatrix[fillPosition] = true; commands.Add(botQueues[i].Dequeue()); } else if (botQueues[i].Peek() is GFill gFillCommand) { foreach (var cell in Cuboid.FromPoints(botsToEvaluate[i] + gFillCommand.NearShift, botsToEvaluate[i] + gFillCommand.NearShift + gFillCommand.FarShift).AllPoints()) { buildingMatrix[cell] = true; } commands.Add(botQueues[i].Dequeue()); } else if (botQueues[i].Peek() is Voidd voidCommand) { var voidPosition = botsToEvaluate[i] + voidCommand.Shift; buildingMatrix[voidPosition] = false; commands.Add(botQueues[i].Dequeue()); } else { commands.Add(botQueues[i].Dequeue()); } } if (commands.All(x => x is Wait)) { firstHigh = isHighEnergy = true; commands[0] = new Flip(); } for (var i = 0; i < commands.Count; i++) { if (commands[i] is SMove sMove) { botsToEvaluate[i] += sMove.Shift; } if (commands[i] is LMove lMove) { botsToEvaluate[i] += lMove.firstShift.Shift + lMove.secondShift.Shift; } yield return(commands[i]); } } foreach (var command in fast ? GoHome2(botsToEvaluate) : GoHome(botsToEvaluate)) { yield return(command); } }
public void HasNotGrounded(params string[] matrix) { var componentTrackingMatrix = new CorrectComponentTrackingMatrix(new Matrix(matrix).Voxels); componentTrackingMatrix.HasNonGroundedVoxels.Should().BeTrue(); }