Example #1
0
        public void doMove(bool cap, BoardTile from, BoardTile to)
        {
            to.setPiece(from.getPiece());

            if (to.y == 0 || to.y == 7)
            {
                to.getPiece().setKing(true);
            }

            from.remPiece();

            if (!cap)
            {
                turn = 1 - turn; //Switch player
            }
            else
            {
                if (to.x > from.x)
                {
                    if (to.y > from.y)
                    {
                        //LR
                        boardRecs[from.x + 1, from.y + 1].remPiece();

                    }
                    else
                    {
                        //UR
                        boardRecs[from.x + 1, from.y - 1].remPiece();

                    }

                }
                else
                {
                    if (to.y > from.y)
                    {
                        //LL
                        boardRecs[from.x - 1, from.y + 1].remPiece();

                    }
                    else
                    {
                        //UL
                        boardRecs[from.x - 1, from.y - 1].remPiece();

                    }

                }
            }
            moves = new List<BoardTile>();
            caps = new List<BoardTile>();
        }
Example #2
0
 /// <summary>
 /// Get number of remaining pieces with the given color and shape.
 /// </summary>
 /// <param name="color">Pieces color.</param>
 /// <param name="shape">Pieces shape.</param>
 /// <returns>
 /// Number of remaining pieces with the given color and shape.
 /// </returns>
 public int PieceCount(PColor color, PShape shape) =>
 numberOfPieces[new Piece(color, shape)];
Example #3
0
    /// <summary>
    /// Creates a new board.
    /// </summary>
    /// <param name="rows">Number of rows.</param>
    /// <param name="cols">Number of columns.</param>
    /// <param name="piecesInSequence">
    /// Number of required pieces in a row for player to win.
    /// </param>
    /// <param name="roundPieces">
    /// Initial number of round pieces per player.
    /// </param>
    /// <param name="squarePieces">
    /// Initial number of square pieces per player.
    /// </param>
    public Board(int rows        = 7, int cols = 7, int piecesInSequence = 4,
                 int roundPieces = 10, int squarePieces = 11)
    {
        // Aux. variables for determining win corridors
        List <Pos> aCorridor;
        List <IEnumerable <Pos> > corridors;

        // Is it possible to win?
        if (rows < piecesInSequence && cols < piecesInSequence)
        {
            throw new InvalidOperationException(
                      "Invalid parameters, since it is not possible to win");
        }

        // Keep number of rows
        this.rows = rows;

        // Keep number of columns
        this.cols = cols;

        // Keep number of pieces in sequence to find winner
        this.piecesInSequence = piecesInSequence;

        // Keep initial number of round pieces
        this.roundPieces = roundPieces;

        // Keep initial number of square pieces
        this.squarePieces = squarePieces;

        // Number of moves initially zero
        numMoves = 0;

        // Initially, it's player 1 turn
        Turn = PColor.White;

        // Instantiate the array representing the board
        board = new Piece?[cols, rows];

        // Initialize the array of functions for checking pieces
        pieceFuncsPlayers = new PieceFuncPlayer[]
        {
            // Shape must come before color
            new PieceFuncPlayer(p => p.shape == PShape.Round, PColor.White),
            new PieceFuncPlayer(p => p.shape == PShape.Square, PColor.Red),
            new PieceFuncPlayer(p => p.color == PColor.White, PColor.White),
            new PieceFuncPlayer(p => p.color == PColor.Red, PColor.Red)
        };

        // Create and populate array of win corridors
        corridors = new List <IEnumerable <Pos> >();
        aCorridor = new List <Pos>(Math.Max(rows, cols));

        // Initialize move sequence with initial capacity for all possible
        // moves
        moveSequence = new Stack <Pos>(rows * cols);

        // Setup initial number of pieces
        numberOfPieces = new Dictionary <Piece, int>()
        {
            { new Piece(PColor.White, PShape.Round), roundPieces },
            { new Piece(PColor.White, PShape.Square), squarePieces },
            { new Piece(PColor.Red, PShape.Round), roundPieces },
            { new Piece(PColor.Red, PShape.Square), squarePieces },
        };

        //
        // Horizontal corridors
        //
        if (cols >= piecesInSequence)
        {
            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < cols; c++)
                {
                    aCorridor.Add(new Pos(r, c));
                }
                corridors.Add(aCorridor.ToArray());
                aCorridor.Clear();
            }
        }

        //
        // Vertical corridors
        //
        if (rows >= piecesInSequence)
        {
            for (int c = 0; c < cols; c++)
            {
                for (int r = 0; r < rows; r++)
                {
                    aCorridor.Add(new Pos(r, c));
                }
                corridors.Add(aCorridor.ToArray());
                aCorridor.Clear();
            }
        }

        //
        // Diagonal corridors /
        //
        // Down
        for (int row = rows - 1; row >= 0; row--)
        {
            int r = row;
            int c = 0;
            while (r < rows && c < cols)
            {
                aCorridor.Add(new Pos(r, c));
                r++;
                c++;
            }
            if (aCorridor.Count >= this.piecesInSequence)
            {
                corridors.Add(aCorridor.ToArray());
            }
            aCorridor.Clear();
        }
        // Right
        for (int col = 1; col < cols; col++)
        {
            int r = 0;
            int c = col;
            while (r < rows && c < cols)
            {
                aCorridor.Add(new Pos(r, c));
                r++;
                c++;
            }
            if (aCorridor.Count >= this.piecesInSequence)
            {
                corridors.Add(aCorridor.ToArray());
            }
            aCorridor.Clear();
        }

        //
        // Diagonal corridors \
        //
        // Down
        for (int row = rows - 1; row >= 0; row--)
        {
            int r = row;
            int c = cols - 1;
            while (r < rows && c >= 0)
            {
                aCorridor.Add(new Pos(r, c));
                r++;
                c--;
            }
            if (aCorridor.Count >= this.piecesInSequence)
            {
                corridors.Add(aCorridor.ToArray());
            }
            aCorridor.Clear();
        }
        // Left
        for (int col = cols - 2; col >= 0; col--)
        {
            int r = 0;
            int c = col;
            while (r < rows && c >= 0)
            {
                aCorridor.Add(new Pos(r, c));
                r++;
                c--;
            }
            if (aCorridor.Count >= this.piecesInSequence)
            {
                corridors.Add(aCorridor.ToArray());
            }
            aCorridor.Clear();
        }

        // Keep the final list of win corridors
        winCorridors = corridors.ToArray();
    }
