//PlayRandom va a obtener las posibles operaciones a realizar (movimientos o limpieza) //aleatoriamente va a ejecutar una //Si es un movimiento y el robot carga un niño, puede aleatoriamente volver a ejecutar //un movimiento o no hacer nada. public override void Play() { var carrying = IsCarryingChild(); var adjacents = Environment.AdjacentCells(CurrentPos, p => !Environment[p].IsObstacled() && (!Environment[p].IsChild() || !IsCarryingChild()) && (!Environment[CurrentPos].IsPlaypen() || !IsCarryingChild() || Environment[p].IsPlaypen())); if (adjacents.Count == 0) { adjacents = Environment.AdjacentCells(CurrentPos, p => !Environment[p].IsObstacled() && (!Environment[p].IsChild() || !IsCarryingChild())); } //Si hay otro lugar a donde ir que no regrese al punto anterior if (adjacents.Count > 1) { adjacents.RemoveWhere(x => x.Item2 == PreviousPos); } var opers = AllowedOperations(adjacents); if (opers == null || opers.Count == 0) { return; } ExecuteRandomOperation(opers, adjacents); if (carrying && IsCarryingChild()) { adjacents = Environment.AdjacentCells(CurrentPos, p => (PreviousPos != p) && !Environment[p].IsObstacled() && (!Environment[p].IsChild() || !IsCarryingChild()) && (!Environment[CurrentPos].IsPlaypen() || !IsCarryingChild() || Environment[p].IsPlaypen())); opers = AllowedOperations(adjacents); if (opers == null || opers.Count == 0) { return; } ExecuteRandomOperation(opers, adjacents); } isMoving = false; }
//PlayCleaningFirst prioriza la limpieza antes que el movimiento //Obtiene las posibles operaciones a realizar que prioricen la limpieza: limpiar si la //casilla está sucia y moverse a una casilla sucia. Si no hay casillas sucias alrededor //del robot y carga un niño, debe moverse a la que más vecinas sucias tenga public override void Play() { if (Environment[CurrentPos].IsDirty()) { Clean(); } else { //Si el robot está en el corral y soltó al niño, salir del corral var adjacents = Environment.AdjacentCells(CurrentPos, p => Environment[CurrentPos].IsChild() && Environment[CurrentPos].IsPlaypen() && !Environment[p].IsPlaypen() && !Environment[p].IsObstacled()); if (adjacents.Count > 0) { RandomMove(adjacents); } else { adjacents = Environment.AdjacentCells(CurrentPos, p => Environment[p].IsEmpty() && Environment[p].IsPlaypen()); if (IsCarryingChild() && adjacents.Count > 0) { RandomMove(adjacents); } else { adjacents = Environment.AdjacentCells(CurrentPos, p => Environment[p].IsDirty()); if (adjacents.Count > 0) { RandomMove(adjacents); } else //Si no hay ninguna casilla adyacente sucia //se verifica si en el próximo paso puede caer en una casilla sucia { // var carrying = IsCarryingChild(); //Obtener las casillas adyacentes hacia donde se puede mover adjacents = Environment.AdjacentCells(CurrentPos, p => !Environment[p].IsObstacled() && (!Environment[p].IsChild() || !IsCarryingChild()) && (!Environment[CurrentPos].IsPlaypen() || !IsCarryingChild() || Environment[p].IsPlaypen())); var adjacentsArray = adjacents.ToArray <Tuple <MovementDirection, Point> >(); var dirtyNeighbors = new HashSet <Tuple <MovementDirection, Point> > [adjacentsArray.Length]; var maxDirt = 0; var maxIndex = -1; //Busca las casillas sucias alrededor de cada una de las casillas adyacentes for (var i = 0; i < adjacentsArray.Length; i++) { var dirtyAdjacents = Environment.AdjacentCells(adjacentsArray[i].Item2, p => Environment[p].IsDirty()); dirtyNeighbors[i] = dirtyAdjacents; if (dirtyNeighbors[i].Count > maxDirt) { maxDirt = dirtyNeighbors[i].Count; maxIndex = i; } } if (maxDirt > 0) { MoveTo(adjacentsArray[maxIndex].Item2); //Moverse a la casilla que tiene más vecinas sucias MovementCount++; if (carrying && IsCarryingChild()) { RandomMove(dirtyNeighbors[maxIndex], null); //Moverse aleatoriamente a una de las casillas sucias } } else { //Si no había vecinas sucias para ninguno de los posibles movimientos //se mueve aleatoriamente, vuelve a obtener los posibles movimientos //y se vuelve a mover aleatoriamente excluyendo la posición de la que partió RandomMove(adjacents, null); if (carrying && IsCarryingChild()) { adjacents = Environment.AdjacentCells(CurrentPos, p => (p != PreviousPos) && !Environment[p].IsObstacled() && (!Environment[p].IsChild() || !IsCarryingChild()) && (!Environment[CurrentPos].IsPlaypen() || !IsCarryingChild() || Environment[p].IsPlaypen())); RandomMove(adjacents, null); } } } } } } }
//Jugada del niño en la que escoge hacia dónde se mueve y ejecuta el movimiento public void Play() { //Si está cargado o en el corral no puede moverse if ((Status == ChildStatus.Carried) || (Status == ChildStatus.Penned)) { return; } if (Playing != null) { Playing(this, null); } //Direcciones hacia donde se puede mover var adjacents = Environment.AdjacentCells(CurrentPos, p => !Environment[p].IsPlaypen() && (Environment[p].IsEmpty() || Environment[p].IsObstacled())); int n; if (adjacents.Count == 0) { return; } n = randomMov.Next(); if (adjacents.Count <= n) { return; } //Escoger aleatoriamente una dirección var tuple = adjacents.ToArray <Tuple <MovementDirection, Point> >()[n]; var moved = MoveTo(tuple.Item2, p => !Environment[p].IsObstacled() || PushObstacle(p, tuple.Item1)); if (!moved) { return; } //Obtener la cuadrícula de la posición anterior var grid = Environment.Grid(PreviousPos); //Obtener el número de niños dentro de la cuadrícula var ch = Environment.ChildrenInGrid(grid); //Eliminar las casillas que no están limpias grid = Environment.CleanGrid(grid); //Obtener el número máximo de suciedad que puede ser generada //dependiendo de la cantidad de casillas vacías y de niños var dirt = Math.Min(grid.Count, ch <= 3 ? Environment.dirtPerGrid[ch] : Environment.dirtPerGrid[3]); //Generar aleatoriamente de 0-dirt casillas sucias Environment.GenDirt(dirt, grid); if (Played != null) { Played(this, null); } }