// TODO !!!!!!! public float Evaluate(Board CurrentGame, int Move) { long me, en; // test blue if (CurrentGame.CurrentPlayer!=State.blue) { me = CurrentGame.BoardBlue; en = CurrentGame.BoardRed; } else { en = CurrentGame.BoardBlue; me = CurrentGame.BoardRed; } long empty = me; long occupied = (me | en); long oppThreats = 0L; long ownThreats = 0L; // horizontal ownThreats |= (me & (me >> 7) & (me >> 7 * 2) & empty); //XXX_ ownThreats |= (me & (me >> 1 * 7) & (me >> 3 * 7) & empty); //XX_X ownThreats |= (me & (me >> 2 * 7) & (me >> 3 * 7) & empty); // vertical ownThreats |= (me & (me >> 1) & (me >> 2) & empty); //XXX_ return Utile.CountBits(ownThreats); }
public override int Play(Board Current) { int ColumnToPlay = -1; float BestValue = float.MinValue; MCEvaluation.SetStrength(Strength); List<int> CandidateMoves = Current.GetValidMoves(); TProcess.Maximum = CandidateMoves.Count; TProcess.Value = 0; if (CandidateMoves.Count == 1) { return CandidateMoves[0]; } foreach (int Move in CandidateMoves) { TProcess.PerformStep(); float CurrentValue = MCEvaluation.Evaluate(Current, Move); if (CurrentValue > BestValue) { BestValue = CurrentValue; ColumnToPlay = Move; } } return ColumnToPlay; }
protected State Expand(Board Game) { // maybe the next move int MoveId; // until the game ends play it while (Game.TestVictory() == State.empty) { List<int> ValidMoves = Game.GetValidMoves(); MoveId = Rnd.Next(0, ValidMoves.Count - 1); Game.Move(ValidMoves[MoveId]); } // return the winner return Game.TestVictory(); }
public static int GetPlayoutsNumber(Board Current, int ms) { int playouts_to_think = 0; MCScore MCEvaluation = new MCScore(); // test speed MCEvaluation.SetStrength(1000); Stopwatch sw = new Stopwatch(); sw.Start(); int Move = Current.GetValidMoves()[0]; float f = MCEvaluation.Evaluate(Current, Move); sw.Stop(); playouts_to_think = Convert.ToInt32(1000 / (float)sw.Elapsed.TotalMilliseconds * (ms/(float)Current.GetValidMoves().Count)); return playouts_to_think; }
public float Evaluate(Board Current, int Move) { int Value = 0; // value of move for (int Plays = 0; Plays < NumberOfPlayouts; Plays++) { Board MCPlayout = Current.Clone(); MCPlayout.Move(Move); State Winner = Expand(MCPlayout); if (Winner == Current.CurrentPlayer) Value++; // win means +1 else if (Winner == Current.CurrentOpponent) Value--; // loss means -1 } return (Value / (float)NumberOfPlayouts); // project into [-1,1] }
/// <summary> /// returns a move by minimax and deep cuts /// </summary> /// <param name="CurrentSituation">current game situation</param> /// <returns>move to play</returns> public override int Play(Board CurrentSituation) { List<int> CandidateMoves = CurrentSituation.GetValidMoves(); // get a possible Moves TProcess.Maximum = CandidateMoves.Count; // display the current thinking progress TProcess.Value = 0; float alpha = float.MinValue; // current best valuation alpha int ColumnToPlay = -1; // column to play foreach (int M in CandidateMoves) // test a canditate moves { TProcess.PerformStep(); // next move => update progressbar float eval = ScoreMove(CurrentSituation, M, 0); // Score the move if (eval > alpha) // is this move better? { alpha = eval; // then we take this move ColumnToPlay = M; } } return ColumnToPlay; }
public static List<int> PreprocessMoves(Board Current, List<int> TestCandidates) { List<int> CandidateMoves = new List<int> { }; foreach (int Move in TestCandidates) { Board CheckWin = Current.Clone(); // test if immediate win possible CheckWin.Move(Move); if (CheckWin.TestVictory() == Current.CurrentPlayer) { CandidateMoves.Add(Move); return CandidateMoves; } else { // test if we make an assist for our opponent List<int> OpponentMoves = CheckWin.GetValidMoves(); bool IsBad = false; foreach (int OMove in OpponentMoves) { Board Tmp = CheckWin.Clone(); Tmp.Move(OMove); // did we make an assist? if (Tmp.TestVictory() == Current.CurrentOpponent) { // forget the move! IsBad = true; break; } } if (!IsBad) { CandidateMoves.Add(Move); } } } return CandidateMoves; }
/// <summary> /// internal score of move /// </summary> /// <param name="Situation">current game situation</param> /// <param name="Move">move to do</param> /// <param name="deep">current deep</param> /// <returns>value of move</returns> protected float ScoreMove(Board Situation, int Move, int deep) { // game finished? State Result = Situation.TestVictory(); // if game is finished ... if (Result != State.empty) { // is draw? if (Result == State.draw) return 0.0f; // else return score 1.0f for winning and -1.0f for loosing return (Result == Situation.CurrentPlayer) ? 1f : -1f; } // cut deep if (deep == MAX_DEEP) { // adjust strength dynamically int S = Convert.ToInt32(Strength / ((double)Math.Pow(7, MAX_DEEP))); Scores.SetStrength(S); // Score Board due monte carlo return Scores.Evaluate(Situation, Move); } Situation.Move(Move); // do move List<int> CandidateMoves = Situation.GetValidMoves(); // new situation, so new possible moves float val = float.MinValue; // temp alpha value foreach (int M in CandidateMoves) { val = Math.Max(val, -1f * ScoreMove(Situation, M, deep + 1)); // evaluate each move by recursion } Situation.UnMove(Move); // redo move return val; // return value }
/// <summary> /// returns a move by minimax and deep cuts /// </summary> /// <remarks> /// THIS IS STILL BUGGY!!! /// </remarks> /// <param name="CurrentSituation">current game situation</param> /// <returns>move to play</returns> public override int Play(Board CurrentSituation) { Scores.SetStrength(100); CP = CurrentSituation.CurrentPlayer; List<int> CandidateMoves = CurrentSituation.GetValidMoves(); TProcess.Maximum = CandidateMoves.Count; TProcess.Value = 0; float value = float.MinValue; int ColumnToPlay = -1; WorkingBoard = CurrentSituation.Clone(); foreach (int M in CandidateMoves) { TProcess.PerformStep(); float eval = ScoreMove(M, 0, float.MinValue, float.MaxValue); //MessageBox.Show(value.ToString()); if (eval > value) { value = eval; ColumnToPlay = M; } } return ColumnToPlay; }
public override int Play(Board Situation) { List<int> ValidMoves = Situation.GetValidMoves(); int MoveId = r.Next(0, ValidMoves.Count - 1); return ValidMoves[MoveId]; }
public Board Clone() { Board tmp = new Board(Height, Width); tmp.CurrentPlayer = this.CurrentPlayer; tmp.CurrentOpponent = this.CurrentOpponent; tmp.BoardBlue = this.BoardBlue; tmp.BoardRed = this.BoardRed; for (int col = 0; col < this.Width; col++) tmp.DiscsPerColumn[col] = this.DiscsPerColumn[col]; return tmp; }
private void Form1_Load(object sender, EventArgs e) { Game = new Board(BoardHeight, BoardWidth); pbxBoard.Width = BoardWidth * fieldsize + 1; pbxBoard.Height = BoardHeight * fieldsize + 1; cmbOpponent.SelectedIndex = 1; AIS = new List<IPlayer> { }; Stupid S1 = new Stupid(); S1.SetGUIMembers(pgbThinking, txtLog); MonteCarlo MC1 = new MonteCarlo(); MC1.SetStrength(20000); MC1.SetGUIMembers(pgbThinking, txtLog); MonteCarlo MC2 = new MonteCarlo(); MC2.SetStrength(50000); MC2.SetGUIMembers(pgbThinking, txtLog); MonteCarlo MC3 = new MonteCarlo(); MC3.SetStrength(100000); MC3.SetGUIMembers(pgbThinking, txtLog); MonteCarloPlus MCP1 = new MonteCarloPlus(); MCP1.SetStrength(20000); MCP1.SetGUIMembers(pgbThinking, txtLog); MonteCarloPlus MCP2 = new MonteCarloPlus(); MCP2.SetStrength(50000); MCP2.SetGUIMembers(pgbThinking, txtLog); MonteCarloPlus MCP3 = new MonteCarloPlus(); MCP3.SetStrength(100000); MCP3.SetGUIMembers(pgbThinking, txtLog); MonteCarloTime MCT1 = new MonteCarloTime(); MCT1.SetStrength(5000); MCT1.SetGUIMembers(pgbThinking, txtLog); MonteCarloTime MCT2 = new MonteCarloTime(); MCT2.SetStrength(7000); MCT2.SetGUIMembers(pgbThinking, txtLog); MonteCarloTime MCT3 = new MonteCarloTime(); MCT3.SetStrength(10000); MCT3.SetGUIMembers(pgbThinking, txtLog); MonteCarloTime MCT4 = new MonteCarloTime(); MCT4.SetStrength(20000); MCT4.SetGUIMembers(pgbThinking, txtLog); MiniMax MM1 = new MiniMax(); MM1.SetStrength(40000); MM1.SetGUIMembers(pgbThinking, txtLog); AlphaBeta AB1 = new AlphaBeta(); AB1.SetGUIMembers(pgbThinking, txtLog); AIS.Add(S1); AIS.Add(MC1); AIS.Add(MC2); AIS.Add(MC3); AIS.Add(MCP1); AIS.Add(MCP2); AIS.Add(MCP3); AIS.Add(MCT1); AIS.Add(MCT2); AIS.Add(MCT3); AIS.Add(MCT4); AIS.Add(MM1); AIS.Add(AB1); string[] labels = new string[]{ "MonteCarlo (50000)", "MonteCarlo (100000)", "MonteCarloPlus (20000)", "MonteCarloPlus (50000)", "MonteCarloPlus (100000)", "MonteCarlo (5sec)", "MonteCarlo (7sec)", "MonteCarlo (10sec)", "MonteCarlo (20sec)", "MiniMax (deep=2,dyn=70000)", "AlphaBeta (deep=3,1000)"}; foreach(string t in labels){ cmbOpponent.Items.Add(t); } cmbOpponent.MaxDropDownItems = labels.Length; cmbOpponent.Refresh(); pgbThinking.Maximum = BoardWidth; DrawBoard(); }
private void btnNewGame_Click(object sender, EventArgs e) { Game = new Board(BoardHeight, BoardWidth); DrawBoard(); lblVictory.Visible = false; lblCurrent.Text = "Current: blue"; for (int i = 0; i < BoardWidth; i++) { PlayBtn[i].BackColor = Color.YellowGreen; } }
public abstract int Play(Board Current);
public float Evaluate(Board CurrentGame, int Move) { return (float)CurrentGame.Rnd.Next(-100, 100)/100.0f; }