예제 #1
0
 public void BallLost()
 {
     if (state == GameSessionState.InProgress)
     {
         state = GameSessionState.Lost;
     }
 }
예제 #2
0
        async Task ITankGameSession.NotifyPosition(ActorId TankId, float x, float y, float z, float r)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                List <Task> notes = new List <Task>();

                TankPosistionResponse resp = new TankPosistionResponse(TankId.GetGuidId(), x, y, z, r);
                string         serialized  = resp.Serialize();
                List <ActorId> TargetUids  = state.Players.Select(p => p.UserId).Distinct().ToList();
                foreach (TankSessionMemberItem i in state.Players)
                {
                    if (i.TankId != TankId)
                    {
                        GateResponse gr = new GateResponse((int)RequestProcessorEnum.TankPosition, (int)HttpStatusCode.OK, i.UserId.GetGuidId(), serialized);
                        await i.UserId.Proxy <IUser>().SendGateResponseAsync(gr);
                    }
                }
            }
            catch (Exception E)
            {
                this.Log(E);
            }
        }
예제 #3
0
        async Task <bool> ITankGameSession.StartRound(ActorId aUserId)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                List <Task> tasks            = new List <Task>();
                int         currentuserround = 0;
                foreach (TankSessionMemberItem i in state.Players)
                {
                    tasks.Add(i.TankId.Proxy <ITank>().ResetAsync());
                    if (i.UserId == aUserId)
                    {
                        i.CurrentRound++;
                        currentuserround = i.CurrentRound;
                    }
                }
                await Task.WhenAll(tasks);

                await this.SetStateAsync(state);


                //And notify
                StartRoundResponse srr = new StartRoundResponse();
                srr.RoundNum = currentuserround;
                srr.Status   = HttpStatusCode.OK;
                srr.UserId   = aUserId.GetGuidId();
                foreach (TankSessionMemberItem i in state.Players)
                {
                    GateResponse gr = new GateResponse((int)RequestProcessorEnum.StartRound, (int)HttpStatusCode.OK, i.UserId.GetGuidId(), srr.Serialize());
                    await i.UserId.Proxy <IUser>().SendGateResponseAsync(gr);
                }

                bool OnSameRound = true;
                for (int i = 0; i < state.Players.Count - 1; i++)
                {
                    if (state.Players[i].CurrentRound != state.Players[i + 1].CurrentRound)
                    {
                        OnSameRound = false;
                    }
                }
                if (OnSameRound)
                {
                    BeginRounResponse brr = new BeginRounResponse(this.Id.GetGuidId(), currentuserround);
                    brr.Status = HttpStatusCode.OK;
                    foreach (TankSessionMemberItem i in state.Players)
                    {
                        GateResponse gr = new GateResponse((int)RequestProcessorEnum.BeginRound, (int)HttpStatusCode.OK, i.UserId.GetGuidId(), brr.Serialize());
                        await i.UserId.Proxy <IUser>().SendGateResponseAsync(gr);
                    }
                }

                return(true);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(false);
            }
        }
예제 #4
0
        async Task <int> ITankGameSession.JoinAsync(ActorId UserId)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                if (state.Players != null && state.Players.Count < 2)
                {
                    int seq = state.Players.Count + 1;
                    state.Players.Add(new TankSessionMemberItem(UserId, seq));
                    await this.SetStateAsync(state);

                    return(seq);
                }
                else
                {
                    return(0);
                }
            }
            catch (Exception E)
            {
                this.Log(E);
                return(0);
            }
        }
예제 #5
0
        async Task <bool> ITankGameSession.StartSession(CancellationToken cancellationToken)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>(cancellationToken);

                List <Task> tasks = new List <Task>();
                foreach (TankSessionMemberItem i in state.Players)
                {
                    tasks.Add(i.TankId.Proxy <ITank>().ResetAsync());
                }
                await Task.WhenAll(tasks);

                state.PlayerOneScore = 0;
                state.PlayerTwoScore = 0;
                await this.SetStateAsync(state, cancellationToken);

                return(true);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(false);
            }
        }
예제 #6
0
 public static void OnSessionStateChanged(GameSessionState state)
 {
     Debug.Log("Event called: " + state.ToString());
     if (CustomEvents.SessionStateChanged != null)
     {
         CustomEvents.SessionStateChanged(state);
     }
 }
