Exemple #1
0
        private void initGame()
        {
            // Init decks
            List <STC.Card> cardsInDeck = new List <STC.Card>();

            HearthMirror.Objects.Deck MirrorDeck = Core.Game.CurrentSelectedDeck;
            if (MirrorDeck != null)
            {
                MirrorDeck.Cards.ForEach(card =>
                {
                    for (var i = 0; i < card.Count; i++)
                    {
                        cardsInDeck.Add(STC.Cards.FromId(card.Id));
                    }
                });
            }

            List <STC.Card> UnknownDeck = new List <STC.Card>();

            for (int i = 0; i < 30; i++)
            {
                UnknownDeck.Add(new STC.Card()
                {
                    Id   = "Unknown",
                    Name = "Unknown",
                    Tags = new Dictionary <GameTag, int> {
                        [GameTag.CARDTYPE] = (int)CardType.MINION, [GameTag.COST] = 51
                    },
                });
            }

            // Init agent
            _agent = new Expectiminimax(cardsInDeck, Converter.GetCardClass(Core.Game.Player.Class), Strategy.Control);

            // Init game
            GameV2 gameV2 = Core.Game;

            _game = new STC.Game(
                new GameConfig()
            {
                StartPlayer      = gameV2.Player.HandCount == 3 ? 1 : 2,
                Player1Name      = gameV2.Player.Name,
                Player1HeroClass = Converter.GetCardClass(gameV2.Player.Class),
                Player1Deck      = cardsInDeck,
                Player2Name      = gameV2.Opponent.Name,
                Player2HeroClass = Converter.GetCardClass(gameV2.Opponent.Class),
                Player2Deck      = UnknownDeck,
                FillDecks        = false,
                Shuffle          = false,
                SkipMulligan     = false,
                AutoNextStep     = false,
                Logging          = false,
                History          = false,
                RandomController = _randomController
            });
            _game.StartGame();
            _game.BeginDraw();
            _game.BeginMulligan();
            Converter.SyncEntityIds(ref _entityIdMapping, _game, gameV2);
        }
