|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace nPuzzel
{
/// <summary>
/// Interaction logic for PuzzelControl.xaml
/// </summary>
public partial class PuzzelControl : UserControl
{
int moves;
int dimension;
BitmapSource image;
List<PuzzelPiece> buttons = new List<PuzzelPiece>();
bool gameFinished;
public PuzzelControl(int dimension, string imagePath)
{
InitializeComponent();
this.dimension = dimension;
image = new BitmapImage(new Uri(imagePath));
mainCanvas.Width = image.Width;
mainCanvas.Height = image.Height;
CreateButtons();
RandomiseButtons(buttons.Count - 1);
}
public void UseImage(bool value)
{
foreach (var button in buttons)
{
button.UseImage = value;
}
}
void RandomiseButtons(int emptyIndex)
{
Random rand = new Random();
for (int i = 0; i < 1000; i++)
{
try
{
Direction randomDirection = (Direction)rand.Next(4);
emptyIndex = MoveButton(emptyIndex, randomDirection);
}
catch { }
}
}
void CreateButtons()
{
int vSize = (int)(image.Height / dimension);
int hSize = (int)(image.Width / dimension);
for (int i = 0; i < dimension * dimension; i++)
{
Int32Rect srcRect = new Int32Rect((int)((i % dimension) * hSize), (int)((i / dimension) * vSize), hSize, vSize);
CroppedBitmap bm = new CroppedBitmap(image, srcRect);
ImageBrush brush = new ImageBrush(bm);
PuzzelPiece b = new PuzzelPiece(i, brush);
buttons.Add(b);
b.Width = hSize;
b.Height = vSize;
b.Location = new Point((i % dimension) * hSize, (i / dimension) * vSize);
b.Click += new RoutedEventHandler(b_Click);
mainCanvas.Children.Add(b);
b.Style = (Style)Application.Current.FindResource("PuzzelButtonStyle");
}
buttons.Last().MakeEmpty();
}
void b_Click(object sender, RoutedEventArgs e)
{
if (!gameFinished)
{
int index = buttons.IndexOf(sender as PuzzelPiece);
int emptyIndex = GetEmptyNeighbour(index);
if (emptyIndex >= 0)
{
SwapButtons(buttons[index], buttons[emptyIndex]);
moves++;
if (GameWon())
{
MessageBox.Show("You won the game after " + moves + " moves");
foreach (var b in buttons)
{
b.UseImage = true;
}
gameFinished = true;
}
}
}
}
void SwapButtons(PuzzelPiece p1, PuzzelPiece p2)
{
int index = p1.PieceIndex;
ImageBrush b = p1.PieceBrush;
bool enabled = p1.IsEnabled;
p1.PieceIndex = p2.PieceIndex;
p2.PieceIndex = index;
p1.IsEnabled = p2.IsEnabled;
p2.IsEnabled = enabled;
p1.PieceBrush = p2.PieceBrush;
p2.PieceBrush = b;
p1.SetBackground();
p2.SetBackground();
}
bool GameWon()
{
for (int i = 0; i < dimension * dimension - 1; i++)
{
if (buttons[i].PieceIndex != i)
return false;
}
return true;
}
int GetEmptyNeighbour(int index)
{
int currentRow = index / dimension;
int currentCol = index % dimension;
if (currentCol - 1 >= 0) //left
{
if (!buttons[index - 1].IsEnabled)
{
return index - 1;
}
}
if (currentCol + 1 < dimension) //rirht
{
if (!buttons[index + 1].IsEnabled)
{
return index + 1;
}
}
if (currentRow - 1 >= 0) //top
{
if (!buttons[index - dimension].IsEnabled)
{
return index - dimension;
}
}
if (currentRow + 1 < dimension)//bottom
{
if (!buttons[index + dimension].IsEnabled)
{
return index + dimension;
}
}
return -1;
}
enum Direction { Back, Forward, Up, Down }
int MoveButton(int emptyButtonIndex, Direction direction)
{
if (buttons[emptyButtonIndex].IsEnabled)
{
throw new Exception("The button to move is not empty!");
}
int newIndex = emptyButtonIndex;
switch (direction)
{
case Direction.Back:
if (emptyButtonIndex % dimension > 0)
{
SwapButtons(buttons[emptyButtonIndex], buttons[emptyButtonIndex - 1]);
newIndex = emptyButtonIndex - 1;
}
break;
case Direction.Forward:
if (emptyButtonIndex % dimension < dimension - 1)
{
SwapButtons(buttons[emptyButtonIndex], buttons[emptyButtonIndex + 1]);
newIndex = emptyButtonIndex + 1;
}
break;
case Direction.Up:
if (emptyButtonIndex / dimension > 0)
{
SwapButtons(buttons[emptyButtonIndex], buttons[emptyButtonIndex - dimension]);
newIndex = emptyButtonIndex - dimension;
}
break;
case Direction.Down:
if (emptyButtonIndex / dimension < dimension - 1)
{
SwapButtons(buttons[emptyButtonIndex], buttons[emptyButtonIndex + dimension]);
newIndex = emptyButtonIndex + dimension;
}
break;
}
return newIndex;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am a full-stack developer. My skills include JavaScript, C#/.Net, MS Azure cloud etc. I love to work on complex programming tasks requiring deep analysis, planning and use of efficient algorithms and data structures.