예제 #1
0
        /// <summary>
        /// Updates the opponent's history of played cards and returns the last played cards of the opponent.
        /// This cards will be used for the prediction.
        /// </summary
        /// <param name="decayFactor">the decay factor by which the probability will be decrease</param>
        /// <param name="opponent">the controller of the opponent</param>
        /// <returns>the last played cards</returns>
        private PlayedCards updateTasks(double decayFactor, Controller opponent)
        {
            double initValue = 1;

            // add cards which were in the opponent's board and weren't played
            Minion[] oppBoard = opponent.BoardZone.GetAll();
            oppBoard.Select(b => b.Card)
            .Where(c => !_oppBoardCards.Cards.Contains(c)).ToList()
            .ForEach(c => {
                _oppBoardCards.Add(c, initValue);
            });

            List <PlayHistoryEntry> history = opponent.PlayHistory;

            history.Where(h => !_oppHistory.Contains(h)).ToList()
            .Select(h => h.SourceCard)
            .Where(c => !_oppBoardCards.Cards.Contains(c)).ToList()
            .ForEach(c =>
            {
                _oppBoardCards.Add(c, initValue);
            });

            PlayHistoryEntry[] copyHistory = new PlayHistoryEntry[history.Count];
            history.CopyTo(copyHistory);
            _oppHistory = copyHistory.ToList();

            return(_oppBoardCards);
        }
 public void Initialize(POGame game)
 {
     if (_oppHistory == null)
     {
         List <PlayHistoryEntry> history = game.CurrentOpponent.PlayHistory;
         var copyHistory = new PlayHistoryEntry[history.Count];
         history.CopyTo(copyHistory);
         _oppHistory = copyHistory.ToList();
     }
 }
예제 #3
0
        private async Task PlayMusic(IVoiceChannel channel, Playlist playlist)
        {
            var token = tokenSource.Token;

            PlayerState  = PlayerState.Idle;
            VoiceChannel = channel;
            Playlist     = playlist;
            playedSongs.Clear();
            var logTag = $"[Music {VoiceChannel.GuildId}] ";

            logger.LogInformation($"{logTag}Starting music player in guild {Guild.Name}, channel {VoiceChannel.Name}");
            ConnectionState = ConnectionState.Connecting;

            IAudioClient   audioClient   = null;
            AudioOutStream discordStream = null;

            try
            {
                audioClient = await VoiceChannel.ConnectAsync();

                discordStream = audioClient.CreateOpusStream();
                logger.LogDebug($"{logTag}Connected");
                ConnectionState = ConnectionState.Connected;

                while (!token.IsCancellationRequested)
                {
                    var songId = playlist.GetNextSong();
                    if (songId == null)
                    {
                        break;
                    }
                    logger.LogDebug($"{logTag}Playing next song (Id: {songId})");
                    var song = await musicService.GetSong(songId);

                    if (song == null)
                    {
                        logger.LogWarning($"{logTag}Failed to get data for song id {songId}");
                        continue;
                    }
                    var playHistoryEntry = new PlayHistoryEntry {
                        song = song, state = SongState.Playing
                    };
                    var oggStream = await song.GetOggStream();

                    if (oggStream == null)
                    {
                        logger.LogWarning($"{logTag}Failed to get ogg stream for current song (Id: {songId})");
                        playHistoryEntry.state = SongState.Error;
                        playedSongs.Add(playHistoryEntry);
                        continue;
                    }
                    playedSongs.Add(playHistoryEntry);
                    try
                    {
                        var opusStream = new OpusOggReadStream(null, oggStream);
                        PlayerState = PlayerState.Playing;
                        while (opusStream.HasNextPacket && !token.IsCancellationRequested)
                        {
                            var packet = opusStream.RetrieveNextPacket();
                            if (packet == null)
                            {
                                break;
                            }
                            await discordStream.WriteAsync(packet, 0, packet.Length);
                        }
                        playHistoryEntry.state             = SongState.Finished;
                        playedSongs[playedSongs.Count - 1] = playHistoryEntry;
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"{logTag}Exception while playing, skipping to next track");
                        playHistoryEntry.state             = SongState.Error;
                        playedSongs[playedSongs.Count - 1] = playHistoryEntry;
                    }
                    finally
                    {
                        oggStream.Dispose();
                        await discordStream.FlushAsync();
                    }
                    PlayerState = PlayerState.Idle;
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"{logTag}Exception in music player");
            }
            finally
            {
                logger.LogInformation($"{logTag}Stopping music player");
                VoiceChannel    = null;
                Playlist        = null;
                ConnectionState = ConnectionState.Disconnecting;
                discordStream?.Dispose();
                if (audioClient != null)
                {
                    audioClient.Disconnected -= ClientDisconnected;
                    audioClient.Dispose();
                }
                ConnectionState = ConnectionState.Disconnected;
                PlayerState     = PlayerState.Disconnected;
                logger.LogDebug($"{logTag}Stopped music player");
            }


            Task ClientDisconnected(Exception ex)
            {
                return(Task.Run(() => {
                    if (ex != null)
                    {
                        logger.LogError(ex, "Audio client disconnected with exception");
                    }
                    tokenSource.Cancel();
                }));
            }
        }
