Ejemplo n.º 1
0
        /// <summary>
        /// Un joueur tente de jouer un coup. Joue le coup et change de tour si possible.
        /// Si l'autre joueur doit passer, reviens au premier joueur.
        /// Si la partie est terminée, affichage des score et du gagnant.
        /// </summary>
        private void Pawn_Click(object sender, RoutedEventArgs e)
        {
            contextPlayers.Timer.Stop();
            CellButton cellButton = (CellButton)sender;
            int        c          = cellButton.C;
            int        l          = cellButton.L;


            if (board.PlayMove(c, l, whiteTurn))
            {
                // Coup jouable et joué
                cellButton.Val = board.GetBoard()[c, l];
                whiteTurn      = !whiteTurn;
                var newWhiteTurn = whiteTurn;

                CheckFinished();

                // L'IA joue que si elle n'a pas passé son tour (donc whiteTurn n'a pas été modifié dans CheckFinished().)
                if (playAgainstIA && newWhiteTurn == whiteTurn)
                {
                    PlayIAMove();
                    CheckFinished();
                }
            }
            else
            {
                // Impossible de jouer ce coup
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Refresh the button of the grid according to the board state
        /// </summary>
        public void UpdateGridValue()
        {
            int[,] gridBoard = board.GetBoard();
            int numPlayableTiles = 0;
            int numEmptyTiles    = 0;

            for (int y = 0; y < Constants.GRID_SIZE; y++)
            {
                for (int x = 0; x < Constants.GRID_SIZE; x++)
                {
                    //Set the playable tiles
                    if (board.IsPlayable(x, y, board.GetTurn()))
                    {
                        tiles[x, y].IsPlayable = true;
                        numPlayableTiles++;
                    }
                    else
                    {
                        tiles[x, y].IsPlayable = false;
                    }

                    if (gridBoard[x, y] == -1)
                    {
                        numEmptyTiles++;
                    }

                    tiles[x, y].State = gridBoard[x, y];
                }
            }

            updateImagePlayer();
            checkGameEnd(numPlayableTiles, numEmptyTiles);
        }
Ejemplo n.º 3
0
 public Board(Board boardSource)
 {
     board       = (int[, ])boardSource.GetBoard().Clone();
     playerWhite = boardSource.PlayerWhite;
     playerBlack = boardSource.PlayerBlack;
     isWhite     = boardSource.GetTurn();
 }
Ejemplo n.º 4
0
    static void Main(string[] args)
    {
      var boardInput = new List<string>();
      string current;

      using (var reader = new System.IO.StringReader(input))
      {
        current = reader.ReadLine();

        string line;
        while ((line = reader.ReadLine()) != null)
        {
          boardInput.Add(line);
        }
      }

      var board = Board.GetBoard(boardInput);

    }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates and displays board
        /// </summary>
        private void PrintBoard()
        {
            canBoard.Children.Clear();
            //Getting board canvas dimensions
            int canvasHeight = (int)canBoard.ActualHeight;
            int canvasWidth  = (int)canBoard.ActualWidth;
            //Background
            Rectangle bg = new Rectangle
            {
                Height = canvasHeight,
                Width  = canvasWidth
            };

            //Modifying canvas based on background
            Canvas.SetTop(bg, 0);
            Canvas.SetLeft(bg, 0);
            bg.Fill = Brushes.White;
            canBoard.Children.Add(bg);
            //Brush
            Brush myBrush = new SolidColorBrush(Color.FromArgb(100, 200, 10, 10));

            //Painting board lines
            for (int i = 0; i < 4; i++)
            {
                Line myLine = new Line
                {
                    Stroke          = myBrush,
                    X1              = 0,
                    X2              = canvasWidth,
                    Y1              = (canvasHeight / 4.0 * i) + (canvasWidth / 16.0),
                    Y2              = (canvasHeight / 4.0 * i) + (canvasHeight / 16.0),
                    StrokeThickness = (int)(canvasHeight / 8.0)
                };
                canBoard.Children.Add(myLine);
                myLine = new Line
                {
                    Stroke          = myBrush,
                    Y1              = 0,
                    Y2              = canvasHeight,
                    X1              = (canvasWidth / 4.0 * i) + (canvasWidth / 16.0),
                    X2              = (canvasHeight / 4.0 * i) + (canvasHeight / 16.0),
                    StrokeThickness = (int)(canvasWidth / 8.0)
                };
                canBoard.Children.Add(myLine);
            }
            //Texture rectangle
            Rectangle textileFilter = new Rectangle
            {
                Height = canvasHeight,
                Width  = canvasWidth
            };

            //Modifying canvas based on rectangle
            Canvas.SetTop(textileFilter, 0);
            Canvas.SetLeft(textileFilter, 0);
            //Filling rectangle with texture image
            ImageBrush textileBrush = new ImageBrush {
                ImageSource = new BitmapImage(new Uri(@"imgs\texttexture.png", UriKind.Relative))
            };

            textileFilter.Fill = textileBrush;
            //Painting board squares
            canBoard.Children.Add(textileFilter);
            //Painting existing counters on board
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (board.GetBoard()[i, j] >= 0)
                    {
                        Rectangle square = new Rectangle
                        {
                            Height = canvasHeight / 8.0,
                            Width  = canvasWidth / 8.0
                        };
                        Canvas.SetTop(square, j * canvasHeight / 8.0);
                        Canvas.SetLeft(square, i * canvasWidth / 8.0);
                        //Setting counter image based on player
                        if (board.GetBoard()[i, j] == 0)
                        {
                            square.Fill = skinPlayer1.Clone();
                        }
                        else
                        {
                            square.Fill = skinPlayer2.Clone();
                        }
                        canBoard.Children.Add(square);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        // Alpha beta searching with transposition table
        private double AlphaBeta(int[,] board, int color, int depth = 0, double alpha = double.NegativeInfinity, double beta = double.PositiveInfinity)
        {
            nodeCount += 1;

            evaluator.SetBoard(board);

            // Return evaluation value if reaching depth = depthMax or terminal node
            if (depth >= currentDepthMax)
            {
                return(evaluator.Evaluate(selfColor));
            }


            // Return evaluation when game ends
            List <Pos> newOptions    = evaluator.Availables(color);
            List <Pos> oppNewOptions = evaluator.Availables(StoneColor.OppColor(color));

            if (newOptions.Count == 0 && oppNewOptions.Count == 0)
            {
                int selfStones = evaluator.CountStones(selfColor);
                int oppStones  = evaluator.CountStones(StoneColor.OppColor(selfColor));
                if (selfStones > oppStones)
                {
                    return(double.PositiveInfinity);
                }
                else if (selfStones < oppStones)
                {
                    return(double.NegativeInfinity);
                }
                else
                {
                    return(evaluator.Evaluate(selfColor));
                }
            }


            // When only the opponent can put stone, go to next depth
            if (newOptions.Count == 0)
            {
                depth     += 1;
                color      = StoneColor.OppColor(color);
                newOptions = oppNewOptions;
            }


            // Expand board and store the all child boards in children list
            // Associate the child and the action of that time
            List <int[, ]>            children         = new List <int[, ]>();
            Dictionary <int[, ], Pos> actionChildTable = new Dictionary <int[, ], Pos>();

            foreach (Pos action in newOptions)
            {
                Board childBoard = new Board();
                childBoard.SetBoard(board);
                childBoard.UpdateBoard(action, color);
                children.Add(childBoard.GetBoard());
                actionChildTable.Add(childBoard.GetBoard(), action);
            }


            // Sort children in order of the score
            // In descending order when self turn and in ascending order when opponent turn
            st.Start();
            if (depth <= 3)
            {
                children = OrderBoards(children, color);
            }
            st.Stop();


            // Alpha beta searching
            if (color == selfColor)
            {
                // In self turn, search max value of children

                double score = double.NegativeInfinity;

                foreach (int[,] child in children)
                {
                    // Check if the child is stored in transposition table and the node type is EXACT
                    // If it does, set the value for the score
                    // If not, start alpha-beta-searching in next depth and store the score

                    string childHash = BoardToHash(child);

                    if (transpositionTable.ContainsKey(childHash) && transpositionTable[childHash].Depth >= currentDepthMax && transpositionTable[childHash].NodeType == "EXACT")
                    {
                        transpositionCutCount += 1;
                        score = transpositionTable[childHash].Score;
                    }
                    else
                    {
                        score = AlphaBeta(child, StoneColor.OppColor(color), depth + 1, alpha, beta);
                        transpositionTable[childHash] = new TranspositionTableEntry(child, currentDepthMax, score);
                    }


                    if (score > alpha)
                    {
                        alpha = score;

                        // Get best action
                        if (depth == 0)
                        {
                            foreach (KeyValuePair <int[, ], Pos> kvp in actionChildTable)
                            {
                                if (kvp.Key.Cast <int>().SequenceEqual(child.Cast <int>()))
                                {
                                    bestAction = kvp.Value;
                                }
                            }
                        }
                    }

                    // Beta cut
                    if (alpha >= beta)
                    {
                        betaCutCount += 1;
                        break;
                    }
                }
                return(alpha);
            }
            else
            {
                // If the opponent turn, search minimum value of children

                double score = double.PositiveInfinity;

                foreach (int[,] child in children)
                {
                    string childHash = BoardToHash(child);

                    if (transpositionTable.ContainsKey(childHash) && transpositionTable[childHash].Depth >= currentDepthMax && transpositionTable[childHash].NodeType == "EXACT")
                    {
                        transpositionCutCount += 1;
                        score = transpositionTable[childHash].Score;
                    }
                    else
                    {
                        score = AlphaBeta(child, StoneColor.OppColor(color), depth + 1, alpha, beta);
                        transpositionTable[childHash] = new TranspositionTableEntry(child, currentDepthMax, score);
                    }

                    beta = Math.Min(beta, score);

                    // Alpha cut
                    if (beta <= alpha)
                    {
                        alphaCutCount += 1;
                        break;
                    }
                }
                return(beta);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Demande à l'IA de jouer un coup.
        /// Méthode asynchrone pour permettre l'affichage du coup du joueur avant que l'IA joue.
        /// </summary>
        private void PlayIAMove()
        {
            int difficulty = 2;

            // Le joueur humain est bloqué
            foreach (var cell in cells)
            {
                cell.IsEnabled = false;
            }

            // Copie des variables utilisées dans un BackgroundWorker pour éviter la concurrence
            Board            copyBoard      = new Board(board);
            bool             copyWhiteTurn  = whiteTurn;
            int              copyDifficulty = difficulty;
            Tuple <int, int> move           = null;

            BackgroundWorker bgWorker = new BackgroundWorker();

            // On fait réfléchir l'IA dans un BackgroudWorker
            bgWorker.DoWork += (sender, ev) =>
            {
                Thread.Sleep(1000);
                move = copyBoard.GetNextMove(copyBoard.GetBoard(), copyDifficulty, copyWhiteTurn);
            };

            // Quand elle trouve un coup, on met à jour le board
            bgWorker.RunWorkerCompleted += (sender, ev) =>
            {
                int c = move.Item1;
                int l = move.Item2;

                // Vérifie que l'IA n'a pas passé son tour
                if (c >= 0 && l >= 0)
                {
                    if (board.PlayMove(c, l, whiteTurn))
                    {
                        // Coup jouable et joué
                        whiteTurn = !whiteTurn;
                    }
                    else
                    {
                        // Impossible de jouer ce coup
                    }
                }

                var newWhiteTurn = whiteTurn;

                CheckFinished();

                if (newWhiteTurn != whiteTurn)
                {
                    // Le joueur a passé son tour (whiteTurn a été modifié dans CheckFinished())
                    PlayIAMove();
                }

                // Débloque le joueur humain
                foreach (var cell in cells)
                {
                    cell.IsEnabled = true;
                }
            };

            // On lance le background worker
            bgWorker.RunWorkerAsync();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Commence ou recommence une partie.
        /// </summary>
        private void StartGame()
        {
            UpdateTitle();

            // Le joueur noir commence toujours
            whiteTurn = false;
            // Création du contexte pour les infos des joueurs
            contextPlayers = new ContextPlayers(2, 2);
            // On bind les infos au DataContext de la fenêtre.
            DataContext = contextPlayers;
            // Nouveau plateau de jeu
            board = new Board();
            cells = new CellButton[8, 8];
            // Style des boutons (pions)
            Style resource = (Style)FindResource("PawnStyle");
            var   tabBoard = board.GetBoard();

            for (int c = 0; c < 8; c++)
            {
                for (int l = 0; l < 8; l++)
                {
                    // Création et ajout du pion dans le plateau de jeu
                    var        val     = tabBoard[c, l];
                    CellButton pawnBtn = new CellButton(c, l, val)
                    {
                        Style = resource
                    };
                    pawnBtn.Click += Pawn_Click;
                    cells[c, l]    = pawnBtn;

                    // Ajout graphique du pion : Border(Grid(bouton transparent, ellipse visible))
                    Border border = new Border
                    {
                        BorderBrush     = Brushes.White,
                        BorderThickness = new Thickness(1, 1, 0, 0)
                    };
                    if (c == 0)
                    {
                        border.BorderThickness = new Thickness(0, 1, 0, 0);
                        if (l == 0)
                        {
                            border.BorderThickness = new Thickness(0, 0, 0, 0);
                        }
                    }
                    else if (l == 0)
                    {
                        border.BorderThickness = new Thickness(1, 0, 0, 0);
                    }

                    Grid grid = new Grid
                    {
                        Background = Brushes.Green
                    };
                    Viewbox viewbox = new Viewbox
                    {
                        Child  = pawnBtn.Ellipse,
                        Margin = new Thickness(4)
                    };
                    grid.Children.Add(viewbox);
                    grid.Children.Add(pawnBtn);

                    border.Child = grid;
                    Grid.SetColumn(border, c + 1);
                    Grid.SetRow(border, l + 1);
                    gridBoard.Children.Add(border);
                }
            }
            // Ajout des en-têtes au plateau (A-H dans les colonnes, 1-8 pour les lignes)
            AddHeader();
            // Refresh de la GUI
            UpdateUI(false);
        }