예제 #1
0
 public void RegisterWin(IGameAgent player)
 {
     ++gameAmount;
     if (player != null)
     {
         ++playerToWinAmounts[player];
         ++playerToLosAmounts[player.opponent];
     }
     else
     {
         ++drawAmount;
     }
     if (gameAmount % 1000 == 999)
     {
         string            s          = string.Empty;
         List <IGameAgent> gameAgents = new List <IGameAgent>(playerToWinAmounts.Keys);
         foreach (IGameAgent gameAgent in gameAgents)
         {
             s += $"{gameAgent.GetName()}: wins: {playerToWinAmounts[gameAgent]} - losses: {playerToLosAmounts[gameAgent]}\n";
             playerToWinAmounts[gameAgent] = 0;
             playerToLosAmounts[gameAgent] = 0;
         }
         Debug.Log($"{s}Draws: {drawAmount}\n");
         drawAmount = 0;
     }
 }
예제 #2
0
 protected float GetScore(Board board, IGameAgent gameAgent, float alpha = float.MinValue, float beta = float.MaxValue, int depth = int.MaxValue)
 {
     Game.State gameState = game.GetState(board, gameAgent);
     if (gameState != Game.State.playing || depth == 0)
     {
         return(game.GetScore(board, gameAgent, gameState));
     }
     else
     {
         float           score         = float.MinValue;
         List <Position> possibleMoves = game.GetPossibleMoves(board, gameAgent);
         for (int i = 0; i < possibleMoves.Count; ++i)
         {
             Board newBoard = new Board(board, gameAgent, possibleMoves[i]);
             if (i == 0)
             {
                 score = -GetScore(newBoard, gameAgent.opponent, -beta, -alpha, depth - 1);
             }
             else
             {
                 score = -GetScore(newBoard, gameAgent.opponent, -alpha - 1, -alpha, depth - 1);
             }
             if (alpha < score && score < beta)
             {
                 score = -GetScore(newBoard, gameAgent.opponent, -beta, -score, depth - 1);
             }
             alpha = Mathf.Max(alpha, score);
             if (beta <= alpha)
             {
                 break;
             }
         }
         return(alpha);
     }
 }
예제 #3
0
    public Position BestNodeSearch(Board board, IGameAgent gameAgent, float alpha = float.MinValue, float beta = float.MaxValue, int depth = int.MaxValue)
    {
        List <Position> possibleMoves     = game.GetPossibleMoves(game.board, this);
        Position        bestMove          = possibleMoves.GetRandom();
        int             subtreeCount      = possibleMoves.Count;
        int             betterMovesAmount = 0;

        do
        {
            float testValue = Guess(alpha, beta, subtreeCount);
            betterMovesAmount = 0;
            for (int i = 0; i < possibleMoves.Count; ++i)
            {
                float moveValue = -TTNegaMaxAlphaBeta(new Board(game.board, this, possibleMoves[i]), opponent, -testValue, -testValue + 1);
                if (testValue <= moveValue)
                {
                    ++betterMovesAmount;
                    bestMove = possibleMoves[i];
                }
            }
            if (betterMovesAmount == 0)
            {
                beta = testValue;
            }
            else
            {
                subtreeCount = betterMovesAmount;
                alpha        = testValue;
            }
        }while (2 < beta - alpha && betterMovesAmount != 1);
        return(bestMove);
    }
예제 #4
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
    protected void NextMove()
    {
        if (isTrainingGame)
        {
            activeGameAgent = activeGameAgent.opponent;
            switch (activeGameAgent.GetPlayer())
            {
            case GameAgent.Player.agent:
                activeGameAgent.RequestMove();
                break;

            case GameAgent.Player.human:
                //wait for input
                break;

            case GameAgent.Player.random:
                DoMove(GetPossibleMoves(board, activeGameAgent).GetRandom());
                break;
            }
        }
        else
        {
            StartCoroutine(NextMoveCoroutine());
        }
    }
예제 #5
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
    protected IEnumerator Begin()
    {
        if (randomStartingPlayer)
        { /* randomize players */
            int playerIndex0 = Random.Range(0, players.Length);
            players.Swap(0, playerIndex0);
            int playerIndex1 = Random.Range(0, players.Length);
            while (playerIndex0 == playerIndex1)
            {
                playerIndex1 = Random.Range(0, players.Length);
            }
            players.Swap(1, playerIndex1);
        }

        yield return(new WaitUntil(() => players[0].isReady && players[1].isReady));

        board.Clear();
        userInterface?.Clear();
        activeGameAgent = players[0];

        players[0].id       = -1;
        players[1].id       = +1;
        players[0].opponent = players[1];
        players[1].opponent = players[0];
        players[0].HandleOnGameBegin();
        players[1].HandleOnGameBegin();

        NextMove();
    }
