public void Move(PositionModel positionModel) { if (_movePositions.Contains(positionModel)) { return; } _movePositions.Enqueue(positionModel); if (_puzzleMovementState != PuzzleMovementState.None) { return; } SubscribeMovementAction(); void SubscribeMovementAction() { _nowPosition = _movePositions.Peek(); _puzzleMovementState = PuzzleMovementState.Moving; var targetPos = _gamePageView.GetLandElement(_nowPosition).transform.position; _movementDisposable.DisposeSafe(); _movementDisposable = Observable.EveryUpdate() .TakeWhile(_ => _movePositions.Any()) .Subscribe(_ => { transform.MoveTowards(transform.position, targetPos, Time.deltaTime); if (_puzzleMovementState == PuzzleMovementState.Moving && Vector2.Distance(transform.position, targetPos) <= GameConstants.PuzzleMovementSpeed) { _puzzleMovementState = PuzzleMovementState.Almost; if (!PuzzleModel.PositionModel.Equals(_nowPosition)) { PuzzleModel.PositionModel.Set(_nowPosition); } } if (_puzzleMovementState == PuzzleMovementState.Almost && Vector2.Distance(transform.position, targetPos) <= float.Epsilon) { if (!_movePositions.Any()) { return; } _nowPosition = _movePositions.Dequeue(); _puzzleMovementState = PuzzleMovementState.Moving; } }, () => { _puzzleMovementState = PuzzleMovementState.None; _puzzleViewmodel.CompleteAlignedPuzzles(PuzzleModel); _movePositions.Clear(); }); } }
/// <summary> /// 해당 방향에 있는 바로 옆 퍼즐의 키 값을 리턴. /// </summary> public PositionModel GetKeyByAngle(PositionModel positionModel, float angle) { if (!AllLineModels.ContainsKey(positionModel.Column)) { return(PositionModel.EmptyPositionModel); } // To upper direction. if (Enumerable.Range(150, 60).Contains((int)angle)) { return(new PositionModel(positionModel.Column, positionModel.Row + 1)); } // To upper right direction. if (Enumerable.Range(210, 60).Contains((int)angle)) { return(GetPuzzlePosition(false)); } // To lower right direction. if (Enumerable.Range(270, 60).Contains((int)angle)) { return(GetPuzzlePosition(false, false)); } // To upper left direction. if (Enumerable.Range(90, 60).Contains((int)angle)) { return(GetPuzzlePosition()); } // To lower left direction. if (Enumerable.Range(30, 60).Contains((int)angle)) { return(GetPuzzlePosition(toUpper: false)); } // To lower direction. return(new PositionModel(positionModel.Column, positionModel.Row - 1)); PositionModel GetPuzzlePosition(bool toLeft = true, bool toUpper = true) { var checkColumn = positionModel.Column + (toLeft ? -1 : 1); if (!AllLineModels.ContainsKey(checkColumn)) { return(PositionModel.EmptyPositionModel); } var anEvenNumberColumn = positionModel.Column % 2 == 0; var posCoeff = anEvenNumberColumn && toUpper ? 0 : anEvenNumberColumn ? -1 : toUpper ? 1 : 0; return(new PositionModel(checkColumn, positionModel.Row + posCoeff)); } }
/// <summary> /// 해당 위치에서 6방향의 위치를 리턴. /// </summary> private IEnumerable <PositionModel> GetAroundPositionModel(PositionModel positionModel) { return(new[] { GetPositionByDirectionType(positionModel, CheckDirectionTypes.ToUpward), GetPositionByDirectionType(positionModel, CheckDirectionTypes.ToDownward), GetPositionByDirectionType(positionModel, CheckDirectionTypes.ToUpLeft), GetPositionByDirectionType(positionModel, CheckDirectionTypes.ToUpRight), GetPositionByDirectionType(positionModel, CheckDirectionTypes.ToDownLeft), GetPositionByDirectionType(positionModel, CheckDirectionTypes.ToDownRight) }); }
/// <summary> /// 현재 위치에서 해당 방향, 반대 방향의 위치값 리턴. /// </summary> public LinkedListNode <PositionModel> GetPositionKeysByAngle(PositionModel positionModel, CheckDirectionTypes checkCheckTypes, CheckDirectionTypes otherCheckTypes) { var positionNode = new LinkedListNode <PositionModel> (positionModel); var positionList = new LinkedList <PositionModel> (); var besidePosition = GetKeyByAngle(positionModel, (float)checkCheckTypes); var beyondPosition = GetKeyByAngle(besidePosition, (float)checkCheckTypes); var otherBesidePosition = GetKeyByAngle(positionModel, (float)otherCheckTypes); var otherBeyondPosition = GetKeyByAngle(otherBesidePosition, (float)otherCheckTypes); positionList.AddLast(positionNode); positionList.AddFirst(besidePosition); positionList.AddFirst(beyondPosition); positionList.AddLast(otherBesidePosition); positionList.AddLast(otherBeyondPosition); return(positionNode); }
/// <summary> /// 퍼즐 생성. /// Generate puzzles. /// </summary> private void CreatePuzzles(ICollection <PositionModel> obsPostition) { do { Positioning(); } while (!CheckMovablePuzzleState()); void Positioning() { InitializeModels(); for (var c = 0; c < AllLineModels.Count; c++) { for (var r = 0; r < AllLineModels[c].Count; r++) { var positionModel = new PositionModel(c, r); if (!ContainLineModel(positionModel)) { continue; } var puzzleModel = new PuzzleModel(); AllPuzzleModels.Add(puzzleModel); puzzleModel.PositionModel = positionModel; puzzleModel.ObstacleTypes = obsPostition.Contains(positionModel) ? ObstacleTypes.Top : ObstacleTypes.None; SetPuzzleColorTypes(puzzleModel); } } } void InitializeModels() { AllPuzzleModels.Clear(); } }
// 퍼즐 재정렬. #region ArrayPuzzles. /// <summary> /// 아래로 떨어뜨림. /// </summary> private async UniTask FlowDownCheck() { Debug.Log($"{nameof (FlowDownCheck)}ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ"); AllPuzzleModels .Where(CheckMovablePuzzleModel) .OrderBy(x => x.Row) .Foreach(puzzleModel => { if (!ContainLineModel(puzzleModel.PositionModel)) { return; } var existLandRows = AllLineModels[puzzleModel.Column].GetBelowRows(puzzleModel.Row); foreach (var row in existLandRows) { var checkPosition = new PositionModel(puzzleModel.Column, row); var checkPuzzle = GetContainPuzzleModel(checkPosition); if ((checkPuzzle == null || checkPuzzle.IsChecked || _predicatedFlowDownPositions.ContainsKey(checkPuzzle)) && !_predicatedFlowDownPositions.ContainsValue(checkPosition) && !_predicatedFlowSidePositionDict.ContainsValue(checkPosition)) { Debug.Log( $"{puzzleModel} flow down to {checkPosition}"); _predicatedFlowDownPositions.SetOrAdd(puzzleModel, checkPosition); puzzleModel.MoveTo(checkPosition); } } }); await UniTask.Delay(TimeSpan.FromSeconds(GameConstants.FlowCheckTime), cancellationToken : _cancellationTokenSource.Token); }
/// <summary> /// move to position. /// </summary> public void MoveTo(PositionModel positionModel) { MoveToPositionEvent?.Invoke(positionModel); }
public bool Equals(PositionModel other) { return(Column == other.Column && Row == other.Row); }
public void Set(PositionModel positionModel) { Column = positionModel.Column; Row = positionModel.Row; }
/// <summary> /// 체크 영역의 퍼즐들을 체크함. /// </summary> private int FindPuzzleCheckDirectionArea(PositionModel positionModel, PuzzleColorTypes colorTypes, PuzzleCheckTypes puzzleCheckTypes, UnityAction <PuzzleModel> action = null) { var continuoslyCount = 0; var(checkDir, otherCheckDir) = GetCheckDirectionTypesByPuzzleCheckType(puzzleCheckTypes); var positionModels = GetPositionKeysByAngle(positionModel, checkDir, otherCheckDir); positionModels.List .Select((position, index) => (GetContainPuzzleModel(position), index)) .Where(valueTuple => valueTuple.Item1 != null) .Foreach(valueTuple => { var(foundPuzzle, index) = valueTuple; if (foundPuzzle.PuzzleColorTypes == PuzzleColorTypes.None) { return; } if (foundPuzzle.PositionModel.Equals(positionModel)) { Check(); return; } // 체크하려는 포지션에 있는 퍼즐이 대상의 색상과 같지 않음. if (!foundPuzzle.PuzzleColorTypes.Equals(colorTypes)) { return; } if (IndexCheck(index)) { Check(); } void Check() { continuoslyCount++; action?.Invoke(foundPuzzle); } }); // 체크하려는 포지션에서 대상의 퍼즐 포지션 안쪽에 있는 퍼즐과 체크를 함. // ex) 0, 1, 2, 3, 4의 포지션이 있을 경우. 0, 4의 포지션은 각각 1, 3의 포지션의 퍼즐을 체크 함. bool IndexCheck(int index) { if (index != 0 && index != 4) { return(true); } var insidePosition = index == 0 ? positionModels.Previous : positionModels.Next; if (insidePosition == null) { return(false); } var insidePuzzleColorTypes = GetContainPuzzleColorTypes(insidePosition.Value); return(insidePuzzleColorTypes.Equals(colorTypes)); } return(continuoslyCount < (int)PuzzleMatchingTypes.ThreeMatching ? 0 : continuoslyCount); }
/// <summary> /// 해당 enum 타입 방향에 있는 바로 옆 퍼즐의 키 값을 리턴. /// </summary> public PositionModel GetPositionByDirectionType(PositionModel positionModel, CheckDirectionTypes checkDirectionTypes) { return(GetKeyByAngle(positionModel, (float)checkDirectionTypes)); }
private PuzzleColorTypes GetContainPuzzleColorTypes(PositionModel positionModel) { var puzzle = GetContainPuzzleModel(positionModel); return(puzzle?.PuzzleColorTypes ?? PuzzleColorTypes.None); }
private PuzzleModel GetContainPuzzleModel(PositionModel positionModel) { return(AllPuzzleModels.Find(x => x.PositionModel.Equals(positionModel))); }
public PuzzleModel GetBesideModel(PositionModel positionModel, float angle) { var targetPosition = GetKeyByAngle(positionModel, angle); return(GetContainPuzzleModel(targetPosition)); }
public bool GetLandState(PositionModel positionModel) { return(ContainLineModel(positionModel) && AllLineModels[positionModel.Column].ContainRow(positionModel.Row)); }
public bool ContainLineModel(PositionModel positionModel) { return(AllLineModels.ContainsKey(positionModel.Column) && AllLineModels[positionModel.Column].ContainRow(positionModel.Row)); }