示例#1
0
        public bool Equals(PuzzleMove other)
        {
            if (other == null)
            {
                return false;
            }

            return other.StartingState == StartingState &&
                other.GetEndingState() == GetEndingState();
        }
示例#2
0
		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update(GameTime gameTime)
		{
			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
				this.Exit();

			KeyboardState keyboard = Keyboard.GetState();

			if (keyboard.IsKeyDown(Keys.Escape))
				Exit();

			if (keyboard.IsKeyDown(Keys.F11) && prevKeyboardState.IsKeyUp(Keys.F11))
				IsFullScreen = !IsFullScreen;

			//if (keyboard.IsKeyDown(Keys.A) && prevKeyboardState.IsKeyUp(Keys.A))
			//    isAnimating = !isAnimating;

			

			float movement = (float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.02f;
			

			if (keyboard.IsKeyDown(Keys.PageUp))
			{
				cameraPosition = new Vector3(cameraPosition.X, cameraPosition.Y, cameraPosition.Z - movement);
			}

			if (keyboard.IsKeyDown(Keys.PageDown))
			{
				cameraPosition = new Vector3(cameraPosition.X, cameraPosition.Y, cameraPosition.Z + movement);
			}

			float rotation = (float)gameTime.ElapsedGameTime.TotalMilliseconds *
					MathHelper.ToRadians(0.1f);

			if (keyboard.IsKeyDown(Keys.Left))
			{
				rotationMatrix = rotationMatrix * Matrix.CreateRotationY(rotation);
			}
			if (keyboard.IsKeyDown(Keys.Right))
			{
				rotationMatrix = rotationMatrix * Matrix.CreateRotationY(-rotation);
			}
			if (keyboard.IsKeyDown(Keys.Up))
			{
				rotationMatrix = rotationMatrix * Matrix.CreateRotationX(rotation);
			}
			if (keyboard.IsKeyDown(Keys.Down))
			{
				rotationMatrix = rotationMatrix * Matrix.CreateRotationX(-rotation);
			}

            bool commandForward = false;
            bool commandBack = false;
            bool commandResetView = false;

#if WINDOWS_PHONE
            TouchCollection touches = TouchPanel.GetState();

            if (touches.Count > 0)
            {
                foreach (TouchLocation touch in touches)
                {
                    if (touch.Position.X <= _buttonTop)
                    {
                        _rotationVelocity = Vector2.Zero;
                    }
                }
            }

            while (TouchPanel.IsGestureAvailable)
            {
                float factor = 0.01f;

                GestureSample gesture = TouchPanel.ReadGesture();
                if (gesture.GestureType == GestureType.FreeDrag)
                {
                    rotationMatrix = rotationMatrix *
                        Matrix.CreateRotationX(gesture.Delta.X * factor) *
                        Matrix.CreateRotationY(-gesture.Delta.Y * factor);
                }
                else if (gesture.GestureType == GestureType.Flick)
                {
                    float seconds = (float)gameTime.ElapsedGameTime.TotalSeconds;
                    _rotationVelocity = new Vector2(gesture.Delta.X * factor, -gesture.Delta.Y * factor);
                }
                else if (gesture.GestureType == GestureType.Tap)
                {
                    //Debug.WriteLine("Tap " + gesture.Position);
                    if (gesture.Position.X >= _buttonTop)
                    {
                        if (gesture.Position.Y <= GraphicsDevice.Viewport.Height / 3)
                        {
                            commandForward = true;   
                        }
                        else if (gesture.Position.Y <= GraphicsDevice.Viewport.Height * 2 / 3)
                        {
                            commandResetView = true;
                        }
                        else
                        {
                            commandBack = true;
                        }
                    }
                }
            }
#endif

            foreach (var kvp in _pieceKeyMapping)
            {
                if (keyboard.IsKeyDown(kvp.Key) && prevKeyboardState.IsKeyUp(kvp.Key))
                {
                    _pieceVisibility[kvp.Value] = !_pieceVisibility[kvp.Value];
                }
            }

            if (keyboard.IsKeyDown(Keys.R) && prevKeyboardState.IsKeyUp(Keys.R))
            {
                commandResetView = true;
            }

            if (keyboard.IsKeyDown(Keys.Space) && prevKeyboardState.IsKeyUp(Keys.Space))
            {
                commandForward = true;
            }

            if (keyboard.IsKeyDown(Keys.B) && prevKeyboardState.IsKeyUp(Keys.B))
            {
                commandBack = true;
            }

            if (keyboard.IsKeyDown(Keys.U) && prevKeyboardState.IsKeyUp(Keys.U))
            {
                lock (_lockObject)
                {
                    if (_solved)
                    {
                        _puzzleState = _moves[_moveIndex].PuzzleState;
                    }
                    else
                    {
                        _puzzleState = _solverState;
                    }
                }
            }

            if (commandResetView)
            {
                rotationMatrix = Matrix.Identity;
                cameraPosition = new Vector3(0.0f, 0.0f, 30.0f);
                _rotationVelocity = Vector2.Zero;
            }

			lock (_lockObject)
			{
                if (_solved)
                {
                    if (commandForward)
                    {
                        if (isAnimating)
                        {
                            EndAnimation();
                        }
                        if (_moveIndex < _moves.Length - 1)
                        {
                            var move = _moves[_moveIndex + 1].BestSolutionPrevMove;

                            if (move.IsRemoval)
                            {
                                _moveIndex++;
                                _puzzleState = _moves[_moveIndex].PuzzleState;
                            }
                            else
                            {
                                SetupAnimation(move, gameTime.TotalGameTime, _moveIndex + 1);
                            }
                        }
                    }

                    if (commandBack)
                    {
                        if (isAnimating)
                        {
                            EndAnimation();
                        }

                        if (_moveIndex > 0)
                        {
                            int newMoveIndex = _moveIndex - 1;
                            var move = _moves[_moveIndex].BestSolutionPrevMove;
                            if (move.IsRemoval)
                            {
                                _moveIndex--;
                                _puzzleState = _moves[_moveIndex].PuzzleState;
                            }
                            else
                            {
                                var moveToReverse = move;
                                PuzzleMove reverseMove = new PuzzleMove(moveToReverse.GetEndingState().Normalize(), moveToReverse.MovingPieces, moveToReverse.Direction.Negate());
                                SetupAnimation(reverseMove, gameTime.TotalGameTime, newMoveIndex);
                            }
                        }
                    }
                }
                else
                {
                    if (commandForward)
                    {
                        _showSolverProgress = !_showSolverProgress;
                    }
                    if (commandBack)
                    {
                        _showSolverProgress = false;
                        _puzzleState = _initialState;
                    }
                }
			}

            if (_rotationVelocity != Vector2.Zero)
            {
                rotationMatrix = rotationMatrix *
                    Matrix.CreateRotationX(_rotationVelocity.X * (float)gameTime.ElapsedGameTime.TotalSeconds) *
                    Matrix.CreateRotationY(_rotationVelocity.Y * (float)gameTime.ElapsedGameTime.TotalSeconds);

                float friction = 0.03f;
                _rotationVelocity *= 1f - (friction - (float)gameTime.ElapsedGameTime.TotalSeconds);
            }



			if (isAnimating)
			{
				if (gameTime.TotalGameTime >= _animationEnd)
				{
					EndAnimation();
				}
				else
				{
					TimeSpan animationElapsed = gameTime.TotalGameTime - _animationStart;
					_animationPercent = (float)(animationElapsed.TotalMilliseconds / _animationLength.TotalMilliseconds);

					modelPosition = _animationStartModelPosition + (_animationEndModelPosition - _animationStartModelPosition) * _animationPercent;
				}
			}
			else
			{
				lock (_lockObject)
				{
					modelPosition = GetCenteringVector(_puzzleState);
				}
			}


			prevKeyboardState = keyboard;			

			base.Update(gameTime);
		}
示例#3
0
		private void SetupAnimation(PuzzleMove move, TimeSpan totalGameTime, int endMoveIndex)
		{
			isAnimating = true;
			_puzzleAnimationDirection = move.Direction;
			_puzzlePiecesMoving = move.MovingPieces;
			
			_animationPercent = 0;
			_animationStart = totalGameTime;
			_animationEnd = totalGameTime.Add(_animationLength);

			_animationStartModelPosition = GetCenteringVector(move.StartingState);
			var nonNormalizedEndPosition = move.GetEndingState();
			_animationEndModelPosition = GetCenteringVector(nonNormalizedEndPosition);

			_animationEndMoveIndex = endMoveIndex;

		}
        private Point GetExitDirection(PuzzlePiecePosition piece)
        {
            Point minBounds;
            Point maxBounds;
            CalculateBounds(new[] { piece.Piece }, out minBounds, out maxBounds);

            foreach (var kvp in _exitTests)
            {
                Point direction = kvp.Key;
                var test = kvp.Value;
                var testPosition = piece;
                Point vector = Point.Zero;
                while (true)
                {
                    if (test(testPosition.CurrentPoints, minBounds, maxBounds))
                    {
                        return direction;
                    }

                    testPosition = testPosition.Move(direction);
                    vector = Point.Add(vector, direction);
                    PuzzleMove testMove = new PuzzleMove(this, piece.Piece, vector);
                    if (!testMove.IsLegal())
                    {
                        break;
                    }
                }
            }

            //if (piece.CurrentPoints.All(p => p.X > maxBounds.X))
            //{
            //    return new Point(1, 0, 0);
            //}
            //if (piece.CurrentPoints.All(p => p.X < minBounds.X))
            //{
            //    return new Point(-1, 0, 0);
            //}

            //if (piece.CurrentPoints.All(p => p.Y > maxBounds.Y))
            //{
            //    return new Point(0, 1, 0);
            //}

            //if (piece.CurrentPoints.All(p => p.Y < minBounds.Y))
            //{
            //    return new Point(0, -1, 0);
            //}

            //if (piece.CurrentPoints.All(p => p.Z > maxBounds.Z))
            //{
            //    return new Point(0, 0, 1);
            //}
            //if (piece.CurrentPoints.All(p => p.Z < minBounds.Z))
            //{
            //    return new Point(0, 0, -1);
            //}

            return Point.Zero;
        }
        public IEnumerable<PuzzleMove> GetLegalMoves()
        {
            Queue<PuzzleMove> potentialExitMoves = new Queue<PuzzleMove>();
            Queue<PuzzleMove> potentialMoves = new Queue<PuzzleMove>();
            List<PuzzleMove> ret = new List<PuzzleMove>();

            foreach (var piece in Pieces)
            {
                Point exitDirection = GetExitDirection(piece);
                if (exitDirection != Point.Zero)
                {
                    //	If a piece can be removed, the only valid moves are removing it, and putting it back in the puzzle
                    PuzzleMove removeMove = new PuzzleMove(this, piece.Piece, exitDirection, true);
                    //	We've already verified that the remove move is valid, and we want to take removal moves first anyway
                    //ret.Add(removeMove);
                    potentialExitMoves.Enqueue(removeMove);

                    //PuzzleMove move = new PuzzleMove(this, piece.Piece, new Point(-exitDirection.X, -exitDirection.Y, -exitDirection.Z));
                    //potentialExitMoves.Enqueue(move);
                }
                else
                {
                    foreach (var direction in Point.Directions)
                    {
                        PuzzleMove move = new PuzzleMove(this, piece.Piece, direction);
                        potentialMoves.Enqueue(move);
                    }
                }
            }

            if (potentialExitMoves.Any())
            {
                //  If any pieces can be removed from the puzzle, only consider those as valid moves
                potentialMoves = potentialExitMoves;
            }

            while (potentialMoves.Count > 0)
            {
                var move = potentialMoves.Dequeue();
                if (move.IsLegal())
                {
                    if (!ret.Contains(move))
                    {
                        ret.Add(move);
                    }
                }
                else
                {
                    var blockers = move.GetBlockingPieces();
                    var newMovePieces = move.MovingPieces.Concat(blockers);

                    if (newMovePieces.Count() <= this.Pieces.Count() / 2)
                    {
                        var newMove = new PuzzleMove(this, newMovePieces, move.Direction);
                        potentialMoves.Enqueue(newMove);
                    }
                }
            }

            return ret;
        }
示例#6
0
        private void Push(PuzzleState newState, PuzzleMove move, SolverFrame prevFrame)
        {
            SolverFrame newFrame = new SolverFrame();
            newFrame.PuzzleState = newState;
            newFrame.PrevFame = prevFrame;
            newFrame.BestSolutionPrevFrame = prevFrame;
            newFrame.BestSolutionPrevMove = move;
            newFrame.ChildFrames = new Dictionary<SolverFrame, object>();

            newFrame.CalculateSolutionDepth();

            var possibleMoves = newFrame.PuzzleState.GetLegalMoves();
            WriteLine("Possible moves:");
            foreach (var possible in possibleMoves)
            {
                WriteLine("\t" + possible.ToString());
            }
            newFrame.PossibleMoves = new Queue<PuzzleMove>(possibleMoves);

            Stack.Push(newFrame);
        }