public Position() { Field = new XoField(); Field.F = new byte[3, 3]; Evaluation = 255; Next = new List<Position>(); }
public XoMove GetMove(XoField field) { var root = AnalysePosition(field); // Создаём список вариантов var moves = new List<XoMove>(); foreach (var nextChoice in root.Next) { // Если оценки совпали это лучший ход if (nextChoice.Evaluation == root.Evaluation) { // Ищем что же за ход это был var move = new XoMove { line = 255, column = 255 }; for (byte i = 0; i <= 2; i++) { for (byte j = 0; j <= 2; j++) { if (nextChoice.Field.F[i, j] != root.Field.F[i, j]) { move.line = i; move.column = j; } } } moves.Add(move); } } // Выбираем случайный var rnd1 = new Random(); var randMoveIndex = rnd1.Next(0, moves.Count - 1); return moves[randMoveIndex]; }
public Position AnalysePosition(XoField field) { // Построение дерева // Создаём корневой узел var root = new Position {Field = {F = field.F}}; // Создаём дерево CreatePositionsBranches(root); return root; }
public Position(Position source) { Field = new XoField(); Field.F = new byte[3, 3]; for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { Field.F[i, j] = source.Field.F[i, j]; } } Evaluation = 255; Next = new List<Position>(); }
// Следующий ход делают: 1 - X; 2 - O private byte DetectMove(XoField field) { byte xcol = 0, ocol = 0; for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { switch (field.F[i, j]) { case 1: xcol++; break; case 2: ocol++; break; } } } return (byte)((xcol > ocol) ? 2 : 1); }
private void EnginesTest() { var engines = GetXoGameEngines(); var engineInfo1 = ChooseEngine(engines, "Выберите первый игровой движок: ", true); var engineInfo2 = ChooseEngine(engines, "Выберите второй игровой движок: ", false); Console.Write("Введите количество туров: "); var roundQuantity = int.Parse(Console.ReadLine()); var engine1 = LoadEngine(engineInfo1); var engine2 = LoadEngine(engineInfo2); int engine1Wins = 0, // Побед первого движка engine2Wins = 0, // Побед второго движка engine1Faults = 0, // Ошибок первого движка engine2Faults = 0, // Ошибок второго движка draws = 0; // Ничьих var engineMove = new XoMove(); byte correctMoves; for (int i = 1; i < (roundQuantity * 2) + 1; i++) { _field = new XoField {F = new byte[,] {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; do { correctMoves = 0; switch (DetectMove(_field)) { case 1: // X engineMove = i % 2 == 1 ? engine1.GetMove(_field) : engine2.GetMove(_field); break; case 2: // O engineMove = i % 2 == 1 ? engine2.GetMove(_field) : engine1.GetMove(_field); break; } if (CheckMove(engineMove, _field)) MakeMove(engineMove); else correctMoves = (byte)(((DetectMove(_field)) == 1) ? ((i % 2 == 1) ? 1 : 2) : ((i % 2 == 1) ? 2 : 1)); } while ((Finished == 3) && (correctMoves == 0)); if (correctMoves != 0) { if (correctMoves == 1) // Ошибся 1-й движок engine1Faults++; else // Второй engine2Faults++; } else { switch (Finished) { case 0: draws++; break; case 1: if (i%2 == 1) { engine1Wins++; } else { engine2Wins++; } break; case 2: if (i%2 == 1) { engine2Wins++; } else { engine1Wins++; } break; } } Console.Clear(); Console.WriteLine("Всего игр = {0}.", i); Console.WriteLine("Ничьих = {0}", draws); Console.WriteLine("Побед {0} = {1}", engineInfo1.Name, engine1Wins); Console.WriteLine("Побед {0} = {1}", engineInfo2.Name, engine2Wins); Console.WriteLine("Ошибок {0} = {1}", engineInfo1.Name, engine1Faults); Console.WriteLine("Ошибок {0} = {1}", engineInfo2.Name, engine2Faults); } Console.ReadKey(); }
private static bool CheckMove(XoMove engineMove, XoField field) { return field.F[engineMove.line, engineMove.column] == 0; }