예제 #7
0
    private void ChangeGameState(GameSessionState gameSessionState)
    {
        _gameState = gameSessionState;

        ChangeCanvasGroupState(_menuCanvasGroup, (gameSessionState == GameSessionState.Menu));
        ChangeCanvasGroupState(_retryCanvasGroup, (gameSessionState == GameSessionState.Lose));
        ChangeCanvasGroupState(_winningCanvasGroup, (gameSessionState == GameSessionState.Win));
        ChangeCanvasGroupState(_hudCanvasGroup, (gameSessionState == GameSessionState.Playing));
    }
예제 #8
0
        public void SetNewState(GameSessionState roundState)
        {
            if (CurrentRoundState == roundState)
            {
                return;
            }

            PreviousRoundState = CurrentRoundState;
            CurrentRoundState  = roundState;

            RoundStateChanged?.Invoke(this, new RoundStateChangedArgs(PreviousRoundState, CurrentRoundState));
        }
예제 #9
0
 public void SessionStateChangeHandler(GameSessionState state)
 {
     if (state == GameSessionState.Won)//Обработка события
     {
         VictoryPanel.SetActive(true);
         Logger.AddContent(UILogDataType.Monetization, "Ads is ready : " + AdCaller.isReady);
     }
     if (state == GameSessionState.Lost)//Обработка события
     {
         DefeaturePanel.SetActive(true);
     }
 }
예제 #10
0
        async Task <List <TankSessionMemberItem> > ITankGameSession.GetPlayersAsync()
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                return(state.Players);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(new List <TankSessionMemberItem>());
            }
        }
예제 #11
0
 public void BallInVictoryZone()
 {
     if (ballsInVictoryZone == 0)
     {
         AdCaller.LoadAds();
     }
     ballsInVictoryZone += 1;
     Logger.UpdateContent(UILogDataType.GameState, "Balls amount: " + ballsTotal + ", balls in box: " + ballsInVictoryZone);
     if (ballsTotal == ballsInVictoryZone)
     {
         Logger.UpdateContent(UILogDataType.GameState, "Victory!!!");
         if (state == GameSessionState.InProgress)
         {
             state = GameSessionState.Won;
         }
     }
 }
예제 #12
0
        async Task <bool> ITankGameSession.TakeDamage(ActorId TankID, float amount)
        {
            try
            {
                bool             isDead    = false;
                float            newHealth = 0.0f;
                GameSessionState state     = await this.GetStateAsync <GameSessionState>();

                foreach (TankSessionMemberItem i in state.Players)
                {
                    if (i.TankId == TankID)
                    {
                        newHealth = await(i.TankId.Proxy <ITank>().TakeDamageAsync(amount));
                        if (newHealth <= 0)
                        {
                            isDead = true;
                        }
                    }
                }
                await this.SetStateAsync(state);

                //Notify clients
                TakeDamageResponse tdr = new TakeDamageResponse();
                tdr.Status            = System.Net.HttpStatusCode.OK;
                tdr.TankGameSessionId = this.Id.GetGuidId();
                tdr.TankId            = TankID.GetGuidId();
                tdr.Health            = newHealth;
                tdr.isDead            = isDead;

                List <Task> tasks = new List <Task>();
                foreach (TankSessionMemberItem i in state.Players)
                {
                    GateResponse gr = new GateResponse((int)RequestProcessorEnum.TakeDamage, (int)HttpStatusCode.OK, i.UserId.GetGuidId(), tdr.Serialize());
                    tasks.Add(i.UserId.Proxy <IUser>().SendGateResponseAsync(gr));
                }
                await Task.WhenAll(tasks);

                //End notify clients
                return(isDead);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(false);
            }
        }
예제 #13
0
        async Task <bool> ITankGameSession.FinishRound()
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                //state.TotalRounds++;
                await this.SetStateAsync(state);

                return(true);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(false);
            }
        }
예제 #14
0
        async Task <bool> ITankGameSession.CanStart(CancellationToken cancellationToken)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>(cancellationToken);

                if (state.Players != null && state.Players.Count == 2)
                {
                    return(true);
                }
                return(false);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(false);
            }
        }
예제 #15
0
        async Task ITankGameSession.NotifyFireShell(ActorId TankId, string SerializedData)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                List <ActorId> TargetUids = state.Players.Select(p => p.UserId).Distinct().ToList();
                foreach (TankSessionMemberItem i in state.Players)
                {
                    GateResponse gr = new GateResponse((int)RequestProcessorEnum.FireShell, (int)HttpStatusCode.OK, i.UserId.GetGuidId(), SerializedData);
                    await i.UserId.Proxy <IUser>().SendGateResponseAsync(gr);
                }
            }
            catch (Exception E)
            {
                this.Log(E);
            }
        }