Example #4
0
        public void Setup()
        {
            Console.Write("Enter video framerate: ");
            var framerate = Console.ReadLine();

            Console.Write("Enter total frame count: ");
            var frames = int.Parse(Console.ReadLine());

            Console.Write("Enter output video file name (no extension): ");
            var name = Console.ReadLine().Trim();

            Console.Write("Enter resolution separated by a comma (480,480): ");
            var res = Console.ReadLine().Split(',').ToList().ConvertAll(resPart => int.Parse(resPart)).ToArray();

            Console.Write("Enter mandelbrot power range (x in f(z)=z^x + c) separated by a comma (1,10): ");
            var range = Console.ReadLine().Split(',').ToList().ConvertAll(rangePart => int.Parse(rangePart)).ToArray();
            var s     = Stopwatch.StartNew();

            Console.WriteLine("Generation is starting, please wait...");
            var done = 0;

            var items  = Enumerable.Range(0, frames).ToArray();
            var chunks = items
                         .Select((s2, i) => new { Value = s2, Index = i })
                         .GroupBy(x => x.Index / 10)
                         .Select(grp => grp.Select(x => x.Value).ToArray()).ToList();

            var threads = new List <Thread>();

            for (var t = 0; t < Environment.ProcessorCount - 1; t++)
            {
                var t2     = t;
                var thread = new Thread(() =>
                {
                    start:;
                    if (chunks.Count == 0)
                    {
                        goto exit;
                    }

                    var assignedChunk = chunks[0];
                    chunks.RemoveAt(0);
                    foreach (var a in assignedChunk)
                    {
                        var pow   = PMath.Map(a, 1, frames, range[0], range[1]);
                        var Image = new PSprite(res[0], res[1]);

                        var pixels = Image.Art.GetPixels();
                        for (var y = 0; y < Image.Height; y++)
                        {
                            for (var x = 0; x < Image.Width; x++)
                            {
                                var xTarget = 4f;
                                var yTarget = (xTarget / Image.Width) * Image.Height;

                                var x2 = (x / (Image.Width / (xTarget))) - (xTarget / 2);
                                var y2 = (y / (Image.Height / (yTarget))) - (yTarget / 2);

                                var c         = new Complex(x2, y2);
                                var z         = Complex.Zero;
                                var max       = -1f;
                                var maxWasHit = false;
                                for (var i = 0; i < maxDepth; i++)
                                {
                                    z = (Complex.Pow(z, pow)) + c;
                                    if ((z.Real * z.Real) + (z.Imaginary * z.Imaginary) > 16 && max == -1f)
                                    {
                                        max       = i;
                                        maxWasHit = true;
                                        break;
                                    }
                                }

                                var color = PColor.Black;

                                if (maxWasHit)
                                {
                                    var floorMax = (int)Math.Floor(max);
                                    var c1       = pallet[floorMax % pallet.Length];
                                    var c2       = pallet[(floorMax + 1) % pallet.Length];
                                    color        = PColor.Lerp(c1, c2, 0.5f);
                                }

                                var pos = ((y * Image.Width) + x) * 4;

                                pixels[pos]     = (byte)(color.R);
                                pixels[pos + 1] = (byte)(color.G);
                                pixels[pos + 2] = (byte)(color.B);
                                pixels[pos + 3] = 255;
                            }
                        }
                        Image.Art.SetPixels(pixels);
                        Image.Save(folder + a.ToString("000000") + ".png");
                        var percent           = (done / (float)frames);
                        var remaining         = (1f - percent) * 100;
                        var secondsPerPercent = s.Elapsed.TotalSeconds / (percent * 100f);
                        var minutesRemaining  = ((secondsPerPercent * remaining) / 60f);
                        var estimatedTime     = DateTime.Now.AddMinutes(done == 0 ? 0 : minutesRemaining);
                        Console.WriteLine("Progress: " + done + "/" + frames + "  " + (percent * 100f).ToString("0.00") +
                                          "%   Estimated completion time: " + estimatedTime);
                        done++;
                    }
                    goto start;
                    exit:;
                })
                {
                    Name     = "Mandelbrot: Core " + (t + 1),
                    Priority = ThreadPriority.AboveNormal,
                };
                threads.Add(thread);
                thread.Start();
            }
            ;

            var info = new ProcessStartInfo()
            {
                FileName         = "ffmpeg",
                Arguments        = string.Format(" -framerate {0} -i %06d.png -c:v libx264 -r {0} {1}.mp4", framerate, name),
                WorkingDirectory = folder,
            };

            var activeThreads = 1;

            do
            {
                Console.Title = "Active thread count: " + activeThreads;
                activeThreads = threads.Where(t => t.IsAlive).Count();
                Thread.Sleep(1000);
                Title(activeThreads);
            }while (activeThreads > 0);

            Console.Title = "Active thread count: 0";

            var p = Process.Start(info);

            p.WaitForExit();

            Console.WriteLine(@"Saved as " + folder + "out.mp4");
            Console.ReadLine();
            Close();
        }
