Example #1
0
        /// <summary>CounterSection constructor.</summary>
        public CounterSection(CounterSheet counterSheet, CounterSectionProperties properties, List <Piece> pieceList)
        {
            this.counterSheet = counterSheet;
            type = properties.Type;
            frontImageLocation = properties.FrontImageLocation;
            for (int i = (int)counterSheet.Properties.FrontImageResolution; i > 0; --i)
            {
                frontImageLocation = new RectangleF(frontImageLocation.X * 2, frontImageLocation.Y * 2, frontImageLocation.Width * 2, frontImageLocation.Height * 2);
            }
            backImageLocation = properties.BackImageLocation;
            for (int i = (int)counterSheet.Properties.BackImageResolution; i > 0; --i)
            {
                backImageLocation = new RectangleF(backImageLocation.X * 2, backImageLocation.Y * 2, backImageLocation.Width * 2, backImageLocation.Height * 2);
            }

            // create pieces for that section
            pieceFrontSize = new SizeF(
                frontImageLocation.Width / properties.Columns,
                frontImageLocation.Height / properties.Rows);
            pieceBackSize = new SizeF(
                backImageLocation.Width / properties.Columns,
                backImageLocation.Height / properties.Rows);
            pieceFrontDiagonal = (float)Math.Sqrt(pieceFrontSize.Width * pieceFrontSize.Width + pieceFrontSize.Height * pieceFrontSize.Height);
            pieceBackDiagonal  = (float)Math.Sqrt(pieceBackSize.Width * pieceBackSize.Width + pieceBackSize.Height * pieceBackSize.Height);
            shadowLength       = properties.ShadowLength;
            supply             = properties.Supply;
            pieces             = new Piece[properties.Rows * properties.Columns * properties.Supply];
            for (int row = 0; row < properties.Rows; ++row)
            {
                for (int col = 0; col < properties.Columns; ++col)
                {
                    for (int copy = 0; copy < properties.Supply; ++copy)
                    {
                        Piece piece = (counterSheet.Properties.Type == CounterSheetType.Terrain ?
                                       (Piece) new TerrainPrototype(pieceList.Count, this, row, col) :
                                       (Piece) new Counter(pieceList.Count, this, row, col));
                        pieces[(row * properties.Columns + col) * properties.Supply + copy] = piece;
                        pieceList.Add(piece);
                    }
                }
            }
        }
Example #2
0
        /// <summary>Returns the top-most piece (but not terrain) at a given position on this board.</summary>
        /// <param name="position">Position in local coordinates.</param>
        /// <returns>A piece or null.</returns>
        public IPiece GetPieceAtPosition(PointF position)
        {
            // for each layer (bottom layer is for unpunched pieces, next layer is for punched cards, top layer is for punched counters)
            for (int layer = 2; layer >= 0; --layer)
            {
                for (int pass = 0; pass < 2; ++pass)
                {
                    for (int i = Stacks.Count - 1; i >= 0; --i)
                    {
                        Stack    stack  = Stacks[i];
                        IPiece[] pieces = stack.Pieces;
                        if (stack.Unfolded == (pass == 0) &&
                            !(pieces[0] is ITerrain) &&
                            ((layer == 0 && stack.AttachedToCounterSection) ||
                             (layer == 1 && !stack.AttachedToCounterSection && pieces[0] is ICard) ||
                             (layer == 2 && !stack.AttachedToCounterSection && pieces[0] is ICounter)) &&
                            stack.BoundingBox.Contains(position))
                        {
                            // ignore attached pieces on the opposite side
                            ICounterSection    counterSection = pieces[0].CounterSection;
                            CounterSectionType type           = counterSection.Type;
                            if (!stack.AttachedToCounterSection ||
                                (counterSection.ContainsCounters && ((int)type & ((int)((ICounterSheet)this).Side + 1)) != 0) ||
                                (!counterSection.ContainsCounters && counterSection.HasCardFaceOnFront == (((ICounterSheet)this).Side == Side.Front)))
                            {
                                for (int j = pieces.Length - 1; j >= 0; --j)
                                {
                                    IPiece piece = pieces[j];
                                    if (piece.BoundingBox.Contains(position))
                                    {
                                        // we have to compute the model coordinates of the position
                                        // relative to the counter sheet

                                        // we have to handle rotations of the piece
                                        // apply the inverse rotation to the position
                                        PointF piecePosition       = piece.Position;
                                        PointF transformedPosition = new PointF(
                                            position.X - piecePosition.X,
                                            position.Y - piecePosition.Y);

                                        if (piece.RotationAngle != 0.0f)
                                        {
                                            // rotation:
                                            // x <- x * cos - y * sin
                                            // y <- x * sin + y * cos
                                            float sin = (float)Math.Sin(piece.RotationAngle);
                                            float cos = (float)Math.Cos(piece.RotationAngle);

                                            transformedPosition = new PointF(
                                                transformedPosition.X * cos - transformedPosition.Y * sin,
                                                transformedPosition.X * sin + transformedPosition.Y * cos);
                                        }

                                        SizeF size = piece.Size;
                                        if (new RectangleF(
                                                -size.Width * 0.5f,
                                                -size.Height * 0.5f,
                                                size.Width,
                                                size.Height).Contains(transformedPosition))
                                        {
                                            // is the piece completely transparent at that location?
                                            if (piece.Graphics != null)
                                            {
                                                uint color = piece.Graphics.GetColorAtPosition(transformedPosition);
                                                if ((color & 0xFF000000) != 0x00000000)
                                                {
                                                    // no it is not
                                                    if (!stack.Unfolded && piece is ICard)
                                                    {
                                                        return(pieces[pieces.Length - 1]);
                                                    }
                                                    else
                                                    {
                                                        return(piece);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }