コード例 #1
0
ファイル: Game1.cs プロジェクト: dsplaisted/Disentanglement
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            IsMouseVisible = true;

            // Allow users to resize the window, and handle the Projection Matrix on Resize
            Window.Title = "Disentanglement";
            Window.AllowUserResizing = true;
            Window.ClientSizeChanged += OnClientSizeChanged;

            _puzzleState = PuzzleParser.GetGordionCubePuzzle();
            _initialState = _puzzleState;

            foreach (var piece in _puzzleState.Pieces)
            {
                _pieceVisibility[piece.Piece.Name] = true;
            }

            _pieceKeyMapping[Keys.D1] = "Orange";
            _pieceKeyMapping[Keys.D2] = "Blue";
            _pieceKeyMapping[Keys.D3] = "Yellow";
            _pieceKeyMapping[Keys.D4] = "Red";
            _pieceKeyMapping[Keys.D5] = "Green";
            _pieceKeyMapping[Keys.D6] = "Purple";
            #if NETFX_CORE
            Windows.System.Threading.ThreadPool.RunAsync(delegate { Solve(); });
            #else
            System.Threading.ThreadPool.QueueUserWorkItem(delegate { Solve(); });
            #endif
        }
コード例 #2
0
        public PuzzleMove(PuzzleState startingState, IEnumerable<PuzzlePiece> movingPieces, Point direction)
        {
            this.StartingState = startingState;
            this.MovingPieces = movingPieces;
            this.Direction = direction;

            _movingDict = MovingPieces.ToDictionary(p => p);
        }
コード例 #3
0
ファイル: Solver.cs プロジェクト: CartBlanche/Disentanglement
        public Solver(PuzzleState initialState)
        {
            //EnableDebugLog = true;
            Stack = new Stack<SolverFrame>();

            Push(initialState.Normalize(), null, null);

            _visitedStates = new Dictionary<PuzzleState, SolverFrame>();
        }
コード例 #4
0
		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw(GameTime gameTime)
		{
			PuzzleState currentState;
			bool solved;
			lock (_lockObject)
			{
                if (_showSolverProgress && !_solved && _solverState != null)
                {
                    _puzzleState = _solverState;
                }
                currentState = _puzzleState;
				solved = _solved;
			}

			if (solved)
			{
				graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
			}
			else
			{
				graphics.GraphicsDevice.Clear(Color.Black);
			}

            //_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullNone);

            //int buttonTop = GraphicsDevice.Viewport.Width - 80;
            //_spriteBatch.DrawString(_spriteFont, "Prev", new Vector2(buttonTop, 0), Color.Black, -MathHelper.PiOver2, Vector2.Zero, 1f, SpriteEffects.None, 0);

            //_spriteBatch.End();

			GraphicsDevice.SetVertexBuffer(boxVB);
			GraphicsDevice.Indices = boxIB;


			

			//var min = ToVector(currentState.MinBounds);
			//var max = ToVector(currentState.MaxBounds);

			//var center = (max + min) / 2;
			//modelPosition = -center;

			foreach (var piece in currentState.Pieces)
			{
                if (!_pieceVisibility[piece.Piece.Name])
                {
                    continue;
                }

				Vector3 pieceColor = new Vector3(0, 0, 0);
				if (piece.Piece.Name == "Orange")
				{
					pieceColor = RGB(255, 140, 0);
				}
				else if (piece.Piece.Name == "Blue")
				{
					pieceColor = RGB(0, 0, 255);
				}
				else if (piece.Piece.Name == "Yellow")
				{
					pieceColor = RGB(255, 255, 0);
				}
				else if (piece.Piece.Name == "Red")
				{
					pieceColor = RGB(255, 0, 0);
				}
				else if (piece.Piece.Name == "Green")
				{
					pieceColor = RGB(0, 255, 0);
				}
				else if (piece.Piece.Name == "Purple")
				{
					pieceColor = RGB(160, 32, 240);
				}

				foreach (var point in piece.CurrentPoints)
				{
					Vector3 pointPosition = ToVector(point);
					if (_puzzlePiecesMoving.Contains(piece.Piece))
					{
						pointPosition += ToVector(_puzzleAnimationDirection) * _animationPercent;
					}

					//effect.World = Matrix.CreateFromYawPitchRoll(rectangleAngle,
					//			rectangleAngle, rectangleAngle) * rectangleTransform;
                    effect.World = Matrix.CreateTranslation(pointPosition) *
                                    Matrix.CreateTranslation(modelPosition) *
                                    rotationMatrix;
                                

#if WINDOWS_PHONE
                    Vector3 upViewVector = Vector3.Right;
#else
                    Vector3 upViewVector = Vector3.Up;
#endif

                    effect.View = Matrix.CreateLookAt(cameraPosition,
                        Vector3.Zero, upViewVector);

                    //effect.View = Matrix.CreateLookAt(cameraPosition,
                    //    modelPosition, Vector3.Up);
					
                    
                    //effect.Projection = Matrix.CreatePerspectiveFieldOfView(
					//    MathHelper.ToRadians(45.0f), aspectRatio,
					//    1.0f, 10000.0f);

					effect.AmbientLightColor = pieceColor * 0.2f;
					//effect.DiffuseColor = new Vector3(.5f, 0, 0);
					effect.LightingEnabled = true;
					//if (solved)
					{
						effect.DirectionalLight0.Enabled = true;
						effect.DirectionalLight1.Enabled = true;
						effect.DirectionalLight2.Enabled = true;
					}
                    //effect.DirectionalLight0.DiffuseColor = pieceColor * 0.8f;
                    //effect.DirectionalLight1.DiffuseColor = pieceColor * new Vector3(0.8f, 0.6f, 0.6f);
                    //effect.DirectionalLight2.DiffuseColor = pieceColor * new Vector3(0.6f, 0.8f, 0.8f);
                    effect.DirectionalLight0.DiffuseColor = pieceColor * 0.8f;
                    effect.DirectionalLight1.DiffuseColor = pieceColor * 0.8f;
                    effect.DirectionalLight2.DiffuseColor = pieceColor * 0.8f;
                    //effect.DirectionalLight0.Direction = Vector3.Down;
                    //effect.DirectionalLight1.Direction = Vector3.Normalize(Vector3.Right + Vector3.Up + Vector3.Forward);
                    //effect.DirectionalLight2.Direction = Vector3.Normalize(Vector3.Left + Vector3.Up + Vector3.Forward);
                    effect.DirectionalLight0.Direction = Vector3.Normalize(Vector3.Forward + Vector3.Left + Vector3.Down);
                    effect.DirectionalLight1.Direction = Vector3.Normalize(Vector3.Right + Vector3.Up);
                    effect.DirectionalLight2.Direction = Vector3.Normalize(Vector3.Left + Vector3.Down);


					effect.CurrentTechnique.Passes[0].Apply();

					GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 24, 0, 12);
					
				}
			}

			base.Draw(gameTime);
		}