예제 #6
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
    protected void UndoMove()
    {
        Position position = moves[board.moveIndex];

        board.SetState(position, 0);
        --board.moveIndex;
        userInterface?.UndoMove(position);
        activeGameAgent = activeGameAgent.opponent;
    }
예제 #7
0
 private void StopAndRemoveAgent(IGameAgent agent)
 {
     foreach (var agentItem in mGameAgentList)
     {
         if (agent == agentItem)
         {
             agent.Stop();
             mGameAgentList.Remove(agent);
             break;
         }
     }
 }
예제 #8
0
    public override float GetReward(Game.State gameState, Board board, IGameAgent gameAgent)
    {
        switch (gameState)
        {
        case Game.State.win:
            return(+(1 - (board.moveIndex - 4) / 5f));

        case Game.State.draw:
            return(0.1f);

        case Game.State.loss:
            return(-(1 - (board.moveIndex - 4) / 5f));

        default:
            return(0);
        }
    }
예제 #9
0
    public override float GetReward(Game.State gameState, Board board, IGameAgent gameAgent)
    {
        switch (gameState)
        {
        case Game.State.win:
            return(1 - 0.5f * board.moveIndex / 9.0f);

        case Game.State.draw:
            return(0.01f);

        case Game.State.loss:
            return(-1 + 0.5f * board.moveIndex / 9.0f);

        default:
            return(0);
        }
    }
예제 #10
0
 protected float GetScore(Board board, IGameAgent gameAgent, int depth = int.MaxValue)
 {
     Game.State gameState = game.GetState(board, gameAgent);
     if (gameState != Game.State.playing || depth == 0)
     {
         return(game.GetScore(board, gameAgent, gameState));
     }
     else
     {
         float           score         = float.MinValue;
         List <Position> possibleMoves = game.GetPossibleMoves(board, gameAgent);
         for (int i = 0; i < possibleMoves.Count; ++i)
         {
             score = Mathf.Max(score, -GetScore(new Board(board, gameAgent, possibleMoves[i]), gameAgent.opponent, depth - 1));
         }
         return(score);
     }
 }
예제 #11
0
        private IGameAgent CreateGameAgent(SGameRoomItem item)
        {
            IGameAgent agent = null;

            switch (item.HostType)
            {
            case enGameHostType.IPC:
            {
                break;
            }

            case enGameHostType.Scene:
            {
                string strPrefix = item.GameNameID.ToString();
                if (strPrefix.Length > 6)
                {
                    strPrefix = strPrefix.Substring(0, 6);
                }

                int prefix = int.Parse(strPrefix);
                if (mGameAssemblies.ContainsKey(prefix))
                {
                    var impl = mGameAssemblies[prefix];
                    var obj  = Activator.CreateInstance(impl);
                    agent = obj as IGameAgent;
                }
                else
                {
                    throw new NotImplementedException("no implemented found by gameid:" + item.GameNameID);
                }

                break;
            }

            case enGameHostType.Socket:
            {
                break;
            }
            }

            return(agent);
        }
예제 #12
0
    protected float GetScore(Board board, IGameAgent gameAgent, float alpha = float.MinValue, float beta = float.MaxValue, int depth = int.MaxValue)
    {
        if (cache.ContainsKey(board.GetBitMask(gameAgent.id).bits))
        {
            if (cache[board.GetBitMask(gameAgent.id).bits].ContainsKey(board.GetBitMask(-gameAgent.id).bits))
            {
                return(cache[board.GetBitMask(gameAgent.id).bits][board.GetBitMask(-gameAgent.id).bits]);
            }
        }
        else
        {
            cache.Add(board.GetBitMask(gameAgent.id).bits, new Dictionary <ulong, float>());
        }

        float score = float.MinValue;;

        Game.State gameState = game.GetState(board, gameAgent);
        if (gameState != Game.State.playing || depth == 0)
        {
            score = game.GetScore(board, gameAgent, gameState);
        }
        else
        {
            List <Position> possibleMoves = game.GetPossibleMoves(board, gameAgent);
            for (int i = 0; i < possibleMoves.Count; ++i)
            {
                score = Mathf.Max(score, -GetScore(new Board(board, gameAgent, possibleMoves[i]), gameAgent.opponent, -beta, -alpha, depth - 1));
                beta  = Mathf.Max(score, beta);
                if (beta <= alpha)
                {
                    break;
                }
            }
        }

        if (depth != 0) //don't cache a heuristic score
        {
            cache[board.GetBitMask(gameAgent.id).bits].Add(board.GetBitMask(-gameAgent.id).bits, score);
        }

        return(score);
    }
