Exemplo n.º 1
0
 /// <summary>
 /// Ballの生成
 /// </summary>
 private void CreateBall()
 {
     Pong.BallFactory factory = new Pong.BallFactory();
     ball = Instantiate(factory.Create(), new Vector3(0, 0, 0), Quaternion.identity);
     UnityEngine.Assertions.Assert.IsNotNull(ball);
     ballScript = ball.GetComponent <Ball>();
     UnityEngine.Assertions.Assert.IsNotNull(ballScript);
 }
Exemplo n.º 2
0
        /// <summary>
        /// ゴールイベント
        /// </summary>
        /// <param name="position">ゴールした方のプレイヤー</param>
        public void Goal(PlayerConstant.Position position)
        {
            // Ball削除(オブザーバー解除してからオブジェクトを削除)
            RequestRemoveObserver(ballScript);
            Destroy(ball.gameObject);
            ballScript = null;
            ball       = null;

            if (position == PlayerConstant.Position.Left)
            {
                Debug.Log("GameTask(Goal) Left");
            }
            else
            {
                Debug.Log("GameTask(Goal) Right");
            }
            // スコアの加算
            score.Add(position);
            Debug.Log("score left  " + score.Get(PlayerConstant.Position.Left));
            Debug.Log("score right " + score.Get(PlayerConstant.Position.Right));
            // スコア更新通知
            scoreSubject.NotifyObservers(score);

            // ゲーム終了したか
            if (gameRule.CheckEnd(score))
            {
                // 文字列の設定
                if (gameRule.GetWinner(score) == PlayerConstant.Position.Left)
                {
                    SetResultLeftWin();
                }
                else
                {
                    SetResultRightWin();
                }

                // タッチしたままEndにいった
                if (touchAction.IsDragging() || touchAction.IsTouchStationary())
                {
                    isResultTouchPushing = true;
                }

                scene = Scene.Ended;
            }
            else
            {
                scene = Scene.GoalSeStart;
            }
        }