コード例 #5
0
		private Vector3 GetCenteringVector(PuzzleState state)
		{
			var min = ToVector(state.MinBounds);
			var max = ToVector(state.MaxBounds);

			var center = (max + min) / 2;
			return -center;

		}
コード例 #6
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);
		}
コード例 #7
0
		private void EndAnimation()
		{
			isAnimating = false;
			_animationPercent = 0;
			_puzzleAnimationDirection = Point.Zero;
			_puzzlePiecesMoving = Enumerable.Empty<PuzzlePiece>();

			_moveIndex = _animationEndMoveIndex;

			_puzzleState = _moves[_moveIndex].PuzzleState;
			modelPosition = GetCenteringVector(_puzzleState);
		}
コード例 #8
0
		private void Solve()
		{
			var initialState = _puzzleState;
			var solver = new Solver(initialState);

            while (!solver.Done)
            {
                solver.Step();
                lock (_lockObject)
                {
                    _solverState = solver.CurrentState;
                }
            }


			lock (_lockObject)
			{
				_moves = solver.GetMoveSequence();

                Console.WriteLine("Moves: " + _moves.Length);
				_moveIndex = 0;

				_puzzleState = _moves[_moveIndex].PuzzleState;
				_solved = true;
			}
		}
コード例 #9
0
        public bool Equals(PuzzleState other)
        {
            if (other == null)
            {
                return false;
            }

            if (Pieces.Count() != other.Pieces.Count())
            {
                return false;
            }

            if (Pieces.Select(p => p.Piece).Except(other.Pieces.Select(p => p.Piece)).Any())
            {
                return false;
            }

            foreach (var piece in Pieces)
            {
                if (other.GetPiecePosition(piece.Piece) != piece)
                {
                    return false;
                }
            }

            return true;
        }
コード例 #10
0
ファイル: Solver.cs プロジェクト: CartBlanche/Disentanglement
        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);
        }
コード例 #11
0
 public PuzzleMove(PuzzleState startingState, PuzzlePiece movingPiece, Point direction)
     : this(startingState, new[] { movingPiece }, direction)
 {
 }
コード例 #12
0
 public PuzzleMove(PuzzleState startingState, PuzzlePiece movingPiece, Point direction, bool isRemoval)
     : this(startingState, movingPiece, direction)
 {
     this.IsRemoval = isRemoval;
 }