private async Task RunOneGame(OneRoundTempData round) { await round.Semaphore.WaitAsync(); int[] teams; int gameId = -1; try { teams = round.SelectPlayers(simulator.NumPlayers); { await using var cmd = new NpgsqlCommand("insert into Game (round, teams, start_time) VALUES (@round, @teams, @starttime) RETURNING id", conn); cmd.Parameters.AddWithValue("round", round.Round); cmd.Parameters.AddWithValue("teams", NpgsqlTypes.NpgsqlDbType.Array | NpgsqlTypes.NpgsqlDbType.Integer, teams); Int64 unixTimestamp = (Int64)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds; cmd.Parameters.AddWithValue("starttime", unixTimestamp); gameId = (int)await cmd.ExecuteScalarAsync(); } } finally { round.Semaphore.Release(); } Console.WriteLine("Simulating game between " + String.Join(", ", teams)); GameLaunchParams launch = new GameLaunchParams(); launch.Practice = false; foreach (int team in teams) { launch.Teams.Add(new TeamData { Id = team, BinaryPath = round.Teams[team].BinaryPath }); } var result = await simulator.Launch(launch); double[] eloDeltas = Elo.ComputeEloDelta(teams.Select(t => round.Teams[t].StartingElo).ToArray(), result.Points.ToArray(), round.EloKFactor); await round.Semaphore.WaitAsync(); try { round.UpdateRatings(teams, eloDeltas, gameId, false); { await using var cmd = new NpgsqlCommand( "update Game set end_time = @endtime, scores = @scores, result_path = @resultpath, " + "elo_deltas = @elodeltas where id = @id", conn); Int64 unixTimestamp = (Int64)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds; cmd.Parameters.AddWithValue("endtime", unixTimestamp); cmd.Parameters.AddWithValue("scores", NpgsqlTypes.NpgsqlDbType.Array | NpgsqlTypes.NpgsqlDbType.Double, result.Points.ToArray()); cmd.Parameters.AddWithValue("elodeltas", NpgsqlTypes.NpgsqlDbType.Array | NpgsqlTypes.NpgsqlDbType.Double, eloDeltas); cmd.Parameters.AddWithValue("id", gameId); cmd.Parameters.AddWithValue("resultpath", result.ResultPath); await cmd.ExecuteNonQueryAsync(); } } finally { round.Semaphore.Release(); } }
public async Task <GameResults> Launch(GameLaunchParams p) { Simulator.GameRunner runner = new Simulator.GameRunner(p.Practice, _sandboxPath); var result = await runner.Run(p.Teams.Select(t => _binaryDirectory + "/" + t.BinaryPath).ToList(), random.Next()); var ret = new GameResults(); ret.Points.AddRange(result.Scores); var memoryStream = new MemoryStream(); using (ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) { var entry = archive.CreateEntry("record"); using (var entryStream = entry.Open()) { var bytes = result.ToByteArray(); entryStream.Write(bytes, 0, bytes.Length); } } var serialized = memoryStream.ToArray(); SHA256 sha = SHA256.Create(); var filename = ByteArrayToString(sha.ComputeHash(serialized)); var resultsFile = _recordsDirectory + "/" + filename; await File.WriteAllBytesAsync(resultsFile, serialized); new Mono.Unix.UnixFileInfo(resultsFile).FileAccessPermissions = Mono.Unix.FileAccessPermissions.UserRead | Mono.Unix.FileAccessPermissions.UserExecute; ret.ResultPath = filename; ret.NumTurns = result.Turns.Count; ret.NumStars.AddRange(result.NumStars); ret.CpuTime.AddRange(result.CpuTime); return(ret); }
public async Task Run() { while (true) { var tasks = new List <(int id, int team, string binary)> (); { await using var cmd = new NpgsqlCommand("select id, team, binary_path from Binaries where validation_result_path is null ORDER BY upload_time ASC", conn); await using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { tasks.Add((reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2))); } } if (tasks.Count == 0) { await Task.Delay(10000); continue; } foreach (var(id, team, binary) in tasks) { var launch = new GameLaunchParams(); launch.Practice = true; for (int i = 0; i < 2; i++) { launch.Teams.Add( new TeamData() { Id = team, BinaryPath = binary } ); } Console.WriteLine($"Practice mode: simulating game for team {team} binary {binary}"); var result = await sim.Launch(launch); bool success = result.NumStars.Sum() >= Simulator.GameState.NUM_STARS * 3 / 4; { await using var cmd = new NpgsqlCommand("update Binaries set validation_result_path = @path, validation_passed = @success where id = @id", conn); cmd.Parameters.AddWithValue("path", result.ResultPath); cmd.Parameters.AddWithValue("id", id); cmd.Parameters.AddWithValue("success", success); await cmd.ExecuteNonQueryAsync(); } } } }
public async Task <GameResults> Launch(GameLaunchParams p) { double[] scores = new double[2]; double rating_i = expected_elo[p.Teams[0].Id]; double rating_j = expected_elo[p.Teams[1].Id]; double win_rate = 1.0 / (1.0 + Math.Pow(10, (rating_j - rating_i) / 400)); if (random.NextDouble() < win_rate) { scores[0] = 1; } else { scores[1] = 1; } GameResults results = new GameResults(); results.ResultPath = "test_path"; results.Points.AddRange(scores); return(results); }