public void GameRemoveFromCollection() { // Arrange var factory = new Games(); var gameNames = new List <String> { "player1", "player2", "player3", "player4" }; var index = factory.CreateGame(gameNames); var g = factory.GetGame(index); var index2 = factory.CreateGame(gameNames); var g2 = factory.GetGame(index); // Act factory.RemoveGame(index); // Assert Assert.Null(factory.GetGame(index)); Assert.Equal(1, factory.Count()); Assert.NotNull(factory.GetGame(index2)); Assert.False(g2.gameDone); Assert.Equal(4, g2.numberOfPlayers); Assert.NotNull(g2.players[3]); }
public void GoRightExecute() { var currentIndex = Games.IndexOf(CurrentGame); if (currentIndex == -1) { return; } if (currentIndex < Games.Count() - 1) { currentIndex++; CurrentGame = Games[currentIndex]; } else { CurrentGame = Games.FirstOrDefault(); } }
/// <summary> /// save current library and create backup of old library file /// </summary> public static void Save() { using (var tb = new TimedBlock($"Save({ GameLibraryFile })")) { try { // backup old library if (File.Exists(GameLibraryFile)) { var newBackup = Utils.Compress(File.ReadAllText(GameLibraryFile)); File.WriteAllBytes(Path.Combine(BackupDirectory, GamesLibraryFileName + $"{ BackupExtension }{ DateTime.Now.ToString(TimestampFormat) }"), newBackup); // keep only last week backup files var oldBackupFiles = Directory.GetFiles(BackupDirectory, $"*{ BackupExtension }*"); foreach (var backupToDelete in BackupsOlderThan(7)) { Log.WriteLine($"DeleteBackup({ backupToDelete })"); File.Delete(backupToDelete); } } // save current library File.WriteAllText(GameLibraryFile, Utils.GetFormattedXml(Utils.Serialize(Games))); var stats = new string[] { $"{ nameof(IgdbComData) }={ Games.Count(g => g.Value.Data.Any(d => d is IgdbComData)) }", $"{ nameof(SteamDbInfoData) }={ Games.Count(g => g.Value.Data.Any(d => d is SteamDbInfoData)) }", $"{ nameof(SteamCryoTankNetData) }={ Games.Count(g => g.Value.Data.Any(d => d is SteamCryoTankNetData)) }", $"{ nameof(SalenautsComData) }={ Games.Count(g => g.Value.Data.Any(d => d is SalenautsComData)) }", $"{ nameof(UserData) }={ Games.Count(g => g.Value.Data.Any(d => d is UserData)) }", }; Log.WriteLine($"GameDataStats(All={ Games.Count }, { string.Join(", ", stats) })"); } catch (Exception ex) { Log.WriteLine(ex.ToString()); } } }
/// <summary> /// Called when [activated]. /// </summary> /// <param name="disposables">The disposables.</param> protected override void OnActivated(CompositeDisposable disposables) { Games = gameService.Get(); previousGame = SelectedGame = Games.FirstOrDefault(s => s.IsSelected); var changed = this.WhenAnyValue(s => s.SelectedGame).Where(s => s != null && Games?.Count() > 0).Subscribe(s => { if (gameService.SetSelected(Games, s) && previousGame != s) { var args = new SelectedGameChangedEventArgs() { Game = gameService.GetSelected() }; ReactiveUI.MessageBus.Current.SendMessage(args); previousGame = s; } }).DisposeWith(disposables); activeGameRequestHandler.Subscribe(m => { if (m.Game != null) { SelectedGame = Games.FirstOrDefault(p => p.Type.Equals(m.Game.Type, StringComparison.OrdinalIgnoreCase)); } }).DisposeWith(disposables); base.OnActivated(disposables); }
public void Run(Options options, string logFolderPath) { this.options = options; // 評価関数フォルダと思考エンジンの存在確認を行う if (!File.Exists(options.Engine1FilePath)) { ShowErrorMessage("思考エンジン1が見つかりませんでした。正しいexeファイルを指定してください。"); return; } else if (!File.Exists(options.Engine2FilePath)) { ShowErrorMessage("思考エンジン2が見つかりませんでした。正しいexeファイルを指定してください。"); return; } else if (!Directory.Exists(options.Eval1FolderPath)) { ShowErrorMessage("評価関数フォルダ1が見つかりませんでした。正しい評価関数フォルダを指定してください"); return; } else if (!Directory.Exists(options.Eval2FolderPath)) { ShowErrorMessage("評価関数フォルダ2が見つかりませんでした。正しい評価関数フォルダを指定してください"); return; } else if (!File.Exists(options.SfenFilePath)) { ShowErrorMessage("開始局面ファイルが見つかりませんでした。正しい開始局面ファイルを指定してください"); return; } Status.NumGames = options.NumGames; Status.Nodes = new int[] { options.Nodes1, options.Nodes2 }; ProgressIntervalMs = options.ProgressIntervalMs; // 開始局面集を読み込む string[] openings = File.ReadAllLines(options.SfenFilePath); Console.WriteLine("Initializing engines..."); Console.Out.Flush(); Directory.CreateDirectory(logFolderPath); var sfenFilePath = Path.Combine(logFolderPath, "sfen.txt"); var sqlite3FilePath = Path.Combine(logFolderPath, "result.sqlite3"); var computerInfo = new ComputerInfo(); var previousAvailablePhysicalMemory = computerInfo.AvailablePhysicalMemory; // 各エンジンに渡すThreadIdOffsetの値を計算する際に使用するストライド // CPUの論理コア数を超えるIDが設定される場合や、 // スレッド数がエンジン1とエンジン2で異なる場合が考えられるが、 // とりあえずこの計算式で計算することにする。 int threadIdStride = Math.Max(options.NumThreads1, options.NumThreads2); for (int gameIndex = 0; gameIndex < options.NumConcurrentGames; ++gameIndex) { // 残り物理メモリサイズを調べ、エンジンの起動に必要なメモリが足りない場合、 // 警告を表示して終了する。 // 残り物理メモリ量 · Issue #13 · nodchip/TanukiColiseum https://github.com/nodchip/TanukiColiseum/issues/13 var currentAvailablePhysicalMemory = computerInfo.AvailablePhysicalMemory; var consumedMemoryPerGame = previousAvailablePhysicalMemory - currentAvailablePhysicalMemory; if (consumedMemoryPerGame > currentAvailablePhysicalMemory) { ShowErrorMessage("利用可能物理メモリが足りません。同時対局数やハッシュサイズを下げてください。"); FinishEngines(); return; } previousAvailablePhysicalMemory = currentAvailablePhysicalMemory; int numaNode = gameIndex * options.NumNumaNodes / options.NumConcurrentGames; // エンジン1初期化 Dictionary <string, string> overriddenOptions1 = new Dictionary <string, string>() { { "EvalDir", options.Eval1FolderPath }, { "USI_Hash", options.HashMb.ToString() }, { "MinimumThinkingTime", "1000" }, { "NetworkDelay", "0" }, { "NetworkDelay2", "0" }, { "EvalShare", "true" }, { "BookMoves", options.NumBookMoves1.ToString() }, { "BookFile", options.BookFileName1 }, { "Threads", options.NumThreads1.ToString() }, { "BookEvalDiff", options.BookEvalDiff1.ToString() }, { "ConsiderBookMoveCount", options.ConsiderBookMoveCount1 }, { "IgnoreBookPly", options.IgnoreBookPly1 }, { "BookDepthLimit", "0" }, { "MaxMovesToDraw", "256" }, { "ThreadIdOffset", (gameIndex * threadIdStride).ToString() }, { "LargePageEnable", "false" }, }; Console.WriteLine($"Starting an engine process. gameIndex={gameIndex} engine=1 Engine1FilePath={options.Engine1FilePath}"); Console.Out.Flush(); engine1 = new Engine(options.Engine1FilePath, this, gameIndex * 2, gameIndex, 0, numaNode, overriddenOptions1); // Windows 10 May 2019 Updateにおいて、 // 複数のプロセスが同時に大量のメモリを確保しようとしたときに // フリーズする現象を確認した // 原因がわかるまでは1プロセスずつメモリを確保するようにする // isreadyコマンド受信時にメモリが確保されることを想定する if (!engine1.Usi() || !engine1.Isready()) { ShowErrorMessage($"エンジン1が異常終了またはタイムアウトしました gameIndex={gameIndex}"); return; } // エンジン2初期化 Dictionary <string, string> overriddenOptions2 = new Dictionary <string, string>() { { "EvalDir", options.Eval2FolderPath }, { "USI_Hash", options.HashMb.ToString() }, { "MinimumThinkingTime", "1000" }, { "NetworkDelay", "0" }, { "NetworkDelay2", "0" }, { "EvalShare", "true" }, { "BookMoves", options.NumBookMoves2.ToString() }, { "BookFile", options.BookFileName2 }, { "Threads", options.NumThreads2.ToString() }, { "BookEvalDiff", options.BookEvalDiff2.ToString() }, { "ConsiderBookMoveCount", options.ConsiderBookMoveCount2 }, { "IgnoreBookPly", options.IgnoreBookPly2 }, { "BookDepthLimit", "0" }, { "MaxMovesToDraw", "256" }, { "ThreadIdOffset", (gameIndex * threadIdStride).ToString() }, { "LargePageEnable", "false" }, }; Console.WriteLine($"Starting an engine process. gameIndex={gameIndex} engine=2 Engine2FilePath={options.Engine2FilePath}"); Console.Out.Flush(); engine2 = new Engine(options.Engine2FilePath, this, gameIndex * 2 + 1, gameIndex, 1, numaNode, overriddenOptions2); if (!engine2.Usi() || !engine2.Isready()) { ShowErrorMessage($"エンジン2が異常終了またはタイムアウトしました gameIndex={gameIndex}"); return; } // ゲーム初期化 // 偶数番目はengine1が先手、奇数番目はengine2が先手 Games.Add(new Game(gameIndex & 1, options.Nodes1, options.Nodes2, options.NodesRandomPercent1, options.NodesRandomPercent2, options.NodesRandomEveryMove1, options.NodesRandomEveryMove2, options.Time1, options.Time2, options.Byoyomi1, options.Byoyomi2, options.Inc1, options.Inc2, options.Rtime1, options.Rtime2, engine1, engine2, options.NumBookMoves, openings, sfenFilePath, sqlite3FilePath, ShowErrorMessage)); } Console.WriteLine("Initialized engines..."); Console.WriteLine("Started games..."); Console.Out.Flush(); // numConcurrentGames局同時に対局できるようにする GameSemaphoreSlim = new SemaphoreSlim(options.NumConcurrentGames, options.NumConcurrentGames); var random = new Random(); for (int i = 0; i < options.NumGames; ++i) { GameSemaphoreSlim.Wait(); // 空いているゲームインスタンスを探す Game game = Games.Find(x => !x.Running); game.OnNewGame(); game.Go(); } while (Games.Count(game => game.Running) > 0) { FinishSemaphoreSlim.Wait(); } FinishEngines(); Debug.Assert(engine1 != null); Debug.Assert(engine2 != null); ShowStatus(options, Status, engine1, engine2); Directory.CreateDirectory(logFolderPath); File.WriteAllText(Path.Combine(logFolderPath, "result.txt"), CreateStatusMessage(options, Status, engine1, engine2)); }
private void DataChanged(object data) { Categories = GetAllCategories(); var catCount = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase); if (data is IEnumerable <IGame> ) { EnableThreeState = true; foreach (var game in Games) { if (game.Categories == null) { continue; } foreach (var cat in game.Categories) { if (catCount.ContainsKey(cat)) { catCount[cat] += 1; } else { catCount.Add(cat, 1); } } } foreach (var cat in Categories) { if (catCount.ContainsKey(cat.Name)) { if (catCount[cat.Name] == Games.Count()) { cat.Enabled = true; } else { cat.Enabled = null; } } } } else { EnableThreeState = false; if (Game.Categories != null) { foreach (var cat in Game.Categories) { var existingCat = Categories.FirstOrDefault(a => string.Equals(a.Name, cat, StringComparison.OrdinalIgnoreCase)); if (existingCat == null) { existingCat.Enabled = false; } else { existingCat.Enabled = true; } } } } Categories = new ObservableCollection <Category>(Categories.OrderBy(a => a.Name)); ListCategories.ItemsSource = Categories; }
private int GamesWonCount(Player player) { return(Games.Count(x => x.Winner.Equals(player))); }
public object Run(Platform machine) { try { // Lecture du fichier xml de la plateforme (verbatim) UpdateStatus?.Invoke(this, "Get infos from platform"); //var srcPlatform = XML_Platforms.Read(_SelectedPlatformXML); //string platformName = XML_Platforms.GetByTag(srcPlatform.Element("Platform"), "Name") as string; // L'objet n'est utilisé que pour avoir des données, il ne sert pas pour l'écriture if (machine.PlatformFolders.Count < 1) { UpdateStatus?.Invoke(this, "Error: this machine has no path"); return(false); } // Travail sur le fichier des plateformes string platformsFile = Path.Combine(PS.Default.LastLBpath, PS.Default.fPlatforms); WorkOnPlatformFile(platformsFile, machine.Name); // Backup datas string xmlPlateforme = Path.Combine(PS.Default.LastLBpath, PS.Default.dPlatforms, $"{machine.Name}.xml"); if (File.Exists(xmlPlateforme)) { BackupPlatformFile(xmlPlateforme); UpdateStatus?.Invoke(this, $"Backup of '{xmlPlateforme}'"); } // --- Initialisation des dossiers cible string root = Path.GetDirectoryName(Path.GetDirectoryName(machine.FolderPath)); InitTargetPaths(machine, root); int done = 0; int i = 0; foreach (Cont.FileObj game in Games) { UpdateProgressT?.Invoke(this, i); UpdateStatus?.Invoke(this, $"Work on: {game.Nom}"); string gameName = Path.GetFileNameWithoutExtension(game.Nom); string tmpPath = Path.Combine(Config.Folder, Path.GetFileNameWithoutExtension(game.Nom)); // Décompression if (Path.GetExtension(game.Path).Equals(".zip", StringComparison.OrdinalIgnoreCase)) { ZipDecompression.UnCompressArchive(game.Path, tmpPath, CancelToken); } if (CancelToken.IsCancellationRequested) { UpdateStatus?.Invoke(this, "Stopped by user"); return(false); } // Chargement des données du jeu string xmlFile = Path.Combine(tmpPath, "TBGame.xml"); XElement verbatimGame = XML_Games.GetGameNode(xmlFile); BasicGame baseGame = XML_Games.Scrap_BasicGame <BasicGame>(verbatimGame); #if DEBUG baseGame.Platform = "Sega Genesis"; #endif /* * string gameTitle = XML_Games.GetByTag(verbatimGame, "Title"); * UpdateStatus?.Invoke(this, $"Game Title: {gameTitle}"); * * string platformGame = XML_Games.GetByTag(verbatimGame, "Platform"); * UpdateStatus?.Invoke(this, $"Game for {platformGame}"); * * string gameID = XML_Games.GetByTag(verbatimGame, "ID"); * UpdateStatus?.Invoke(this, $"GameId: {gameID}");*/ // Test pour vérifier si ce sont les mêmes plateformes if (!machine.Name.Equals(baseGame.Platform)) { UpdateStatus?.Invoke(this, $"Aborded, wrong plateforme '{game.Nom}'"); i++; UpdateProgressT?.Invoke(this, i); continue; } // Copies //Copy_Images(Path.Combine(tmpPath, PS.Default.Images), TImagesP); // Copie et modifie ManageFiles(verbatimGame, tmpPath, Cst.ManualP); //Copy_TBManager(tmpPath); WorkOnGamesFile(xmlPlateforme, verbatimGame, xmlFile, baseGame); // Effacer le dossier temporaire Delete(tmpPath); //i++; UpdateProgress?.Invoke(this, 100); UpdateStatus?.Invoke(this, "Game Finished"); done++; } UpdateStatus?.Invoke(this, $"Number of games processed: {done}/{Games.Count()}"); return(true); } catch (Exception exc) { return(false); } }