// vracia objekty puzzle novych kuskov, este bez pociatocnych nastaveni
        public static void CreatePieces(PuzzleGameData data)
        {
            int pocetKuskov = data.PiecesCount;

            data.Pieces = new List <PuzzlePiece>();

            for (int i = 0; i < pocetKuskov; i++)
            {
                data.Pieces.Add(new PuzzlePiece());
                data.Pieces[i].ID = i;
                data.Pieces[i].SizeOfPieceImage = new Size(data.PieceDimensions.Width + 2 * data.PieceSurroundingSize,
                                                           data.PieceDimensions.Height + 2 * data.PieceSurroundingSize);
                data.Pieces[i].SizeOfPiece = data.PieceDimensions;
                // zatial nie je spojeny s dalsimi kuskami
                data.Pieces[i].LeftNeighbor   = null;
                data.Pieces[i].TopNeighbor    = null;
                data.Pieces[i].RightNeighbor  = null;
                data.Pieces[i].BottomNeighbor = null;

                // povodni susedia, nastavime neskor pomocou SetPiecesOriginalNeighbours()
                data.Pieces[i].OriginalLeftNeighbor   = null;
                data.Pieces[i].OriginalTopNeighbor    = null;
                data.Pieces[i].OriginalRightNeighbor  = null;
                data.Pieces[i].OriginalBottomNeighbor = null;

                // ci su kusky na spravnom mieste
                data.Pieces[i].IsInTheRightPlace_Current = false;
                data.Pieces[i].IsInTheRightPlace_Final   = false;

                data.Pieces[i].VisitState = false;
            }
        }
        // prednastavi objekty reprezentujuce jednotlive kusky, obrazok kusku, pozicia, kolizne miesta, ...
        public static void SetPiecesImages(PuzzleGameData data)
        {
            //Vytvorime pole vykrojenych obrazkov pre puzzle kusky
            Bitmap[] puzzleShapes = CreatePuzzleShapeImagesFromSourceImage(data);


            //Vykrojene obrazky aplikujeme na kusky
            for (int i = 0; i < data.PiecesCount; i++)
            {
                data.Pieces[i].PieceImage = puzzleShapes[i];
            }
        }
        // pozicia puzzle kuska vramci poskladaneho puzzle, pouzite pri vypocte spravnosti zlozenych kuskov
        public static void SetOriginalPiecesLocations(PuzzleGameData data)
        {
            Point[] locations = GenerateOriginalPiecesLocations(data.GameBoardStartPosition,
                                                                data.PieceDimensions,
                                                                data.PieceSurroundingSize,
                                                                data.PiecesGridDimensions);

            for (int i = 0; i < data.PiecesCount; i++)
            {
                data.Pieces[i].OriginalPosition = locations[i];
                data.Pieces[i].CurrentPosition  = locations[i];
            }
        }
        // vystrihne jednotlive kusku zo zdrojoveho obrazka za pomoci metody CreatePuzzleShapePath
        private static Bitmap[] CreatePuzzleShapeImagesFromSourceImage(PuzzleGameData data)
        {
            Bitmap[] pShapes = new Bitmap[data.PiecesCount];

            //Pre zjednodesenie vyrezavania pridame hranu hrubky SurroundingSize okolo zdrojoveho obrazka,
            //sourceImage == obrazok + hrany dookola
            int hrubkaHrany = data.PieceSurroundingSize;
            int gridWidth   = data.PiecesGridDimensions.Width;
            int gridheight  = data.PiecesGridDimensions.Height;
            int pieceWidth  = data.PieceDimensions.Width;
            int pieceHeight = data.PieceDimensions.Height;

            Bitmap sourceImage = new Bitmap(data.SourcePicture.Width + 2 * hrubkaHrany,
                                            data.SourcePicture.Height + 2 * hrubkaHrany);

            using (Graphics draw = Graphics.FromImage(sourceImage))
            {
                draw.DrawImage(data.SourcePicture, new Point(hrubkaHrany, hrubkaHrany));
            }

            //Vyrezavanie jednotlivych kuskov

            int x = 0, y = 0;
            //Point startP = new Point(x, y);
            //Point endP = new Point((x + pieceWidth + 2 * hrubkaHrany),
            //                       (y + pieceHeight + 2 * hrubkaHrany));
            GraphicsPath shapePath;

            int index;

            for (int j = 0; j < gridheight; j++)
            {
                for (int i = 0; i < gridWidth; i++)
                {
                    index          = j * gridWidth + i;
                    pShapes[index] = PictureEditor.CropImage(sourceImage,
                                                             new Point(x, y),
                                                             new Point((x + pieceWidth + 2 * hrubkaHrany),
                                                                       (y + pieceHeight + 2 * hrubkaHrany)));

                    shapePath      = CreatePuzzleShapePath(hrubkaHrany, data.PieceDimensions, data.Pieces[index].Arrangement);
                    pShapes[index] = PieceCutter.CutOut(pShapes[index], shapePath);

                    x += pieceWidth;
                }
                x  = 0;
                y += pieceHeight;
            }

            return(pShapes);
        }
        // nastavi jednotlivym kuskom ich tvary stran
        public static void SetPiecesArrangement(PuzzleGameData data)
        {
            if (data.Pieces != null)
            {
                PieceArrangement[] arrang = GeneratePiecesArrangement(data.PiecesGridDimensions);

                for (int i = 0; i < data.PiecesCount; i++)
                {
                    data.Pieces[i].Arrangement = arrang[i];
                }
            }
            else
            {
                MessageBox.Show("Neboli vytvorene instancie PuzzlePiece!", "Runtime Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        //pre kazdy kusok nastavi ich originalnych susedov
        public static void SetPiecesOriginalNeighbours(PuzzleGameData data)
        {
            int indexCurrPiece;

            int gridWidth             = (data.PiecesGridDimensions.Width - 1);
            int gridHeight            = (data.PiecesGridDimensions.Height - 1);
            int maxArrayIndex         = (data.PiecesCount - 1);
            List <PuzzlePiece> pieces = data.Pieces;

            for (int j = 0; j < (data.PiecesGridDimensions.Height - 1); j++)
            {
                for (int i = 0; i < (data.PiecesGridDimensions.Width - 1); i++)
                {
                    // jednorozmere pole prechadzame ako dvojrozmerne
                    indexCurrPiece = (j * gridWidth + i);

                    // up neighbour
                    if ((indexCurrPiece - gridWidth) >= 0)
                    {
                        pieces[indexCurrPiece].OriginalTopNeighbor = pieces[indexCurrPiece - gridWidth];
                    }

                    // right neighbour
                    if ((i + 1) <= gridWidth)
                    {
                        pieces[indexCurrPiece].OriginalRightNeighbor = pieces[indexCurrPiece + 1];
                    }

                    // down neighbour
                    if ((indexCurrPiece + gridWidth) <= maxArrayIndex)
                    {
                        pieces[indexCurrPiece].OriginalBottomNeighbor = pieces[indexCurrPiece + gridWidth];
                    }

                    // left neighbour
                    if ((i - 1) >= 0)
                    {
                        pieces[indexCurrPiece].OriginalLeftNeighbor = pieces[indexCurrPiece - 1];
                    }
                }
            }
        }
예제 #7
0
        // Button = nova hra, zahodia sa objekty reprezentujuce staru hru, prednastavenia pred dalsou hrou
        private void button4_Click(object sender, EventArgs e)
        {
            // zoomLabel odstranime z panelu3 (tenky pasik)
            this.panel3.Controls.Clear();

            // gameboard sa prestane zobrazovat v panel-y
            this.gameboard.Visible = false;

            // odoberieme gameboard z panela, pred tym nez ho zahodime
            this.panel4.Controls.Remove(PuzzleGameUtilities.ControlByName(panel4, "gameboard"));

            // zahodime staru hraciu plochu
            gameboard = null;

            // zahodime stare data pre hru
            gameData = null;

            // vytvorime nove data pre hru
            gameData = new PuzzleGameData();

            // naspat zobrazime controls pre vyber obrazka
            textBox1.Visible           = true;
            textBox1.Text              = "";
            pictureBox1.Image          = null;
            pictureBox1.Visible        = false;
            choosePictureLabel.Visible = true;
            choosePictureLabel.BringToFront();
            autorLabel.BringToFront();
            autorLabel.Visible = true;

            button1.Visible = true;
            button2.Visible = true;

            panel5.Visible = false;  //obsahuje button3==Restart, button4==NewGame

            if (showGameInstructions)
            {
                showGameInstructions = false;
                this.panel6.Visible  = false;
            }
        }
        // vraci nadobu pod mysou, pouziva funkciu BucketCoordinates
        public static List <PuzzlePiece> BucketUnderMouse(PuzzleGameData data, Point currMouseCoords) //Skupina puzzle kuskov nachadzajuca sa pod suradnicami mysi
        {
            //
            //Vyberame skupinku kuskov najblizsiu k ukazovatelovi mysi (ak skupinka neexistuje, return null).
            //
            List <PuzzlePiece> value;
            Size realPieceSize = data.PieceDimensions;

            realPieceSize.Width  += 2 * data.PieceSurroundingSize;
            realPieceSize.Height += 2 * data.PieceSurroundingSize;

            Point bucketCoords = PuzzleGameUtilities.BucketCoordinates(realPieceSize, currMouseCoords);

            if (data.bucketOfPieces.TryGetValue(bucketCoords, out value))
            {
                return(value);
            }
            else
            {
                return(null);
            }
        }
        // ak kusok odoberame z pozicie kde bol, odoberieme ho aj z nadob, nad ktorymi boli jeho rohy
        public static void DeregisterPieceFromGrid(PuzzleGameData data, PuzzlePiece piece)
        {
            List <PuzzlePiece> value;

            Point[] pieceToRemove_Corners;
            pieceToRemove_Corners = RealPieceCornerPoints(piece.CurrentPosition,   //ziskame rohy kuska, na ktory prave ukazujeme
                                                          piece.SizeOfPieceImage); //aby sme ho odobrali zo vsetkych policok kde predtym bol

            foreach (var corner in pieceToRemove_Corners)
            {
                if (data.bucketOfPieces.TryGetValue(BucketCoordinates(piece.SizeOfPieceImage, corner), out value))
                {
                    value.Remove(piece); //odoberieme zo vsetkych List<PuzzlePiece> skupiniek(policok) kde kusok patril
                                         //metoda Remove() vracia false ak nebol najdeny objekt pre zmazanie

                    if (!value.Any())    //ak je policko sachovnice (List<>) po odobrani kuska prazdne, odoberieme ho zo zaznamu
                    {
                        data.bucketOfPieces.Remove(BucketCoordinates(piece.SizeOfPieceImage, corner));
                        value = null;
                    }
                }
            }
        }
        // funkcia nahodne rozmiestni puzzle kusky po hracom poli
        public static void RandomizePiecesLocations(PuzzleGameData data)
        {
            Random rnd = new Random();
            Point  startPos, endPos;

            startPos = new Point(data.PieceSurroundingSize, data.PieceSurroundingSize);
            endPos   = new Point((data.GameBoard.Width - (2 * data.PieceSurroundingSize + data.PieceDimensions.Width)),
                                 (data.GameBoard.Height - (2 * data.PieceSurroundingSize + data.PieceDimensions.Height)));
            foreach (var piece in data.Pieces)
            {
                //nahodna pozicia kuska v ramci hracej plochy
                piece.CurrentPosition = new Point(rnd.Next(startPos.X, endPos.X), rnd.Next(startPos.Y, endPos.Y));

                //registracia kuska do virtualnej hracej sachovnice, kde policko v sachovnici reprezentuje skupinu vsetkych kuskov puzzle ktore sa ho priamo dotykaju(prekryvaju)
                RegisterPieceInGrid(data, piece);
            }

            //using (var streamWriter = new System.IO.StreamWriter("output.txt"))
            //{
            //    foreach (var item in data.bucketOfPieces)
            //       streamWriter.WriteLine("[{0} {1}]", item.Key, item.Value);
            //}
        }
        // ak kusok polozime na novu poziciu, pridame ho do nadob, nad ktorymi su jeho rohy vyskytuju
        public static void RegisterPieceInGrid(PuzzleGameData data, PuzzlePiece piece)
        {
            List <PuzzlePiece> value;

            Point[] realPieceCorners;

            realPieceCorners = RealPieceCornerPoints(piece.CurrentPosition, piece.SizeOfPieceImage); //zistime z ktorymi polickami sa pretinaju rohy kuska
            foreach (var cornerPosition in realPieceCorners)
            {
                if (data.bucketOfPieces.TryGetValue(BucketCoordinates(piece.SizeOfPieceImage, cornerPosition), out value))
                {
                    if (value.Last() != piece) // vylucime moznost aby sme zaznamenali viacero rohov kuska do jedneho policka
                    {
                        value.Add(piece);
                    }
                }
                else
                {
                    value = new List <PuzzlePiece>();
                    value.Add(piece);
                    data.bucketOfPieces.Add(BucketCoordinates(piece.SizeOfPieceImage, cornerPosition), value);
                }
            }
        }
예제 #12
0
        // pociatocne nastavenia
        public void Configure(PuzzleGameData data, Form1 form)
        {
            #region Pociatocne nastavenia - rozmiestnenia, velkosti, vztahy medzi controls, events handlers

            this.data                   = data;                               //Je potrebny zdrojovy obrazok v gamedata!!
            this.parentPanel            = (form.Controls["panel4"] as Panel); //Je potrebne nastavit pred zavolanim Configure(), kto je komu rodicom
            this.parentPictBox          = (this.Parent as PictureBox);
            this.parentPictBox.Location = new Point(0 - data.SourcePicture.Width, 0 - data.SourcePicture.Height);
            this.parentPictBox.Size     = new Size(data.SourcePicture.Width + this.parentPanel.Size.Width,
                                                   data.SourcePicture.Height + this.parentPanel.Size.Height);
            this.parentPictBox.BringToFront();
            //
            this.Location  = new Point(data.SourcePicture.Width, data.SourcePicture.Height);  //pozicia gridlayer kvoli posunu picturebox-u
            this.Size      = new Size(this.parentPanel.Size.Width, this.parentPanel.Height);  //velkost gridlayer podla velkosti zobrazovaniecho panelu(panel4)
            this.BackColor = Color.Transparent;
            this.BringToFront();
            this.Anchor = AnchorStyles.None;
            this.Anchor = (AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right);
            this.Controls.Add(widthBox);
            this.Controls.Add(heightBox);
            this.Controls.Add(dimensionBox);
            this.MouseDown += this.customGridLayer_MouseDown;
            this.MouseUp   += this.customGridLayer_MouseUp;
            this.MouseMove += this.customGridLayer_MouseMove;
            this.parentPictBox.ClientSizeChanged += customclientSizeChanged_ParentPictureBox;
            //
            this.parentPictBox.Image = PictureEditor.ImageScale(GridRatioFromSourceImageResolution, data.SourcePicture);


            this.parentPictBox.Padding = new Padding(data.SourcePicture.Width +
                                                     (int)((this.parentPanel.Width - this.parentPictBox.Image.Size.Width) / 2),
                                                     data.SourcePicture.Height +
                                                     (int)((this.parentPanel.Height - this.parentPictBox.Image.Size.Height) / 2), 0, 0);
            TextBoxesVisible = false;
            //====================================================================================================================================
            #endregion

            #region Nastavenie Grid
            //
            //Prednastavenia pred vytvorenim Grid okrazka
            //
            backGroundImageForGrid = PictureEditor.ColouredBackGroundImage(Color.Black, this.Size); //Color.RoyalBlue
            backGroundImageForGrid = PictureEditor.ImageOpacity(0.60F, backGroundImageForGrid);
            pieceDimensions        = new Size(100, 100);
            gridDimensions         = new Size((int)((data.SourcePicture.Width * 0.7) / pieceDimensions.Width),
                                              (int)((data.SourcePicture.Height * 0.7) / pieceDimensions.Height));
            //
            //Nastavenie vygenerovaneho grid obrazka
            //
            this.SetGridImage(GridRatioFromSourceImageResolution);
            ////this.Refresh();


            //
            //Nastavenie textboxov
            //
            widthBox.TextChanged += this.whenTextBox1_Changed;
            widthBox.MouseEnter  += this.whenTextBox1_MouseEnter;
            widthBox.MouseLeave  += this.whenTextBox1_MouseLeave;

            heightBox.TextChanged += this.whenTextBox2_Changed;
            heightBox.MouseEnter  += this.whenTextBox2_MouseEnter;
            heightBox.MouseLeave  += this.whenTextBox2_MouseLeave;

            dimensionBox.TextChanged += this.whenTextBox3_Changed;
            dimensionBox.MouseEnter  += this.whenTextBox3_MouseEnter;
            dimensionBox.MouseLeave  += this.whenTextBox3_MouseLeave;

            //widthBox.Text = "Width";
            //heightBox.Text = "Height";
            //dimensionBox.Text = "Size";

            var textBoxes = this.Controls.OfType <TextBox>().ToArray();
            foreach (var textBox in textBoxes)
            {
                textBox.BackColor   = Color.FromArgb(64, 64, 64);
                textBox.BorderStyle = BorderStyle.FixedSingle;
                textBox.ForeColor   = Color.White;
                textBox.Size        = new Size(50, 20);
                //textBox.Refresh();
            }
            //
            //do textboxov vyplnime pociatocne hodnoty rozmerov grid, a velkost kuska puzzle, zalohujeme text, ktory v nich bol
            //
            textbox1_BackupText = (gridDimensions.Width).ToString();
            widthBox.Text       = "Šírka";
            textbox2_BackupText = (gridDimensions.Height).ToString();
            heightBox.Text      = "Dĺžka";
            textbox3_BackupText = (pieceDimensions.Width).ToString();
            dimensionBox.Text   = "Rozmer";
            //
            //TextBox-y umiestnime do stredu
            //
            TextBoxesInTheMiddle(MiddlePoint_Grid);
            //
            //TextBox-y budu viditelne
            //
            TextBoxesVisible = true;
            this.Refresh();
            //
            // Vzhlad kurzora
            //
            //Pri vybere obrazka sa vzhlad kurzoru zmeni na posovny kurzor, sipky styrmi smermi
            this.Cursor = Cursors.SizeAll;

            //
            // Zistime ako su od seba posunuta mriezka a obrazok a prevedieme to do skutocneho rozdielu, ak by bol obrazok nescalovany
            // Pri zmene velkosti okna totiz nesmie dojst k posunu mriezky vzhladom k obrazku, mriezka by mohla vyjst mimo obrazok
            //
            originalCornersDiff = OriginalCornersDiff;

            #endregion
        }