コード例 #1
0
ファイル: Fluffy.cs プロジェクト: omegaGoTeam/omegaGo.Core
        public override AIDecision RequestMove(AiGameInformation gameInformation)
        {
            var moves = gameInformation.GameTree.PrimaryMoveTimeline.ToList();

            if (moves.Any() &&
                moves.Last().Kind == MoveKind.Pass)
            {
                return(AIDecision.MakeMove(Move.Pass(gameInformation.AIColor), "You passed, too!"));
            }

            JokerGame currentGame = new JokerGame(gameInformation.GameInfo.BoardSize.Height,
                                                  gameInformation.GameInfo.BoardSize.Width,
                                                  null,
                                                  null);

            foreach (Move move in gameInformation.GameTree.PrimaryMoveTimeline)
            {
                currentGame.moves.AddLast(new JokerMove(move.WhoMoves == StoneColor.Black ? 'B' : 'W',
                                                        new JokerPoint(move.Coordinates.X, move.Coordinates.Y)));
            }

            currentGame.board = JokerExtensionMethods.OurBoardToJokerBoard(GetLastNodeOrEmptyBoard(gameInformation.GameTree).BoardState, gameInformation.GameInfo.BoardSize);

            JokerPoint point = new AlphaBetaPlayer(gameInformation.AIColor == StoneColor.Black ? 'B' : 'W').betterPlanMove(currentGame, this.TreeDepth);


            return(AIDecision.MakeMove(Move.PlaceStone(gameInformation.AIColor, new Position(point.x, point.y)),
                                       "I chose using the minimax algorithm and heuristics."));
        }
コード例 #2
0
ファイル: OldFuego.cs プロジェクト: omegaGoTeam/omegaGo.Core
        private void FixHistory(AiGameInformation aiGameInformation)
        {
            // Initialize if not yet.
            if (!this._initialized)
            {
                Initialize(aiGameInformation);
                this._initialized = true;
            }

            // Fix history.
            var trueHistory = aiGameInformation.GameTree.PrimaryMoveTimeline.ToList();

            for (int i = 0; i < trueHistory.Count; i++)
            {
                if (this._history.Count == i)
                {
                    var trueMove = trueHistory[i];
                    this._history.Add(trueMove);
                    string moveDescription = trueMove.Coordinates.ToIgsCoordinates();
                    if (trueMove.Kind == MoveKind.Pass)
                    {
                        moveDescription = "PASS";
                    }

                    SendCommand("play " + (trueMove.WhoMoves == StoneColor.Black ? "B" : "W") + " " + moveDescription);
                }
            }
        }
コード例 #3
0
        public AIDecision RequestMove(Fuego fuego, AiGameInformation gameInformation)
        {
            var action = FuegoAction.ThatReturnsAiDecision(() => TrueRequestMove(fuego, gameInformation));

            EnqueueAction(action);
            return(action.GetAiDecisionResult());
        }
コード例 #4
0
ファイル: OldFuego.cs プロジェクト: omegaGoTeam/omegaGo.Core
        /// <summary>
        ///     Requests a move from Fuego
        /// <para>
        /// This is called ASYNCHRONOUSLY by the AI agent.
        /// </para>
        /// </summary>
        /// <param name="gameInformation">Information about the requested move and the game</param>
        /// <returns>Decision</returns>
        public override AIDecision RequestMove(AiGameInformation gameInformation)
        {
            OldFuegoAction action = new FuegoSpace.OldFuegoAction(this, () => TrueRequestMove(gameInformation));

            EnqueueAction(action);
            return(action.GetAiDecisionResult());
        }