Example #5
0
    private FutureMove?CheckCols(
        Board board,
        int col,
        Player player,
        CheckType checkType)
    {
        List <bool> threeInLine = new List <bool>(3);
        Piece       piece;

        PColor enemyColor =
            color == PColor.White ? PColor.Red : PColor.White;

        PShape enemyShape =
            color == PColor.White ? PShape.Square : PShape.Round;

        for (int i = 0; i < board.rows; i++)
        {
            if (board[i, col] == null)
            {
                return(null);
            }

            piece = (Piece)board[i, col];

            if (checkType == CheckType.color)
            {
                if (piece.color == board.Turn)
                {
                    threeInLine.Add(true);
                }
                else
                {
                    threeInLine.RemoveRange(0, threeInLine.Count);
                }
            }
            else
            {
                if (piece.shape == shape)
                {
                    threeInLine.Add(true);
                }
                else
                {
                    threeInLine.RemoveRange(0, threeInLine.Count);
                }
            }

            if (threeInLine.Count == 3)
            {
                if (!board.IsColumnFull(col))
                {
                    if (board[i + 1, col].HasValue ||
                        i == board.rows)
                    {
                        piece = (Piece)board[i + 1, col];

                        if (checkType == CheckType.color)
                        {
                            if (piece.color == enemyColor)
                            {
                                threeInLine.RemoveRange(
                                    0,
                                    threeInLine.Count);
                            }
                            else
                            if (piece.shape == enemyShape)
                            {
                                threeInLine.RemoveRange(
                                    0,
                                    threeInLine.Count);
                            }
                        }
                    }
                    else
                    {
                        if (player == Player.me)
                        {
                            myWinCorridors.Add(new Play(col, i, win));
                        }
                        else
                        {
                            myWinCorridors.Add(new Play(col, i, block));
                        }

                        return(new FutureMove(col, shape));
                    }
                }
            }
        }

        return(null);
    }
Example #6
0
 public HumanPlayer(PColor Color, Form1 Window)
     : base(Player.PlayerType.Human, Color)
 {
     this.Window = Window;
 }
Example #7
0
 // constructor
 public Rook(PColor PieceColor)
 {
     m_Color = PieceColor;
     m_Value = PValue.Rook;
     m_Type = (m_Color == PColor.White) ? PType.WhiteRook : PType.BlackRook;
 }
Example #8
0
 /// <summary>Create a new piece.</summary>
 /// <param name="color">The piece color.</param>
 /// <param name="shape">The piece shape.</param>
 public Piece(PColor color, PShape shape)
 {
     this.color = color;
     this.shape = shape;
 }
        private Color toColor(PColor pcolor)
        {
            Color newColor = new Color(pcolor.RGBA);

            return(newColor);
        }
Example #10
0
 // constructor
 public King(PColor PieceColor)
 {
     m_Color = PieceColor;
     m_Value = PValue.King;
     m_Type = (m_Color == PColor.White) ? PType.WhiteKing : PType.BlackKing;
 }
Example #11
0
        // Negamax with alpha beta pruning.
        private (FutureMove move, float score) Negamax(
            Board board, CancellationToken ct, PColor turn, int depth,
            float alpha, float beta)
        {
            (FutureMove move, float score)currentMove;

            Winner winner;

            // In case of cancellation request, skips rest of algorithm.
            if (ct.IsCancellationRequested)
            {
                // Makes no move.
                currentMove = (FutureMove.NoMove, float.NaN);
            }

            // If game has ended, returns final score.
            else if ((winner = board.CheckWinner()) != Winner.None)
            {
                // Oizys wins, returns maximum score.
                if (winner.ToPColor() == turn)
                {
                    currentMove = (FutureMove.NoMove, float.PositiveInfinity);
                }

                // Opponent wins, returns minimum score.
                else if (winner.ToPColor() == turn.Other())
                {
                    currentMove = (FutureMove.NoMove, float.NegativeInfinity);
                }

                // A draw board, return 0.
                else
                {
                    currentMove = (FutureMove.NoMove, 0f);
                }
            }

            // If maximum depth has been reached, get heuristic value.
            else if (depth == maxDepth)
            {
                currentMove = (FutureMove.NoMove, Heuristic(board, turn));
            }

            // Board isn't final and maximum depth hasn't been reached.
            else
            {
                // Set up currentMove for future maximizing.
                currentMove = (FutureMove.NoMove, float.NegativeInfinity);

                // Iterate each column.
                for (int c = 0; c < Cols; c++)
                {
                    // If column is full, skip to next column.
                    if (board.IsColumnFull(c))
                    {
                        continue;
                    }

                    // Try both shapes.
                    for (int s = 0; s < 2; s++)
                    {
                        // Store current shape.
                        PShape shape = (PShape)s;

                        // If player doesn't have this piece, skip.
                        if (board.PieceCount(turn, shape) == 0)
                        {
                            continue;
                        }

                        // Test move.
                        board.DoMove(shape, c);

                        // Call Negamax and register board's score.
                        float score = -Negamax(
                            board, ct, turn.Other(), depth + 1, -beta,
                            -alpha).score;

                        // Undo move.
                        board.UndoMove();

                        // If this move has the best score yet, keep it.
                        if (score > currentMove.score)
                        {
                            currentMove = (new FutureMove(c, shape), score);
                        }

                        // Update alpha value.
                        if (score > alpha)
                        {
                            alpha = score;
                        }

                        // Beta pruning.
                        if (alpha >= beta)
                        {
                            return(currentMove);
                        }
                    }
                }
            }

            // Returns move and its value.
            return(currentMove);
        }