예제 #4
0
        /// <summary>
        /// TODO: API
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public override MCTSNode simulate(POGame.POGame game)
        {
            POGame.POGame gameCopy = game.getCopy();

            // initials root node
            var initLeafs = new List <MCTSNode>();
            var root      = new MCTSNode(_playerId, new List <MCTSNode.ScoreExt> {
                new MCTSNode.ScoreExt(1.0, _scoring)
            }, gameCopy, null, null);

            // simulate
            MCTSNode bestNode = simulate(_deltaTime, root, ref initLeafs);

            // initials opponent's history
            if (_oppHistory == null)
            {
                List <PlayHistoryEntry> history     = gameCopy.CurrentOpponent.PlayHistory;
                PlayHistoryEntry[]      copyHistory = new PlayHistoryEntry[history.Count];
                history.CopyTo(copyHistory);
                _oppHistory = copyHistory.ToList();
            }

            var simulationQueue = new Queue <KeyValuePair <POGame.POGame, List <MCTSNode> > >();

            simulationQueue.Enqueue(new KeyValuePair <POGame.POGame, List <MCTSNode> >(gameCopy, initLeafs));

            int i = 0;

            while (i < _predictionParameters.SimulationDepth &&
                   simulationQueue.Count > 0)
            {
                // calculate the lower and upper time bound of the current depth
                double lowerSimulationTimeBound = _deltaTime + i * (2 * _deltaTime);

                KeyValuePair <POGame.POGame, List <MCTSNode> > simulation = simulationQueue.Dequeue();
                POGame.POGame   simulationGame = simulation.Key;
                List <MCTSNode> leafs          = simulation.Value;

                leafs = leafs.Where(l => l.Game != null)
                        .OrderByDescending(l => l.Score)
                        .Take((leafs.Count > _predictionParameters.LeafCount)
                                                        ? _predictionParameters.LeafCount : leafs.Count)
                        .ToList();
                if (leafs.Count() < 0)
                {
                    return(bestNode);
                }

                Controller        opponent       = getOpponent(simulationGame);
                List <Prediction> predicitionMap = getPredictionMap(simulationGame, opponent);
                var oldSimulations = new Dictionary <POGame.POGame, List <MCTSNode> >();

                // the simulation time for one leaf
                double timePerLeaf = (2 * _deltaTime) / leafs.Count;

                // get all games from all leaf nodes
                for (int j = 0; j < leafs.Count; j++)
                {
                    // calculate the lower time bound of the current leaf
                    double lowerLeafTimeBound = lowerSimulationTimeBound + j * timePerLeaf;

                    MCTSNode      leafNode = leafs[j];
                    POGame.POGame oppGame  = leafNode.Game;
                    double        leafScore;
                    // XXX: game can be null

                    leafScore = simulateOpponentWithPrediction(lowerLeafTimeBound, timePerLeaf,
                                                               oppGame, opponent, predicitionMap, ref oldSimulations);
                    // back-propagate score
                    backpropagate(leafNode, leafScore);
                }

                var newSimulations = new Dictionary <POGame.POGame, List <MCTSNode> >();
                oldSimulations.ToList()
                .OrderByDescending(s => s.Value.Sum(l => l.TotalScore))
                .Take((leafs.Count > _predictionParameters.OverallLeafCount) ? _predictionParameters.OverallLeafCount : leafs.Count)
                .ToList()
                .ForEach(l => newSimulations.Add(l.Key, l.Value));

                // add new simulations
                foreach (KeyValuePair <POGame.POGame, List <MCTSNode> > sim in oldSimulations)
                {
                    simulationQueue.Enqueue(sim);
                }
                i++;
            }
            return(root.Children
                   .OrderByDescending(c => c.TotalScore)
                   .First());
        }