コード例 #1
0
        void Start()
        {
            Client = GameManager.Instance.Client;

            if (Client.IsPlayer)
            {
                Destroy(gameObject);
                return;
            }

            Instance = this;

            GameGraph        = new BoardGraph();
            BoardSpaces      = new Dictionary <int, BoardSpace>();
            FriendlyMonsters = new List <Monster>();
            EnemyMonsters    = new List <Monster>();
            AttackCalculator = new AttackCalculator();
            MoveCalculator   = new MoveCalculator();

            AvailablePushDestinations = new List <Node>();

            BattleSmoke.gameObject.SetActive(false);

            Client.GameState = this;

            float attackResultTextRotationOffset = Client.IsHost ? 180 : 0;

            AttackResultTextPrefab.YRotationOffset = attackResultTextRotationOffset;

            _actionNumber = 1;

            if (!Client.IsHost)
            {
                _actionNumber = 3;

                var table = GameObject.Find("Table");
                table.transform.localRotation = Quaternion.Euler(table.transform.localRotation.eulerAngles.x,
                                                                 table.transform.localRotation.eulerAngles.y + 180, table.transform.localRotation.eulerAngles.z);
            }

            _subActionNumber = 1;

            for (int i = 0; i < SpacePrefabs.Count; i++)
            {
                BoardSpace spacePrefab = SpacePrefabs[i];
                if (!BoardSpaces.ContainsKey(i))
                {
                    spacePrefab.Node = GameGraph.Nodes[i];
                    BoardSpaces.Add(i, spacePrefab);
                }
            }
        }
コード例 #2
0
        void Start()
        {
            DontDestroyOnLoad(gameObject);

            ActionNumber    = 1;
            SubActionNumber = 1;

            GameGraph        = new BoardGraph();
            HostMonsters     = new List <Monster>();
            GuestMonsters    = new List <Monster>();
            AttackCalculator = new AttackCalculator();
            MoveCalculator   = new MoveCalculator();

            AvailablePushDestinations = new List <Node>();

            GameManager gameManager = GameManager.Instance;

            if (gameManager == null || gameManager.Server == null)
            {
                throw new InvalidOperationException("Server must exist to begin game");
            }

            _hostServer = gameManager.Server;

            if (_hostServer == null || !_hostServer.IsServerStarted)
            {
                throw new InvalidOperationException("Server must be running to begin game");
            }

            if (SceneManager.GetSceneByName("startup").isLoaded)
            {
                SceneManager.UnloadSceneAsync("startup");
            }

            AssignMonstersToPlayers();

            GameStartMessage gameStartMessage = new GameStartMessage
            {
                HostMonsters    = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)),
                GuestMonsters   = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)),
                ActionNumber    = 1,
                SubActionNumber = 1
            };

            _hostServer.SendToAll(gameStartMessage.MessageTypeId, gameStartMessage);
        }
コード例 #3
0
        internal void Apply(ProcessTurnCommand command)
        {
            foreach (var move in ActiveTurnMoves)
            {
                if (move.Deployment) //deployed
                {
                    ApplyDomainEvent(new DeployedEvent(Id, Guid.NewGuid(), move.Player, move.Source));
                }
                else //attack
                {
                    //pick a random unit from the opposing players units in this category to hit
                    var possiblyAttacked = Units.Where(m => m.Value.OwnedByPlayer != move.Player && m.Value.Type == move.Target).ToArray();
                    if (!possiblyAttacked.Any())
                    {
                        continue;                          // they all died! :(
                    }
                    var attacked      = possiblyAttacked[_rand.Generate(possiblyAttacked.Length)].Key;
                    var attackResults = AttackCalculator.Attack(_rand, move.Source, move.Target);

                    if (attackResults.success)
                    {
                        ApplyDomainEvent(new DamagedEvent(Id, attacked, move.Target, attackResults.dmg));

                        //check for destruction
                        if (Units[attacked].Health <= attackResults.dmg)
                        {
                            ApplyDomainEvent(new DestroyedEvent(Id, attacked, Units[attacked].OwnedByPlayer, Units[attacked].Type));
                        }
                    }
                    else if (attackResults.exc == null)
                    {
                        // haha, failed, do nothing
                    }
                    else
                    {
                        //push an error event...
                    }
                }
            }

            ApplyDomainEvent(new MatchTurnEndedEvent(Id, CurrentTurn));
        }
