private int Minimax(int _depth, int _value, bool _IsMainPlayer, GameStage _stage, int _alpha, int _beta, PlayerName _mainPlayer) { if (_depth <= 0) { return(_value); } if (_IsMainPlayer) { int best = MIN_VALUE; for (int i = 0; i < _stage.PosiblePosition.Count; i++) { var nextStage = _stage.Clone(); nextStage.SelectPosition(_stage.PosiblePosition[i]); var wonPlayer = nextStage.CheckWonPlayer(); var reward = _mainPlayer == wonPlayer ? 2 : 1; _value += wonPlayer != PlayerName.None ? reward : 0; nextStage.SetNextPlayer(); int value = Minimax(_depth - 1, _value, false, _stage, _alpha, _beta, _mainPlayer); best = Math.Max(best, value); _alpha = Math.Max(_alpha, best); if (_beta <= _alpha) { break; } } return(best); } else { int best = MAX_VALUE; for (int i = 0; i < _stage.PosiblePosition.Count; i++) { var nextStage = _stage.Clone(); nextStage.SelectPosition(_stage.PosiblePosition[i]); _value += nextStage.CheckWonPlayer() != PlayerName.None ? 1 : 0; int value = Minimax(_depth - 1, _value, true, _stage, _alpha, _beta, _mainPlayer); best = Math.Min(best, value); _beta = Math.Min(_beta, best); if (_beta <= _alpha) { break; } } return(best); } }
// ------------------------------------------------------------------------------------- // Private Funtion private Position FindBestSolution(GameStage _stage) { var isMinimax = _stage.Players[0] != _stage.CurrentTurn; var bestList = new List <Position>(); bestList.Add(_stage.RandomPosition()); var bestValue = isMinimax ? MAX_VALUE : MIN_VALUE; var bestPos = _stage.RandomPosition(); for (int i = 0; i < _stage.PosiblePosition.Count; i++) { var nextStage = _stage.Clone(); nextStage.SelectPosition(_stage.PosiblePosition[i]); nextStage.SetNextPlayer(); var value = Minimax(3, 0, false, nextStage, MIN_VALUE, MAX_VALUE, _stage.CurrentTurn); if (isMinimax) { if (bestValue > value) { bestList = new List <Position>(); bestValue = value; bestPos = _stage.PosiblePosition[i]; bestList.Add(_stage.PosiblePosition[i]); } else if (bestValue == value) { bestList.Add(_stage.PosiblePosition[i]); } } else { if (bestValue < value) { bestList = new List <Position>(); bestValue = value; bestPos = _stage.PosiblePosition[i]; bestList.Add(_stage.PosiblePosition[i]); } else if (bestValue == value) { bestList.Add(_stage.PosiblePosition[i]); } } } return(bestList[UnityEngine.Random.Range(0, bestList.Count)]); }
private IObservable <bool> OnTurnProcessAsObservable() { return(Observable.Create <bool> ( _observer => { _CanStartNextTurn = false; var gameStage = GetGameStage(); var player = GetPlayer(); _OnBeginTurn?.Invoke(gameStage.CurrentTurn); Debug.Log(gameStage.CurrentTurn); if (gameStage.Status == StageStatus.MatchOver) { _observer.OnNext(true); _observer.OnCompleted(); } var disposable = player.MakeDicision(gameStage, m_GameTime).Subscribe(_position => { if (_position == Position.None) { _position = gameStage.RandomPosition(); } gameStage.SelectPosition(_position); _OnGameSelected?.Invoke(new ActionInfo(player.PlayerName, _position)); _TurnCount++; var nextStage = new GameStage(_BoardSize, gameStage.BoardData, _PlayersName, GetPlayerName()); while (_GameStageList.Count >= _TurnCount) { _GameStageList.RemoveAt(_GameStageList.Count - 1); } _GameStageList.Add(nextStage); _observer.OnNext(false); _observer.OnCompleted(); }).AddTo(this); return Disposable.Create(() => { _CanStartNextTurn = true; disposable?.Dispose(); }); } )); }
// ------------------------------------------------------------------------------------- // Public Funtion public abstract IObservable <Position> MakeDicision(GameStage _stage, GameTime _gameTime);