Exemplo n.º 3
0
        public void tdUpdate(Ball b, string actionChosen)
        {
            // Q(s,a)
            double currQVal = 0.0;
            //var discreteStateTuple = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, this.DiscretePaddleY, actionChosen);

            //double newPaddleY = this._paddleY;
            //int discreteNewPaddleY = this._discretePaddleY;

            //if (actionChosen.Equals("UP"))
            //{
            //    newPaddleY -= 0.04;
            //    if (newPaddleY < 0)
            //    {
            //        newPaddleY = 0;
            //    }
            //    discreteNewPaddleY = (Int32)Math.Floor(this._boardY * newPaddleY / (1 - this._paddleHeight));

            //    var discreteStateTuple = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, discreteNewPaddleY);
            //}
            //else if (actionChosen.Equals("DOWN"))
            //{
            //    newPaddleY = this._paddleY;
            //    if (newPaddleY > 1 - GlobalValues.PaddleHeight)
            //    {
            //        newPaddleY = 1 - GlobalValues.PaddleHeight;
            //    }
            //    discreteNewPaddleY = (Int32)Math.Floor(this._boardY * newPaddleY / (1 - this._paddleHeight));

            //    var discreteStateTuple = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, discreteNewPaddleY);

            //}
            // s

            // Should I have moved it based on the action to get Q(s,a).  Currently, no action was taken.
            var discreteStateTuple = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, this.DiscretePaddleY);

            try
            {
                this._Q.TryGetValue(discreteStateTuple, out currQVal);
            }
            catch
            {
                ;
            }

            // R(s) Current Reward in initial state, regardless of action
            int stateReward = 0;

            if (b.BallX > this._paddleX)
            {
                // right player deflects it
                // Calculate Y coordinate when ball is at the same level as the paddle
                double yIntersect = b.VelocityY * b.BallX + b.BallY;

                if (yIntersect <= this._paddleY + GlobalValues.PaddleHeight && yIntersect >= this._paddleY)
                {
                    stateReward = 1;
                }
                else
                {
                    stateReward = -1;
                }
            }

            // Pretend to be in successor state
            Ball nextBallState = new Pong.Ball(b.BallX, b.BallY, b.VelocityX, b.VelocityY, this._boardX, this._boardY, b.TwoPlayers);

            nextBallState.MoveBall();

            double newPaddleY         = this._paddleY;
            int    discreteNewPaddleY = this.DiscretePaddleY;

            if (actionChosen.Equals("UP"))
            {
                newPaddleY -= 0.04;
                if (newPaddleY < 0)
                {
                    newPaddleY = 0;
                }
                discreteNewPaddleY = (Int32)Math.Floor(this._boardY * newPaddleY / (1 - this._paddleHeight));
            }
            else if (actionChosen.Equals("DOWN"))
            {
                newPaddleY += 0.04;
                if (newPaddleY > 1 - GlobalValues.PaddleHeight)
                {
                    newPaddleY = 1 - GlobalValues.PaddleHeight;
                }
                discreteNewPaddleY = (Int32)Math.Floor(this._boardY * newPaddleY / (1 - this._paddleHeight));
            }
            else
            {
                // HOLD
                // Do nothing
            }

            // s'
            //var discreteSuccessorStateTuple = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, discreteNewPaddleY, actionChosen);
            var discreteSuccessorStateTuple = Tuple.Create(nextBallState.DiscreteBallX, nextBallState.DiscreteBallY, nextBallState.DiscreteVelocityX, nextBallState.DiscreteVelocityY, discreteNewPaddleY, actionChosen);

            // Get max Action in successor state
            double upQ;
            double downQ;
            double holdQ;

            moveDict.Clear();
            // Simulate Next Decision, get Max Q
            // Q(s',a')

            //var discreteNextStateTupleUp = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, discreteNewPaddleY, "UP");
            //this._Q.TryGetValue(discreteNextStateTupleUp, out upQ);
            //moveDict.Add("UP", upQ);

            //var discreteNextStateTupleDown = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, discreteNewPaddleY, "DOWN");
            //this._Q.TryGetValue(discreteNextStateTupleDown, out downQ);
            //moveDict.Add("DOWN", downQ);

            //var discreteNextStateTupleHold = Tuple.Create(b.DiscreteBallX, b.DiscreteBallY, b.DiscreteVelocityX, b.DiscreteVelocityY, discreteNewPaddleY, "HOLD");
            //this._Q.TryGetValue(discreteNextStateTupleHold, out holdQ);
            //moveDict.Add("HOLD", holdQ);

            // Get Successor State actions by changing Y
            double nextPaddleY         = newPaddleY;
            int    discreteNextPaddleY = discreteNewPaddleY;

            // TODO: move the ball again?

            // Get successor state UP action

            nextPaddleY -= 0.04;
            if (nextPaddleY < 0)
            {
                nextPaddleY = 0;
            }
            discreteNextPaddleY = (Int32)Math.Floor(this._boardY * nextPaddleY / (1 - this._paddleHeight));
            var discreteNextStateTupleUp = Tuple.Create(nextBallState.DiscreteBallX, nextBallState.DiscreteBallY, nextBallState.DiscreteVelocityX, nextBallState.DiscreteVelocityY, discreteNextPaddleY);

            this._Q.TryGetValue(discreteNextStateTupleUp, out upQ);
            moveDict.Add("UP", upQ);

            // Get successor state DOWN action
            nextPaddleY  = newPaddleY;
            nextPaddleY += 0.04;
            if (nextPaddleY > 1 - GlobalValues.PaddleHeight)
            {
                nextPaddleY = 1 - GlobalValues.PaddleHeight;
            }
            discreteNextPaddleY = (Int32)Math.Floor(this._boardY * nextPaddleY / (1 - this._paddleHeight));
            var discreteNextStateTupleDown = Tuple.Create(nextBallState.DiscreteBallX, nextBallState.DiscreteBallY, nextBallState.DiscreteVelocityX, nextBallState.DiscreteVelocityY, discreteNextPaddleY);

            this._Q.TryGetValue(discreteNextStateTupleDown, out downQ);
            moveDict.Add("DOWN", upQ);

            // Get successor state HOLD action
            nextPaddleY         = newPaddleY;
            discreteNextPaddleY = (Int32)Math.Floor(this._boardY * nextPaddleY / (1 - this._paddleHeight));
            var discreteNextStateTupleHold = Tuple.Create(nextBallState.DiscreteBallX, nextBallState.DiscreteBallY, nextBallState.DiscreteVelocityX, nextBallState.DiscreteVelocityY, discreteNextPaddleY);

            this._Q.TryGetValue(discreteNextStateTupleHold, out downQ);
            moveDict.Add("HOLD", upQ);

            Dictionary <string, double> sortedMoveDict = moveDict.OrderByDescending(v => v.Value).ToDictionary(x => x.Key, x => x.Value);

            // MaxQ(s',a')
            double maxNextQValue = sortedMoveDict.First().Value;

            var discreteStateActionTuple = Tuple.Create(discreteStateTuple.Item1, discreteStateTuple.Item2, discreteStateTuple.Item3, discreteStateTuple.Item4, discreteStateTuple.Item5, actionChosen);

            // Number of times seen this state/action pair
            int stateActionCount = 0;

            try
            {
                this._N.TryGetValue(discreteStateActionTuple, out stateActionCount);
            }
            catch
            {
                ;
            }

            double decayedLearningRate = this._learningConstant / (this._learningConstant + stateActionCount);

            this._Q[discreteStateTuple] = currQVal + decayedLearningRate * (stateReward + _discountFactor * maxNextQValue - currQVal);

            //// Check if states have value, else default it to 0
            //double currQVal = 0.0;
            //double nextQVal = 0.0;
            //int learningRateCount = 0;

            //// Calculate Q
            //try
            //{
            //    this._Q.TryGetValue(discreteStateTuple, out currQVal);
            //}
            //catch
            //{
            //    ;
            //}


            //try
            //{
            //    this._Q.TryGetValue(discreteSuccessorStateTuple, out nextQVal);
            //}
            //catch
            //{
            //    ;
            //}

            //// Number of times seen this state/action pair
            //try
            //{
            //    this._N.TryGetValue(discreteStateTuple, out learningRateCount);
            //}
            //catch
            //{
            //    ;
            //}


            //double decayedLearningRate = this._learningRate / (this._learningRate + learningRateCount);

            //var tmpUp = Tuple.Create(6,6,1,0,6, "UP");
            //var tmpDown = Tuple.Create(6, 6, 1, 0, 6, "DOWN");
            //var tmpHold = Tuple.Create(6, 6, 1, 0, 6, "HOLD");

            //nextQVal = maxNextQValue;

            //this._Q[discreteStateTuple] = currQVal + decayedLearningRate * (stateReward + _discountFactor * nextQVal - currQVal);
        }
Exemplo n.º 4
0
 /// <summary>
 /// ゴール通知の解除リクエスト
 /// </summary>
 /// <param name="ballScript">Ballスクリプト</param>
 private void RequestRemoveObserver(Pong.Ball ballScript)
 {
     ballScript.RequestRemoveObserver(this);
 }
Exemplo n.º 5
0
 /// <summary>
 /// ゴール通知の登録
 /// </summary>
 /// <param name="balScript">Ballスクリプト</param>
 private void AddGoalObserver(Pong.Ball balScript)
 {
     ballScript.AddGoalObserver(this);
 }