private List <Action> getLegalActions(BoardBot board, int actionType, int agent, int turnNum) { // Generate all possible actions List <Action> result = new List <Action>(); if (actionType == 1) { // return the two possible squares we can collapse into. SpookyMarkBot sm = board.toCollapse; if (sm == null) { //log error Debug.Log("ERROR: Illegal action requested from bot."); return(null); } int pos1 = sm.position1; int pos2 = sm.position2; Debug.Log("Will collapse position: " + board.squares[pos1].position); result.Add(new Action(board.squares[pos1])); result.Add(new Action(board.squares[pos2])); return(result); } // Otherwise we return all the possible spookyMarks to add // First find all possible squares we can put marks on. List <int> validSquares = new List <int>(); for (int i = 0; i < 9; i++) { SquareBot sq = board.squares[i]; if (!sq.classicallyMarked && sq.filledMarks < 8) { validSquares.Add(i); } } // If no valid squares, return null if (validSquares.Count == 0) { return(null); } // If only one valid square, duplicate it so combinations(2, count) doesn't freak out if (validSquares.Count == 1) { validSquares.Add(validSquares[0]); } foreach (int first in validSquares) { foreach (int second in validSquares) { if (second <= first) { continue; } result.Add(new Action(first, second)); } } return(result); }
private int evalState(BoardBot board) { int Xscore = evalplayer(board, 0); int Oscore = -evalplayer(board, 1); return(Xscore + Oscore); }
public virtual void PerformInteraction(Board board, BoardBot bot, Direction direction, IDiamondGeneratorService DiamondGenerator) { PerformInteraction(board, bot, direction); }
public BoardBot(BoardBot b, GameManagerBot gameManager) { this.gameManager = gameManager; SquareBot[] s = b.squares; SquareBot[] sb = new SquareBot[s.Length]; for (int i = 0; i < s.Length; i++) { sb[i] = new SquareBot(gameManager, s[i]); } List<SpookyMarkBot> smb = new List<SpookyMarkBot>(); foreach (SpookyMarkBot sm in b.spookyMarks) { smb.Add(new SpookyMarkBot(sm)); } List<MarkBot> mb = new List<MarkBot>(); foreach (MarkBot m in b.currentSpookyMark) { mb.Add(new MarkBot(m)); } List<int> collapsed = new List<int>(b.collapsed); if (b.toCollapse == null) { this.init(new GraphBot(b.entGraph, gameManager), sb, smb, collapsed, null, mb, b.nextAction); } else { this.init(new GraphBot(b.entGraph, gameManager), sb, smb, collapsed, new SpookyMarkBot(b.toCollapse), mb, b.nextAction); } }
private BoardBot generateSuccessor(BoardBot board, int agent, Action action) { numCopies++; GameManagerBot gmCopy = new GameManagerBot(board.gameManager); BoardBot copy = gmCopy.board; action.performAction(copy); return(copy); }
public void executeTurn(int actionType, int turnNum) { numCopies = 0; GameManagerBot gmCopy = new GameManagerBot(gameManager); BoardBot copy = gmCopy.board; Action act = getNextMove(copy, actionType, startDifficulty, turnNum); act.performAction(actualBoard); Debug.Log("Made " + numCopies + " copies."); }
// Start is called before the first frame update public void init(int currentPlayer, int turnNum, int numMarks, bool won, bool draw, BoardBot board) { this.currentPlayer = currentPlayer; this.turnNum = turnNum; this.numMarks = numMarks; this.won = won; this.draw = draw; this.board = board; }
private void AttemptDeliverInBase(Position position, BoardBot bot) { var positionIsOwnBase = position.Equals(bot.Base); if (positionIsOwnBase == false) { return; } bot.Score += bot.Diamonds; bot.Diamonds = 0; }
public Action getNextMove(BoardBot board, int actionType, int difficulty, int turnNum) { List <Action> legalmoves = getLegalActions(board, actionType, 1, turnNum); // 1 means bot List <int> Scores = new List <int>(); if (legalmoves == null) { return(new Action()); } int alpha = int.MinValue; int beta = int.MaxValue; Debug.Log("Number of legal moves: " + legalmoves.Count); foreach (Action i in legalmoves) { if (i.actionType == actionType) { BoardBot successor = generateSuccessor(board, 1, i); Debug.Log(i); int val = getValue(successor, 1, difficulty, alpha, beta); if (val < alpha) { break; } beta = beta < val ? beta : val; Debug.Log("Score: " + val); Scores.Add(val); } } int min = Scores.Min(); int index = Scores.IndexOf(min); // Build a list of indices of all min scores List <int> minScoreIndices = new List <int>(); for (int i = 0; i < Scores.Count; i++) { int s = Scores[i]; if (s == min) { minScoreIndices.Add(i); } } // Now randomly choose one from the min scores return(legalmoves[minScoreIndices[Random.Range(0, minScoreIndices.Count)]]); }
public override void PerformInteraction(Board board, BoardBot bot, Direction direction) { BaseGameObject targetTeleporter = board.GameObjects.Where(gf => gf is Teleporter && (gf as Teleporter).LinkedTeleporterString == this.LinkedTeleporterString && !this.Position.Equals(gf.Position)).FirstOrDefault(); if (targetTeleporter == null) { return; } if (targetTeleporter != null && !board.IsPositionBlocked(targetTeleporter.Position)) { bot.Position = targetTeleporter.Position; } }
private void AttemptPickUpDiamond(Position position, Board board, BoardBot bot) { bool positionHasDiamond = board.Diamonds.Any(p => p.Equals(position)); bool hasLessThanFiveDiamond = bot.Diamonds < 5; bool shouldPickUpDiamond = positionHasDiamond && hasLessThanFiveDiamond; if (shouldPickUpDiamond == false) { return; } bot.Diamonds += 1; board.Diamonds = board.Diamonds .Where(p => p.Equals(position) == false) .ToList(); // TODO: Remember to generate new diamonds when the total diamond count is too low. We don't know yet where this should be in the code. //In general update method in board, to also regenerate other objects? }
public void performAction(BoardBot board) { if (actionType == 0) { board.squares[p1].addMark(); board.squares[p2].addMark(); } else if (actionType == 1) { SpookyMarkBot toCollapse = board.toCollapse; int positionToCollapse = sqBot.position; if (positionToCollapse == toCollapse.position1) { board.collapse(1); } else if (positionToCollapse == toCollapse.position2) { board.collapse(2); } } }
private int getValue(BoardBot board, int agent, int depth, int alph, int beta) { int winner = board.checkWin(); if (winner == 0) { return(int.MaxValue); } else if (winner == 1) { return(int.MinValue); } else if (depth == 0) { return(evalState(board)); } if (agent == 0) { return(maxValue(board, agent, depth - 1, alph, beta)); } return(minValue(board, agent, depth - 1, alph, beta)); }
private int minValue(BoardBot board, int agent, int depth, int alph, int beta) { List <Action> legalmoves = getLegalActions(board, board.nextAction, agent, gameManager.getTurnNum() + startDifficulty - depth); int v = int.MaxValue; if (legalmoves == null) { return(v); } foreach (Action action in legalmoves) { BoardBot successor = generateSuccessor(board, 1, action); int newVal = getValue(successor, (agent + 1) % 2, depth, alph, beta); v = v < newVal ? v : newVal; if (v < alph) { return(v); } beta = beta < v ? beta : v; } return(v); }
private void AttemptPickUpDiamond(Position position, Board board, BoardBot bot) { bool positionHasDiamond = board.Diamonds.Any(p => p.Equals(position)); if (positionHasDiamond == false) { return; } DiamondPosition diamond = board.Diamonds.First(p => p.Equals(position)); bool hasEnoughSpace = bot.Diamonds <= (5 - diamond.Points); if (hasEnoughSpace == false) { return; } bot.Diamonds += diamond.Points; board.Diamonds = board.Diamonds .Where(p => p.Equals(position) == false) .ToList(); // TODO: Remember to generate new diamonds when the total diamond count is too low. We don't know yet where this should be in the code. }
private void RemoveBot(BoardBot bot, Board board) { var removed = board.Bots.Remove(bot); _storage.UpdateBoard(board); }
/** * Currently untriggerable. * Will be needed once walls, etc, * are incorporated into the board. */ private bool CanMoveToPosition(Board board, BoardBot bot, Position position) { return(PositionIsInBoard(position, board) && PositionIsOpponentBase(position, bot.BotId, board.Bots) == false && PositionHasBot(position, board.Bots) == false); }
private void AttemptTriggerGameObject(Board board, Direction direction, Position attemptedNextPosition, BoardBot bot, IDiamondGeneratorService generator) { var gameObject = board.GameObjects.Where(gf => gf.Position.Equals(attemptedNextPosition)). DefaultIfEmpty(new DoNothingGameObject()).FirstOrDefault(); gameObject.PerformInteraction(board, bot, direction, generator); }
private bool CanMoveToPosition(Board board, BoardBot bot, Position position) { return(PositionIsInBoard(position, board) && PositionIsOpponentBase(position, bot.BotId, board.Bots) == false && board.IsPositionBlocked(position) == false); //Includes bots and GameObjects which return true for blockable. }
private async Task RemoveBotAsync(BoardBot bot, Board board) { var removed = board.Bots.Remove(bot); await _storage.UpdateBoardAsync(board); }
public abstract void PerformInteraction(Board board, BoardBot bot, Direction direction );
private int evalplayer(BoardBot board, int agent) { // return Score int score = 0; agent++; // Look through every square for (int i = 0; i < 9; i++) { //Debug.Log("Square " + i + ": "); SquareBot sq = board.squares[i]; if (sq.classicallyMarked && sq.finalPlayer != agent) { continue; } List <int> neighbors = getNeighbor(i); // Look into every neighbor foreach (int k in neighbors) { int gain = 0; SquareBot neigh = board.squares[k]; // Always good to be next to your own classical mark if (neigh.classicallyMarked && neigh.finalPlayer == agent) { gain += 100; } // Always good to have empty neighbor. More chance for expansion. else if (neigh.filledMarks == 0) { gain += 5; } // Last case is when neighbor has spooky marks else { // more marks means more competition. Gotta win! gain += 10 * neigh.presentMarks.Count; // Penalize if spooky mark is the opponent foreach (MarkBot m in neigh.presentMarks) { if (m.player == agent) { gain += 2; } if (m.player != agent) { gain -= 5; } } } if (sq.classicallyMarked) { gain *= 2; } score += gain; } } return(score); }
public override void PerformInteraction(Board board, BoardBot bot, Direction Direction) { //No interaction, just block. }