コード例 #5
0
        public async Task <IEnumerable <Position> > GetIsolatedDeadPositions(Fuego fuego, GameController gameController)
        {
            var action = FuegoAction.ThatReturnsGtpResponse(() =>
            {
                var information = new AiGameInformation(gameController.Info, StoneColor.Black,
                                                        gameController.Players.Black, gameController.GameTree);
                TrueInitialize(information);
                FixHistory(information);
                // Set the player's strength
                if (_lastMaxGames != fuego.MaxGames)
                {
                    SendCommand("uct_param_player max_games " + fuego.MaxGames);
                    _lastMaxGames = fuego.MaxGames;
                }
                var result = SendCommand("final_status_list dead");
                return(result);
            });

            EnqueueAction(action);
            var response = await action.GetGtpResponseAsync();

            var positions = response.Text.Split(new[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            var mark      = new List <Position>();

            foreach (string position in positions)
            {
                mark.Add(Position.FromIgsCoordinates(position));
            }
            return(mark);
        }
コード例 #6
0
        private void FixHistory(AiGameInformation aiGameInformation)
        {
            // Fix history.
            var trueHistory = aiGameInformation.GameTree.PrimaryTimeline.ToList();

            for (int i = 0; i < trueHistory.Count; i++)
            {
                if (this._history.Count == i)
                {
                    var trueNode = trueHistory[i];
                    foreach (var pos in trueNode.AddBlack)
                    {
                        SendCommand("play B " + pos.ToIgsCoordinates());
                    }
                    foreach (var pos in trueNode.AddWhite)
                    {
                        SendCommand("play W " + pos.ToIgsCoordinates());
                    }
                    if (trueNode.Move != null && trueNode.Move.Kind != MoveKind.None)
                    {
                        var trueMove = trueNode.Move;
                        this._history.Add(trueMove);
                        string moveDescription = trueMove.Coordinates.ToIgsCoordinates();
                        if (trueMove.Kind == MoveKind.Pass)
                        {
                            moveDescription = "PASS";
                        }
                        SendCommand("play " + (trueMove.WhoMoves == StoneColor.Black ? "B" : "W") + " " +
                                    moveDescription);
                    }
                }
            }
        }
コード例 #7
0
        public void MovePerformed(AiGameInformation aiGameInformation)
        {
            var action = new FuegoAction(() =>
            {
                FixHistory(aiGameInformation);
            });

            EnqueueAction(action);
        }
コード例 #8
0
        /// <summary>
        /// Schedules the initialization of Fuego for a game.
        /// </summary>
        public void Initialize(AiGameInformation gameInformation)
        {
            var init = new FuegoAction(() =>
            {
                TrueInitialize(gameInformation);
            });

            EnqueueAction(init);
        }
コード例 #9
0
 public override AIDecision RequestMove(AiGameInformation gameInformation)
 {
     if (_brokenDueToInvalidLaunch)
     {
         return(AIDecision.Resign(
                    "Fuego already plays in another game. Fuego may only play in one game at a time."));
     }
     RequireInitialization(gameInformation);
     return(FuegoSingleton.Instance.RequestMove(this, gameInformation));
 }
コード例 #10
0
        public override AIDecision RequestMove(AiGameInformation gameInformation)
        {
            RandomPlayer internalPlayer = new RandomPlayer(gameInformation.AIColor == StoneColor.Black ? 'B' : 'W');

            char[,] board = JokerExtensionMethods.OurBoardToJokerBoard(GetLastNodeOrEmptyBoard(gameInformation.GameTree).BoardState, gameInformation.GameInfo.BoardSize);
            JokerPoint point = internalPlayer.makeMove(board, gameInformation.GameInfo.BoardSize.Width, gameInformation.GameInfo.BoardSize.Height);

            return(AIDecision.MakeMove(Move.PlaceStone(gameInformation.AIColor, new Position(point.x, point.y)),
                                       "I chose at random."));
        }
コード例 #11
0
ファイル: OldFuego.cs プロジェクト: omegaGoTeam/omegaGo.Core
        private void Initialize(AiGameInformation gameInformation)
        {
            this._engine = AISystems.FuegoBuilder.CreateEngine(gameInformation.GameInfo.BoardSize.Width);

            // Board size
            SendCommand("boardsize " + gameInformation.GameInfo.BoardSize.Width);


            // Rules
            switch (gameInformation.GameInfo.RulesetType)
            {
            case RulesetType.AGA:
            case RulesetType.Chinese:
                SendCommand("go_rules chinese");
                SendCommand("go_param_rules japanese_scoring 0");
                break;

            case RulesetType.Japanese:
                SendCommand("go_rules japanese");
                SendCommand("go_param_rules japanese_scoring 1");
                break;
            }
            SendCommand("komi " + gameInformation.GameInfo.Komi.ToString(CultureInfo.InvariantCulture));


            // Strength
            SendCommand("uct_param_player ponder " + (this.Ponder ? "1" : "0"));
            if (this.MaxGames > 0)
            {
                SendCommand("uct_param_player max_games " + this.MaxGames);
            }

            if (!this.AllowResign)
            {
                SendCommand("uct_param_player resign_threshold 0");
            }

            // TODO (future work) Petr: on IGS, make it so two passes don't end a game

            // Time settings
            string timeSettings = gameInformation.AiPlayer.Clock.GetGtpInitializationCommand();

            if (timeSettings != null)
            {
                SendCommand(timeSettings);
            }

            // Regardless of time controls, we are never willing to wait more than 15 seconds.
            SendCommand("go_param timelimit 15");

            // Print beginning info
            Note("Komi set to " + SendCommand("get_komi").Text);
            DebuggingNote("Random seed is " + SendCommand("get_random_seed").Text);
            SendCommand("go_param_rules");
        }
コード例 #12
0
        public AIDecision GetIsolatedHint(Fuego fuego, AiGameInformation gameInformation)
        {
            var action = FuegoAction.ThatReturnsAiDecision(() =>
            {
                TrueInitialize(gameInformation);
                return(TrueRequestMove(fuego, gameInformation));
            });

            EnqueueAction(action);
            return(action.GetAiDecisionResult());
        }
コード例 #13
0
 /// <summary>
 /// Taking effect only once per game, this method initializes the <see cref="FuegoSingleton"/> by setting the correct
 /// game rule parameters (such as chinese vs. japanese).
 /// This is only used by <see cref="MovePerformed(Move, GameTree, GamePlayer, GameInfo)"/> and <see cref="RequestMove(AiGameInformation)"/> which are only used when this is an actual player in a game.
 /// </summary>
 /// <param name="aiGameInformation">The ai game information.</param>
 private void RequireInitialization(AiGameInformation aiGameInformation)
 {
     if (!_initialized)
     {
         _initialized = true;
         if (_isPrimaryPlayer)
         {
             FuegoSingleton.Instance.Initialize(aiGameInformation);
         }
     }
 }
コード例 #14
0
        public AIDecision GetHint(Fuego fuego, AiGameInformation gameInformation)
        {
            var action = FuegoAction.ThatReturnsAiDecision(() =>
            {
                var result = TrueRequestMove(fuego, gameInformation);
                UndoOneMove();
                return(result);
            });

            EnqueueAction(action);
            return(action.GetAiDecisionResult());
        }
コード例 #15
0
ファイル: OldFuego.cs プロジェクト: omegaGoTeam/omegaGo.Core
        /// <summary>
        /// Gets a hint from the AI.
        /// <para>
        /// This is called ASYNCHRONOUSLY by the assistant.
        /// </para>
        /// </summary>
        /// <param name="gameInformation"></param>
        /// <returns></returns>
        public override AIDecision GetHint(AiGameInformation gameInformation)
        {
            var action = new OldFuegoAction(this, () =>
            {
                var result = TrueRequestMove(gameInformation);
                UndoOneMove();
                return(result);
            });

            EnqueueAction(action);
            return(action.GetAiDecisionResult());
        }
コード例 #16
0
 public override AIDecision GetHint(AiGameInformation gameInformation)
 {
     if (FuegoSingleton.Instance.CurrentGame == null)
     {
         return(FuegoSingleton.Instance.GetIsolatedHint(this, gameInformation));
     }
     else
     {
         if (FuegoSingleton.Instance.CurrentGame.Info.Equals(gameInformation.GameInfo))
         {
             return(FuegoSingleton.Instance.GetHint(this, gameInformation));
         }
         else
         {
             // Fuego is playing elsewhere, we cannot get hints.
             return(null);
         }
     }
 }
コード例 #17
0
        /// <summary>
        /// Initializes Fuego for a game, by setting board size, rules and time control.
        /// </summary>
        /// <param name="gameInformation">The game information.</param>
        private void TrueInitialize(AiGameInformation gameInformation)
        {
            // Clear locals
            _history     = new List <Move>();
            _storedNotes = new List <string>();

            // Board size
            SendCommand("boardsize " + gameInformation.GameInfo.BoardSize.Width);

            // Rules
            switch (gameInformation.GameInfo.RulesetType)
            {
            case RulesetType.AGA:
            case RulesetType.Chinese:
                SendCommand("go_rules chinese");
                SendCommand("go_param_rules japanese_scoring 0");
                break;

            case RulesetType.Japanese:
                SendCommand("go_rules japanese");
                SendCommand("go_param_rules japanese_scoring 1");
                break;
            }

            // Komi
            SendCommand("komi " + gameInformation.GameInfo.Komi.ToString(CultureInfo.InvariantCulture));

            // Time settings
            string timeSettings = gameInformation.AiPlayer.Clock.GetGtpInitializationCommand();

            if (timeSettings != null)
            {
                SendCommand(timeSettings);
            }

            // Regardless of time controls, we are never willing to wait more than 15 seconds.
            SendCommand("go_param timelimit 15");

            // Print beginning info
            Debug.WriteLine("AI: Komi set to " + SendCommand("get_komi").Text);
            Debug.WriteLine("AI: Random seed is " + SendCommand("get_random_seed").Text);
        }
コード例 #18
0
ファイル: RandomAI.cs プロジェクト: omegaGoTeam/omegaGo.Core
        public override AIDecision RequestMove(AiGameInformation preMoveInformation)
        {
            var moves = preMoveInformation.GameTree.PrimaryMoveTimeline.ToList();

            if (moves.Any() &&
                moves.Last().Kind == MoveKind.Pass)
            {
                return(AIDecision.MakeMove(Move.Pass(preMoveInformation.AIColor), "You passed, too!"));
            }

            GameBoard createdBoard = GameBoard.CreateBoardFromGameTree(preMoveInformation.GameInfo, preMoveInformation.GameTree);

            MoveResult[,] moveResults =
                Ruleset.Create(
                    preMoveInformation.GameInfo.RulesetType,
                    preMoveInformation.GameInfo.BoardSize, CountingType.Area).GetMoveResult(GetLastNodeOrEmptyBoard(preMoveInformation.GameTree));
            List <Position> possibleIntersections = new List <Position>();

            for (int x = 0; x < preMoveInformation.GameInfo.BoardSize.Width; x++)
            {
                for (int y = 0; y < preMoveInformation.GameInfo.BoardSize.Height; y++)
                {
                    if (moveResults[x, y] == MoveResult.Legal)
                    {
                        possibleIntersections.Add(new Position(x, y));
                    }
                }
            }

            if (possibleIntersections.Count == 0)
            {
                // TODO (future): The AI should probably pass, not resign.
                return(AIDecision.Resign("There are no more moves left to do."));
            }

            Position chosen = possibleIntersections[Randomizer.Next(possibleIntersections.Count)];

            return(AIDecision.MakeMove(Move.PlaceStone(preMoveInformation.AIColor, chosen), "I chose at random."));
        }
コード例 #19
0
        public override AIDecision RequestMove(AiGameInformation gameInformation)
        {
            DateTime whenEndWaiting = DateTime.Now.AddSeconds(2);

            while (DateTime.Now < whenEndWaiting)
            {
                // Active waiting.
            }
            if (gameInformation.Node == null)
            {
                return(AIDecision.MakeMove(Move.PlaceStone(gameInformation.AIColor, new Position(0, 0)), "The board is empty so I'll just play at A1."));
            }
            for (int y = 0; y < gameInformation.GameInfo.BoardSize.Height; y++)
            {
                for (int x = 0; x < gameInformation.GameInfo.BoardSize.Width; x++)
                {
                    if (gameInformation.Node.BoardState[x, y] == StoneColor.None)
                    {
                        return(AIDecision.MakeMove(Move.PlaceStone(gameInformation.AIColor, new Position(x, y)), "I always place stones in the first point that's unoccupied."));
                    }
                }
            }
            return(AIDecision.MakeMove(Move.Pass(gameInformation.AIColor), "Board is full. This should never happen."));
        }
コード例 #20
0
ファイル: OldFuego.cs プロジェクト: omegaGoTeam/omegaGo.Core
        private AIDecision TrueRequestMove(AiGameInformation gameInformation)
        {
            FixHistory(gameInformation);

            // Move for what color?
            string movecolor = gameInformation.AIColor == StoneColor.Black ? "B" : "W";

            // Update remaining time
            var timeLeftArguments = gameInformation.AiPlayer.Clock.GetGtpTimeLeftCommandArguments();

            if (timeLeftArguments != null)
            {
                int secondsRemaining = timeLeftArguments.NumberOfSecondsRemaining;
                secondsRemaining = Math.Max(secondsRemaining - 2, 0);
                // let's give the AI less time to ensure it does its move on time
                SendCommand("time_left " + movecolor + " " + secondsRemaining + " " +
                            timeLeftArguments.NumberOfStonesRemaining);
            }

            // Generate the next move
            string result = SendCommand("genmove " + movecolor).Text;

            if (result == "resign")
            {
                var resignDecision = AIDecision.Resign("Resigned because of low win chance.");
                resignDecision.AiNotes = this._storedNotes;
                this._storedNotes.Clear();
                return(resignDecision);
            }
            var move = result == "PASS"
                ? Move.Pass(gameInformation.AIColor)
                : Move.PlaceStone(gameInformation.AIColor, Position.FromIgsCoordinates(result));

            // Change history
            this._history.Add(move);

            // Get win percentage
            string commandResult = SendCommand("uct_value_black").Text;
            float  value         = float.Parse(commandResult, CultureInfo.InvariantCulture);

            if (gameInformation.AIColor == StoneColor.White)
            {
                value = 1 - value;
            }
            string winChanceNote = (Math.Abs(value) < OldFuego.ComparisonTolerance) ||
                                   (Math.Abs(value - 1) < OldFuego.ComparisonTolerance)
                ? "Reading from opening book."
                : "Win chance (" + gameInformation.AIColor + "): " + 100 * value + "%";

            Note(winChanceNote);
            var moveDecision = AIDecision.MakeMove(
                move, winChanceNote);

            moveDecision.AiNotes = this._storedNotes.ToList(); // copy

            // Prepare the way
            this._storedNotes.Clear();

            // Return result
            return(moveDecision);
        }
コード例 #21
0
 public void MovePerformed(Move move, AiGameInformation aiGameInformation)
 {
     Program.MovePerformed(move, aiGameInformation.GameTree, aiGameInformation.AiPlayer,
                           aiGameInformation.GameInfo);
 }
コード例 #22
0
 /// <summary>
 /// Requests a move from the AI
 /// </summary>
 /// <param name="gameInformation">Move request info</param>
 /// <returns>AI decision</returns>
 public override AIDecision RequestMove(AiGameInformation gameInformation)
 {
     return(AIDecision.Resign("I could have won but I decided to let you win."));
 }
コード例 #23
0
        private AIDecision TrueRequestMove(Fuego fuego, AiGameInformation gameInformation)
        {
            FixHistory(gameInformation);

            // Set whether a player can resign
            bool allowResign = fuego.AllowResign && gameInformation.GameInfo.NumberOfHandicapStones == 0;

            if (allowResign != this._lastAllowResign)
            {
                this._lastAllowResign = allowResign;
                if (!allowResign)
                {
                    SendCommand("uct_param_player resign_threshold 0");
                }
            }

            // Set whether a player can ponder
            if (!_ponderSet)
            {
                SendCommand("uct_param_player ponder " + (fuego.Ponder ? "1" : "0"));
                _ponderSet = true;
            }

            // Set the player's strength
            if (_lastMaxGames != fuego.MaxGames)
            {
                SendCommand("uct_param_player max_games " + fuego.MaxGames);
                _lastMaxGames = fuego.MaxGames;
            }

            // Move for what color?
            string movecolor = gameInformation.AIColor == StoneColor.Black ? "B" : "W";

            // Update remaining time
            var timeLeftArguments = gameInformation.AiPlayer.Clock.GetGtpTimeLeftCommandArguments();

            if (timeLeftArguments != null)
            {
                int secondsRemaining = timeLeftArguments.NumberOfSecondsRemaining;
                secondsRemaining = Math.Max(secondsRemaining - 2, 0);
                // let's give the AI less time to ensure it does its move on time
                SendCommand("time_left " + movecolor + " " + secondsRemaining + " " +
                            timeLeftArguments.NumberOfStonesRemaining);
            }

            // Generate the next move
            string result = SendCommand("genmove " + movecolor).Text;

            if (result == "resign")
            {
                var resignDecision = AIDecision.Resign("Resigned because of low win chance.");
                resignDecision.AiNotes = this._storedNotes;
                this._storedNotes.Clear();
                return(resignDecision);
            }
            var move = result == "PASS"
                ? Move.Pass(gameInformation.AIColor)
                : Move.PlaceStone(gameInformation.AIColor, Position.FromIgsCoordinates(result));

            // Change history
            this._history.Add(move);

            // Get win percentage
            string commandResult = SendCommand("uct_value_black").Text;
            float  value         = float.Parse(commandResult, CultureInfo.InvariantCulture);

            if (gameInformation.AIColor == StoneColor.White)
            {
                value = 1 - value;
            }
            string winChanceNote = (Math.Abs(value) < ComparisonTolerance) ||
                                   (Math.Abs(value - 1) < ComparisonTolerance)
                ? "Reading from opening book."
                : "Win chance (" + gameInformation.AIColor + "): " + 100 * value + "%";

            Debug.WriteLine(winChanceNote);
            var moveDecision = AIDecision.MakeMove(
                move, winChanceNote);

            moveDecision.AiNotes = this._storedNotes.ToList(); // copy

            // Prepare the way
            this._storedNotes.Clear();

            // Return result
            return(moveDecision);
        }