Example #12
0
        // Heuristic that iterates win corridors and changes its score
        // based on the pieces in each of those corridors.
        // Aditionally, this version also gives extra value to absolute sequences
        // (sequences of pieces with same color and shape).
        private float Heuristic(Board board, PColor turn)
        {
            // Heuristic score.
            float score = 0;

            // Iterate every win corridor in the board.
            foreach (IEnumerable <Pos> corridor in board.winCorridors)
            {
                // Stores sequence of pieces found.
                float sequence = 0, range = 0;

                // Iterate every position in the corridor.
                foreach (Pos pos in corridor)
                {
                    // Try to get piece in current board position.
                    Piece?piece = board[pos.row, pos.col];

                    range += 1;

                    // Check if there is a piece.
                    if (piece.HasValue)
                    {
                        // Has same shape and color as player.
                        if (piece.Value.shape == turn.Shape() &&
                            piece.Value.color == turn)
                        {
                            // Add 2 points.
                            score += 2;

                            sequence += 1;
                        }

                        // Has same shape but different color as player.
                        else if (piece.Value.shape == turn.Shape() &&
                                 piece.Value.color != turn)
                        {
                            // Add 1 point.
                            score += 1;
                        }

                        // Has different shape but same color as player.
                        else if (piece.Value.shape != turn.Shape() &&
                                 piece.Value.color == turn)
                        {
                            // Remove 1 point.
                            score -= 1;
                        }

                        // Has different shape and color as player.
                        else if (piece.Value.shape != turn.Shape() &&
                                 piece.Value.color != turn)
                        {
                            // Remove 2 points.
                            score -= 2;

                            if (range < WinSequence)
                            {
                                sequence = 0;
                            }

                            range = 0;
                        }
                    }

                    if (range == WinSequence)
                    {
                        if (sequence == WinSequence)
                        {
                            score += 50;
                        }

                        if (sequence == (WinSequence - 1))
                        {
                            score += 10;
                        }

                        if (sequence == (WinSequence - 2))
                        {
                            score += 5;
                        }
                    }
                }
            }

            // Return the final heuristic score.
            return(score);
        }
Example #13
0
 // constructor
 public Bishop(PColor PieceColor)
 {
     m_Color = PieceColor;
     m_Value = PValue.Bishop;
     m_Type = (m_Color == PColor.White) ? PType.WhiteBishop : PType.BlackBishop;
 }
Example #14
0
 // constructor
 public Knight(PColor PieceColor)
 {
     m_Color = PieceColor;
     m_Value = PValue.Knight;
     m_Type = (m_Color == PColor.White) ? PType.WhiteKnight : PType.BlackKnight;
 }
        /// Current thinker makes its move
        private Winner Play()
        {
            // Get a reference to the current thinker
            IThinker thinker = matchData.CurrentThinker;

            // Determine the color of the current thinker
            PColor color = board.Turn;

            // Match result so far
            Winner winner = Winner.None;

            // Real think time in milliseconds
            int thinkTimeMillis;

            // Apparent thinking time left
            int timeLeftMillis;

            // Task to execute the thinker in a separate thread
            Task <FutureMove> thinkTask;

            // Start stopwatch
            stopwatch.Restart();

            // Notify listeners that next turn is about to start
            NextTurn?.Invoke(color, thinker.ToString());

            // Ask thinker to think about its next move
            thinkTask = Task.Run(
                () => thinker.Think(board.Copy(), ts.Token));

            // The thinking process might throw an exception, so we wrap
            // task waiting in a try/catch block
            try
            {
                // Wait for thinker to think... until the allowed time limit
                if (thinkTask.Wait(timeLimitMillis))
                {
                    // Thinker successfully made a move within the time limit

                    // Get the move selected by the thinker
                    FutureMove move = thinkTask.Result;

                    // Was the thinker able to chose a move?
                    if (move.IsNoMove)
                    {
                        // Thinker was not able to chose a move

                        // Raise an invalid play event and set the other
                        // thinker as the winner of the match
                        winner = OnInvalidPlay(
                            color, thinker,
                            "Thinker unable to perform move");
                    }
                    else
                    {
                        // Thinker was able to chose a move

                        // Perform move in game board, get column where move
                        // was performed
                        int row = board.DoMove(move.shape, move.column);

                        // If the column had space for the move...
                        if (row >= 0)
                        {
                            // Obtain thinking end time
                            thinkTimeMillis =
                                (int)stopwatch.ElapsedMilliseconds;

                            // How much time left for the minimum apparent move
                            // time?
                            timeLeftMillis =
                                minMoveTimeMillis - thinkTimeMillis;

                            // Was the minimum apparent move time reached
                            if (timeLeftMillis > 0)
                            {
                                // If not, wait until it is reached
                                Thread.Sleep(timeLeftMillis);
                            }

                            // Notify listeners of the move performed
                            MovePerformed?.Invoke(
                                color, thinker.ToString(),
                                move, thinkTimeMillis);

                            // Get possible winner and solution
                            winner = board.CheckWinner(solution);
                        }
                        else
                        {
                            // If we get here, column didn't have space for the
                            // move, which means that thinker made an invalid
                            // move and should lose the game


                            // Raise an invalid play event and set the other
                            // thinker as the winner of the match
                            winner = OnInvalidPlay(
                                color, thinker,
                                "Tried to place piece in column "
                                + $"{move.column}, which is full");
                        }
                    }
                }
                else // Did the time limit expired?
                {
                    // Notify thinker to voluntarily stop thinking
                    ts.Cancel();

                    // Try to wait a bit more
                    if (!thinkTask.Wait(
                            UncooperativeThinkerException.HardThinkingLimitMs))
                    {
                        // If the thinker didn't terminate, throw an
                        // exception which will eventually terminate the app
                        throw new UncooperativeThinkerException(thinker);
                    }

                    // Raise an invalid play event and set the other thinker
                    // as the winner of the match
                    winner = OnInvalidPlay(
                        color, thinker, "Time limit expired");
                }
            }
            catch (UncooperativeThinkerException)
            {
                // This exception is bubbled up, terminating the app
                throw;
            }
            catch (Exception e)
            {
                // Is this an inner exception?
                if (e.InnerException != null)
                {
                    // If so, use it for error message purposes
                    e = e.InnerException;
                }

                // Raise an invalid play event and set the other thinker as
                // the winner of the match
                winner = OnInvalidPlay(
                    color, thinker,
                    $"Thinker exception: '{e.Message}'");
            }

            // Notify listeners that the board was updated
            BoardUpdate?.Invoke(board);

            // Return winner
            return(winner);
        }
