/// <summary> /// Find best move async /// </summary> /// <returns></returns> protected override Task MakeTurnAsync() { Action action = () => { if (PlayersTurn == TicTacToe.Turn.PlayerX) { _computer = Board.ElementType.X; _opponent = Board.ElementType.O; } else { _isFirstTurn = false; _computer = Board.ElementType.O; _opponent = Board.ElementType.X; } var bestMove = new Move(); if (_isFirstTurn) { bestMove = Move.Random(0, 3, 0, 3); _isFirstTurn = false; } else { var maxDepth = 0; switch (_difficulty) { case DifficultyType.Easy: maxDepth = 1; break; case DifficultyType.Medium: maxDepth = 4; break; case DifficultyType.Hard: maxDepth = 7; break; default: break; } bestMove = FindBestMove(CurrentBoard, maxDepth); } BestMoveFound.Invoke(bestMove); }; var task = Task.Factory.StartNew(action); return(task); }
private void OnBestMoveFound(BestMoveParams bestMoveParams, EvaluatedMove evaluatedMove) { if (null == evaluatedMove) { throw new ArgumentNullException(nameof(evaluatedMove)); } if (evaluatedMove != bestMoveParams.BestMove) { BestMoveFound?.Invoke(this, new BestMoveFoundEventArgs(evaluatedMove.Move, evaluatedMove.Depth, evaluatedMove.ScoreAfterMove)); bestMoveParams.BestMove = evaluatedMove; } }
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (string.IsNullOrWhiteSpace(e.Data)) { return; } string command; string[] output; if (e.Data.Contains(" ")) { int indexOfSpace = e.Data.IndexOf(' '); command = e.Data.Substring(0, indexOfSpace); string data = e.Data.Substring(indexOfSpace + 1); if (data.Contains(" ")) { output = data.Split(' '); } else { output = new string[1]; output[0] = data; } } else { command = e.Data; output = null; } switch (command) { case "id": switch (output[0]) { case "name": Name = e.Data.Substring(8); break; case "author": Author = e.Data.Substring(10); break; } break; case "uciok": _autoResetEvent.Set(); break; case "readyok": _autoResetEvent.Set(); break; case "bestmove": BestMoveFound?.Invoke(e.Data.Substring(9)); break; case "copyregistration": break; case "registration": break; case "info": string[] infoComponents = output; List <InfoType> types = new List <InfoType>(); List <string> values = new List <string>(); bool isCurrMove = true; for (int i = 0; i < infoComponents.Length; i++) { if (infoComponents[i] == "pv") { isCurrMove = false; break; } } int currentType = -1; string currentInfoData = ""; for (int i = 0; i < infoComponents.Length; i++) { bool infoType = false; for (int typeI = 0; typeI < _infoTypeNames.Length; typeI++) { if (infoComponents[i] == _infoTypeNames[typeI]) { if (currentInfoData != "" && currentType != -1) { OutputDataInfoReceived?.Invoke(isCurrMove, currentInfoData, (InfoType)currentType); } if (!isCurrMove) { types.Add((InfoType)currentType); values.Add(currentInfoData); } currentType = typeI; currentInfoData = ""; infoType = true; break; } } if (!infoType) { currentInfoData += $"{infoComponents[i]} "; } } OutputDataInfoReceived?.Invoke(isCurrMove, currentInfoData, (InfoType)currentType); if (!isCurrMove) { types.Add((InfoType)currentType); values.Add(currentInfoData); Evaluation evaluation = new Evaluation(types.ToArray(), values.ToArray()); EvaluationReceived?.Invoke(evaluation); } break; case "option": string option = e.Data.Substring(12); if (!_options.Contains(option)) { _options.Add(e.Data.Substring(12)); } break; } }