Exemple #2
0
            public static string PrintGame(Game game)
            {
                var current  = game.CurrentPlayer;
                var opponent = game.CurrentOpponent;
                var sb       = new StringBuilder();

                sb.AppendLine("");
                sb.AppendLine($"ROUND {(game.Turn + 1) / 2} - {current.Name}\n");
                //sb.AppendLine($"Hero[P1]: {game.Player1.Hero.Health + game.Player1.Hero.Armor} / Hero[P2]: {game.Player2.Hero.Health + game.Player2.Hero.Armor}");
                sb.AppendLine($"[Op Hero: {opponent.Hero.Health}{(opponent.Hero.Armor == 0 ? "" : $" + {opponent.Hero.Armor}")}][{game.CurrentOpponent.Hero}]");
        public static SabberGame GetTestGame()
        {
            var game = new SabberGame(new GameConfig
            {
                FillDecks = false,
                History   = false,
                Logging   = false,
                Shuffle   = false
            });

            game.StartGame();
            return(game);
        }
Exemple #4
0
        public static Game GenerateGame(string deckString1, string deckString2, bool history = false,
                                        long seed = 0)
        {
            Deck deck1, deck2;

            try
            {
                deck1 = Deserialise(deckString1);
            }
            catch (Exception e)
            {
                Console.WriteLine("Deckstring #1 is not a valid deckstring");
                throw e;
            }

            try
            {
                deck2 = Deserialise(deckString2);
            }
            catch (Exception e)
            {
                Console.WriteLine("Deckstring #2 is not a valid deckstring");
                throw e;
            }

            if (seed == 0)
            {
                seed = DateTime.UtcNow.Ticks;
            }

            var game = new Game(new SabberStoneCore.Config.GameConfig
            {
                StartPlayer      = -1,
                Player1HeroClass = deck1.Class,
                Player1Deck      = deck1.GetCardList(),
                Player2HeroClass = deck2.Class,
                Player2Deck      = deck2.GetCardList(),

                Logging      = false,
                History      = history,
                FillDecks    = false,
                Shuffle      = true,
                SkipMulligan = true,
                RandomSeed   = seed
            });

            game.StartGame();

            return(game);
        }
Exemple #5
0
 private void launchAgent()
 {
     if (_isMulliganDone && _activePlayer == ActivePlayer.Player && _isMulliganDone)
     {
         _messenger.Reset();
         _messenger.Add("AI in progress ...");
         STC.Game          STCGame = _game.Clone(false, true, new STC.RandomController());
         List <PlayerTask> tasks   = _agent.PlayTurn(STCGame, STCGame.Player1);
         _messenger.Reset();
         tasks.ForEach(task =>
         {
             _messenger.Add(task.FullPrint());
         });
     }
 }
            public POGame(SabberStoneCore.Model.Game game, bool debug)
            {
                this.origGame     = game;
                this.game         = game.Clone();
                game.Player1.Game = game;
                game.Player2.Game = game;
                prepareOpponent();
                this.debug = debug;

                if (debug)
                {
                    Console.WriteLine("Game Board");
                    Console.WriteLine(game.FullPrint());
                }
            }
Exemple #7
0
        public static API.Game GenerateGameAPI(string deckString1, string deckString2)
        {
            Deck deck1, deck2;

            try
            {
                deck1 = Deserialise(deckString1);
            }
            catch (Exception e)
            {
                Console.WriteLine("Deckstring #1 is not a valid deckstring");
                throw e;
            }

            try
            {
                deck2 = Deserialise(deckString2);
            }
            catch (Exception e)
            {
                Console.WriteLine("Deckstring #2 is not a valid deckstring");
                throw e;
            }



            var game = new Game(new SabberStoneCore.Config.GameConfig
            {
                StartPlayer      = -1,
                Player1HeroClass = deck1.Class,
                Player1Deck      = deck1.GetCardList(),
                Player2HeroClass = deck2.Class,
                Player2Deck      = deck2.GetCardList(),

                Logging      = false,
                History      = false,
                FillDecks    = false,
                Shuffle      = true,
                SkipMulligan = true,
            });

            game.StartGame();

            Console.WriteLine(Printers.PrintGame(game));

            return(new API.Game(game));
        }
            /**
             * Simulates the tasks against the current game and
             * returns a Dictionary with the following POGame-Object
             * for each task (or null if an exception happened
             * during that game)
             */
            public Dictionary <PlayerTask, POGame> Simulate(List <PlayerTask> tasksToSimulate)
            {
                Dictionary <PlayerTask, POGame> simulated = new Dictionary <PlayerTask, POGame>();

                foreach (PlayerTask task in tasksToSimulate)
                {
                    SabberStoneCore.Model.Game clone = this.origGame.Clone();
                    try {
                        clone.Process(task);
                        simulated.Add(task, new POGame(clone, this.debug));
                    }
                    catch (Exception) {
                        simulated.Add(task, null);
                    }
                }
                return(simulated);
            }
Exemple #9
0
        public static void Test()
        {
            var game = new SabberStoneCore.Model.Game(new GameConfig
            {
                StartPlayer = 1,
                Shuffle     = false,
                History     = false,
                Logging     = false,
                Player1Deck = new List <Card>
                {
                    Cards.FromName("Stonetusk Boar"),
                    Cards.FromName("Wisp"),
                    Cards.FromName("Bloodfen Raptor"),
                    Cards.FromName("Dalaran Mage")
                }
            });

            game.StartGame();

            var    unmanagedHand = new HandZone_unmanaged(game.CurrentPlayer.HandZone);
            IntPtr ptr           = unmanagedHand.Playables;

            for (int i = 0; i < unmanagedHand.Count; i++)
            {
                Playable playable = Marshal.PtrToStructure <Playable>(ptr);
                ptr += Marshal.SizeOf <Playable>();

                Console.WriteLine("- Card 1:");
                Console.WriteLine($"\t{Cards.FromAssetId(playable.CardId).Name}");
                Console.WriteLine($"\tCost: {playable.Cost}");
                Console.WriteLine($"\tATK: {playable.ATK}");
                Console.WriteLine($"\tHP: {playable.BaseHealth}");
            }

            unmanagedHand.Free();
        }
Exemple #10
0
        public static PlayerTask GetPlayerTask(Option option, Game g)
        {
            const bool SkipPrePhase = true;
            Controller c            = g.CurrentPlayer;

            switch (option.Type)
            {
            case Choose:
                return(ChooseTask.Pick(c, option.Choice));

            case Concede:
                return(ConcedeTask.Any(c));

            case EndTurn:
                return(EndTurnTask.Any(c));

            case HeroAttack:
                return(HeroAttackTask.Any(c, GetOpponentTarget(option.TargetPosition), SkipPrePhase));

            case Option.Types.PlayerTaskType.HeroPower:
                return(HeroPowerTask.Any(c, GetTarget(option.TargetPosition), option.SubOption, SkipPrePhase));

            case MinionAttack:
                return(MinionAttackTask.Any(c, c.BoardZone[option.SourcePosition - 1], GetOpponentTarget(option.TargetPosition), SkipPrePhase));

            case PlayCard:
                IPlayable source = c.HandZone[option.SourcePosition];
                if (source.Card.Type == CardType.MINION)
                {
                    return(PlayCardTask.Any(c, source, null, option.TargetPosition - 1, option.SubOption, SkipPrePhase));
                }
                else
                {
                    return(PlayCardTask.Any(c, source, GetTarget(option.TargetPosition),
                                            0, option.SubOption, SkipPrePhase));
                }

            default:
                throw new ArgumentOutOfRangeException();
            }

            ICharacter GetOpponentTarget(int position)
            {
                if (position == Option.OP_HERO_POSITION)
                {
                    return(c.Opponent.Hero);
                }
                return(c.Opponent.BoardZone[position - 9]);
            }

            ICharacter GetTarget(int position)
            {
                if (position == -1)
                {
                    return(null);
                }
                if (position >= Option.OP_HERO_POSITION)
                {
                    return(GetOpponentTarget(position));
                }
                if (position == Option.HERO_POSITION)
                {
                    return(c.Hero);
                }
                return(c.BoardZone[position - 1]);
            }
        }
 public static unsafe int MarshalGameToMMF(SModel.Game game, in byte *mmfPtr, int id)
Exemple #12
0
 /// <summary>
 /// Constructs a new instance of a SabberStoneState.
 /// </summary>
 /// <param name="game">The SabberStone Game that the new SabberStoneState should represents.</param>
 public SabberStoneState(SabberStoneCore.Model.Game game)
 {
     Game = game;
 }
Exemple #13
0
        internal void ProcessPlayerAction()
        {
            foreach (var playerAction in _playerActions)
            {
                _isProcessingTask = true;
                _randomController.RandomHappened = false;
                if (playerAction.ActionType == ActionType.PLAYCARD && playerAction.Player == 2)
                {
                    STCEntities.IPlayable toBePlayed = STCEntities.Entity.FromCard(_game.Player2, STC.Cards.FromAssetId(playerAction.Source.Card.DbfIf));
                    _game.Player2.HandZone.Replace(_game.Player2.HandZone[0], toBePlayed);
                    _entityIdMapping.Add(playerAction.Source.Id, toBePlayed.Id);
                }
                List <PlayerTask> allOptions      = playerAction.Player == 1 ? _game.Player1.Options(true) : _game.Player2.Options(true);
                List <PlayerTask> filteredOptions = new List <PlayerTask>();
                allOptions.ForEach(option =>
                {
                    try
                    {
                        switch (playerAction.ActionType)
                        {
                        case ActionType.HEROPOWER:
                            if (option is HeroPowerTask)
                            {
                                filteredOptions.Add(option);
                            }
                            break;

                        case ActionType.PLAYCARD:
                            if (option is PlayCardTask)
                            {
                                if (option.Source.Id == _entityIdMapping[playerAction.Source.Id])
                                {
                                    filteredOptions.Add(option);
                                }
                            }
                            break;

                        case ActionType.MINIONATTACK:
                            if (option is MinionAttackTask)
                            {
                                if (option.Source.Id == _entityIdMapping[playerAction.AttackInfo.Attacker.Id])
                                {
                                    filteredOptions.Add(option);
                                }
                            }
                            if (option is HeroAttackTask)
                            {
                                if (option.Controller.HeroId == _entityIdMapping[playerAction.AttackInfo.Attacker.Id])
                                {
                                    filteredOptions.Add(option);
                                }
                            }
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                });

                if (filteredOptions.Count > 0)
                {
                    if (filteredOptions.Count == 1)
                    {
                        _game.Process(filteredOptions[0]);
                        _game.MainCleanUp();
                    }
                    else
                    {
                        STC.Game nextGame = null;
                        List <List <string> > errorsList = new List <List <string> >();
                        foreach (PlayerTask task in filteredOptions)
                        {
                            STC.Game clonedGame = _game.Clone(false, false, _randomController.Clone());
                            clonedGame.Process(task);
                            clonedGame.MainCleanUp();
                            var errors = Converter.AreGamesInSync(clonedGame, Core.Game);
                            if (errors.Count == 0)
                            {
                                nextGame = clonedGame;
                                break;
                            }
                            else
                            {
                                errorsList.Add(errors);
                            }
                        }
                        if (nextGame == null)
                        {
                            System.Diagnostics.Debugger.Break();
                        }
                        _game             = nextGame;
                        _randomController = (RandomController)nextGame.RandomController;
                    }
                    Converter.SyncEntityIds(ref _entityIdMapping, _game, Core.Game);
                    _game.Step = Step.MAIN_ACTION;
                    _randomController.Reset();
                    if (_randomController.RandomHappened)
                    {
                        launchAgent();
                    }
                }
                else
                {
                    System.Diagnostics.Debugger.Break();
                    var foo = playerAction.Player == 1 ? _game.Player1.Options(true) : _game.Player2.Options(true);
                }
            }
            _isProcessingTask = false;
            _randomController.RandomHappened = false;
            _playerActions = new List <PlayerAction>();
        }
        public bool PlayGame(bool addToGameStats = true, bool debug = false)
        {
            SabberStoneCore.Model.Game game = new SabberStoneCore.Model.Game(gameConfig, setupHeroes);
            //var game = new Game(gameConfig, setupHeroes);
            player1.InitializeGame();
            player2.InitializeGame();

            AbstractAgent currentAgent;
            Stopwatch     currentStopwatch;
            POGame        poGame;
            PlayerTask    playertask = null;

            Stopwatch[] watches   = new[] { new Stopwatch(), new Stopwatch() };
            bool        printGame = false;
            int         numturns  = 0;

            game.StartGame();
            if (gameConfig.SkipMulligan == false)
            {
                var originalStartingPlayer  = game.CurrentPlayer;
                var originalStartinOpponent = game.CurrentOpponent;

                game.CurrentPlayer = originalStartingPlayer;
                currentAgent       = gameConfig.StartPlayer == 1 ? player1 : player2;
                poGame             = new POGame(game, debug);
                playertask         = currentAgent.GetMove(poGame);
                game.Process(playertask);

                game.CurrentPlayer = originalStartinOpponent;
                currentAgent       = gameConfig.StartPlayer == 1 ? player2 : player1;
                poGame             = new POGame(game, debug);
                playertask         = currentAgent.GetMove(poGame);
                game.Process(playertask);

                game.CurrentPlayer = originalStartingPlayer;
                game.MainReady();
            }
#if DEBUG
            try
            {
#endif
            while (game.State != State.COMPLETE && game.State != State.INVALID)
            {
                //if (debug)
                numturns = game.Turn;
                //Console.WriteLine("Turn " + game.Turn);



                //ShowLog(game, LogLevel.INFO);


                if (printGame)
                {
                    //Console.WriteLine(MCGS.SabberHelper.SabberUtils.PrintGame(game));
                    printGame = false;
                }

                if (game.Turn >= maxTurns)
                {
                    break;
                }

                currentAgent = game.CurrentPlayer == game.Player1 ? player1 : player2;
                Controller currentPlayer = game.CurrentPlayer;
                currentStopwatch = game.CurrentPlayer == game.Player1 ? watches[0] : watches[1];
                poGame           = new POGame(game, debug);

                currentStopwatch.Start();
                playertask = currentAgent.GetMove(poGame);
                currentStopwatch.Stop();

                game.CurrentPlayer.Game   = game;
                game.CurrentOpponent.Game = game;

                if (debug)
                {
                    //Console.WriteLine(playertask);
                }

                if (playertask.PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    printGame = true;
                }

                if (playertask.PlayerTaskType == PlayerTaskType.END_TURN && game.CurrentPlayer == game.Player1)
                {
                    if (game.Turn > new Random().Next(-5, 20))
                    {
                        OutputCurrentGameForTrainingData(game);
                    }
                }

                game.Process(playertask);
            }
#if DEBUG
        }

        catch (Exception e)
        //Current Player loses if he throws an exception
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.StackTrace);
            game.State = State.COMPLETE;
            game.CurrentPlayer.PlayState   = PlayState.CONCEDED;
            game.CurrentOpponent.PlayState = PlayState.WON;

            if (addToGameStats && game.State != State.INVALID)
            {
                gameStats.registerException(game, e);
            }
        }
#endif

            if (game.State == State.INVALID || (game.Turn >= maxTurns && repeatDraws))
            {
                return(false);
            }

            if (addToGameStats)
            {
                gameStats.addGame(game, watches);
            }

            List <int> features;

            if (game.Player1.PlayState == PlayState.WON)
            {
                while (tmpData.Count > 0)
                {
                    features = tmpData.Dequeue();
                    features.Add(1);
                    trainingData.Enqueue(features);
                }
            }
            else if (game.Player2.PlayState == PlayState.WON)
            {
                while (tmpData.Count > 0)
                {
                    features = tmpData.Dequeue();
                    features.Add(-1);
                    trainingData.Enqueue(features);
                }
            }
            else
            {
                while (tmpData.Count > 0)
                {
                    features = tmpData.Dequeue();
                    features.Add(-1);
                    trainingData.Enqueue(features);
                }
            }


            player1.FinalizeGame();
            player2.FinalizeGame();

            turnsRecords.Add(numturns);


            //ShowLog(game, LogLevel.INFO);

            return(true);
        }