Example #16
0
        private Play Negamax(int depth, Board board, PColor turn, CancellationToken cancellationToken, int alpha = int.MinValue, int beta = int.MaxValue)
        {
            Play   selectedMove = new Play(null, int.MinValue);
            PColor nextTurn     = (turn == PColor.Red) ? PColor.White : PColor.Red;

            if (cancellationToken.IsCancellationRequested)
            {
                return(new Play(null, 0));
            }

            if (depth <= 0)
            {
                int tempScore = _random.Next(0, 100);

                if (board.CheckWinner() != Winner.None)
                {
                    tempScore = 300;
                }
                tempScore += board.winCorridors.Count() * 10;

                if (tempScore % 2 != 0)
                {
                    tempScore *= -1;
                }
                selectedMove.Score = tempScore;


                return(selectedMove);
            }
            for (int j = 0; j < board.cols; j++)
            {
                int column = j;
                for (int i = 0; i < board.rows; i++)
                {
                    if (board[i, j] == null)
                    {
                        int  roundPieces  = board.PieceCount(board.Turn, PShape.Round);
                        int  squarePieces = board.PieceCount(board.Turn, PShape.Square);
                        Play move         = default;

                        if (roundPieces > 0)
                        {
                            shape = PShape.Round;
                            board.DoMove(shape, j);
                            if ((board.CheckWinner() == Winner.None))
                            {
                                move = Negamax(depth - 1, board, nextTurn, cancellationToken, -beta, -alpha);
                            }
                            board.UndoMove();
                            move.Score = -move.Score;
                            if (move.Score > bestMove.Score)
                            {
                                bestMove = move;
                            }

                            if (bestMove.Score > alpha)
                            {
                                alpha = bestMove.Score;
                            }

                            if (bestMove.Score >= beta)
                            {
                                bestMove.Score    = alpha;
                                bestMove.Position = column;
                                return(bestMove);
                            }
                        }

                        if (squarePieces > 0)
                        {
                            shape = PShape.Square;
                            board.DoMove(shape, j);
                            if ((board.CheckWinner() == Winner.None))
                            {
                                move = Negamax(depth - 1, board, nextTurn, cancellationToken, -beta, -alpha);
                            }
                            board.UndoMove();
                            if (move.Score > bestMove.Score)
                            {
                                bestMove = move;
                            }

                            if (bestMove.Score > alpha)
                            {
                                alpha = bestMove.Score;
                            }

                            if (bestMove.Score >= beta)
                            {
                                bestMove.Score    = alpha;
                                bestMove.Position = column;
                                return(bestMove);
                            }
                        }
                    }
                }
            }
            return(bestMove);
        }
Example #17
0
        //////////////////////////////////////////////////////////////////////////
        // Public Methods
        //////////////////////////////////////////////////////////////////////////
        #region Public Methods

        // constructor
        public Pawn(PColor PieceColor)
        {
            m_Color = PieceColor;
            m_Value = PValue.Pawn;
            m_Type  = (m_Color == PColor.White) ? PType.WhitePawn : PType.BlackPawn;
        }
Example #18
0
 public Piece( PColor piece_color)
 {
     clr = piece_color;
 }
Example #19
0
 /// <summary>Indexer for getting a player based on his color.</summary>
 /// <param name="color">Player color.</param>
 /// <returns>The player associated with the given color.</returns>
 /// <exception cref="System.InvalidOperationException">
 /// Thrown when an invalid color is given.
 /// </exception>
 public                  IPlayer this[PColor color] => color == PColor.White ? player1
         : color == PColor.Red ? player2
             : throw new InvalidOperationException(
           $"Invalid player color");
Example #20
0
 public override bool IsAccessibleFor(PColor Color)
 {
     return(true);
 }
Example #21
0
 abstract public bool IsAccessibleFor(PColor Color);
