Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пятнашки.doc
Скачиваний:
34
Добавлен:
15.06.2014
Размер:
91.09 Кб
Скачать

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

Омский государственный технический университет

Кафедра Информатики и вычислительной техники

Курсовой проект

на тему: игра «Пятнашки»

по дисциплине «Алгоритмические языки и программирование»

Студент Емельянцев Денис Александрович группы В-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.