void FastGameInSecondThread() { var state = _currentStateInSecondThread; int turnWithExceptionCount = 0; GameForm.GameInSecondThreadIsRunning = true; while (!state.IsFinished) { Turn firstPlayerTurn = GetTurnFromProgramExecuter(state, state.players[0]); if (firstPlayerTurn != null && firstPlayerTurn.TurnStatus == ExternalProgramExecuteResult.InternalError) { turnWithExceptionCount++; } Turn secondPlayerTurn = GetTurnFromProgramExecuter(state, state.players[1]); if (secondPlayerTurn != null && secondPlayerTurn.TurnStatus == ExternalProgramExecuteResult.InternalError) { turnWithExceptionCount++; } bool stopGame = GameForm.UserWantsToClose; if (turnWithExceptionCount >= 2) { var dialogResult = MessageBox.Show("Внешняя программа несколько раз завершилась с ошибкой. Остановить игру? Да = остановить, Нет = продолжить до следующей ошибки, Отмена = продолжить до конца игры, не обращая внимания на ошибки", "Внимание", MessageBoxButtons.YesNoCancel); if (dialogResult == DialogResult.No) { turnWithExceptionCount = 1; } else if (dialogResult == DialogResult.Yes) { stopGame = true; } else { turnWithExceptionCount = -1000000; } } SimultaneousTurn turn = new SimultaneousTurn(); turn.FirstPlayerTurn = firstPlayerTurn; turn.SecondPlayerTurn = secondPlayerTurn; //записываем ход и проигрываем его, чтоб можно было дальше программы вызывать _engine.DoTurn(ref state, turn); recordedTurns.TryAdd(state.turn, turn); state.turn++; if (state.turn == Const.NumberOfTurns || stopGame) { state.IsFinished = true; } } Thread.Sleep(500); //чтобы удалить темп, надо подождать, пока программы отдадут права на редактирование директории GameForm.GameInSecondThreadIsRunning = false; //сохраним игру полностью string file = startTime.ToString("yy-MM-dd-hh-mm-ss") + "-" + (state.players[0].programAddress == null ? "человек" : Path.GetFileNameWithoutExtension(state.players[0].programAddress)) + "-" + (state.players[1].programAddress == null ? "человек" : Path.GetFileNameWithoutExtension(state.players[1].programAddress)) + "-" + state.players[0].Score.ToString() + "-" + state.players[1].Score.ToString(); bool success = TrySaveReplay(Application.StartupPath + "\\..\\Replays\\" + file + ".rpl"); ExternalProgramExecuter.DeleteTempSubdir(); }
Turn GetTurnFromProgramExecuter(State state, Player player) { ExternalProgramExecuter epe = new ExternalProgramExecuter(player.programAddress, "input.txt", "output.txt", _javaPath); bool reflected = player.Owner == OwnerType.Player1 ? false : true; Turn ret = new Turn(); string input = ret.input = GetInput(state, player, reflected ? state.players[0] : state.players[1]); string output; string comment; try { ExternalProgramExecuteResult res = epe.Execute(input, 2, out output, out comment); //пустой файл допускается if (res == ExternalProgramExecuteResult.EmptyOutput) { output = ""; res = ExternalProgramExecuteResult.Ok; } ret.TurnStatus = res; if (res == ExternalProgramExecuteResult.Ok) { ret.rawOutput = output; StringReader reader = new StringReader(output); string linexxx; List <string> lines = new List <string>(); while (!string.IsNullOrEmpty(linexxx = reader.ReadLine())) { lines.Add(linexxx); } player.Memory = null; if (lines.Count > 0 && lines.Last().Contains("memory")) { ret.memory = lines.Last(); lines.RemoveAt(lines.Count - 1); player.Memory = ret.memory.Replace("memory", ""); } for (int i = 0; i < lines.Count; i++) { string line = lines[i]; var command = new Turn.Command(); try { string[] temp = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); command.type = (Turn.CommandType)(Convert.ToInt32(temp[0])); for (int j = 1; j < temp.Length; j++) { command.arguments.Add(Convert.ToInt32(temp[j])); } if ((command.type == Turn.CommandType.Buy && command.arguments.Count < 3) || (command.type == Turn.CommandType.Start && command.arguments.Count < 2) || (command.type == Turn.CommandType.Remove && command.arguments.Count < 1)) { throw new Exception(); } //нарушение логики проверяется в Engine //не надо ничего писать в коммент, если команда хорошая // command.comment = "ok"; } catch { command.type = Turn.CommandType.Error; command.comment = "неверный формат"; } ret.commands.Add(command); } } } catch (ApplicationException err) { return(ret); } return(ret); }