/*private int FindBestAttack(laneContents lane){ * float[] confidence = new float[current_hand.Count]; * int bestCard = 0; * float bestConfidence = -10.0f; * if(lane.state == LaneState.Empty) * { * for(int i = 0; i < current_hand.Count; i++){ * Card card = current_hand[i].GetComponent<Card>(); * confidence[i] = 0.1f * card.health; * confidence[i] += 0.1f * card.attack_power; * confidence[i] += 0.2f * (card.casting_time + card.attack_time); * if(confidence[i] > bestConfidence) * { * bestCard = i; * bestConfidence = confidence[i]; * } * } * } * else * { * * for(int i = 0; i < current_hand.Count; i++){ * Card card = current_hand[i].GetComponent<Card>(); * * * if(lane.defencePower != 0.0f) * confidence[i] = 0.1f * Mathf.Floor(card.health / lane.defencePower); * else * confidence[i] = -0.1f * card.health; * * if(card.attack_power != 0.0f) * confidence[i] -= 0.1f * Mathf.Floor(lane.health / card.attack_power); * else * confidence[i] -= 0.1f * lane.health; * * * if(card.casting_time + card.attack_time < lane.timeUntilCast + lane.timeUntilDefence) * { * confidence[i] += 0.2f; * } * if(confidence[i] > bestConfidence){ * bestCard = i; * bestConfidence = confidence[i]; * } * } * } * return bestCard; * }*/ void FixedUpdate() { // Make a decision every interval, with a bit of random delay so it seems more human if (Time.time > timeUntilNextDecision) { AIDecision choice = makeDecision(); if (choice == AIDecision.draw) { AIDraw(); } else if ((int)choice >= (int)AIDecision.defend1) { AIPlayAttacker((int)choice - 6, current_hand [0] .GetComponent <Card>()); } else if ((int)choice >= (int)AIDecision.attack1) { AIPlayAttacker((int)choice - 1, current_hand [0] .GetComponent <Card>()); } timeUntilNextDecision = Time.time + decisionTimer + decisionDelay + Random.Range(0.0f, decisionUncertainty); decisionTimer = 0.0f; } }
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.")); }
public async Task <AIDecision> Hint(GameInfo gameInfo, GamePlayer player, GameTree tree, StoneColor color) { var aiTask = Task.Run(() => Program.GetHint(new AiGameInformation(gameInfo, color, player, tree))); AIDecision decision = await aiTask; return(decision); }
private void ChooseBestDecision() { DecisionBest = null; PoorDecisions.Clear(); float weightMax = 0; // Debug.Log("decisions count: " + decisions.Count); foreach (var decision in Decisions) { // Debug.LogFormat(decision.weight.ToString()); if (decision.Weight > weightMax) { weightMax = decision.Weight; DecisionBest = decision; } if (decision.Weight > 0 && decision.Weight < weightMax) { if (LogDecisionsInfo) { Debug.Log("player " + Owner.PlayerNumber + " almost best decision weight: " + decision.Weight); } PoorDecisions.Add(decision); } } if (DecisionBest != null) { if (DecisionBest.BeginPlanet == DecisionBest.TargetPlanet) { Debug.Log("same planet!"); } if (LogDecisionsInfo) { Debug.Log("player " + Owner.PlayerNumber + " best decision weight: " + DecisionBest.Weight); Debug.Log("player " + Owner.PlayerNumber + " best decision type: " + DecisionBest.Type.ToString()); } // chould we release units from a couple planets? if (DecisionBest.BeginPlanets != null && DecisionBest.BeginPlanets.Count > 1) { // Debug.Log("releasing from multiple"); foreach (var b in DecisionBest.BeginPlanets) { b.Spawner.ReleaseUnits(DecisionBest.TargetPlanet.gameObject); } } else { // Debug.Log("releasing from one"); DecisionBest.BeginPlanet.Spawner.ReleaseUnits(DecisionBest.TargetPlanet.gameObject); } // mark planets which were already targeted if (DecisionBest.TargetPlanet.Owner.PlayerNumber == -1) { PlanetsToBeCaptured.Add(DecisionBest.TargetPlanet); } } // else // Debug.Log("no best decision"); }
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)); }
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.")); }
public override async void PleaseMakeAMove() { GameTreeNode respondingToWhatNode = GameState.GameTree.LastNode; var aiTask = Task.Run(() => _aiProgram.RequestMove(new AiGameInformation( GameInfo, Color, GameState.Players[Color], GameState.GameTree ))); AIDecision decision = await aiTask; foreach (var aiNote in decision.AiNotes) { SendAiNote(aiNote); } if (respondingToWhatNode != GameState.GameTree.LastNode) { // Ignore. That result is now obsolete. _aiProgram.YourMoveWasRejected(); return; } switch (decision.Kind) { case AgentDecisionKind.Move: if (decision.Move.Kind == MoveKind.PlaceStone) { OnPlaceStone(decision.Move.Coordinates); } else { OnPass(); } break; case AgentDecisionKind.Resign: OnResign(); break; default: throw new Exception("This decision kind does not exist."); } }
private async void GetHint() { AIDecision hint = await Assistant.Hint(this.Game.Info, this.Game.Controller.TurnPlayer, this.Game.Controller.GameTree, this.Game.Controller.TurnPlayer.Info.Color); string content = ""; string title = ""; if (hint != null) { switch (hint.Kind) { case AgentDecisionKind.Resign: title = LocalizedStrings.YouShouldResign; content = LocalizedStrings.ResignExplanation.Replace("\\n", Environment.NewLine) + " " + hint.Explanation; break; case AgentDecisionKind.Move: title = hint.Move.ToString(); if (hint.Move.Kind == MoveKind.Pass) { content = LocalizedStrings.YouShouldPassExplanation.Replace("\\n", Environment.NewLine) + " " + hint.Explanation; } else { content = String.Format(LocalizedStrings.YouShouldPlayExplanation.Replace("\\n", Environment.NewLine), hint.Move.Coordinates) + " " + hint.Explanation; } break; } } else { title = LocalizedStrings.HintUnavailable; content = LocalizedStrings.HintUnavailableExplanation; } await DialogService.ShowAsync(content, title); }
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.")); }
public static AIDecision StartDecision(SetupRouter sr, Monster monster) { AIDecision decision = new AIDecision(0, 0, 0); switch (monster.level) { default: break; case AILevel.Random: int movePool = 4; if (monster.ActionSet.Count < movePool) { movePool = monster.ActionSet.Count; } decision.moveIndex = GetRandomValue(movePool); decision.targetOtherIndex = GetRandomValue(sr.director.GetLunenCountOut(Director.Team.PlayerTeam)); decision.targetSelfIndex = GetRandomValue(sr.director.GetLunenCountOut(Director.Team.EnemyTeam)); break; } return(decision); }
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.")); }
public void PerformAction(AIDecision decision) { sr.canvasCollection.EnemySelfTarget = decision.targetSelfIndex; sr.canvasCollection.EnemyOtherTarget = decision.targetOtherIndex; PerformAction(decision.moveIndex); }
/// <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.")); }
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); }
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); }
public AIDecision CalculateTotalScore(Character Self, ItemSkill SkillToScore) // Note : The Skill Part of Context is optional. Beware, that Considerations that use the Skill cannot be used for Move Pattern Scoring! { // Base Score: AIDecision Decision = new AIDecision { TargetCharacter = null, Score = 1, ConsiderationsCounter = 0 }; CharacterEnemy User = (CharacterEnemy)(Self); List <Character> PlayersInAttentionRange = User.GetAttention().GetPlayersInAttentionRange(); if (PlayersInAttentionRange.Count <= 0) { Decision.Score = 0; return(Decision); } // Score of Self Targeted Considerations: Consideration.Context TempContext = new Consideration.Context { Skill = SkillToScore, User = Self, Target = Self }; for (int i = 0; i < ConsiderationsSelf.Length; i++) { Decision.Score = Decision.Score * ConsiderationsSelf[i].CalculateScore(TempContext); } Decision.ConsiderationsCounter += ConsiderationsSelf.Length; // Score of Targeted Considerations: float TempScore = 1; float TempBestScore = 0; // Calculate Score of Skill with each Player as target: for (int plT = 0; plT < PlayersInAttentionRange.Count; plT++) { TempScore = 1; TempContext.Target = PlayersInAttentionRange[plT]; for (int i = 0; i < ConsiderationsTargeted.Length; i++) { TempScore = TempScore * ConsiderationsTargeted[i].CalculateScore(TempContext); } if (TempScore > TempBestScore) { TempBestScore = TempScore; Decision.TargetCharacter = TempContext.Target; } } Decision.Score *= TempBestScore; Decision.ConsiderationsCounter += ConsiderationsTargeted.Length; // Compensation based on number of multiplications: if (Decision.ConsiderationsCounter > 0) { float ModFactor = 1 - (1 / (float)(Decision.ConsiderationsCounter)); float CompensationValue = (1 - Decision.Score) * ModFactor; Decision.Score += CompensationValue * Decision.Score; } Decision.Score *= Weight; //Debug.Log("TOTAL SCORE: " + Decision.Score); return(Decision); }