Example #22
0
    private Play Negamax(
        Board board,
        PColor turn,
        int maxDepth,
        CancellationToken ct)
    {
        Play bestMove = new Play(null, null, int.MinValue);

        PColor proxTurn =
            turn == PColor.Red ? PColor.White : PColor.Red;

        if (ct.IsCancellationRequested)
        {
            return(new Play(null, null, 0));
        }
        else
        {
            if (cDepth == maxDepth)
            {
                return(bestMove);
            }

            cDepth++;

            foreach (Play play in myWinCorridors)
            {
                for (int j = 0; j < board.cols; j++)
                {
                    int pos = j;

                    if (board[(int)play.posCol, (int)play.posRow] == null)
                    {
                        int roundPieces =
                            board.PieceCount(board.Turn, PShape.Round);

                        int squarePieces =
                            board.PieceCount(board.Turn, PShape.Square);

                        if (shape == PShape.Round)
                        {
                            if (roundPieces == 0)
                            {
                                shape = PShape.Square;
                            }
                            else
                            if (squarePieces == 0)
                            {
                                shape = PShape.Round;
                            }
                        }

                        Play move = default;

                        board.DoMove(shape, j);

                        if (board.CheckWinner() == Winner.None)
                        {
                            move = Negamax(board, proxTurn, maxDepth, ct);
                        }

                        board.UndoMove();

                        move.score = -move.score;

                        if (move.score > bestMove.score)
                        {
                            bestMove.score  = move.score;
                            bestMove.posCol = pos;
                        }
                    }
                }
            }

            return(bestMove);
        }
    }
Example #23
0
 // Renders info about the next turn
 private void NextTurn(PColor thinkerColor, string thinkerName)
 {
     Console.WriteLine($"{thinkerColor.FormatName(thinkerName)} turn");
 }
Example #24
0
    public FutureMove Think(Board board, CancellationToken ct)
    {
        FutureMove?test;
        Play       play;

        random = new Random();

        color = board.Turn;

        if (color == PColor.White)
        {
            shape = PShape.Round;
        }

        else
        {
            shape = PShape.Square;
        }

        if (shape == PShape.Round &&
            board.PieceCount(color, PShape.Round) == 0)
        {
            shape = PShape.Square;
        }

        else if (shape == PShape.Square &&
                 board.PieceCount(color, PShape.Square) == 0)
        {
            shape = PShape.Round;
        }

        Check(board);

        test = CheckPlayer(board, Player.me);
        if (test != null)
        {
            return((FutureMove)test);
        }

        test = CheckPlayer(board, Player.enemy);
        if (test != null)
        {
            return((FutureMove)test);
        }

        PColor myColor = board.Turn;
        PShape myShape = shape;

        CheckWinCorridors(Player.me, myColor, myShape, board);

        PColor enemyColor =
            color == PColor.White ? PColor.Red : PColor.White;
        PShape enemyShape =
            shape == PShape.Round ? PShape.Square : PShape.Round;

        CheckWinCorridors(Player.enemy, enemyColor, enemyShape, board);

        play = Negamax(board, board.Turn, maxDepth, ct);

        if (test != null)
        {
            if (play.posCol == null)
            {
                return(FutureMove.NoMove);
            }

            else
            {
                return(new FutureMove((int)play.posCol, PShape.Round));
            }
        }

        return(new FutureMove(random.Next(0, board.cols), shape));
    }
Example #25
0
 // Displays notification that the specified thinker lost due to an
 // invalid play
 private void InvalidMove(
     PColor thinkerColor, string thinkerName, string reason)
 {
     Console.WriteLine(String.Format("{0} loses match! Reason: {1}",
                                     thinkerColor.FormatName(thinkerName), reason));
 }
Example #26
0
        private void pnlChart_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                if (needDraw)
                {
                    Font  font         = new Font("微软雅黑", 12);
                    SizeF size         = e.Graphics.MeasureString("第1排第5层", font);
                    float adjustHeight = Math.Abs(size.Height - cellHeight) / 2;
                    size = e.Graphics.MeasureString("13", font);
                    float adjustWidth = (cellWidth - size.Width) / 2;

                    for (int i = 0; i <= 1; i++)
                    {
                        int key = currentPage * 2 + i - 1;
                        if (!shelf.ContainsKey(key))
                        {
                            DataRow[] rows = cellTable.Select(string.Format("ShelfCode='{0}'", ShelfCode[key]), "CellCode desc");
                            shelf.Add(key, rows);
                        }

                        DrawShelf(shelf[key], e.Graphics, top[i], font, adjustWidth);

                        int tmpLeft = left + columns * cellWidth + 5;

                        for (int j = 0; j < rows; j++)
                        {
                            string s = string.Format("第{0}排第{1}层", key, Convert.ToString(rows - j).PadLeft(2, '0'));
                            e.Graphics.DrawString(s, font, Brushes.DarkCyan, tmpLeft, top[i] + (j + 1) * cellHeight + adjustHeight);
                        }
                    }

                    if (filtered)
                    {
                        int i = currentPage * 2;
                        foreach (DataGridViewRow gridRow in dgvMain.Rows)
                        {
                            DataRowView cellRow = (DataRowView)gridRow.DataBoundItem;
                            int         shelf   = 0;
                            for (int j = 1; j <= ShelfCode.Count; j++)
                            {
                                if (ShelfCode[j].CompareTo(cellRow["ShelfCode"].ToString()) >= 0)
                                {
                                    shelf = j;
                                    break;
                                }
                            }
                            if (shelf == i || shelf == i - 1)
                            {
                                int top = 0;
                                if (shelf % 2 == 0)
                                {
                                    top = pnlContent.Height / 2;
                                }

                                int column   = Convert.ToInt32(cellRow["CellColumn"]);
                                int row      = rows - Convert.ToInt32(cellRow["CellRow"]) + 1;
                                int quantity = ReturnColorFlag(cellRow["ProductCode"].ToString(), cellRow["IsActive"].ToString(), cellRow["IsLock"].ToString(), cellRow["ErrorFlag"].ToString());
                                //FillCell(e.Graphics, top, row, column, quantity);
                                FillCell(e.Graphics, top, row, column, quantity, cellRow["ShelfCode"].ToString());
                            }
                        }
                    }
                }
                PColor.Refresh();
                IsWheel = false;
            }
            catch (Exception ex)
            {
                string str = ex.Message;
            }
        }