예제 #16
0
        async Task <int> ITankGameSession.GetPlayerCountAsync(CancellationToken cancellationToken)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>(cancellationToken);

                if (state.Players != null)
                {
                    return(state.Players.Count);
                }
                return(0);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(0);
            }
        }
예제 #17
0
 protected override void ParsePayoad(string line)
 {
     if (Payload.Contains("Precountdown to Countdown"))
     {
         State = GameSessionState.Countdown;
     }
     else if (Payload.Contains("Countdown to Playing"))
     {
         State = GameSessionState.Playing;
     }
     else if (Payload.Contains("Playing to GameOver"))
     {
         State = GameSessionState.GameOver;
     }
     else if (Payload.Contains("GameOver to Results"))
     {
         State = GameSessionState.Results;
     }
     else
     {
         IsIndefined = true;
     }
 }
예제 #18
0
        async Task <bool> ITankGameSession.CanStartRound(int roundNo)
        {
            try
            {
                GameSessionState state = await this.GetStateAsync <GameSessionState>();

                bool areonround = true;
                foreach (TankSessionMemberItem i in state.Players)
                {
                    if (i.CurrentRound != roundNo)
                    {
                        areonround = false;
                    }
                }
                return(areonround);
            }
            catch (Exception E)
            {
                this.Log(E);
                return(false);

                throw;
            }
        }