예제 #13
0
 protected float GetScore(Board board, IGameAgent gameAgent, float alpha = float.MinValue, float beta = float.MaxValue, int depth = int.MaxValue)
 {
     Game.State gameState = game.GetState(board, gameAgent);
     if (gameState != Game.State.playing || depth == 0)
     {
         return(game.GetScore(board, gameAgent, gameState));
     }
     else
     {
         float           score         = float.MinValue;
         List <Position> possibleMoves = game.GetPossibleMoves(board, gameAgent);
         //--- Killer heuristic ---
         for (int i = 0; i < possibleMoves.Count; ++i)
         {
             if (killers.Contains(possibleMoves[i]))
             {
                 Position move = possibleMoves[i];
                 possibleMoves.RemoveAt(i);
                 possibleMoves.Insert(0, move);
             }
         }
         //-------------------------
         for (int i = 0; i < possibleMoves.Count; ++i)
         {
             score = Mathf.Max(score, -GetScore(new Board(board, gameAgent, possibleMoves[i]), gameAgent.opponent, -beta, -alpha, depth - 1));
             beta  = Mathf.Max(score, beta);
             if (beta <= alpha)
             {
                 //--- Killer heuristic ---
                 killers.Enqueue(possibleMoves[i]);
                 if (2 < killers.Count)
                 {
                     killers.Dequeue();
                 }
                 //-------------------------
                 break;
             }
         }
         return(score);
     }
 }
예제 #14
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
    protected IEnumerator NextMoveCoroutine()
    {
        activeGameAgent = activeGameAgent.opponent;
        yield return(new WaitForSeconds(0.1f));

        switch (activeGameAgent.GetPlayer())
        {
        case GameAgent.Player.agent:
            activeGameAgent.RequestMove();
            break;

        case GameAgent.Player.human:
            //wait for input
            break;

        case GameAgent.Player.random:
            DoMove(GetPossibleMoves(board, activeGameAgent).GetRandom());
            break;
        }
        yield break;
    }
예제 #15
0
    protected float GetScore(Board board, IGameAgent gameAgent, int depth = int.MaxValue)
    {
        float guess      = GuessScore(board, gameAgent);
        float lowerBound = float.MinValue;
        float upperBound = float.MaxValue;

        while (lowerBound < upperBound)
        {
            float beta = Mathf.Max(guess, lowerBound + 1);
            guess = TTNegaMaxAlphaBeta(board, gameAgent, beta - 1, beta, depth);
            if (guess < beta)
            {
                upperBound = guess;
            }
            else
            {
                lowerBound = guess;
            }
        }
        return(guess);
    }
 public SudokuSocketMiddleware(IGameAgent gameAgent, RequestDelegate next)
 {
     _gameAgent = gameAgent ?? throw new ArgumentNullException(nameof(gameAgent));
     _next      = next ?? throw new ArgumentNullException(nameof(next));
 }
예제 #17
0
 public float GetReward(Game.State gameState, Board board, IGameAgent gameAgent)
 {
     Debug.LogError("AlgorithmAgent.GetReward(...): this function should not be used");
     return 0;
 }
예제 #18
0
 public override float GuessScore(Board board, IGameAgent gameAgent)
 {
     return(+1 - board.moveIndex / 10f);
 }
예제 #19
0
 public abstract float GetReward(Game.State gameState, Board board, IGameAgent gameAgent);
예제 #20
0
 public abstract float GuessScore(Board board, IGameAgent gameAgent);
예제 #21
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
 public abstract float GetScore(Board board, IGameAgent gameAgent, State gameState);
예제 #22
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
 public abstract State GetState(Board board, IGameAgent gameAgent);
예제 #23
0
파일: Game.cs 프로젝트: Ro2Be/BoardGameAI
 public abstract List <Position> GetPossibleMoves(Board board, IGameAgent gameAgent);