Example #27
0
 public AIPlayer(PColor Color)
     : base(PlayerType.AI, Color)
 {
 }
Example #28
0
    /// <summary>
    /// Make a move, return row
    /// </summary>
    /// <param name="shape">
    /// Shape of piece used in move (color is obtained from
    /// <see cref="Board.Turn"/>).
    /// </param>
    /// <param name="col">Column where to drop piece.</param>
    /// <returns>Row where piece was placed or -1 if move is invalid.</returns>
    public int DoMove(PShape shape, int col)
    {
        // The row were to place the piece, initially assumed to be the top row
        int row = rows - 1;

        // The color of the piece to place, depends on who's playing
        PColor color = Turn;

        // The piece to place
        Piece piece = new Piece(color, shape);

        // If the column is not a valid column, there is a client code bug,
        // so let's throw an exception
        if (col < 0 || col >= cols)
        {
            throw new InvalidOperationException($"Invalid board column: {col}");
        }

        // If we already found a winner, there is a client code bug, so let's
        // throw an exception
        if (CheckWinner() != Winner.None)
        {
            throw new InvalidOperationException(
                      "Game is over, unable to make further moves.");
        }

        // If there are no more pieces of the specified kind, there is a client
        // bug, so let's throw an exception
        if (numberOfPieces[piece] == 0)
        {
            throw new InvalidOperationException(
                      $"No more {piece} pieces available");
        }

        // If column is already full, return negative value, indicating the
        // move is invalid
        if (board[col, row].HasValue)
        {
            return(-1);
        }

        //
        // If we get here, move is valid, so let's do it
        //

        // Find row where to place the piece
        for (int r = row - 1; r >= 0 && !board[col, r].HasValue; r--)
        {
            row = r;
        }

        // Place the piece
        board[col, row] = piece;

        // Decrease the piece count
        numberOfPieces[piece]--;

        // Remember the move
        moveSequence.Push(new Pos(row, col));

        // Increment number of moves
        numMoves++;

        // Update turn
        Turn = Turn == PColor.White ? PColor.Red : PColor.White;

        // Return true, indicating the move was successful
        return(row);
    }