예제 #19
0
        /// <summary>
        /// Game session state machine (worker thread)
        /// </summary>
        private void Run()
        {
            GameSessionState currentState = GameSessionState.InitialDiceRoll;

            NetworkBackgammonEventQueueElement eventQueueElement = null;

            // Number of moves left for the active player
            UInt32 activePlayerMovesLeft   = 0;
            bool   activePlayerMoveDoubles = false;

            while (bStateMachineKeepRunning)
            {
                // Wait for another event
                semStateMachine.WaitOne();

                // HACK: Add function here to deal with the big switch statement
                if (!bStateMachineKeepRunning)
                {
                    break;
                }

                // Read the event element queue to get information on the next event to be processed
                if (eventQueue.Count > 0)
                {
                    eventQueueElement = eventQueue.Dequeue();
                }

                #region State Machine Pre-Processing

                // Handle special events that interfere with the regular game play (e.g. player resignation)
                if (eventQueueElement != null)
                {
                    if (eventQueueElement.Event is GameSessionPlayerResignationEvent)
                    {
                        currentState = GameSessionState.PlayerResigned;
                    }
                }

                #endregion

                #region State Machine Main Processing

                switch (currentState)
                {
                    #region State: Initial Dice Roll

                case GameSessionState.InitialDiceRoll:
                {
                    // Initialize both players checkers to their intial configuration
                    // (start positions)
                    player1.InitCheckers();
                    player2.InitCheckers();

                    // Use random number generator to figure out which player starts
                    RollDice();

                    player1.Active = false;
                    player2.Active = false;

                    player1.InitialDice = dice[0];
                    player2.InitialDice = dice[1];

                    Broadcast(new GameSessionInitialDiceRollEvent(
                                  player1.PlayerName, player1.InitialDice,
                                  player2.PlayerName, player2.InitialDice));

                    currentState = GameSessionState.InitialDiceRollAcknowledgeExpected;
                }
                break;

                    #endregion

                    #region State: Initial Dice Roll Acknowledge Expected

                case GameSessionState.InitialDiceRollAcknowledgeExpected:
                {
                    if (eventQueueElement != null)
                    {
                        try
                        {
                            if (eventQueueElement.Event is GameSessionInitialDiceRollAcknowledgeEvent)
                            {
                                GameSessionInitialDiceRollAcknowledgeEvent gameSessionEvent = (GameSessionInitialDiceRollAcknowledgeEvent)eventQueueElement.Event;

                                NetworkBackgammonPlayer sendingPlayer = (NetworkBackgammonPlayer)eventQueueElement.Notifier;

                                // Latch (flag) acknowledge of initial dice roll from respective player
                                sendingPlayer.InitialDice.FlagUsed = true;

                                // Check whether both players have acknowledged initial dice roll
                                if (player1.InitialDice.FlagUsed && player2.InitialDice.FlagUsed)
                                {
                                    // If dice rolled are a tie, roll again
                                    if (dice[0].CurrentValue == dice[1].CurrentValue)
                                    {
                                        RollDice();

                                        player1.InitialDice = dice[0];
                                        player2.InitialDice = dice[1];

                                        Broadcast(new GameSessionInitialDiceRollEvent(
                                                      player1.PlayerName, player1.InitialDice,
                                                      player2.PlayerName, player2.InitialDice));
                                    }
                                    else
                                    {
                                        // Determine active player (the one who won the initial dice roll
                                        if (dice[0].CurrentValueUInt32 > dice[1].CurrentValueUInt32)
                                        {
                                            player1.Active = true;
                                        }
                                        else
                                        {
                                            player2.Active = true;
                                        }

                                        // Calculate number of moves left for active player (based on dice values)
                                        activePlayerMoveDoubles = dice[0].CurrentValue == dice[1].CurrentValue;
                                        activePlayerMovesLeft   = (UInt32)(activePlayerMoveDoubles ? 4 : 2);

                                        // Calculate possible moves for active player (and figure out whether active player
                                        // actually has possible moves)
                                        bool activePlayerHasPossibleMoves =
                                            NetworkBackgammonGameEngine.CalculatePossibleMoves(
                                                ref player1,
                                                ref player2,
                                                activePlayerMoveDoubles ?
                                                new NetworkBackgammonDice[] { dice[0] } :
                                                dice);

                                        // Send initial checkers with positions (and possible valid moves
                                        // for the active player) to both players
                                        Broadcast(new GameSessionCheckerUpdatedEvent(player1, player2, dice[0], dice[1]));

                                        if (activePlayerHasPossibleMoves)
                                        {
                                            // Inform players about who's expected to make the next move
                                            Broadcast(new GameSessionMoveExpectedEvent(player1.Active ? player1.PlayerName : player2.PlayerName));

                                            // Set next iteration's state
                                            currentState = GameSessionState.MoveExpected;
                                        }
                                        else
                                        {
                                            // Inform both players that currently active player has no moves left
                                            // which needs to be acknowledged by the active player
                                            Broadcast(new GameSessionNoPossibleMovesEvent(player1.Active ? player1.PlayerName : player2.PlayerName));

                                            currentState = GameSessionState.NoPossibleMovesAcknowledgeExpected;
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception)
                        {
                            Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.Error));
                        }
                    }
                }
                break;

                    #endregion

                    #region State: Move Expected

                case GameSessionState.MoveExpected:
                {
                    if (eventQueueElement != null)
                    {
                        try
                        {
                            NetworkBackgammonPlayer      sendingPlayer     = (NetworkBackgammonPlayer)eventQueueElement.Notifier;
                            GameSessionMoveSelectedEvent moveSelectedEvent = (GameSessionMoveSelectedEvent)eventQueueElement.Event;

                            // Check whether the active player attempted to move
                            if (sendingPlayer.Active)
                            {
                                // Perform the selected move of the active player (and check whether the active player won the game
                                if (!NetworkBackgammonGameEngine.ExecuteMove(ref player1, ref player2, moveSelectedEvent.CheckerSelected, moveSelectedEvent.MoveSelected))
                                {
                                    // Figure out the next active player (could be the current
                                    // active player since up to 4 moves are allowed per turn)
                                    if (--activePlayerMovesLeft <= 0)
                                    {
                                        player1.Active = !player1.Active;
                                        player2.Active = !player2.Active;

                                        // Roll dice for active player
                                        RollDice();

                                        // Calculate number of moves left for active player (based on dice values)
                                        activePlayerMoveDoubles = dice[0].CurrentValue == dice[1].CurrentValue;
                                        activePlayerMovesLeft   = (UInt32)(activePlayerMoveDoubles ? 4 : 2);
                                    }

                                    // Calculate possible moves for active player (and figure out whether active player
                                    // actually has possible moves)
                                    bool activePlayerHasPossibleMoves = NetworkBackgammonGameEngine.CalculatePossibleMoves(
                                        ref player1,
                                        ref player2,
                                        activePlayerMoveDoubles ?
                                        new NetworkBackgammonDice[] { dice[0] } :
                                        activePlayerMovesLeft == 2 ?
                                        dice :
                                        new NetworkBackgammonDice[] { dice[0] == moveSelectedEvent.MoveSelected ? dice[1] : dice[0] });

                                    // Send updated checkers with positions (and possible valid moves
                                    // for the active player) to both players
                                    Broadcast(new GameSessionCheckerUpdatedEvent(player1, player2, dice[0], dice[1]));

                                    if (activePlayerHasPossibleMoves)
                                    {
                                        // Inform players about who's expected to make the next move
                                        Broadcast(new GameSessionMoveExpectedEvent(player1.Active ? player1.PlayerName : player2.PlayerName));
                                    }
                                    else
                                    {
                                        // Inform both players that currently active player has no moves left
                                        // which needs to be acknowledged by the active player
                                        Broadcast(new GameSessionNoPossibleMovesEvent(player1.Active ? player1.PlayerName : player2.PlayerName));

                                        currentState = GameSessionState.NoPossibleMovesAcknowledgeExpected;
                                    }
                                }
                                else
                                {
                                    // Inform both players that the game has been won by the active player
                                    Broadcast(new GameSessionPlayerWonEvent(sendingPlayer.PlayerName));

                                    currentState = GameSessionState.GameFinished;
                                }
                            }
                            else
                            {
                                Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.Error));
                            }
                        }
                        catch (Exception)
                        {
                            Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.Error));
                        }
                    }
                }
                break;

                    #endregion

                    #region State: No Possible Moves Acknowledge Expected

                case GameSessionState.NoPossibleMovesAcknowledgeExpected:
                {
                    if (eventQueueElement != null)
                    {
                        try
                        {
                            GameSessionNoPossibleMovesAcknowledgeEvent gameSessionNoPossibleMovesAcknowledgeEvent = (GameSessionNoPossibleMovesAcknowledgeEvent)eventQueueElement.Event;

                            // Make sure that the active player acknowledges (and not the waiting player)
                            if (gameSessionNoPossibleMovesAcknowledgeEvent.PlayerName == (player1.Active ? player1.PlayerName : player2.PlayerName))
                            {
                                player1.Active = !player1.Active;
                                player2.Active = !player2.Active;

                                // Roll dice for (new) active player
                                RollDice();

                                // Calculate number of moves left for active player (based on dice values)
                                activePlayerMoveDoubles = dice[0].CurrentValue == dice[1].CurrentValue;
                                activePlayerMovesLeft   = (UInt32)(activePlayerMoveDoubles ? 4 : 2);

                                bool activePlayerHasPossibleMoves = NetworkBackgammonGameEngine.CalculatePossibleMoves(
                                    ref player1,
                                    ref player2,
                                    activePlayerMoveDoubles ?
                                    new NetworkBackgammonDice[] { dice[0] } :
                                    activePlayerMovesLeft == 2 ?
                                    dice :
                                    new NetworkBackgammonDice[] { dice[0], dice[1] });

                                // Send updated checkers with positions (and possible valid moves
                                // for the active player) to both players
                                Broadcast(new GameSessionCheckerUpdatedEvent(player1, player2, dice[0], dice[1]));

                                if (activePlayerHasPossibleMoves)
                                {
                                    // Inform players about who's expected to make the next move
                                    Broadcast(new GameSessionMoveExpectedEvent(player1.Active ? player1.PlayerName : player2.PlayerName));

                                    currentState = GameSessionState.MoveExpected;
                                }
                                else
                                {
                                    // Inform both players that currently active player has no moves left
                                    // which needs to be acknowledged by the active player
                                    Broadcast(new GameSessionNoPossibleMovesEvent(player1.Active ? player1.PlayerName : player2.PlayerName));
                                }
                            }
                            else
                            {
                                Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.Error));
                            }
                        }
                        catch (Exception)
                        {
                            Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.Error));
                        }
                    }
                }
                break;

                    #endregion

                    #region State: Player Resigned

                case GameSessionState.PlayerResigned:
                {
                    if (eventQueueElement != null)
                    {
                        try
                        {
                            NetworkBackgammonPlayer resignedPlayer = (NetworkBackgammonPlayer)eventQueueElement.Notifier;

                            Broadcast(new GameSessionPlayerResignationEvent(resignedPlayer.PlayerName));

                            currentState = GameSessionState.GameFinished;
                        }
                        catch (Exception ex)
                        {
                            Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.Error));
                        }
                    }
                }
                break;

                    #endregion

                default:
                    break;
                }

                #endregion

                #region State Machine Post-Processing

                if (currentState == GameSessionState.GameFinished)
                {
                    Broadcast(new NetworkBackgammonGameSessionEvent(NetworkBackgammonGameSessionEvent.GameSessionEventType.GameFinished));

                    bStateMachineKeepRunning = false;
                }

                #endregion

                eventQueueElement = null;
            }
        }
예제 #20
0
 public RoundStateMachine(GameSessionState initialState)
 {
     PreviousRoundState = GameSessionState.Undefined;
     CurrentRoundState  = GameSessionState.Undefined;
 }
예제 #21
0
 internal RoundStateChangedArgs(GameSessionState previousState, GameSessionState newState)
 {
     PreviousState = previousState;
     NewState      = newState;
 }
예제 #22
0
 public GameSession(Scene lvl)
 {
     level = lvl;
     state = GameSessionState.InProgress;
 }