public async Task <IStorageFile> GetGameFileAsync(GameID gameID)
        {
            var localStorageRoot  = ApplicationData.Current.LocalFolder;
            var activeGamesFolder = await localStorageRoot.GetFolderAsync(ActiveGamesFolderName);

            var completedGamesFolder = await localStorageRoot.GetFolderAsync(CompletedGamesFolderName);

            var         filename = GetFileNameFromGameID(gameID);
            StorageFile gameFile = null;

            try
            {
                gameFile = await activeGamesFolder.GetFileAsync(filename);
            }
            catch (FileNotFoundException)
            {
                // continue to check completed games folder
            }

            if (gameFile == null)
            {
                try
                {
                    gameFile = await completedGamesFolder.GetFileAsync(filename);
                }
                catch (FileNotFoundException)
                {
                    throw new ArgumentException("The specified GameID does not correspond to a saved game.");
                }
            }

            return(gameFile);
        }
        public async Task <bool> CompleteGameAsync(GameID gameID)
        {
            var localStorageRoot  = ApplicationData.Current.LocalFolder;
            var activeGamesFolder = await localStorageRoot.GetFolderAsync(ActiveGamesFolderName);

            var completedGamesFolder = await localStorageRoot.GetFolderAsync(CompletedGamesFolderName);

            var previousGameInfo = await GetGameInformationAsync(gameID);

            try
            {
                var gameFile = await activeGamesFolder.GetFileAsync(GetFileNameFromGameID(gameID));

                await gameFile.MoveAsync(completedGamesFolder, GetFileNameFromGameID(gameID));
            }
            catch (Exception)
            {
                return(false);
            }

            OnGameCompleted(new GameCompletedEventArgs(new GameInformation(
                                                           previousGameInfo.GameDataStore,
                                                           previousGameInfo.FriendlyName,
                                                           previousGameInfo.GameType,
                                                           previousGameInfo.TimeLastMoved,
                                                           previousGameInfo.MoveCount,
                                                           false)));

            return(true);
        }
        private static string GetFriendlyNameFromGameID(GameID gameID)
        {
            var gameIDStr = gameID.GetOfflineTwoPlayerGameID();
            var parts     = gameIDStr.Split(new char[] { '_' });

            System.Diagnostics.Debug.Assert(parts.Length == 2);
            System.Diagnostics.Debug.Assert(parts[1].EndsWith(_extension));
            return(parts[0]);
        }
        public async Task <GameInformation> GetGameInformationAsync(GameID gameID)
        {
            bool isActive = true;

            var localStorageRoot  = ApplicationData.Current.LocalFolder;
            var activeGamesFolder = await localStorageRoot.GetFolderAsync(ActiveGamesFolderName);

            var completedGamesFolder = await localStorageRoot.GetFolderAsync(CompletedGamesFolderName);

            var         filename = GetFileNameFromGameID(gameID);
            StorageFile gameFile = null;

            try
            {
                gameFile = await activeGamesFolder.GetFileAsync(filename);
            }
            catch (FileNotFoundException)
            {
                isActive = false;
                // continue to check completed games folder
            }

            if (gameFile == null)
            {
                try
                {
                    gameFile = await completedGamesFolder.GetFileAsync(filename);
                }
                catch (FileNotFoundException)
                {
                    throw new ArgumentException("The specified GameID does not correspond to a saved game.");
                }
            }

            var fileProperties = await gameFile.GetBasicPropertiesAsync();

            using (var fileStream = await gameFile.OpenReadAsync())
            {
                using (var reader = new DataReader(fileStream))
                {
                    await reader.LoadAsync((uint)fileStream.Size);

                    reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                    reader.ByteOrder       = Windows.Storage.Streams.ByteOrder.LittleEndian;
                    var moveCount = reader.ReadUInt32();

                    return(new GameInformation(
                               new GameDataStore(this, gameID),
                               GetFriendlyNameFromGameID(gameID),
                               GameType.OfflineTwoPlayer,
                               fileProperties.DateModified.LocalDateTime,
                               moveCount,
                               isActive));
                }
            }
        }
        public async Task <string> GetGameStateAsync(GameID gameID)
        {
            var localStorageRoot  = ApplicationData.Current.LocalFolder;
            var activeGamesFolder = await localStorageRoot.GetFolderAsync(ActiveGamesFolderName);

            var completedGamesFolder = await localStorageRoot.GetFolderAsync(CompletedGamesFolderName);

            var         filename = GetFileNameFromGameID(gameID);
            StorageFile gameFile = null;

            try
            {
                gameFile = await activeGamesFolder.GetFileAsync(filename);
            }
            catch (FileNotFoundException)
            {
                // continue to check completed games folder
            }

            if (gameFile == null)
            {
                try
                {
                    gameFile = await completedGamesFolder.GetFileAsync(filename);
                }
                catch (FileNotFoundException)
                {
                    throw new ArgumentException("The specified GameID does not correspond to a saved game.");
                }
            }

            System.Diagnostics.Debug.Assert(gameFile != null);

            string stateString = null;

            using (var fileStream = await gameFile.OpenReadAsync())
            {
                using (var reader = new DataReader(fileStream))
                {
                    await reader.LoadAsync((uint)fileStream.Size);

                    reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                    reader.ByteOrder       = Windows.Storage.Streams.ByteOrder.LittleEndian;
                    var numMoves = reader.ReadUInt32();
                    if (reader.UnconsumedBufferLength > 0)
                    {
                        stateString = reader.ReadString(reader.UnconsumedBufferLength);
                    }
                    return(stateString);
                }
            }
        }
        public async Task <bool> StoreTurnRecordAsync(GameID gameID, string turnRecordStr)
        {
            var localStorageRoot  = ApplicationData.Current.LocalFolder;
            var activeGamesFolder = await localStorageRoot.GetFolderAsync(ActiveGamesFolderName);

            StorageFile gameFile = null;

            try
            {
                gameFile = await activeGamesFolder.GetFileAsync(GetFileNameFromGameID(gameID));
            }
            catch (FileNotFoundException)
            {
                return(false);
            }

            var previousGameInfo = await GetGameInformationAsync(gameID);

            var previousState = await GetGameStateAsync(gameID);

            previousState = previousState ?? String.Empty;

            using (var transaction = await gameFile.OpenTransactedWriteAsync())
            {
                using (var writer = new DataWriter(transaction.Stream.GetOutputStreamAt(0)))
                {
                    writer.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                    writer.ByteOrder       = ByteOrder.LittleEndian;
                    writer.WriteUInt32((uint)(previousGameInfo.MoveCount + 1));
                    writer.WriteString(previousState + Environment.NewLine + turnRecordStr);
                    transaction.Stream.Size = await writer.StoreAsync();

                    await transaction.CommitAsync();

                    writer.DetachStream();
                }
            }

            return(true);
        }
        private static string GetFileNameFromGameID(GameID gameID)
        {
            var id = gameID.GetOfflineTwoPlayerGameID();

            return(id + _extension);
        }