public IAttemptResult <int> AddVideo(STypes::Video video) { //既にデータベースに存在する場合は再利用 if (this.Exists(video.NiconicoId)) { IAttemptResult <STypes::Video> vResult = this.GetVideo(video.NiconicoId); if (!vResult.IsSucceeded || vResult.Data is null) { return(AttemptResult <int> .Fail(vResult.Message)); } //動画情報が存在する場合は更新 if (string.IsNullOrEmpty(video.Title)) { return(AttemptResult <int> .Succeeded(vResult.Data.Id)); } video.Id = vResult.Data.Id; IAttemptResult uResult = this.UpdateInternal(video); if (uResult.IsSucceeded) { this._logger.Log($"動画を上書きモードで追加しました。(niconicoID:{video.NiconicoId})"); } return(uResult.IsSucceeded switch { true => AttemptResult <int> .Succeeded(vResult.Data.Id), _ => AttemptResult <int> .Fail(uResult.Message) });
public async Task <IAttemptResult <IListVideoInfo> > GetVideoListInfoAsync(string id, CancellationToken?ct = null) { IListVideoInfo video = this._videoInfoContainer.GetVideo(id); bool registerOnlyID = this._settingHandler.GetBoolSetting(SettingsEnum.StoreOnlyNiconicoID); if (registerOnlyID) { return(AttemptResult <IListVideoInfo> .Succeeded(video)); } this._messageHandler.AppendMessage($"{id}の取得を開始します。"); IAttemptResult <IListVideoInfo> result = await this._wacthPagehandler.TryGetVideoInfoAsync(id); if (!result.IsSucceeded || result.Data is null) { this._messageHandler.AppendMessage($"{id}の取得に失敗しました。(詳細:{result.Message})"); return(AttemptResult <IListVideoInfo> .Fail($"{id}の取得に失敗しました。(詳細:{result.Message})")); } else { this._messageHandler.AppendMessage($"{id}の取得に成功しました。"); video.SetNewData(result.Data); } return(AttemptResult <IListVideoInfo> .Succeeded(video)); }
public void ローカルプレイリストとして設定する() { //プレイリストを作成する IAttemptResult <STypes::Playlist> rootResult = this.playlistStorehandler !.GetRootPlaylist(); Assert.That(rootResult.IsSucceeded, Is.True); Assert.That(rootResult.Data, Is.Not.Null); Assert.That(rootResult.Data !.IsRoot, Is.True); int rootId = rootResult.Data !.Id; IAttemptResult <int> playlistResult = this.playlistStorehandler.AddPlaylist(rootId, "プレイリスト1"); Assert.That(playlistResult.IsSucceeded, Is.True); int playlistId = playlistResult.Data; this.playlistStorehandler.SetAsLocalPlaylist(playlistId); IAttemptResult <STypes::Playlist> playlist = this.playlistStorehandler.GetPlaylist(playlistId); Assert.That(playlist.IsSucceeded, Is.True); Assert.That(playlist.Data, Is.Not.Null); Assert.That(playlist.Data !.IsRemotePlaylist, Is.False); Assert.That(playlist.Data.IsWatchLater, Is.False); Assert.That(playlist.Data.IsMylist, Is.False); Assert.That(playlist.Data.IsSeries, Is.False); Assert.That(playlist.Data.IsChannel, Is.False); Assert.That(playlist.Data.IsUserVideos, Is.False); }
public IAttemptResult UnWireVideo(int videoId, int playlistId) { if (!this.Exists(playlistId)) { return(AttemptResult.Fail("指定したプレイリストが存在しません。")); } IAttemptResult <STypes::Playlist> pResult = this.GetPlaylist(playlistId); if (!pResult.IsSucceeded || pResult.Data is null) { return(AttemptResult.Fail("プレイリストの取得に失敗しました。")); } STypes::Playlist playlist = pResult.Data; playlist.Videos.RemoveAll(v => v.Id == videoId); playlist.CustomVideoSequence.RemoveAll(v => v == videoId); var uResult = this.databaseInstance.Update(playlist, STypes::Playlist.TableName); if (!uResult.IsSucceeded) { return(AttemptResult.Fail($"動画の削除に失敗しました。(詳細:{uResult.ExceptionMessage})")); } this.logger.Log($"{playlist.PlaylistName}からの動画({videoId})を削除しました。"); return(AttemptResult.Succeeded()); }
public IAttemptResult InstallAddon() { if (!this.IsLoaded.Value) { return(new AttemptResult() { Message = "アドオンの読み込みが完了していません。" }); } IAttemptResult <AddonInfomation> result = this.installer.Install(this.tempPath !, this.updateInfo); if (!result.IsSucceeded) { return(new AttemptResult() { Message = result.Message, Exception = result.Exception }); } this.IsInstalling.Value = false; this.updateInfo = null; return(new AttemptResult() { IsSucceeded = true }); }
public AddonInstallPageViewModel() { this.Install = this.IsInstalling .Select(value => !value) .ToReactiveCommand() .WithSubscribe(() => { this.IsInstalling.Value = true; this.Clear(); this.AppendLine("インストールを開始します。"); IAttemptResult result = WS::AddonPage.InstallManager.InstallAddon(); if (!result.IsSucceeded) { this.AppendLine("インストールに失敗しました。"); this.AppendLine($"詳細:{result.Message}"); } else { this.AppendLine("インストールが完了しました。"); this.MessageQueue.Enqueue("インストールを完了するには、再起動が必要です。", "再起動", () => { WS::AddonPage.PowerManager.Restart(); }); } this.IsInstalling.Value = false; }).AddTo(this.disposables); }
public IAttemptResult WireVideoToPlaylist(int videoID, int playlistID) { IAttemptResult <STypes::Video> vResult = this._videoStoreHandler.GetVideo(videoID); if (!vResult.IsSucceeded || vResult.Data is null) { return(AttemptResult.Fail("追加する動画はDBに保存されていません。")); } STypes::Video video = vResult.Data; video.PlaylistIds.AddUnique(playlistID); this._videoStoreHandler.Update(video); IAttemptResult result = this._playlistStoreHandler.WireVideo(video, playlistID); ITreePlaylistInfo playlistInfo = this._playlistInfoContainer.GetPlaylist(playlistID); IListVideoInfo videoInfo = this._videoInfoContainer.GetVideo(video.NiconicoId); if (!playlistInfo.Videos.Any(v => v.Id.Value == videoID)) { playlistInfo.Videos.Add(videoInfo); } return(result); }
public void スタイルを取得する() { IAttemptResult <UserChrome> result = this.chromeHandler !.GetUserChrome(); Assert.That(result.Data, Is.Not.Null); Assert.That(result.Data !.MainPage.VideoList.ItemHeight, Is.EqualTo(200)); }
/// <summary> /// 子プレイリストを辿って削除する /// </summary> /// <param name="parentId"></param> private IAttemptResult RemoveChildPlaylist(STypes::Playlist self) { if (self.IsConcretePlaylist) { return(AttemptResult.Succeeded()); } IAttemptResult <List <STypes::Playlist> > cResult = this.GetChildPlaylists(self.Id); if (!cResult.IsSucceeded || cResult.Data is null) { return(AttemptResult.Fail("子プレイリストの取得に失敗しました。")); } foreach (var childPlaylist in cResult.Data) { IAttemptResult crResult = this.RemoveChildPlaylist(childPlaylist); if (!crResult.IsSucceeded) { return(AttemptResult.Fail("子孫プレイリストの削除に失敗しました。")); } IAttemptResult dResul = this.DeletePlaylist(childPlaylist.Id); if (!dResul.IsSucceeded) { return(AttemptResult.Fail("子プレイリストの削除に失敗しました。")); } this.logger.Log($"{self.Id}の子プレイリストを削除しました。"); } return(AttemptResult.Succeeded()); }
public IAttemptResult MoveVideoToForward(int videoIndex, int playlistID) { IAttemptResult <ITreePlaylistInfo> result = this.GetPlaylist(playlistID); if (!result.IsSucceeded || result.Data is null) { return(AttemptResult.Fail(result.Message)); } ITreePlaylistInfo playlist = result.Data; playlist.VideoSortType = STypes::VideoSortType.Custom; if (videoIndex == playlist.Videos.Count - 1) { return(AttemptResult.Fail("指定された動画は最後に存在するため前に移動できません。")); } try { playlist.Videos.InsertIntoForward(videoIndex); } catch (Exception e) { this._logger.Error($"動画の並び替え操作に失敗しました。({nameof(this.MoveVideoToForward)})", e); return(AttemptResult.Fail($"動画の並び替え操作に失敗しました。(詳細:{e.Message})", e)); } return(this.Update(playlist)); }
public IAttemptResult LoadAddon() { //解凍 IAttemptResult <string> extractResult = this.installer.Extract(this.addonPath !); if (!extractResult.IsSucceeded || extractResult.Data is null) { this.Cancel(); return(new AttemptResult() { Message = extractResult.Message, Exception = extractResult.Exception }); } this.tempPath = extractResult.Data; IAttemptResult <AddonInfomation> mResult = this.installer.LoadManifest(extractResult.Data); if (!mResult.IsSucceeded || mResult.Data is null) { this.Cancel(); return(new AttemptResult() { Message = mResult.Message, Exception = mResult.Exception }); } this.IsLoaded.Value = true; this.Infomation.Value = mResult.Data; return(new AttemptResult() { IsSucceeded = true }); }
public IAttemptResult MoveVideoToPrev(int playlistID, int videoIndex) { if (!this.Exists(playlistID)) { return new AttemptResult() { Message = $"指定されたプレイリストは存在しません。(id={playlistID})" } } ; IAttemptResult <STypes::Playlist> pResult = this.GetPlaylist(playlistID); if (!pResult.IsSucceeded || pResult.Data is null) { return(AttemptResult.Fail("プレイリストの取得に失敗しました。")); } STypes::Playlist playlist = pResult.Data; if (playlist.Videos.Count < videoIndex + 1) { return new AttemptResult() { Message = $"指定されたインデックスは範囲外です。(index={videoIndex}, actual={playlist.Videos.Count})" } } ; if (videoIndex == 0) { return new AttemptResult() { Message = $"指定されたインデックスは最初の動画です。(index={videoIndex})" } } ; try { playlist.CustomVideoSequence.InsertIntoPrev(videoIndex); } catch (Exception e) { return(new AttemptResult() { Message = $"挿入操作に失敗しました。", Exception = e }); } playlist.SortType = STypes.VideoSortType.Custom; this.Update(playlist); this.logger.Log($"{playlistID}の{videoIndex + 1}番目の動画を一つ後ろに挿入しました。"); return(new AttemptResult() { IsSucceeded = true }); }
public IAttemptResult <STypes::Playlist> GetPlaylist(Expression <Func <STypes::Playlist, bool> > predicate) { IAttemptResult <STypes::Playlist> result = this.databaseInstance.GetRecord <STypes::Playlist>(STypes::Playlist.TableName, predicate); if (!result.IsSucceeded || result.Data is null) { if (result.Exception is not null) { this.logger.Error("プレイリストの取得に失敗しました。", result.Exception); } else { this.logger.Error("プレイリストの取得に失敗しました。"); } return(AttemptResult <STypes::Playlist> .Fail("プレイリストの取得に失敗しました。")); } if (result.Data.Videos.Count > 0 && result.Data.CustomVideoSequence.Count != result.Data.Videos.Count) { var ids = result.Data.Videos.Select(v => v.Id).Where(id => !result.Data.CustomVideoSequence.Contains(id)); result.Data.CustomVideoSequence.AddRange(ids); } this.logger.Log($"プレイリスト(name:{result.Data.PlaylistName}, ID:{result.Data.Id})を取得しました。"); return(AttemptResult <STypes::Playlist> .Succeeded(result.Data)); }
public STypes::Playlist ConvertLocalPlaylistToStorePlaylist(ITreePlaylistInfo source) { var converted = new STypes::Playlist(); converted.Id = source.Id; converted.IsRoot = source.IsRoot; converted.PlaylistName = source.Name.Value; converted.FolderPath = source.Folderpath; converted.IsExpanded = source.IsExpanded; converted.SortType = source.VideoSortType; converted.IsVideoDescending = source.IsVideoDescending; converted.IsTemporary = source.IsTemporary; converted.IsDownloadSucceededHistory = source.IsDownloadSucceededHistory; converted.IsDownloadFailedHistory = source.IsDownloadFailedHistory; converted.IsRemotePlaylist = source.RemoteType != RemoteType.None; converted.RemoteId = source.RemoteId; converted.IsWatchLater = source.RemoteType == RemoteType.WatchLater; converted.IsMylist = source.RemoteType == RemoteType.Mylist; converted.IsSeries = source.RemoteType == RemoteType.Series; converted.IsChannel = source.RemoteType == RemoteType.Channel; converted.IsUserVideos = source.RemoteType == RemoteType.UserVideos; converted.BookMarkedVideoID = source.BookMarkedVideoID; converted.Videos.Clear(); converted.Videos.AddRange(source.Videos.Select(v => this.ConvertLocalVideoToStoreVideo(v))); IAttemptResult <STypes::Playlist> pResult = this._playlistStoreHandler.GetPlaylist(source.ParentId); if (pResult.IsSucceeded && pResult.Data is not null) { converted.ParentPlaylist = pResult.Data; } return(converted); }
public void 複数プレイリストに単一動画を追加する() { var videoInfo = new STypes::Video(); videoInfo.NiconicoId = "sm9"; videoInfo.Title = "テスト動画"; IAttemptResult <int> videoResult = this.handler !.AddVideo(videoInfo); IAttemptResult <int> v1Result = this.handler !.AddVideo(videoInfo); IAttemptResult <int> v2Result = this.handler.AddVideo(videoInfo); int videoId1 = v1Result.Data; int videoId2 = v2Result.Data; IAttemptResult <STypes::Video> video = this.handler.GetVideo(videoId1); Assert.That(v1Result.IsSucceeded, Is.True); Assert.That(v2Result.IsSucceeded, Is.True); Assert.AreEqual(videoId1, videoId2); Assert.That(video.IsSucceeded, Is.True); Assert.That(video.Data, Is.Not.Null); Assert.That(video.Data !.Id, Is.EqualTo(videoId1)); Assert.That(video.Data.NiconicoId, Is.EqualTo("sm9")); Assert.That(video.Data.Title, Is.EqualTo("テスト動画")); }
public void プレイリストを削除する() { //親-子-孫の関係を作る IAttemptResult <STypes::Playlist> rootResult = this.playlistStorehandler !.GetRootPlaylist(); Assert.That(rootResult.IsSucceeded, Is.True); Assert.That(rootResult.Data, Is.Not.Null); Assert.That(rootResult.Data !.IsRoot, Is.True); int rootId = rootResult.Data !.Id; IAttemptResult <int> childResult = this.playlistStorehandler.AddPlaylist(rootId, "子プレイリスト"); Assert.That(childResult.IsSucceeded, Is.True); int childId = childResult.Data; IAttemptResult <int> grandchildResult = this.playlistStorehandler.AddPlaylist(childId, "孫プレイリスト"); Assert.That(grandchildResult.IsSucceeded, Is.True); int grandChildId = grandchildResult.Data; //削除 this.playlistStorehandler.DeletePlaylist(childId); //プレイリストが存在しないことを確認 Assert.IsFalse(this.database?.Exists <STypes::Playlist>(STypes::Playlist.TableName, childId)); Assert.IsFalse(this.database?.Exists <STypes::Playlist>(STypes::Playlist.TableName, grandChildId)); }
public IAttemptResult Update(IListVideoInfo video) { STypes::Video converted = this._converter.ConvertLocalVideoToStoreVideo(video); IAttemptResult result = this._videoStoreHandler.Update(converted); return(result); }
public async Task リリースを取得する() { IAttemptResult <Release> result = await this.checker !.GetTheLatestAsync("", ""); Assert.That(result.IsSucceeded, Is.True); Assert.That(result.Data, Is.Not.Null); Assert.That(result.Data !.Name, Is.EqualTo("v0.7.1")); }
public void ルートプレイリストを取得() { IAttemptResult <STypes::Playlist> root = this.playlistStorehandler !.GetRootPlaylist(); Assert.That(root.IsSucceeded, Is.True); Assert.That(root.Data, Is.Not.Null); Assert.That(root.Data !.IsRoot, Is.True); }
public async Task ファイルを確認する() { Release release = (await this.checker !.GetTheLatestAsync("", "")).Data !; IAttemptResult <string> result = this.checker !.GetAssetUrl(@"^niconicome-win-x64-self-contained.*$", release); Assert.That(result.IsSucceeded, Is.True); Assert.That(result.Data !, Is.EqualTo("https://api.github.com/repos/Hayao-H/Niconicome/releases/assets/39480024")); }
/// <summary> /// Thread要求を構築する /// </summary> /// <param name="threadInfo"></param> /// <param name="dmcInfo"></param> /// <param name="option"></param> /// <returns></returns> private async Task <IAttemptResult <Request::Thread> > GetThreadAsync(IThread threadInfo, IDmcInfo dmcInfo, ICommentFetchOption option) { var thread = new Request::Thread() { ThreadNo = threadInfo.ID.ToString(), UserID = dmcInfo.UserId, Fork = threadInfo.Fork, Language = 0, WithGlobal = 1, Scores = 1, Nicoru = 3, Force184 = threadInfo.Is184Forced ? "1" : null, }; //投コメを判定 if (threadInfo.IsOwnerThread) { thread.ResFrom = -1000; thread.Version = "20061206"; } else { thread.Version = "20090904"; } //Force184? if (threadInfo.Is184Forced) { thread.Force184 = "1"; } //公式動画を判別 if (threadInfo.IsThreadkeyRequired) { thread.ThreadKey = threadInfo.Threadkey; } else { thread.UserKey = dmcInfo.Userkey; } //過去ログ if (option.DownloadLog) { IAttemptResult <WayBackKey> wResult = await this._officialCommentHandler.GetWayBackKeyAsync(threadInfo.ID.ToString()); if (!wResult.IsSucceeded || wResult.Data is null) { return(AttemptResult <Request::Thread> .Fail(wResult.Message)); } thread.When = option.When; thread.WayBackKey = wResult.Data.Key; } return(AttemptResult <Request::Thread> .Succeeded(thread)); }
public IAttemptResult Uninstall(int id) { if (!this.storeHandler.IsInstallled(addon => addon.Id == id)) { return(new AttemptResult() { Message = $"アドオン(id:{id})はインストールされていません。" }); } AddonInfomation addon = this.container.GetAddon(id); string addonDir = Path.Combine(FileFolder.AddonsFolder, addon.PackageID.Value); if (this.contexts.Has(id)) { try { this.contexts.Kill(id); } catch (Exception e) { this.logger.Error($"アドオンコンテクストの破棄に失敗しました。(name:{addon.Name.Value})", e); return(new AttemptResult() { Message = "アドオンコンテクストの破棄に失敗しました。", Exception = e }); } } IAttemptResult storeResult = this.storeHandler.Delete(addon => addon.Id == id); if (!storeResult.IsSucceeded) { return(storeResult); } string newName = Path.Combine(FileFolder.AddonsFolder, $"{addon.PackageID}-deleted"); try { this.fileIO.AppendText(Path.Combine(FileFolder.AddonsFolder, Const::AddonConstant.UninstalledAddonsFile), addon.PackageID.Value); } catch (Exception ex) { this.logger.Error("アドオンディレクトリの削除予定処理に失敗しました。", ex); return(new AttemptResult() { Message = "アドオンフォルダーの削除予定処理に失敗しました。", Exception = ex }); } this.container.Remove(id); return(new AttemptResult() { IsSucceeded = true }); }
/// <summary> /// マニフェストを読み込む /// </summary> /// <param name="path"></param> /// <returns></returns> public IAttemptResult <AddonInfomation> LoadManifest(string path) { if (!this.fileIO.Exists(path)) { return(new AttemptResult <AddonInfomation>() { Message = $"指定されたマニフェストファイル({path})が存在しません。" }); } string content; try { content = this.fileIO.OpenRead(path); } catch (Exception e) { this.logger.Error($"マニフェストファイルの読み込みに失敗しました。({path})", e); return(new AttemptResult <AddonInfomation>() { Message = "マニフェストファイルの読み込みに失敗しました。", Exception = e }); } V1::Manifest info; try { info = JsonParser.DeSerialize <V1::Manifest>(content); } catch (Exception e) { this.logger.Error($"マニフェストファイルの解析に失敗しました。({path})", e); return(new AttemptResult <AddonInfomation>() { Message = "マニフェストファイルの解析に失敗しました。", Exception = e }); } IAttemptResult manifestResult = this.CheckManifest(info); if (!manifestResult.IsSucceeded) { this.logger.Error($"不正なマニフェストファイルです。({path},{manifestResult.Message})"); return(new AttemptResult <AddonInfomation>() { Message = manifestResult.Message }); } AddonInfomation addon = this.ConvertToAddonInfo(info); return(new AttemptResult <AddonInfomation>() { IsSucceeded = true, Data = addon }); }
/// <summary> /// アドオンを初期化して実行する /// </summary> /// <param name="packageID"></param> /// <returns></returns> public async Task <IAttemptResult <bool> > InitializeAsync(string packageID, bool isDevMode) { if (!this.storeHandler.IsInstallled(addon => addon.PackageID == packageID)) { return(new AttemptResult <bool>() { Data = false, Message = "インストールされていないアドオンです。アドオンのサイドロードは出来ません。" }); } string manifestPath = Path.Combine(Const::FileFolder.AddonsFolder, packageID, "manifest.json"); IAttemptResult <AddonInfomation> mResult = this.manifestLoader.LoadManifest(manifestPath); if (!mResult.IsSucceeded || mResult.Data is null) { return(new AttemptResult <bool>() { Data = true, Message = "マニフェストファイルの読み込みに失敗しました。", Exception = mResult.Exception }); } AddonInfomation dbData = this.storeHandler.GetAddon(data => data.PackageID == packageID) !; if (!isDevMode) { //アドオンを検証 IAttemptResult checkResult = this.CheckSafety(dbData, mResult.Data); if (!checkResult.IsSucceeded) { this.container.Remove(dbData.ID.Value); return(new AttemptResult <bool>() { Data = true, Message = checkResult.Message, Exception = checkResult.Exception }); } } AddonInfomation addon = this.container.GetAddon(dbData.ID.Value); //DBのIDを対応させる mResult.Data.PackageID.Value = packageID; mResult.Data.ID.Value = dbData.ID.Value; addon.SetData(mResult.Data); //コンテクストを登録 IAddonContext context = AddonContext.CreateInstance(); this.contexts.Contexts.Add(addon.ID.Value, context); await Task.Delay(1); return(new AttemptResult <bool>() { Data = true, IsSucceeded = true }); }
public void setItem(string key, string value) { IAttemptResult result = this._handler.SetItem(key, value); if (!result.IsSucceeded) { throw new Exception(result.Message); } }
public void シリーズを解析する() { IAttemptResult <RemotePlaylistInfo> result = this.seriesPageHtmlParser !.GetSeriesInfo(Properties.Resources.Series_Touhou); Assert.That(result.IsSucceeded, Is.True); Assert.That(result.Data, Is.Not.Null); Assert.That(result.Data !.PlaylistName, Is.EqualTo("つくった東方メドレー")); Assert.That(result.Data !.Videos.Count, Is.EqualTo(12)); }
public IAttemptResult Move(int id, int targetId) { IAttemptResult mResult = this._playlistStoreHandler.Move(id, targetId); if (!mResult.IsSucceeded) { return(mResult); } return(this.SetPlaylists()); }
public IAttemptResult <IEnumerable <ITreePlaylistInfo> > GetAllPlaylists() { IAttemptResult <List <STypes::Playlist> > result = this._playlistStoreHandler.GetAllPlaylists(); if (!result.IsSucceeded || result.Data is null) { return(AttemptResult <IEnumerable <ITreePlaylistInfo> > .Fail(result.Message)); } return(AttemptResult <IEnumerable <ITreePlaylistInfo> > .Succeeded(result.Data.Select(p => this._converter.ConvertStorePlaylistToLocalPlaylist(p)))); }
public void Error(string message, IAttemptResult result) { if (result.Exception is not null) { this.Error(message, result.Exception); } else { this.Error(message); } }
protected override void OnBestResultFound(RunResults results, IAttemptResult bestVariant) { var variant = (AttemptResult)bestVariant; if (variant.Migration == null) { return; } results.AddMigrationResultForSpecies(species, variant.Migration); }
public INumber GetNextNumber(IAttemptResult lastAttempt) { var nextNumberToTry = default(INumber); var lastAttemptIndex = this.GetLastAttemptIndex(); var previousAttempt = default(IAttemptResult); if (lastAttemptIndex > 0 && this.previousAttempts.TryGetValue(lastAttemptIndex, out previousAttempt)) { this.CheckAttemptsHistory(); var analysisResult = this.AnalyzeResults(previousAttempt, lastAttempt); this.EvaluateBadCandidates(analysisResult); this.EvaluateGoodCandidates(analysisResult); var badValues = this.GetBadValuesToTry(lastAttempt); var goodUnits = this.GetGoodUnitsToTry(lastAttempt); if (badValues.Any()) { nextNumberToTry = this.numberBuilder.Build(lastAttempt.Number, valuesToReplace: badValues, unitsToAdd: goodUnits); } else { nextNumberToTry = this.numberBuilder.Build(lastAttempt.Number, unitsToReplace: lastAttempt.Bads, unitsToAdd: goodUnits); } } else { if(lastAttempt.Bads == lastAttempt.Number.Units.Count()) { foreach(var numberUnit in lastAttempt.Number.Units) { this.confirmedBads.Add (numberUnit.Value); this.numberBuilder.ExcludeAlways (numberUnit.Value); } } if(lastAttempt.Regulars == lastAttempt.Number.Units.Count()) { foreach(var numberUnit in lastAttempt.Number.Units) { this.goodCandidates.Add (numberUnit); } } if(lastAttempt.Goods == lastAttempt.Number.Units.Count()) { foreach(var numberUnit in lastAttempt.Number.Units) { this.confirmedGoods.Add (numberUnit); this.numberBuilder.IncludeAlways (numberUnit); } } nextNumberToTry = this.numberBuilder.Build(lastAttempt.Number, unitsToReplace: lastAttempt.Bads, unitsToShuffle: lastAttempt.Number.Units.Count() - lastAttempt.Goods - lastAttempt.Bads); } lastAttemptIndex++; this.previousAttempts.Add(lastAttemptIndex, lastAttempt); return nextNumberToTry; }
private IEnumerable<int> GetBadValuesToTry(IAttemptResult lastAttempt) { return this.badCandidates .Where(b => lastAttempt.Number.Units.Select(u => u.Value).Any(v => v == b)) .Take(lastAttempt.Bads) .ToList(); }
private IEnumerable<INumberUnit> GetGoodUnitsToTry(IAttemptResult lastAttempt) { var goodUnits = new List<INumberUnit>(); var missingGoodsToAdd = lastAttempt.Number.Units.Count() - this.confirmedGoods.Count(); if (missingGoodsToAdd > 0 && this.goodCandidates.Any()) { goodUnits = this.goodCandidates.Take(missingGoodsToAdd).ToList(); } return goodUnits; }
public IAnalysisResult AnalyzeResults(IAttemptResult previousAttempt, IAttemptResult currentAttempt) { var analysisResult = new AnalysisResult(); var removedUnits = previousAttempt.Number.Units.Where(u => !currentAttempt.Number.Units.Any(x => x.Value == u.Value)); var newUnits = currentAttempt.Number.Units.Where(u => !previousAttempt.Number.Units.Any(x => x.Value == u.Value)); var shuffledUnitsOld = previousAttempt.Number.Units.Where(u => currentAttempt.Number.Units.Any(x => x.Value == u.Value && x.Position != u.Position)); var shuffledUnitsNew = currentAttempt.Number.Units.Where(u => previousAttempt.Number.Units.Any(x => x.Value == u.Value && x.Position != u.Position)); var maintainedUnits = currentAttempt.Number.Units.Where(u => previousAttempt.Number.Units.Any(x => x.Equals(u))); if (currentAttempt.Bads < previousAttempt.Bads && removedUnits.Any()) { analysisResult.AddBadCanditates(removedUnits.Select(u => u.Value)); } else if (currentAttempt.Bads > previousAttempt.Bads && newUnits.Any()) { analysisResult.AddBadCanditates(newUnits.Select(u => u.Value)); } if (currentAttempt.Goods > previousAttempt.Goods) { var newGoodsCount = currentAttempt.Goods - previousAttempt.Goods; if(shuffledUnitsNew.Any()) { analysisResult.AddGoodCanditates(shuffledUnitsNew.Take(newGoodsCount)); } if (shuffledUnitsNew.Count() < newGoodsCount) { analysisResult.AddGoodCanditates(newUnits.Take(newGoodsCount - shuffledUnitsNew.Count())); } } else if (currentAttempt.Goods < previousAttempt.Goods) { var oldGoodsCount = previousAttempt.Goods - currentAttempt.Goods; if(shuffledUnitsOld.Any()) { analysisResult.AddGoodCanditates(shuffledUnitsOld.Take(oldGoodsCount)); } if (shuffledUnitsOld.Count() < oldGoodsCount) { analysisResult.AddGoodCanditates(removedUnits.Take(oldGoodsCount - shuffledUnitsOld.Count())); } } var sameUnits = currentAttempt.Number.Units.Where(u => previousAttempt.Number.Units.Any(x => x.Equals(u))); if (sameUnits.Any()) { var sameUnitsGoodCandidates = sameUnits .Where (u => !this.confirmedGoods.Any (g => g.Equals (u))); if(sameUnitsGoodCandidates.Any()) { if(!sameUnitsGoodCandidates.All(u => this.goodCandidates.Any(g => g.Equals(u)))) { throw new ApplicationException ("Error: The same units of the previous number are not all good candidates."); } if(currentAttempt.Goods >= previousAttempt.Goods) { analysisResult.AddGoodCanditates(sameUnitsGoodCandidates); foreach (var sameUnitsGoodCandidate in sameUnitsGoodCandidates) { analysisResult.RemoveBadCanditate(sameUnitsGoodCandidate.Value); this.badCandidates.Remove(sameUnitsGoodCandidate.Value); } } else { analysisResult.AddBadCanditates(sameUnitsGoodCandidates.Select(u => u.Value)); foreach (var sameUnitsGoodCandidate in sameUnitsGoodCandidates) { analysisResult.RemoveGoodCanditate(sameUnitsGoodCandidate); var goodCandidateToRemove = this.goodCandidates.FirstOrDefault (g => g.Equals (sameUnitsGoodCandidate)); this.goodCandidates.Remove(goodCandidateToRemove); } } } } var sameValues = currentAttempt.Number.Units .Where(u => !analysisResult.GoodCandidates.Any(g => g.Equals(u))) .Where(u => !analysisResult.BadCandidates.Any(b => b == u.Value)) .Where(u => previousAttempt.Number.Units.Any(x => x.Position != u.Position && x.Value == u.Value)) .Select(u => u.Value); if (sameValues.Any()) { if (currentAttempt.Regulars > 0 && currentAttempt.Regulars == previousAttempt.Regulars) { var goodCandidates = new List<INumberUnit>(); foreach (var sameValue in sameValues) { var previousPosition = previousAttempt.Number.Units.Where(u => u.Value == sameValue).Select(u => u.Position).First(); var currentPosition = currentAttempt.Number.Units.Where(u => u.Value == sameValue).Select(u => u.Position).First(); var newPosition = currentAttempt.Number.Units.Select(u => u.Position).First(p => p != previousPosition && p != currentPosition); goodCandidates.Add(new NumberUnit { Position = newPosition, Value = sameValue }); } analysisResult.AddGoodCanditates(goodCandidates); foreach (var goodCandidate in goodCandidates) { analysisResult.RemoveBadCanditate(goodCandidate.Value); this.badCandidates.Remove(goodCandidate.Value); } } } return analysisResult; }