コード例 #4
0
        public void AttackCalculator_ReturnsAttackResultWithinMarginOfError()
        {
            const int iterations = 1000000;

            //<attack, defense, attackResult>
            Dictionary <int, Dictionary <int, Dictionary <AttackResult, decimal> > > resultAverages =
                new Dictionary <int, Dictionary <int, Dictionary <AttackResult, decimal> > >();

            AttackCalculator attackCalculator = new AttackCalculator();

            for (int a = 2; a < 9; a++)
            {
                //There are no attacks powers of 5
                if (a == 5)
                {
                    continue;
                }

                for (int d = 2; d < 9; d++)
                {
                    if (!resultAverages.ContainsKey(a))
                    {
                        resultAverages.Add(a, new Dictionary <int, Dictionary <AttackResult, decimal> >());
                    }
                    if (!resultAverages[a].ContainsKey(d))
                    {
                        resultAverages[a].Add(d, new Dictionary <AttackResult, decimal>());
                    }
                    resultAverages[a][d].Add(AttackResult.Kill, 0);
                    resultAverages[a][d].Add(AttackResult.Push, 0);
                    resultAverages[a][d].Add(AttackResult.CounterPush, 0);
                    resultAverages[a][d].Add(AttackResult.CounterKill, 0);
                }

                for (int d = 2; d < 9; d++)
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        AttackResult result = attackCalculator.Calculate(a, d);
                        switch (result)
                        {
                        case AttackResult.Kill:
                            resultAverages[a][d][AttackResult.Kill]++;
                            break;

                        case AttackResult.Push:
                            resultAverages[a][d][AttackResult.Push]++;
                            break;

                        case AttackResult.CounterPush:
                            resultAverages[a][d][AttackResult.CounterPush]++;
                            break;

                        case AttackResult.CounterKill:
                            resultAverages[a][d][AttackResult.CounterKill]++;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }

                    resultAverages[a][d][AttackResult.Kill] =
                        Math.Round(resultAverages[a][d][AttackResult.Kill] / iterations, 4);
                    resultAverages[a][d][AttackResult.Push] =
                        Math.Round(resultAverages[a][d][AttackResult.Push] / iterations, 4);
                    resultAverages[a][d][AttackResult.CounterPush] =
                        Math.Round(resultAverages[a][d][AttackResult.CounterPush] / iterations, 4);
                    resultAverages[a][d][AttackResult.CounterKill] =
                        Math.Round(resultAverages[a][d][AttackResult.CounterKill] / iterations, 4);
                }
            }


            System.Diagnostics.Debug.WriteLine(
                "Dictionary<int, Dictionary<int, Dictionary<AttackResult, decimal>>> resultAverages = new Dictionary<int, Dictionary<int, Dictionary<AttackResult, decimal>>>(); ");

            for (int a = 2; a < 9; a++)
            {
                //There are no attacks powers of 5
                if (a == 5)
                {
                    continue;
                }

                System.Diagnostics.Debug.WriteLine("resultAverages.Add(" + a +
                                                   ", new Dictionary<int, Dictionary<AttackResult, decimal>>());");

                for (int d = 2; d < 9; d++)
                {
                    System.Diagnostics.Debug.WriteLine("resultAverages[" + a + "].Add(" + d +
                                                       ", new Dictionary<AttackResult, decimal>());");

                    System.Diagnostics.Debug.WriteLine("resultAverages[" + a + "][" + d + "].Add(AttackResult.Kill, " +
                                                       resultAverages[a][d][AttackResult.Kill] + "m);");
                    System.Diagnostics.Debug.WriteLine("resultAverages[" + a + "][" + d + "].Add(AttackResult.Push, " +
                                                       resultAverages[a][d][AttackResult.Push] + "m);");
                    System.Diagnostics.Debug.WriteLine("resultAverages[" + a + "][" + d + "].Add(AttackResult.CounterPush, " +
                                                       resultAverages[a][d][AttackResult.CounterPush] + "m);");
                    System.Diagnostics.Debug.WriteLine("resultAverages[" + a + "][" + d + "].Add(AttackResult.CounterKill, " +
                                                       resultAverages[a][d][AttackResult.CounterKill] + "m);");
                }
            }
        }