Example #29
0
        public void Setup()
        {
            StartImage = PSprite.FromFilePath(StartImagePath);
            EndImage   = PSprite.FromFilePath(EndImagePath);

            if (Count)
            {
                var startCount = 0;
                var endCount   = 0;

                for (var y = 0; y < Height; y++)
                {
                    for (var x = 0; x < Width; x++)
                    {
                        if (StartImage.Art.GetPixel(x, y).A > 0)
                        {
                            startCount++;
                        }
                        if (EndImage.Art.GetPixel(x, y).A > 0)
                        {
                            endCount++;
                        }
                    }
                }

                Console.WriteLine("Start: " + startCount);
                Console.WriteLine("End: " + endCount);
                Console.ReadLine();

                return;
            }

            var startPixels = StartImage.Art.GetPixels();

            AvailablePositions = new OrderedDictionary();
            pixels             = new List <Pixel>(Width * Height);

            CalculateStart(Width, Height);

            var imagePixels = EndImage.Art.GetPixels();

            var totalDone = 0;

            var width      = Width;
            var height     = Height;
            var generating = false;
            var count      = 0;

            var distance = 0;

            for (var y = 0; y < height; y++)
            {
                for (var x = 0; x < width; x++)
                {
                    var b = (x + (y * width)) * 4;
                    var c = PColor.FromPixels(imagePixels, b);

                    if (c.A > 0)
                    {
                        if (AvailablePositions.Count == 0)
                        {
                            if (generating)
                            {
                                while (generating)
                                {
                                }
                                goto b;
                            }

                            generating = true;
                            CalculateStart(width, height);
                            generating = false;
                        }

                        b :;

                        var pos = (-1, -1);

                        distance -= 2;
                        if (distance < 0)
                        {
                            distance = 0;
                        }
                        goto endWhile; // To Skip
                        do
                        {
                            //for (var y2 = y - distance; y2 < y + distance + 1; y2++)
                            //{
                            //    for (var x2 = x - distance; x2 < x + distance + 1; x2++)
                            //    {
                            //        if (x2 > 0 && x2 < width && y2 > 0 && y2 < height)
                            //        {
                            //            pos = Check(x2, y2);
                            //            if (pos != (-1, -1)) { goto endWhile; }
                            //        }
                            //    }
                            //}

                            for (var y2 = (int)PMath.Clamp(y - distance, 0, height - 1); y2 < (int)PMath.Clamp(y + distance + 1, 0, height - 1); y2++)
                            {
                                var minus   = (int)PMath.Clamp(x - distance, 0, width - 1);
                                var tempPos = (minus, y2);
                                pos = Available2[minus, y2] ? tempPos : (-1, -1);
                                if (pos != (-1, -1))
                                {
                                    goto endWhile;
                                }

                                var plus = (int)PMath.Clamp(x + distance, 0, width - 1);
                                tempPos = (plus, y2);
                                pos     = Available2[plus, y2] ? tempPos : (-1, -1);
                                if (pos != (-1, -1))
                                {
                                    goto endWhile;
                                }
                            }

                            for (var x2 = (int)PMath.Clamp(x - distance, 0, width - 1); x2 < (int)PMath.Clamp(x + distance + 1, 0, width - 1); x2++)
                            {
                                var minus   = (int)PMath.Clamp(y - distance, 0, height - 1);
                                var tempPos = (x2, minus);
                                pos = Available2[x2, minus] ? tempPos : (-1, -1);
                                if (pos != (-1, -1))
                                {
                                    goto endWhile;
                                }

                                var plus = (int)PMath.Clamp(y + distance, 0, height - 1);
                                tempPos = (x2, plus);
                                pos     = Available2[x2, plus] ? tempPos : (-1, -1);
                                if (pos != (-1, -1))
                                {
                                    goto endWhile;
                                }
                            }

                            if (distance > width)
                            {
                                CalculateStart(width, height);
                                distance = 0;
                            }

                            distance++;
                        }while (pos == (-1, -1));
                        endWhile :;
                        pos = ((int, int))AvailablePositions[0];
                        AvailablePositions.RemoveAt(0);

                        //AvailablePositions.Remove(pos);

                        Available2[pos.Item1, pos.Item2] = false;
                        var b2 = (pos.Item1 + (pos.Item2 * width)) * 4;

                        pixels.Add(new Pixel()
                        {
                            StartColor = PColor.FromPixels(startPixels, b2), EndColor = c, StartPos = pos, EndPos = (x, y), Offset = PMath.Random(0, Offset)
                        });
Example #30
0
 // Create an new pair (piece check function, associated player)
 public PieceFuncPlayer(
     Func <Piece, bool> checkPieceFunc, PColor player)
 {
     this.checkPieceFunc = checkPieceFunc;
     this.player         = player;
 }
Example #31
0
 /// @copydoc IMatchDataProvider.GetPlayer
 /// <seealso cref="IMatchDataProvider.GetPlayer(PColor)"/>
 public IPlayer GetPlayer(PColor player) => currentMatch[player];
Example #32
0
        //////////////////////////////////////////////////////////////////////////
        // Public Methods
        //////////////////////////////////////////////////////////////////////////
        #region Public Methods

        // constructor
        public Queen(PColor PieceColor)
        {
            m_Color = PieceColor;
            m_Value = PValue.Queen;
            m_Type  = (m_Color == PColor.White) ? PType.WhiteQueen : PType.BlackQueen;
        }
Example #33
0
        protected bool IsChecked(PColor colorToCheck)
        {
            int indexOfKing = 0;

            // find king piece
            for (; indexOfKing < GameData.g_CurrentGameState.Length; indexOfKing++)
            {
                if (GameData.g_CurrentGameState[indexOfKing] != null)
                {
                    if (colorToCheck == PColor.Black)
                    {
                        if (GameData.g_CurrentGameState[indexOfKing].GetPieceType() == PType.BlackKing)
                            break;
                    }
                    else if (colorToCheck == PColor.White)
                    {
                        if (GameData.g_CurrentGameState[indexOfKing].GetPieceType() == PType.WhiteKing)
                            break;
                    }
                }
            }

            // see if it's being attacked
            if (colorToCheck == PColor.Black)
            {
                if (GameData.g_SquaresAttackedByWhite.Contains(indexOfKing))
                    return true;
            }
            else if (colorToCheck == PColor.White)
            {
                if (GameData.g_SquaresAttackedByBlack.Contains(indexOfKing))
                    return true;
            }

            return false;
        }
Example #34
0
 /// <summary>Name and color of given player.</summary>
 /// <param name="color">Color of player to get name/color of.</param>
 /// <returns>A string with the name and color of player.</returns>
 public string PlrNameColor(PColor color) =>
 color.FormatName(matchData.GetThinker(color).ToString());
 public void ToPColor_CorrectPColor_No(Winner winner, PColor color)
 {
     Assert.NotEqual(color, winner.ToPColor());
 }
Example #36
0
 /// <summary>Is the piece of the specified color and shape?</summary>
 /// <param name="color">The piece color.</param>
 /// <param name="shape">The piece shape.</param>
 /// <returns>
 /// `true` if the piece has the specified color and shape, `false`
 /// otherwise.
 /// </returns>
 public bool Is(PColor color, PShape shape) =>
 this.color == color && this.shape == shape;
Example #37
0
 public Player(PlayerType Type, PColor Color)
 {
     this.Type  = Type;
     this.Color = Color;
 }
Example #38
0
 // constructor
 public Pawn(PColor PieceColor)
 {
     m_Color = PieceColor;
     m_Value = PValue.Pawn;
     m_Type = (m_Color == PColor.White) ? PType.WhitePawn : PType.BlackPawn;
 }
Example #39
0
 // constructor
 public Queen(PColor PieceColor)
 {
     m_Color = PieceColor;
     m_Value = PValue.Queen;
     m_Type = (m_Color == PColor.White) ? PType.WhiteQueen : PType.BlackQueen;
 }