public bool PolicyImprovement() { bool policyStable = true; foreach (var currentState in _allStates) { if (GameSelector.type == GameSelector.GameType.GridWorld) { GridWorldIntent tempPolicy = currentState.gridWorldPolicy; currentState.gridWorldPolicy = GetBestIntent(currentState); if (tempPolicy != currentState.gridWorldPolicy) { policyStable = false; } } else if (GameSelector.type == GameSelector.GameType.Sokoban) { SokobanIntent tempPolicy = currentState.sokobanPolicy; currentState.sokobanPolicy = GetBestIntentSokoban(currentState); if (tempPolicy != currentState.sokobanPolicy) { policyStable = false; } } } if (!policyStable) { PolicyEvaluation(); } return(policyStable); }
public bool CheckIntentSokoban(State currentState, SokobanIntent wantedSokobanIntent) { if (GetNextStateSokoban(currentState, wantedSokobanIntent) == null) { return(false); } if (GetCellType(GetNextStateSokoban(currentState, wantedSokobanIntent).currentPlayerPos) == CellType.Obstacle) { return(false); } return(true); }
private Vector3 GetDirectionFromIntent(SokobanIntent intent) { switch (intent) { case SokobanIntent.Down: return(-Vector3.forward); case SokobanIntent.Up: return(Vector3.forward); case SokobanIntent.Left: return(Vector3.left); case SokobanIntent.Right: return(-Vector3.left); } return(Vector3.zero); }
public SokobanIntent GetBestIntentSokoban(State currentState) { float max = float.MinValue; SokobanIntent bestSokobanIntent = currentState.sokobanPolicy; for (int i = 0; i < 4; ++i) { if (sokobanController.checkCollisionWithGridState(currentState.currentPlayerPos, GetDirectionFromIntent((SokobanIntent)i), currentState.currentGrid)) { State tempState = GetNextStateSokoban(currentState, (SokobanIntent)i); if (tempState.stateValue > max) { max = tempState.stateValue; bestSokobanIntent = (SokobanIntent)i; } } } return(bestSokobanIntent); }
public State GetNextStateSokoban(State currentState, SokobanIntent sokobanIntent) { Cell[][] nextGrid = CopyGrid(currentState.currentGrid); Vector3 nextPlayerPos = currentState.currentPlayerPos; if (currentState.currentPlayerPos.z < currentState.currentGrid.Length - 1 && sokobanController.checkCollisionWithGridState(currentState.currentPlayerPos, GetDirectionFromIntent(sokobanIntent), currentState.currentGrid)) { switch (sokobanIntent) { case SokobanIntent.Up: if (currentState.currentGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z + 1].cellSokobanType == Cell.CellSokobanType.Crate) { nextGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z + 1].cellSokobanType = Cell.CellSokobanType.Empty; if (sokobanController.IsCrateHitTargetBox((int)currentState.currentPlayerPos.x, (int)currentState.currentPlayerPos.z + 2, nextGrid)) { nextGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z + 2].cellSokobanType = Cell.CellSokobanType.CratePlaced; } else { nextGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z + 2].cellSokobanType = Cell.CellSokobanType.Crate; } } nextPlayerPos += Vector3.forward; break; case SokobanIntent.Down: if (currentState.currentGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z - 1].cellSokobanType == Cell.CellSokobanType.Crate) { nextGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z - 1].cellSokobanType = Cell.CellSokobanType.Empty; if (sokobanController.IsCrateHitTargetBox((int)currentState.currentPlayerPos.x, (int)currentState.currentPlayerPos.z - 2, nextGrid)) { nextGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z - 2].cellSokobanType = Cell.CellSokobanType.CratePlaced; } else { nextGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z - 2].cellSokobanType = Cell.CellSokobanType.Crate; } } nextPlayerPos -= Vector3.forward; break; case SokobanIntent.Left: if (currentState.currentGrid[(int)currentState.currentPlayerPos.x][(int)currentState.currentPlayerPos.z + 1].cellSokobanType == Cell.CellSokobanType.Crate) { nextGrid[(int)currentState.currentPlayerPos.x - 1][(int)currentState.currentPlayerPos.z].cellSokobanType = Cell.CellSokobanType.Empty; if (sokobanController.IsCrateHitTargetBox((int)currentState.currentPlayerPos.x - 2, (int)currentState.currentPlayerPos.z, nextGrid)) { nextGrid[(int)currentState.currentPlayerPos.x - 2][(int)currentState.currentPlayerPos.z].cellSokobanType = Cell.CellSokobanType.CratePlaced; } else { nextGrid[(int)currentState.currentPlayerPos.x - 2][(int)currentState.currentPlayerPos.z].cellSokobanType = Cell.CellSokobanType.Crate; } } nextPlayerPos += Vector3.left; break; case SokobanIntent.Right: if (currentState.currentGrid[(int)currentState.currentPlayerPos.x + 1][(int)currentState.currentPlayerPos.z].cellSokobanType == Cell.CellSokobanType.Crate) { nextGrid[(int)currentState.currentPlayerPos.x + 1][(int)currentState.currentPlayerPos.z].cellSokobanType = Cell.CellSokobanType.Empty; if (sokobanController.IsCrateHitTargetBox((int)currentState.currentPlayerPos.x + 2, (int)currentState.currentPlayerPos.z, nextGrid)) { nextGrid[(int)currentState.currentPlayerPos.x + 2][(int)currentState.currentPlayerPos.z].cellSokobanType = Cell.CellSokobanType.CratePlaced; } else { nextGrid[(int)currentState.currentPlayerPos.x + 2][(int)currentState.currentPlayerPos.z].cellSokobanType = Cell.CellSokobanType.Crate; } } nextPlayerPos -= Vector3.left; break; } } State nextState = GetStateFromGrid(nextGrid, currentState.currentPlayerPos); if (nextState != null) { nextState = new State(); nextState.currentGrid = nextGrid; nextState.stateValue = 0; nextState.currentPlayerPos = nextPlayerPos; } return(nextState); }