コード例 #5
0
        void Start()
        {
            Client = GameManager.Instance.Client;

            if (!Client.IsPlayer)
            {
                Destroy(gameObject);
                return;
            }


            Instance = this;

            GameGraph        = new BoardGraph();
            BoardSpaces      = new Dictionary <int, BoardSpace>();
            FriendlyMonsters = new List <Monster>();
            EnemyMonsters    = new List <Monster>();
            AttackCalculator = new AttackCalculator();
            MoveCalculator   = new MoveCalculator();

            AvailablePushDestinations = new List <Node>();

            BattleSmoke.gameObject.SetActive(false);

            Client.GameState = this;

            float attackResultTextRotationOffset = Client.IsHost ? 180 : 0;

            AttackResultTextPrefab.YRotationOffset = attackResultTextRotationOffset;

            _actionNumber = 1;

            if (!Client.IsHost)
            {
                _actionNumber = 3;

                var table = GameObject.Find("Table");
                table.transform.localRotation = Quaternion.Euler(table.transform.localRotation.eulerAngles.x,
                                                                 table.transform.localRotation.eulerAngles.y + 180, table.transform.localRotation.eulerAngles.z);
            }

            _subActionNumber = 1;

            for (int i = 0; i < SpacePrefabs.Count; i++)
            {
                BoardSpace spacePrefab = SpacePrefabs[i];
                if (!BoardSpaces.ContainsKey(i))
                {
                    spacePrefab.Node = GameGraph.Nodes[i];
                    BoardSpaces.Add(i, spacePrefab);
                }
            }

            List <Monster> friendlyMonsters = new List <Monster>();
            List <Monster> enemyMonsters    = new List <Monster>();

            foreach (Monster monster in MonsterPrefabs)
            {
                if (GameManager.Instance.FriendlyMonsterInitialNodeIds.ContainsKey(monster.MonsterTypeId))
                {
                    monster.CurrentNode = GameGraph.Nodes[GameManager.Instance.FriendlyMonsterInitialNodeIds[monster.MonsterTypeId]];
                    friendlyMonsters.Add(monster);
                }
                else
                {
                    monster.CurrentNode = GameGraph.Nodes[GameManager.Instance.EnemyMonsterInitialNodeIds[monster.MonsterTypeId]];
                    enemyMonsters.Add(monster);
                }
            }

            DisplayMonsters(friendlyMonsters, enemyMonsters);

            Client.SendStateAck(GetAdjustedActionNumber(), _subActionNumber);

            if (GameManager.Instance.Difficulty == 1)
            {
                GameObject.Find("selectionPreview").SetActive(false);
            }
        }
