МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Омский государственный технический университет
Кафедра Информатики и вычислительной техники
Курсовой проект
на тему: игра «Пятнашки»
по дисциплине «Алгоритмические языки и программирование»
Студент Емельянцев Денис Александрович группы В-114
Пояснительная записка
Шифр проекта
Руководитель проекта
Шафеева О. П.
(подпись, дата)
Разработал студент
(подпись, дата)
Омск 2005.
Оглавление
1. Задание ................................................... 4
2. Анализ задания .............................................. 5
3. Блок-схемы алгоритма ......................................... 7
4.Приложение:
Текст программы .......................................... 12
Результаты тестирования .................................... 20
Инструкция пользователя ..................................... 21
Введение
Игра “Пятнашки” очень древняя игра зародившаяся как задачка для развития логического мышления. В целом ее эффективность проверенная временем до сих пор дает о себе знать. Мы не выбросили ее на свалку истории как игрушку из которой выросли, наоборот внедрение ее и подобных логических тренажеров в обучающую деятельность в начальных школах и детских садах помогло заложить рациональное зерно в логическое мышление растущего поколения и развить логику.
Анализ задания, формулировка задач и основные характеристики программы
“Пятнадцать” на квадратном поле размером 4х4 клетки с помощью датчика случайных чисел расставлены 15 фишек с номерами от 1 до 15. Имеется одна свободная позиция. Требуется расставить фишки по возрастанию начиная с левого верхнего края рядами с лева на право, при условии что передвигать фишки можно только на соседнюю позицию если она свободна.
Анализ задания
И так мы имеем:
1. Квадратное поле размером 4х4 клетки.
2. 15 фишек.
3. Одну пустую позицию.
4. Фишки можно передвигать на соседнюю свободную позицию.
5. Датчик случайных чисел(для того чтобы расставить фишки).
От нас требуется:
расставить фишки по порядку начиная с левого верхнего угла слева на право
Таким образом мы имеем 16 позиций 15 из которых пронумерованы, и одна символизирует пустое поле. Для упрощения задачи сформируем двумерный массив размером 4х4 из целых чисел так как по правилам фишки не могут выходить за пределы площадки оптимальным будит перемещать пустую позицию обозначим эту позицию целым числом 16. И ограничим его перемещение по массиву. Это число будит перемещаться в массиве с помощью непосредственного обмена с соседними числами а возможность перемещения ограничим в процедурах обмена так чтоб сверху вниз это число не вышло за позиции от 1 до 4 и слева на право от 1 до 4 таким образом при попытке “передвинуть” пустое поле за пределы игрового поля не будит выдаваться сообщение об ошибке просто не будит происходить ни какого перемещения. Так же надо обеспечить события по пришествию которых будит двигаться пустое поле. Для реализации этого назначим клавиши показавшиеся удобными на вспомогательной клавиатуре NumPAD. По нажатии на которые будут запускаться соответствующие процедуры и после проверки будит происходить перемещение или не будит происходить никакого перемещения.
Теперь реализуем случайное распределение чисел в массиве. Для этого воспользуемся Функцией RandomFrom с областью значений от 1 до 16. организуем проверку которая в цикле будит проверять не присвоено ли уже таких значений при не выполнении этого условия будит происходить случайный выбор до тех пор пока не выпадет не присвоенное значение. При этом нам понадобится процедура обнуления массива сформированного в течении выполнения программы(для того чтобы можно было воспользоваться функцией случайного наполнения при уже начатой игре при возникновении встречающихся неразрешимых задач или не удовлетворяющей игрока ситуации, а так же для сброса массива сформированного при запуске программы и являющегося действующим игровым полем но лишь с тем условием что на нем игра не идет и при любых перемещениях на нем игрок не сможет закончить игру, это сделано для того чтобы игрок адаптировался к управлению игрой). Процедура случайного заполнения массива будит запускаться при старте новой игры.
Для обнаружения правильной расстановки чисел в массиве создадим процедуру которая будит выполнять проверку(Сравнивать текущий массив с эталоном) после каждого перемещении при истинности данной проверки будит выводиться стандартное окно сообщения Windows о том что задача выполнена. Для того чтобы не выдавалось сообщение о победе при не начатой игре введем переменную при значении False которой эта проверка вообще не будит проводиться(значение True будит присваиваться при старте новой игры а False при запуске программы и после фиксации выполнения задачи).
Организуем графический интерфейс программы он будит состоять из стандартного окна Windows в котором будут располагаться 16 объектов типа Timage и две кнопки : “Новая игра” и “Выход”. Назначение кнопок понятно “Новая игра” запускает соответствующую процедуру, а процедура “Выход” запускает процедуру выхода. Что касается игрового табло то каждому месту в массиве соответствует позиция картинки а каждому числу в массиве картинка. Так числу 1 будит соответствовать картинка с надписью “1”, 2 -“2” И т. д. Числу 16 будит соответствовать черное или пустое поле. При запуске программы эта процедура будит выстраивать картинки всоответствии виртуальному массиву и при каждом изменении внутри виртуального массива это изменение будит переноситься на графическое отражение этого массива. При этом будит создаваться иллюзия перемещения фишек. Для комфортного восприятия пользователем перемещения фишек
будит благоразумней поменять процедуры перемещения “пустого поля” местами(на обратные вверх-вниз, влево-вправо) при этом будит создаваться иллюзия непосредственного перемещения фишек на соседнюю “пустую позицию”.
unit BaseUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Math, QClipbrd;
type
Buffer = Array[1..4,1..4] of integer;
TMainForm = class(TForm)
Image1: TImage;
Image2: TImage;
Image3: TImage;
Image4: TImage;
Image5: TImage;
Image6: TImage;
Image7: TImage;
Image8: TImage;
Image9: TImage;
Image10: TImage;
Image11: TImage;
Image12: TImage;
Image13: TImage;
Image14: TImage;
Image15: TImage;
Image16: TImage;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
Procedure Imeges(Mass : Buffer);
procedure Find_16(Mass : buffer ; Var x, y : integer);
Function Onleft(Mass:buffer ; n,m :integer) : Buffer ;
Function OnRight(Mass:buffer ; n,m :integer) : Buffer ;
Function OnUp(Mass:buffer ; n,m :integer) : Buffer ;
Function OnDown(Mass:buffer ; n,m :integer) : Buffer ;
Function Win_Question(Mass:buffer) : Boolean ;
procedure FormCreate(Sender: TObject);
Procedure Privedenie(Mass:Buffer;var Inicial : Buffer);
private
Idet_Igra: boolean;
Schotchic_Hodov :Integer;
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
Pyatnashki:Buffer;
implementation
{$R *.dfm}
// *****************************************************************************
// Приведение
Procedure TMainForm.Privedenie(Mass:Buffer;var Inicial : Buffer);
Var
i, j, x :integer;
Begin
x:=1;
For i:=1 to 4 Do
Begin
For j:=1 to 4 Do
Begin
Inicial[i,j] := x;
X:=x+1;
End;
End;
end;
Procedure TMainForm.Imeges(Mass : Buffer);
Begin
SetCurrentDir(ExtractFilePath(paramstr(0)));
Image1.Picture.LoadFromFile(IntToStr(Mass[1,1])+'.bmp');
Image2.Picture.LoadFromFile(IntToStr(Mass[1,2])+'.bmp');
Image3.Picture.LoadFromFile(IntToStr(Mass[1,3])+'.bmp');
Image4.Picture.LoadFromFile(IntToStr(Mass[1,4])+'.bmp');
Image5.Picture.LoadFromFile(IntToStr(Mass[2,1])+'.bmp');
Image6.Picture.LoadFromFile(IntToStr(Mass[2,2])+'.bmp');
Image7.Picture.LoadFromFile(IntToStr(Mass[2,3])+'.bmp');
Image8.Picture.LoadFromFile(IntToStr(Mass[2,4])+'.bmp');
Image9.Picture.LoadFromFile(IntToStr(Mass[3,1])+'.bmp');
Image10.Picture.LoadFromFile(IntToStr(Mass[3,2])+'.bmp');
Image11.Picture.LoadFromFile(IntToStr(Mass[3,3])+'.bmp');
Image12.Picture.LoadFromFile(IntToStr(Mass[3,4])+'.bmp');
Image13.Picture.LoadFromFile(IntToStr(Mass[4,1])+'.bmp');
Image14.Picture.LoadFromFile(IntToStr(Mass[4,2])+'.bmp');
Image15.Picture.LoadFromFile(IntToStr(Mass[4,3])+'.bmp');
Image16.Picture.LoadFromFile(IntToStr(Mass[4,4])+'.bmp');
end;
procedure TMainForm.Find_16(Mass : buffer; Var x, y : integer);
var
n, m :integer;
Begin
for n:=1 to 4 do
Begin
for m:=1 to 4 do
begin
if Mass[n,m] = 16 Then
begin
x := n;
y := m;
Exit;
end;
End;
End;
end;
//******************************************************************************
// New game
procedure TMainForm.Button1Click(Sender: TObject);
Const
Interval : array[0..15] of integer = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
Var
i, j, x : integer;
// *******
// Обнуление
Function Obnulenie : Boolean;
Var
i, j :integer;
Begin
For i:=1 to 4 Do
Begin
For j:=1 to 4 Do
Begin
Pyatnashki[i,j] := 0
End;
End;
end;
// *******
// Проверка
Function Stabilizaciya(mass:Buffer; elem:integer): boolean;
Var
n, m :integer;
Begin
Stabilizaciya:= True;
for n:=1 to 4 do
Begin
for m:=1 to 4 do
begin
if Mass[n,m] = elem Then
begin
Stabilizaciya := False ;
Exit;
end;
End;
End;
End;
begin
Schotchic_Hodov:=0;
Idet_Igra:= True;
Obnulenie;
{
Privedenie(Pyatnashki,Pyatnashki);
}
Randomize;
For i:=1 to 4 Do
Begin
For j:=1 to 4 Do
Begin
repeat
x := RandomFrom(Interval);
until Stabilizaciya(Pyatnashki,x) = true;
Pyatnashki[i,j] := x
End;
End;
Imeges(Pyatnashki);
end;
//******************************************************************************
// Exit
procedure TMainForm.Button2Click(Sender: TObject);
begin
Close;
end;
// *****************************************************************************
// Move-Fishku_Right
Function TMainForm.OnRight(Mass:buffer;n,m :integer) : Buffer ;
Var
buf:integer;
begin
if m>1 then
Begin
buf:= Mass[n,m];
Mass[n,m] := Mass[n,(m-1)];
Mass[n,(m-1)]:= buf;
Schotchic_Hodov:= Schotchic_Hodov + 1;
end;
OnRight := Mass;
end;
// *****************************************************************************
// Move-Fishku_left
Function TMainForm.Onleft(Mass:buffer;n,m :integer) : Buffer ;
Var
buf:integer;
begin
if m<4 then
Begin
buf:= Mass[n,m];
Mass[n,m] := Mass[n,(m+1)];
Mass[n,(m+1)]:= buf;
Schotchic_Hodov:= Schotchic_Hodov + 1;
end;
Onleft := Mass;
end;
// *****************************************************************************
// Move-Fishku_Down
Function TMainForm.OnDown( Mass:buffer; n,m : integer ): Buffer ;
Var
buf : integer ;
begin
if n>1 then
Begin
buf:= Mass[n,m];
Mass[n,m] := Mass[(n-1),m];
Mass[(n-1),m]:= buf;
Schotchic_Hodov:= Schotchic_Hodov + 1;
end;
OnDown := Mass;
end;
// *****************************************************************************
// Move-Fishku_Up
Function TMainForm.OnUp(Mass:buffer;n,m :integer) : Buffer ;
Var
buf:integer;
begin
if n<4 then
Begin
buf:= Mass[n,m];
Mass[n,m] := Mass[(n+1),m];
Mass[(n+1),m]:= buf;
Schotchic_Hodov:= Schotchic_Hodov + 1;
end;
OnUp := Mass;
end;
// *****************************************************************************
// Detecting_the_Win
Function TMainForm.Win_Question(Mass:buffer) : Boolean ;
Var
PravOrLight: boolean;
Function Sravnenie_S_Etalonom(AnaliziruemMass: buffer) : Boolean;
Var
n, m :integer;
Const
Inicial : Buffer = ((1,2,3,4),(5,6,7,8),(9,10,11,12),(13,14,15,16));
Begin
Sravnenie_S_Etalonom := true;
for n:=1 to 4 do
Begin
for m:=1 to 4 do
begin
if AnaliziruemMass[n,m] <> Inicial[n,m] Then
begin
Sravnenie_S_Etalonom:= false;
Exit;
end;
End;
End;
End;
Begin
If ((Sravnenie_S_Etalonom(Pyatnashki)= True) And (Idet_Igra = True)) Then
Begin
MessageBox(0,'Похдравляю! Вы выйграли!','Win',mb_ok);
Idet_Igra := false;
end;
End;
// *****************************************************************************
// Key Presed
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
i,j:integer;
GameRespect: Boolean;
begin
Find_16(Pyatnashki,i,j);
case Key of
VK_NUMPAD4:
Begin
Pyatnashki := OnLeft(Pyatnashki,i,j);
Imeges(Pyatnashki);
Win_Question(Pyatnashki);
End;
VK_NUMPAD6:
Begin
Pyatnashki := OnRight(Pyatnashki,i,j);
Imeges(Pyatnashki);
Win_Question(Pyatnashki);
End;
VK_NUMPAD8:
Begin
Pyatnashki := OnUp(Pyatnashki,i,j);
Imeges(Pyatnashki);
Win_Question(Pyatnashki);
End;
VK_NUMPAD5:
Begin
Pyatnashki := OnDown(Pyatnashki,i,j);
Imeges(Pyatnashki);
Win_Question(Pyatnashki);
End;
End;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
Idet_Igra := false;
Privedenie(Pyatnashki,Pyatnashki);
end;
End.