private void RunAI_Async(object sender, DoWorkEventArgs e) { TakMove move = AIs[CurrentPlayer].ChooseNextMove(); Action a = () => { ActiveInput.Text = move.ToString(); btnSubmit_Click(this, new RoutedEventArgs()); }; Dispatcher.InvokeAsync(a); }
/// <summary> /// Generate the list of all moves that the stack located at the given coordinate can make /// </summary> /// <param name="gameState"></param> /// <param name="row"></param> /// <param name="column"></param> /// <returns></returns> private static List <TakMove> GenerateStackMoves(TakPiece.PieceColor player, GameState gameState, int row, int column) { TakMove m; List <TakMove> moves = new List <TakMove>(); PieceStack stack = gameState.Board[row, column]; List <List <int> > allDrops = new List <List <int> >(); for (int n = 1; n <= Math.Min(stack.Size, gameState.Board.Size); n++) // for 1 to the carry limit of the board { allDrops.Clear(); MakeDrops(n, allDrops, new List <int>()); foreach (List <int> drops in allDrops) { m = new TakMove(player, row, column, TakMove.MoveDirection.Left, drops); if (m.IsLegal(gameState)) { moves.Add(m); } m = new TakMove(player, row, column, TakMove.MoveDirection.Right, drops); if (m.IsLegal(gameState)) { moves.Add(m); } m = new TakMove(player, row, column, TakMove.MoveDirection.Up, drops); if (m.IsLegal(gameState)) { moves.Add(m); } m = new TakMove(player, row, column, TakMove.MoveDirection.Down, drops); if (m.IsLegal(gameState)) { moves.Add(m); } } } return(moves); }
/// <summary> /// Enumerate all legal moves possible for this player, given the state of the game /// /// Returned moves are unsorted (and are in fact shuffles to avoid any biases) /// </summary> /// <param name="player"></param> /// <param name="boardState"></param> /// <returns></returns> public static List <TakMove> EnumerateMoves(TakPiece.PieceColor player, GameState gameState) { TakMove m; List <TakMove> moves = new List <TakMove>(); TakPiece.PieceColor otherPlayer = player == TakPiece.PieceColor.Black ? TakPiece.PieceColor.White : TakPiece.PieceColor.Black; // first off, we can drop pieces on any open space on the board // if we're still evaluating moves it must mean we still have at least 1 piece to place for (int i = 0; i < gameState.Board.Size; i++) { for (int j = 0; j < gameState.Board.Size; j++) { if (gameState.Board[i, j].Size == 0) { // from turn 1 on we place our own pieces and can place flats, capstones, or walls if (gameState.TurnNumber > 0) { m = new TakMove(player, i, j, TakPiece.PieceType.Flat); moves.Add(m); m = new TakMove(player, i, j, TakPiece.PieceType.Wall); moves.Add(m); if (gameState[player].NumCapstones > 0) { m = new TakMove(player, i, j, TakPiece.PieceType.Capstone); moves.Add(m); } } else { // on turn 0 we can only place an opposing flat m = new TakMove(otherPlayer, i, j, TakPiece.PieceType.Flat); moves.Add(m); } } } } // generate all possible moves for each stack we own // this is only allowed from turn 1 onward if (gameState.TurnNumber > 0) { for (int i = 0; i < gameState.Board.Size; i++) { for (int j = 0; j < gameState.Board.Size; j++) { if (gameState.Board[i, j].Owner == player) { List <TakMove> stackMoves = GenerateStackMoves(player, gameState, i, j); foreach (TakMove tm in stackMoves) { moves.Add(tm); } } } } } moves.Shuffle(); return(moves); }
public MoveNode(GameState gs, TakMove move) : base() { Move = move; ResultingState = new GameState(gs); move.Apply(ResultingState); }
/// <summary> /// Submit the move, make sure it's legal, and apply it to the state of the game /// /// Will show a notification if there was an invalid move typed in /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSubmit_Click(object sender, RoutedEventArgs e) { lblError.Visibility = Visibility.Collapsed; try { TakMove move; if (Game.TurnNumber == 0) { move = new TakMove(CurrentPlayer == TakPiece.PieceColor.Black ? TakPiece.PieceColor.White : TakPiece.PieceColor.Black, ActiveInput.Text); } else { move = new TakMove(CurrentPlayer, ActiveInput.Text); } string err; if (move.CheckAndApply(Game, out err)) { ActiveOutput.Text += string.Format("{0:00}. {1}\n", Game.TurnNumber, move); string state = string.Format("{0:00}. {1}\n{2}\n", Game.TurnNumber, move, Board); imgBoard.Source = Bitmap2Source(Board.Draw()); if (!Game.GameOver) { if (CurrentPlayer == TakPiece.PieceColor.White) { CurrentPlayer = TakPiece.PieceColor.Black; } else { CurrentPlayer = TakPiece.PieceColor.White; Game.TurnNumber++; } } else { btnSubmit.IsEnabled = false; ActiveInput.IsEnabled = false; TakPiece.PieceColor?winner = Game.Winner(CurrentPlayer); if (winner != null) { lblError.Content = string.Format("{0} Player Wins!", winner); } else { lblError.Content = "Draw!"; } lblError.Visibility = Visibility.Visible; } } else { lblError.Content = "Illegal move: " + err; lblError.Visibility = Visibility.Visible; } } catch (Exception err) { lblError.Content = "Error: " + err.Message; lblError.Visibility = Visibility.Visible; } }