public int MinValue(Board CurGame, int col, int depth, int alpha, int beta) { State Result = CurGame.TestVictory(); if (Result != State.empty) { if (Result == State.draw) { return(0); } return((Result == playerNumber) ? 10000 : -15000); } // cut deep if (depth == MAX_DEEP) { return(DeapthCut(CurGame, col)); } CurGame.MakeMove(col); List <int> movesList = CurGame.GetValidMoves(); foreach (int T in movesList) { beta = Math.Min(beta, MaxValue(CurGame, T, depth + 1, alpha, beta)); if (beta <= alpha) { break; } } CurGame.UnMove(col); return(beta); }
public int Evaluate(Board CurGame, int col, int depth) { State Result = CurGame.TestVictory(); if (Result != State.empty) { if (Result == State.draw) { return(0); } return((Result == CurGame.CurPlayer) ? 10000 : -15000); } // cut deep if (depth == MAX_DEEP) { return(DeapthCut(CurGame, col)); } CurGame.MakeMove(col); List <int> movesList = CurGame.GetValidMoves(); int alpha = int.MinValue; foreach (int T in movesList) { alpha = Math.Max(alpha, -1 * Evaluate(CurGame, T, depth + 1)); } CurGame.UnMove(col); return(alpha); }
private static int DesperationMove(Board gameBoard) { int ColumnPicked = 0; for (int col = 0; col < Board.NR_COLS; ++col) { if (gameBoard.canMove(col)) { Board nextPos = gameBoard.MakeMove(Player.MIN, col); if (nextPos.isWin(Player.MIN)) { ColumnPicked = col; break; } } } return(ColumnPicked); }
public bool NextTurn() { int move = -1; if (gameBoard.CurPlayer == State.first) { move = this.player1.Play(gameBoard); } else { move = this.player2.Play(gameBoard); } if (move != -1) { gameBoard.MakeMove(move); } this.Winner = gameBoard.TestVictory(); return(this.Winner != State.empty); }
public int DeapthCut(Board CurGame, int move) { int n1, n2; int value1 = 0, value2 = 0; CurGame.MakeMove(move); int[] pInCol = CurGame.piecInCol; for (int row = 0; row < CurGame.Height; row++) { for (int col = 0; col < CurGame.Width; col++) { //if (row == pInCol[col]) break; // horizontal count++; if (col < CurGame.Width - 3) { n1 = 0; n2 = 0; for (int i = 0; i < 4; i++) { if (CurGame.BoardFields[row, col + i] == State.first) { n1++; } if (CurGame.BoardFields[row, col + i] == State.second) { n2++; } } SetValues(n1, n2, ref value1, ref value2); // diagonal l-u if (row < CurGame.Height - 3) { n1 = 0; n2 = 0; for (int i = 0; i < 4; i++) { if (CurGame.BoardFields[row + i, col + i] == State.first) { n1++; } if (CurGame.BoardFields[row + i, col + i] == State.second) { n2++; } } SetValues(n1, n2, ref value1, ref value2); } } // vertical if (row < CurGame.Height - 3) { n1 = 0; n2 = 0; for (int i = 0; i < 4; i++) { if (CurGame.BoardFields[row + i, col] == State.first) { n1++; } if (CurGame.BoardFields[row + i, col] == State.second) { n2++; } } SetValues(n1, n2, ref value1, ref value2); // diagonal r-d if (col >= CurGame.Width + 4) { n1 = 0; n2 = 0; for (int i = 0; i < 4; i++) { if (CurGame.BoardFields[row + i, col - i] == State.first) { n1++; } if (CurGame.BoardFields[row + i, col - i] == State.second) { n2++; } } SetValues(n1, n2, ref value1, ref value2); } } } } CurGame.UnMove(move); return((playerNumber == State.first) ? value1 - value2 : value2 - value1); }
private static void Main(string[] args) { if (args.Length > 0 && args[0].StartsWith("ON")) { Trace.ON = true; } Board gameBoard = new Board(); bool gameOver = false; var counter = 0; Console.WriteLine("MiniMax or AlphaBeta?"); var gameType = Console.ReadLine(); Console.WriteLine("Computer or Player first?"); var firstPlayer = Console.ReadLine(); var nextPlayer = true; if (firstPlayer.ToLower() == "computer") { nextPlayer = true; } else if (firstPlayer.ToLower() == "player") { nextPlayer = false; } while (!gameOver) { if (gameType.ToLower() == "minimax") { if (nextPlayer == true) { Console.WriteLine("I am thinking about my move now"); double highVal = -1.0; int bestMove = 0; for (int col = 0; col < Board.NR_COLS; ++col) { if (gameBoard.canMove(col)) { Board nextPos = gameBoard.MakeMove(Player.MAX, col); double thisVal = MiniMax.Value(nextPos, MAX_DEPTH, Player.MIN); if (thisVal > highVal) { bestMove = col; highVal = thisVal; } } } if (highVal == -1) { bestMove = DesperationMove(gameBoard); } Console.WriteLine($"My move is {(bestMove + 1)} (subj. value {highVal})"); gameBoard = gameBoard.MakeMove(Player.MAX, bestMove); nextPlayer = !nextPlayer; gameBoard.showBoard(); if (gameBoard.isWin(Player.MAX)) { Console.WriteLine("\n I win"); Console.WriteLine("Value method called " + MiniMax.TimesValueCalled); gameOver = true; } } else if (nextPlayer == false) { line61_: Console.WriteLine("Your move"); int theirMove = UserInput.getInteger("Select column 1 - 7", 1, 7) - 1; if (gameBoard.canMove(theirMove)) { gameBoard = gameBoard.MakeMove(Player.MIN, theirMove); nextPlayer = !nextPlayer; Console.WriteLine(""); gameBoard.showBoard(); } else { Console.WriteLine("Can't move there"); ++counter; if (counter < 3) { goto line61_; } else { Console.WriteLine("You lost your turn"); } } if (gameBoard.isWin(Player.MIN)) { Console.WriteLine("\n You win"); Console.WriteLine("Value method called " + MiniMax.TimesValueCalled); gameOver = true; } } } else if (gameType.ToLower() == "alphabeta") { if (nextPlayer == true) { Console.WriteLine("I am thinking about my move now"); double highVal = -1.0; int bestMove = 0; double alfa = -1.0; double beta = 1.0; for (int col = 0; col < Board.NR_COLS; ++col) { if (gameBoard.canMove(col)) { Board nextPos = gameBoard.MakeMove(Player.MAX, col); double thisVal = AlphaBeta.Value(nextPos, MAX_DEPTH, alfa, beta, Player.MIN); if (thisVal > highVal) { bestMove = col; highVal = thisVal; } } } if (highVal == -1) { bestMove = DesperationMove(gameBoard); } Console.WriteLine($"My move is {(bestMove + 1)} (subj. value {highVal})"); gameBoard = gameBoard.MakeMove(Player.MAX, bestMove); nextPlayer = !nextPlayer; gameBoard.showBoard(); if (gameBoard.isWin(Player.MAX)) { Console.WriteLine("\n I win"); Console.WriteLine("Value method called " + AlphaBeta.TimesValueCalled); gameOver = true; } } else if (nextPlayer == false) { line131_: Console.WriteLine("Your move"); int theirMove = UserInput.getInteger("Select column 1 - 7", 1, 7) - 1; if (gameBoard.canMove(theirMove)) { gameBoard = gameBoard.MakeMove(Player.MIN, theirMove); nextPlayer = !nextPlayer; Console.WriteLine(""); gameBoard.showBoard(); } else { Console.WriteLine("Can't move there"); ++counter; if (counter < 3) { goto line131_; } else { Console.WriteLine("You lost your turn"); } } if (gameBoard.isWin(Player.MIN)) { Console.WriteLine("\n You win"); Console.WriteLine("Value method called " + AlphaBeta.TimesValueCalled); gameOver = true; } } } else { Console.WriteLine("Enter MiniMax or AlphaBeta"); gameType = Console.ReadLine(); } } Console.ReadLine(); }
/// <summary> /// This method searches for a empty cell and lets /// the object fall down into this cell /// </summary> /// <param name="gObject">Game Object.</param> IEnumerator dropPiece(GameObject gObject) { isDropping = true; Vector3 startPosition = gObject.transform.position; Vector3 endPosition = new Vector3(); // round to a grid cell int x = Mathf.RoundToInt(startPosition.x); startPosition = new Vector3(x, startPosition.y, startPosition.z); // is there a free cell in the selected column? bool foundFreeCell = false; for (int i = numRows - 1; i >= 0; i--) { if (field[x, i] == 0) { foundFreeCell = true; field[x, i] = isPlayersTurn ? (int)Piece.Blue : (int)Piece.Red; board.MakeMove(x); endPosition = new Vector3(x, i * -1, startPosition.z); break; } } if (foundFreeCell) { // Instantiate a new Piece, disable the temporary GameObject g = Instantiate(gObject) as GameObject; gameObjectTurn.GetComponent <Renderer>().enabled = false; float distance = Vector3.Distance(startPosition, endPosition); float t = 0; while (t < 1) { t += Time.deltaTime * dropTime * ((numRows - distance) + 1); g.transform.position = Vector3.Lerp(startPosition, endPosition, t); yield return(null); } g.transform.parent = gameObjectField.transform; // remove the temporary gameobject DestroyImmediate(gameObjectTurn); // run coroutine to check if someone has won StartCoroutine(Won()); // wait until winning check is done while (isCheckingForWinner) { yield return(null); } isPlayersTurn = !isPlayersTurn; } isDropping = false; yield return(0); }