- •1 Опис актуальності, цілей завдань розроблюваного пз, його призначення й галузь застосування
- •2 Огляд програмних продуктів, що мають аналогічні цілі й призначення
- •3 Розробка інтерфейсу по й короткий опис основних елементів керування
- •4 Розробка алгоритмів і блок-схем, що описують функціональність пз
- •Item is Border
- •5 Розробка прикладного програмного забезпечення
- •6 Висновки
6 Висновки
Дане програмне забезпечення було створено з метою надання користувачам програми, яка дозволяє зібрати п’ятнашки.
Для цього користувачеві надане просте у використанні програмне забезпечення. Це зумовлено тим, що його інтерфейс аналогічний до багатьох інших ігор, а тому інтуїтивно зрозумілий для багатьох користувачів.
СПИСОК ЛІТЕРАТУРИ
С. Байдачний, Windows 8 для С# розробників. – К., 2012. - 277с, ил.
М. Мак-Дональд, Windows Presentation Foundation у .NET 4 – СПб.: Вильямс, 2011. – 1019с.: ил.
Веб-ресурс: https://www.google.com/
МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ, МОЛОДІ ТА СПОРТУ
ДОНЕЦЬКИЙ НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ
ДОДАТОК А
Технічне завдання
МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ
Донецький національний технічний університет
ДОДАТОК Б
Тексти (лістинги) розробленого програмного забезпечення
//файл BlankPage.xaml
<Page
x:Class="PuzzleMetro.BlankPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PuzzleMetro"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="1366" Loaded="UserControl_Loaded" PointerPressed="UserControl_PointerPressed" Tapped="Page_Tapped_1">
<Page.BottomAppBar>
<AppBar Height="88" VerticalAlignment="Bottom">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="btnnewGame" Click="btnnewGame_Click" Style="{StaticResource AddAppBarButtonStyle}"
HorizontalAlignment="Left" />
<Button x:Name="btnShare" Style="{StaticResource UploadAppBarButtonStyle}" Visibility="Collapsed"
HorizontalAlignment="Right" Grid.Column="1" Click="btnShare_Click"/>
<Button x:Name="btnHelp" Style="{StaticResource HelpAppBarButtonStyle}" Grid.Column="2" Click="btnHelp_Click_1"/>
</Grid>
</AppBar>
</Page.BottomAppBar>
<Grid x:Name="LayoutRoot" Background="White">
<!--Background="{StaticResource ApplicationPageBackgroundBrush}"-->
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="405"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="501"/>
</Grid.ColumnDefinitions>
<Canvas x:Name="ContentPanel" Grid.ColumnSpan="9" Grid.RowSpan="10">
<Border Style="{StaticResource BorderStyle}" Canvas.Left="763" Canvas.Top="454" />
<Border Style="{StaticResource BorderStyle}" Canvas.Left="643" Canvas.Top="454" >
<TextBlock Text="15" Tag="15" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="524" Canvas.Top="454" >
<TextBlock Text="14" Tag="14" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="404" Canvas.Top="454" >
<TextBlock Text="13" Tag="13" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="763" Canvas.Top="334" >
<TextBlock Text="12" Tag="12" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="643" Canvas.Top="334" >
<TextBlock Text="11" Tag="11" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="524" Canvas.Top="334">
<TextBlock Text="10" Tag="10" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="404" Canvas.Top="334">
<TextBlock Text="9" Tag="9" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="763" Canvas.Top="214" >
<TextBlock Text="8" Tag="8" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="643" Canvas.Top="214" >
<TextBlock Text="7" Tag="7" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="524" Canvas.Top="214" >
<TextBlock Text="6" Tag="6" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="404" Canvas.Top="214" >
<TextBlock Text="5" Tag="5" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="763" Canvas.Top="94" >
<TextBlock Text="4" Tag="4" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="643" Canvas.Top="94" >
<TextBlock Text="3" Tag="3" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="524" Canvas.Top="94" >
<TextBlock Text="2" Tag="2" Style="{StaticResource NumberStyle}" />
</Border>
<Border Style="{StaticResource BorderStyle}" Canvas.Left="404" Canvas.Top="94" >
<TextBlock Text="1" Tag="1" Style="{StaticResource NumberStyle}" />
</Border>
<TextBlock Canvas.Left="677" Style="{StaticResource H3Style}" Text="ходов:" FontWeight="Thin" Margin="0" Canvas.Top="10" />
<TextBlock Canvas.Left="748" FontWeight="Thin" x:Name="txtMoves" Text="0" Canvas.Top="10" Style="{StaticResource H2Style}"/>
<TextBlock Canvas.Left="498" Text="время:" FontWeight="Thin" Style="{StaticResource H3Style}" Canvas.Top="10" Margin="0"/>
<TextBlock Canvas.Left="572" x:Name="txtTime" Text="00:00:00" Style="{StaticResource H2Style}" Canvas.Top="10" FontWeight="Thin"/>
<TextBlock HorizontalAlignment="Left" Width="372" Height="145"
Canvas.Top="565" Foreground="Black" FontFamily="Segoe UI Light" FontWeight="Thin" FontSize="20" x:Name="Info" Opacity="0">
Цель игры — перемещая костяшки по<LineBreak />коробке добиться упорядочивания их по <LineBreak />номерам, желательно сделав как можно <LineBreak />меньше перемещений.<LineBreak /><LineBreak />Пятнашки. Александр Демченко © 2012
</TextBlock>
</Canvas>
</Grid>
</Page>
//файл BlankPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Windows.ApplicationModel.DataTransfer;
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Notifications;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
namespace PuzzleMetro
{
public sealed partial class BlankPage : Page
{
private readonly int[] _bordersNums = { 0, 4, 8, 12, 3, 7, 11, 15 };
private readonly Random _rnd;
private readonly DispatcherTimer _timer;
private int _moves;
private DateTime _startTime;
BlankPage rootPage = null;
public BlankPage()
{
InitializeComponent();
_rnd = new Random();
_timer = new DispatcherTimer();
_timer.Tick +=_timer_Tick;
_timer.Interval = new TimeSpan(0, 0, 0, 1);
_dataTransferManager = DataTransferManager.GetForCurrentView();
_dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(_dataTransferManager_DataRequested);
}
void _timer_Tick(object sender, object e)
{
var time = DateTime.Now - _startTime;
txtTime.Text = string.Format("{0:00}:{1:00}:{2:00}",time.Hours, time.Minutes, time.Seconds);
}
public void NewGame()
{
_moves = 0;
txtMoves.Text = "0";
txtTime.Text = "00:00:00";
Scrambles();
while (!CheckIfSolvable())
{
Scrambles();
}
_startTime = DateTime.Now;
_timer.Start();
}
// поиск и возврат квадрата по позиции
Border FindStackPanelByTagId(int tag)
{
if (tag == 16)
{
return (from stackPanel in ContentPanel.Children.OfType<Border>() where stackPanel.Child == null select stackPanel).First();
}
else
{
foreach (Border b in ContentPanel.Children)
{
if (b.Child != null && Convert.ToInt32(((TextBlock)b.Child).Text) == tag)
return b;
}
}
return null;
}
// поиск элемента без числа
int FindEmptyItemPosition()
{
int index = 15;
for (int i = 0; i < 15; i++)
{
if (((Border)ContentPanel.Children[i]).Child != null)
return index;
index--;
}
return 0;
}
// возвращает число по позиции элемента, если числа нет - возвращает 16
int FindItemValueByPosition(int position)
{
return ((Border)ContentPanel.Children[position]).Child != null ?
Convert.ToInt32(((TextBlock)((Border)ContentPanel.Children[position]).Child).Tag) : 16;
}
// алгоритм подбора элементов для хранения
void Scrambles()
{
var count = 0;
while (count < 25)
{
var a = _rnd.Next(1, 17);
var b = _rnd.Next(1, 17);
if (a == b) continue;
var stack1 = FindStackPanelByTagId(a);
var stack2 = FindStackPanelByTagId(b);
if (a == 16)
{
var image2 = stack2.Child;
stack2.Child = null;
stack1.Child = image2;
}
else if (b == 16)
{
var image1 = stack1.Child;
stack1.Child = null;
stack2.Child = image1;
}
else
{
var image1 = stack1.Child;
var image2 = stack2.Child;
stack1.Child = null;
stack2.Child = null;
stack1.Child = image2;
stack2.Child = image1;
}
count++;
}
}
// проверка правильности
void CheckBoard()
{
var index = 1;
for (var i = 15; i > 0; i--)
{
if (FindItemValueByPosition(i) != index) return;
index++;
}
_timer.Stop();
DisplayToastWithImage();
btnShare.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
// проверка на возможность решения
bool CheckIfSolvable()
{
var n = 0;
for (var i = 15; i > 0; i--)
{
if (!(ContentPanel.Children[i] is StackPanel)) continue;
var num1 = FindItemValueByPosition(i);
var num2 = FindItemValueByPosition(i - 1);
if (num1 > num2)
{
n++;
}
}
var emptyPos = FindEmptyItemPosition();
return n % 2 == (emptyPos + emptyPos / 4) % 2 ? true : false;
}
/// <summary>
/// Move Item From One SpackPanel to Another.
/// </summary>
/// <param name="item">Gets the Image item you want to move</param>
/// <param name="targetPanel">Destination StackPanel</param>
void MoveItem(TextBlock item, Border targetPanel)
{
foreach (var stackPanel in
ContentPanel.Children.OfType<Border>().Where(stackPanel => stackPanel.Child != null && ((TextBlock)stackPanel.Child).Text == ((TextBlock)item).Text))
{
stackPanel.Child = null;
}
targetPanel.Child = item;
}
// возвращает позиции элементов, если они находятся по краям
bool IsBorderSwich(int a, int b)
{
return _bordersNums.Contains(a) && _bordersNums.Contains(b);
}
// проверка на возможность передвижения
Border CanMove(UIElement itemToMove)
{
var val = ((TextBlock)itemToMove).Text;
var count = ContentPanel.Children.Count;
for (var i = 0; i < count; i++)
{
if (!(ContentPanel.Children[i] is Border)) continue;
var stakePanel = (Border)ContentPanel.Children[i];
if (stakePanel.Child != null && ((TextBlock)stakePanel.Child).Text != val) continue;
if (!IsBorderSwich(i, i + 1) && i + 1 <= 15 && ContentPanel.Children[i + 1] != null && ((Border)ContentPanel.Children[i + 1]).Child == null)
return ((Border)ContentPanel.Children[i + 1]);
if (!IsBorderSwich(i, i - 1) && i - 1 > -1 && ContentPanel.Children[i - 1] != null && ((Border)ContentPanel.Children[i - 1]).Child == null)
return ((Border)ContentPanel.Children[i - 1]);
if (i + 4 <= 15 && ContentPanel.Children[i + 4] != null && ((Border)ContentPanel.Children[i + 4]).Child == null)
return ((Border)ContentPanel.Children[i + 4]);
if (i - 4 > -1 && ContentPanel.Children[i - 4] != null && ((Border)ContentPanel.Children[i - 4]).Child == null)
return ((Border)ContentPanel.Children[i - 4]);
}
return null;
}
// при загрузке приложения
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
NewGame();
}
private void UserControl_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerEventArgs e)
{
var item = (UIElement)e.OriginalSource;
TextBlock work = null;
Border border = null;
if (item is Border)
{
border = item as Border;
if (border.Child != null)
{
work = border.Child as TextBlock;
}
else
return;
}
else if (item is TextBlock)
{
work = item as TextBlock;
border = work.Parent as Border;
}
else
return;
var to = CanMove(work);
if (to != null)
{
_moves++;
txtMoves.Text = _moves.ToString();
CreateFadeOutAnimation(work);
MoveItem(work, to);
CreateFadeInAnimation(work);
CheckBoard();
}
}
private void CreateFadeOutAnimation(UIElement btn)
{
Duration dur = new Duration(TimeSpan.FromSeconds(2));
var da = new DoubleAnimation();
da.From = 1;
da.To = 0;
var sb = new Storyboard();
sb.Duration = dur;
sb.Children.Add(da);
Storyboard.SetTarget(da, btn);
Storyboard.SetTargetProperty(da, "(Opacity)");
sb.Begin();
}
private void CreateFadeInAnimation(UIElement btn)
{
Duration dur = new Duration(TimeSpan.FromSeconds(2));
var da = new DoubleAnimation();
da.From = 0;
da.To = 1;
var sb = new Storyboard();
sb.Duration = dur;
sb.Children.Add(da);
Storyboard.SetTarget(da, btn);
Storyboard.SetTargetProperty(da, "(Opacity)");
sb.Begin();
}
private void btnnewGame_Click(object sender, RoutedEventArgs e)
{
NewGame();
}
void DisplayToastWithImage()
{
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
XmlNodeList textElements = toastXml.GetElementsByTagName("text");
foreach (IXmlNode toastTextAttr in textElements)
{
toastTextAttr.InnerText = "Поздравляем, Вы выиграли!";
}
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
private DataTransferManager _dataTransferManager;
void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
args.Request.Data.Properties.Title = "Metro Puzzle";
args.Request.Data.Properties.Description = "Делюсь победой..";
args.Request.Data.SetText(string.Format("Только что прошел пятнашки за {0} ходов и {1}, думаешь сможешь лучше?", txtMoves.Text, txtTime.Text));
}
private void btnGame_Click(object sender, RoutedEventArgs e)
{
NewGame();
btnShare.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
private void btnShare_Click(object sender, RoutedEventArgs e)
{
DataTransferManager.ShowShareUI();
btnShare.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
private void btnHelp_Click_1(object sender, RoutedEventArgs e)
{
Duration dur = new Duration(TimeSpan.FromSeconds(2));
var da = new DoubleAnimation();
da.From = 0;
da.To = 1;
var sb = new Storyboard();
sb.Duration = dur;
sb.Children.Add(da);
Storyboard.SetTarget(da, Info);
Storyboard.SetTargetProperty(da, "(Opacity)");
if (Info.Opacity == 0)
{
sb.Begin();
}
}
private void Page_Tapped_1(object sender, TappedRoutedEventArgs e)
{
Duration dur = new Duration(TimeSpan.FromSeconds(2));
var da = new DoubleAnimation();
da.From = 1;
da.To = 0;
var sb = new Storyboard();
sb.Duration = dur;
sb.Children.Add(da);
Storyboard.SetTarget(da, Info);
Storyboard.SetTargetProperty(da, "(Opacity)");
if (Info.Opacity == 1)
{
sb.Begin();
}
}
}
}
МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ
Донецький національний технічний університет
ДОДАТОК B
Юзабіліті-тест для програмного забезпечення
1.Чи виникли у вас ускладнення в роботі з програмою ( Якщо так, те вкажіть які саме)
□ Так, виникли ускладнення ____________________________________________________________________________________________________________________________________
□ Ні, ускладнення відсутні
2. При роботі з даною програмою чи виникають у вас помилки, що приводять до автоматичного завершення? (Якщо так, укажіть які помилки)
□ Так, помилки є(які) ____________________________________________________________________________________________________________________________________
□ Ні, помилок немає
3.Чи не виникають у вас питання щодо елементів керування, які необхідно використати для роботи ПЗ? (Якщо так, укажіть які питання)
□ Так, виникли питання (які)
_________________________________________________________________________________________________________________________________
□ Ні, питання не виникли
4. Чи вдалося вам освоїти гру? (Якщо ні, укажіть причину)
□ Ні,(причина)
________________________________________________________________________________________________________________________________
□ Так, освоїв(а)
5. Скільки часу треба було вам для відкриття програми?
□2-3 сек
□4-5сек
□5-6сек
6. Чи влаштовують Вас кольори, використанні у інтерфейсі даної програми?
□Так
□Ні
8. Скільки часу Вам треба було на освоєння програми?
□1-3 хв
□3-4 хв
□5-6 хв
9. Що викликало найбільші труднощі при освоєнні?
□Недостатньо навичок при роботі з комп'ютером
□Відсутність довідкової документації
□Інше _________________________________________________________________________________________________________________________________
10. Чи не виникало критичних помилок під час роботи програми? (Якщо так, укажіть які помилки)
□ Так, помилки є(які) ______________________________________________________________________________________________________________________________________________________________________________________________________
□ Ні, помилок немає
11. Побажання розробникові даної програми (а також, укажіть недоліки) ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
12. Виконує програма всі необхідні функції?
Так
Ні
13. Якими схожі головоломки Ви складали раніше ?
______________________________________________________________________________________________________________________________________________________________________________________________________