public bool PlayAutomated(bool pauseOnTurn) { AutoTurns++; var random = new Random(); var randomChance = random.Next(10); GameLogEntry logEntry = NewLogEntry(); int column = -1; var boardSearch = new BoardSearch(numberToWin); var legalMoves = boardSearch.FindAllLegalMoves(board); if (legalMoves.Count == 0) { return(EndTurn(logEntry, -1, pauseOnTurn)); } if (boardSearch.IsBoardEmpty(board)) { //Console.WriteLine("Random move. "); column = random.Next(6); } else { var strategy = PlayerTurn == 1 ? strategy1 : strategy2; var depth = PlayerTurn == 1 ? Player1SearchDepth : GetSearchDepth(AutoTurns); column = strategy.Run(board, numberToWin, PlayerTurn, depth); } return(EndTurn(logEntry, column, pauseOnTurn, true)); }
public int Run(Board board, int numToWin, int playerNumber, int searchDepth = 8) { Random rand = new Random(); var test = rand.Next(0, 2); if (test == 0) { var search = new BoardSearch(numToWin); var legalMoves = search.FindAllLegalMoves(board); var allColumns = legalMoves.Select(p => p.Col).ToList(); if (!allColumns.Any()) { return(-1); } var index = rand.Next(allColumns.Count() - 1); return(allColumns[index]); } else { var strat = new MinMaxStrategy(); return(strat.Run(board, numToWin, playerNumber)); } }
public bool DoesPlayer1HaveZugzwang(Board board) { //find threats, label even or odd var boardSearch = new BoardSearch(4); var groups = boardSearch.FindGroups(1, board, 1); var hasOddThreat = groups.Select(g => g.Coords.Any(t => t.Row % 2 != 0)).Any(); return(hasOddThreat); }
public int Run(Board board, int numToWin, int playerNumber, int searchDepth = 8) { BoardSearch boardSearch = new BoardSearch(numToWin); var boardToEvaluate = new Board(board.MAX_COL_INDEX, board.MAX_ROW_INDEX); int[,] matrix = (int[, ])board.Matrix.Clone(); boardToEvaluate.Matrix = matrix; Player[,] boardState = BoardToPlayerBoard(boardToEvaluate, playerNumber); var columnToPlay = -1; Connect4State state = new Connect4State(boardState, (Player)playerNumber); try { var searchResult = searchEngine.Search(state, searchDepth); var newBoard = (Connect4State)searchResult.NextMove; for (var r = 0; r <= board.MAX_ROW_INDEX; r++) { for (var c = 0; c <= board.MAX_COL_INDEX; c++) { var value = boardState[r, c]; var newValue = newBoard.Board[r, c]; if (value != newValue) { columnToPlay = c; } } } } catch (NoNeighborsException e) { var legalMoves = boardSearch.FindAllLegalMoves(boardToEvaluate); Random rand = new Random(); columnToPlay = legalMoves[rand.Next(legalMoves.Count - 1)].Col; } return(columnToPlay); }
public int Run(Board board, int numToWin, int playerNumber = 2) { PLAYERNUM = playerNumber; var search = new BoardSearch(numToWin); var legalMoves = search.FindAllLegalMoves(board); var yourThreats = search.FindGroups(PLAYERNUM, board, 1); var oppThreats = search.FindGroups(1, board, 1); int?columnToPlay = 0; //can you win? columnToPlay = MatchThreatsWithLegal(yourThreats, legalMoves); if (columnToPlay.HasValue) { return(columnToPlay.Value); } //should you block? columnToPlay = MatchThreatsWithLegal(oppThreats, legalMoves); if (columnToPlay.HasValue) { return(columnToPlay.Value); } //are there hidden forks for player 1? //look for threats with 2 blanks var forkThreats = search.FindGroups(1, board, 2); //do any threats share a blank? var forkPositions = new List <Position>(); for (var i = 0; i < forkThreats.Count; i++) { var ft = forkThreats[i]; var blanks = ft.Coords.Where(c => c.Mark == 0); for (var j = 0; j < forkThreats.Count; j++) { if (j == i) { continue; } var jft = forkThreats[j]; var jBlanks = jft.Coords.Where(c => c.Mark == 0); var shared = jBlanks.Intersect <Position>(blanks, new PositionEqualityComparer()); forkPositions.AddRange(shared); } } //are any blanks legal moves? columnToPlay = MatchPositionsThreatsWithLegal(forkPositions, legalMoves); if (columnToPlay.HasValue) { return(columnToPlay.Value); } //should we remove a legal move if it will harm us? //can player1 score after this move? //take all legal moves and transpose one row up - do any fulfill player 1 threats? var toRemove = new List <Position>(); foreach (var legalMove in legalMoves) { var transposedMove = new Position(legalMove.Row + 1, legalMove.Col, 0); foreach (var threat in oppThreats) { var blank = threat.Coords.Single(t => t.Mark == 0); if (blank.Equals(transposedMove)) { toRemove.Add(legalMove); } } } toRemove.ForEach(r => legalMoves.Remove(r)); //claimeven var claimevens = search.FindPossibleClaimEvens(board); foreach (var claimEven in claimevens) { foreach (var move in legalMoves) { if (claimEven == move.Col) { return(claimEven); } } } var moveIndex = random.Next(0, legalMoves.Count()); return(legalMoves[moveIndex].Col); }