コード例 #6
0
        public void ProcessAttackAction(int attackingMonsterTypeId, int defendingMonsterTypeId)
        {
            Monster attacker;
            Monster defender;
            bool    isHostAttacker = ActionNumber == 1 || ActionNumber == 2;

            if (isHostAttacker)
            {
                attacker = HostMonsters.Single(m => m.MonsterTypeId == attackingMonsterTypeId);
                defender = GuestMonsters.Single(m => m.MonsterTypeId == defendingMonsterTypeId);
            }
            else
            {
                attacker = GuestMonsters.Single(m => m.MonsterTypeId == attackingMonsterTypeId);
                defender = HostMonsters.Single(m => m.MonsterTypeId == defendingMonsterTypeId);
            }

            AttackResult       attackResult          = AttackCalculator.Calculate(attacker.AttackRating, defender.DefenseRating);
            IEnumerable <Node> friendlyOccupiedNodes = HostMonsters.Select(monster => monster.CurrentNode).ToList();
            IEnumerable <Node> enemyOccupiedNodes    = GuestMonsters.Select(monster => monster.CurrentNode).ToList();

            switch (attackResult)
            {
            case AttackResult.Kill:
                if (isHostAttacker)
                {
                    GuestMonsters.Remove(defender);
                }
                else
                {
                    HostMonsters.Remove(defender);
                }
                SubActionNumber = 0;

                _hostServer.SendToAll(CustomMessageTypes.AttackKillResponse, new AttackKillResponseMessage
                {
                    ActionNumber           = ActionNumber,
                    SubActionNumber        = SubActionNumber,
                    AttackingMonsterTypeId = attackingMonsterTypeId,
                    DefendingMonsterTypeId = defendingMonsterTypeId,
                    AttackResultId         = (int)AttackResult.Kill,
                    Message = "Kill"
                });
                break;

            case AttackResult.CounterKill:
                if (isHostAttacker)
                {
                    HostMonsters.Remove(attacker);
                }
                else
                {
                    GuestMonsters.Remove(attacker);
                }
                SelectedMonster = null;
                SubActionNumber = 0;

                _hostServer.SendToAll(CustomMessageTypes.AttackKillResponse, new AttackKillResponseMessage
                {
                    ActionNumber           = ActionNumber,
                    SubActionNumber        = SubActionNumber,
                    AttackingMonsterTypeId = attackingMonsterTypeId,
                    DefendingMonsterTypeId = defendingMonsterTypeId,
                    AttackResultId         = (int)AttackResult.CounterKill,
                    Message = "Counter Kill"
                });
                break;

            case AttackResult.Push:

                AvailablePushDestinations = MoveCalculator.FindMoves(defender.CurrentNode, 1,
                                                                     friendlyOccupiedNodes.Union(enemyOccupiedNodes)).Select(m => m.DestinationNode);

                if (!AvailablePushDestinations.Any())
                {
                    SubActionNumber = 0;
                    _hostServer.SendToAll(CustomMessageTypes.GameState, new GameStateMessage
                    {
                        ActionNumber      = ActionNumber,
                        SubActionNumber   = SubActionNumber,
                        Message           = "No available push destinations.",
                        HostMonsterState  = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)),
                        GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id))
                    });
                }
                else
                {
                    SubActionNumber = 6;
                    _hostServer.SendToAll(CustomMessageTypes.AttackPushResponse, new AttackPushResponseMessage
                    {
                        ActionNumber                = ActionNumber,
                        SubActionNumber             = SubActionNumber,
                        AttackingMonsterTypeId      = attackingMonsterTypeId,
                        DefendingMonsterTypeId      = defendingMonsterTypeId,
                        AvailablePushDestinationIds = AvailablePushDestinations.Select(d => d.Id).ToArray(),
                        AttackResultId              = (int)AttackResult.Push,
                        Message = "Push"
                    });
                }

                break;

            case AttackResult.CounterPush:

                AvailablePushDestinations = MoveCalculator.FindMoves(attacker.CurrentNode, 1,
                                                                     friendlyOccupiedNodes.Union(enemyOccupiedNodes)).Select(m => m.DestinationNode);

                if (!AvailablePushDestinations.Any())
                {
                    SubActionNumber = 0;
                    _hostServer.SendToAll(CustomMessageTypes.GameState, new GameStateMessage
                    {
                        ActionNumber      = ActionNumber,
                        SubActionNumber   = SubActionNumber,
                        Message           = "No available push destinations.",
                        HostMonsterState  = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)),
                        GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id))
                    });
                }
                else
                {
                    SubActionNumber = 7;
                    _hostServer.SendToAll(CustomMessageTypes.AttackPushResponse, new AttackPushResponseMessage
                    {
                        ActionNumber                = ActionNumber,
                        SubActionNumber             = SubActionNumber,
                        AttackingMonsterTypeId      = attackingMonsterTypeId,
                        DefendingMonsterTypeId      = defendingMonsterTypeId,
                        AvailablePushDestinationIds = AvailablePushDestinations.Select(d => d.Id).ToArray(),
                        AttackResultId              = (int)AttackResult.CounterPush,
                        Message = "Counter Push"
                    });
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }