Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.01.03;
Скачать: [xml.tar.bz2];

Вниз

Игра пятнашки   Найти похожие ветки 

 
AntonioBanderas   (2009-11-12 20:41) [0]

Вообще непонятно, как могут получатся пятнашки с одинаковыми цифрами, ведь не должны же.
Подскажите в чем моя ошибка?


 var
 MainF: TMainF;
 Visit: array[0..14] of Boolean;
 SIZE, NUM: Integer;

implementation

uses Math;

{$R *.dfm}

procedure GenRendomNum_1_15;
var
 NumOfCell: Word;
begin
 Randomize;
 NumOfCell := Random(15);

 if Visit[NumOfCell] = false then
 begin
   NUM := NumOfCell;
   Visit[NumOfCell] := true
 end else
   GenRendomNum_1_15;
end;

procedure TMainF.Init;
var
 i: Integer;
 Cell: TPanel;
begin
 SIZE := 50;
 //очистить доску
 for i := 0 to BoardPanel.ControlCount - 1 do
 begin
   BoardPanel.Controls[0].Free;
 end;

 //расставить фишки
 for i := 0 to 14 do
 begin
   Visit[i] := false;
   Cell := TPanel.Create(BoardPanel);
   Cell.SetBounds((i mod 4)*SIZE,(i div 4)*SIZE,SIZE,SIZE);
   GenRendomNum_1_15;
   Cell.Caption := IntToStr(Num+1);
   Cell.Parent := BoardPanel;
 end;
end;

procedure TMainF.N2Click(Sender: TObject);
begin
 Init;
end;


 
Германн ©   (2009-11-12 20:48) [1]

Randomize нужно вызвать один и только один раз, например при старте программы


 
AntonioBanderas   (2009-11-12 20:54) [2]


> Randomize нужно вызвать один и только один раз, например
> при старте программы


Согласан, забыл. Но ошибка не из-за этого


 
Германн ©   (2009-11-12 21:16) [3]


>  Visit[i] := false;

Эту очистку вынеси в отдельный цикл.


 
AntonioBanderas   (2009-11-12 21:21) [4]


> Германн ©   (12.11.09 21:16) [3]

И что будет? При первом Init уже не правильно получается.
Ну не понятно как он Visit пролетает.


 
AntonioBanderas   (2009-11-12 21:29) [5]


> Германн ©   (12.11.09 21:16) [3]


Ну это моя большая невнимательность, все правильно.


 
Думкин ©   (2009-11-13 06:04) [6]

> AntonioBanderas   (12.11.09 21:29) [5]

Самый нормальный способ получать случайные последовательнсти со значениями на отрезке чисел - это брать этот отрезок и перемешивать.


 
Думкин ©   (2009-11-13 06:58) [7]

И для 15 надо понимать, что произвольный расклад может и не сойтись с вероятностью 1/2.


 
Рамиль ©   (2009-11-13 08:54) [8]


> Думкин ©   (13.11.09 06:58) [7]

Насколько я помню, расклад сходится, если можно собрать четным количеством перестановок пар фишек. Или я забыл уже?


 
Думкин ©   (2009-11-13 09:16) [9]

> Рамиль ©   (13.11.09 08:54) [8]

Начальная позиция - пустой правый нижний? Наверное. Не вникал. Но главное, что делятся на два класса.


 
Думкин ©   (2009-11-13 09:21) [10]

Или имеется в виду, что вытянем в ряд и посмотрим четность перестановки? Наверное, так. Скорее всего так.


 
Рамиль ©   (2009-11-13 09:28) [11]

Не, я не совсем прав.
http://alekstrade.hoter.ru/blog/1179/9955/%D0%9F%D1%8F%D1%82%D0%BD%D0%B0%D1%88%D0%BA%D0%B8
http://ru.wikipedia.org/wiki/%D0%9F%D1%8F%D1%82%D0%BD%D0%B0%D1%88%D0%BA%D0%B8


 
AntonioBanderas   (2009-11-14 23:47) [12]


> Рамиль ©   (13.11.09 09:28) [11]

Если я правильно понял то процедура RealityMove определит сходимость, или я неправильно понял?
Полный код модуля:

unit Main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, Menus, StdCtrls, ComCtrls;

type
 TMainF = class(TForm)
   BoardPanel: TPanel;
   MainMenu: TMainMenu;
   MGame: TMenuItem;
   NewGame: TMenuItem;
   ExitGame: TMenuItem;
   MHelp: TMenuItem;
   About: TMenuItem;
   StatusBar: TStatusBar;
   InfoLabel: TLabel;
   procedure Init;
   procedure NewGameClick(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure MoveCell(Sender: TObject);
   procedure AboutClick(Sender: TObject);
   procedure ExitGameClick(Sender: TObject);
   procedure FormResize(Sender: TObject);
   procedure GameEnd;
   procedure RealityMove;
   procedure FormPaint(Sender: TObject);
 private

 public

 end;

var
 MainF: TMainF;
 Visit: array[0..14] of Boolean;
 SIZE, NUM: Integer;
 Empty, EmptyX, EmptyY: Integer;
 HaosCount, MoveCount: Integer;

implementation

uses Math, AboutB;

{$R *.dfm}

procedure TMainF.FormCreate(Sender: TObject);
begin
 Randomize;
end;

procedure GenRendomNum_1_15;
var
 NumOfCell: Word;
begin
 NumOfCell := Random(15);

 if Visit[NumOfCell] = false then
 begin
   NUM := NumOfCell;
   Visit[NumOfCell] := true
 end else
   GenRendomNum_1_15;
end;

procedure TMainF.RealityMove;
var
 i, j: Integer;
 CurCell: Integer;
begin
 HaosCount := 0;
 for i := 0 to 14 do
 begin
   CurCell := StrToInt(TPanel(BoardPanel.Controls[i]).Caption);
   for j := i to 14 do
   begin
     if CurCell < StrToInt(TPanel(BoardPanel.Controls[j]).Caption) then
     begin
       HaosCount := HaosCount + 1;
     end;
   end;
 end;

 if (HaosCount mod 2) <> 0 then
   InfoLabel.Caption := "Данная расстановка не решаема, попробуете?"
 else
   InfoLabel.Caption := "";

 StatusBar.Panels[0].Text := " Беспорядков = "+IntToStr(HaosCount);  
end;

procedure TMainF.GameEnd;
var
 i: Integer;
 EndFlag: Boolean;
begin
 EndFlag := true;
 for i := 0 to 14 do
 begin
   if (StrToInt(TPanel(BoardPanel.Controls[i]).Caption)-1) <> TPanel(BoardPanel.Controls[i]).Tag
     then  EndFlag := false;
 end;

 if EndFlag then
   InfoLabel.Caption := "Игра окончена";
end;

procedure TMainF.MoveCell(Sender: TObject);
var
 Buf, BufX, BufY: Integer;
begin
 MoveCount := MoveCount + 1;
 StatusBar.Panels[1].Text := " Ходов = "+IntToStr(MoveCount);

 Buf := TPanel(Sender).Tag;
 TPanel(Sender).Tag := Empty;
 Empty := Buf;

 //Move to Top
 if ((Sender as TPanel).Left = EmptyX) and ((Sender as TPanel).Top = EmptyY + SIZE)
 then begin
    BufY := TPanel(Sender).Top;
    TPanel(Sender).Top := EmptyY;
    EmptyY := BufY;
    GameEnd;
    Exit;
 end;

 //Move to Bottom
 if ((Sender as TPanel).Left = EmptyX) and ((Sender as TPanel).Top = EmptyY - SIZE)
 then begin
    BufY := TPanel(Sender).Top;
    TPanel(Sender).Top := EmptyY;
    EmptyY := BufY;
    GameEnd;
    Exit;
 end;

 //Move to Right
 if ((Sender as TPanel).Top = EmptyY) and ((Sender as TPanel).Left = EmptyX - SIZE)
 then begin
    BufX := TPanel(Sender).Left;
    TPanel(Sender).Left := EmptyX;
    EmptyX := BufX;
    GameEnd;
    Exit;
 end;

 //Move to Left
 if ((Sender as TPanel).Top = EmptyY) and ((Sender as TPanel).Left = EmptyX + SIZE)
 then begin
    BufX := TPanel(Sender).Left;
    TPanel(Sender).Left := EmptyX;
    EmptyX := BufX;
    GameEnd;
 end;

end;

procedure TMainF.Init;
var
 i: Integer;
 Cell: TPanel;
begin
 SIZE := 50;
 
 Empty := 15;
 EmptyX := 3*SIZE;
 EmptyY := 3*SIZE;

 for i := 0 to BoardPanel.ControlCount - 1 do
 begin
   BoardPanel.Controls[0].Free;
 end;

 for i := 0 to 14 do
 begin
   Visit[i] := false;
 end;

 for i := 0 to 14 do
 begin
   Cell := TPanel.Create(BoardPanel);
   Cell.SetBounds((i mod 4)*SIZE,(i div 4)*SIZE,SIZE,SIZE);
   GenRendomNum_1_15;
   Cell.Caption := IntToStr(NUM+1);
   Cell.Tag := i;
   Cell.Parent := BoardPanel;
   Cell.OnClick := MoveCell;
 end;

 RealityMove;
end;

procedure TMainF.NewGameClick(Sender: TObject);
begin
 InfoLabel.Caption := "";
 StatusBar.Panels[1].Text := " Ходов = 0";
 Init;
end;

procedure TMainF.AboutClick(Sender: TObject);
begin
 AboutBox.ShowModal;
end;

procedure TMainF.ExitGameClick(Sender: TObject);
begin
 Application.Terminate;
end;

procedure TMainF.FormResize(Sender: TObject);
begin
 BoardPanel.Left := (ClientWidth div 2) - (BoardPanel.Width div 2);
 BoardPanel.Top := 100;
end;

procedure TMainF.FormPaint(Sender: TObject);
begin
 InfoLabel.Left := (ClientWidth div 2) - (InfoLabel.Width div 2);
 InfoLabel.Top := 15;
end;

end.



 
V   (2009-11-15 09:00) [13]


var j:array[1..16] of shortint;

procedure zap;
const fi:array[1..16] of byte=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0);
var ttt:array[1..16] of shortint;
     d,n,t,chq:integer; p:boolean;
begin
randomize;
 Repeat
 n:=1;
  for i:=1 to 16 do begin j[i]:=0; ttt[i]:=0; end;
  repeat
    repeat
     t:=random(15)+1;
     p:=false;
     for i:=1 to 16 do if j[i]=t then begin p:=true; break; end;
    until p=false;
    j[n]:=t; ttt[n]:=j[n]; n:=n+1;
  until n>=16;
  n:=1; chq:=0;
 repeat
  repeat
   if ttt[n]<>fi[n] then begin d:=ttt[n]; ttt[n]:=ttt[d]; ttt[d]:=d;
   chq:=chq+1; end;
  until ttt[n]=fi[n];
  n:=n+1;
  until n>=16;
 until chq mod 2=0; // если 1, то не будет собираться
end;


Писал давно, лет 10 назад, еще на паскале...
Тут заполнится массив j цифрами от 1 до 15 перемешанными, и собираться будет пятнашка, если их вот так расположить...
j[1] j[2] j[3] j[4]
j[5] j[6] j[7] j[8]
j[9] j10 j11] j[12]
j13 j14] j15



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.01.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.006 c
1-1231767209
TStas
2009-01-12 16:33
2010.01.03
Как сделать из gif ов bmp?


2-1258012123
SkyN
2009-11-12 10:48
2010.01.03
как определить, делится ли одно Double на другое Double нацело.


2-1258013944
Scot Storch
2009-11-12 11:19
2010.01.03
record c case


11-1209885490
ForestGamp
2008-05-04 11:18
2010.01.03
OnQueryEndSession


2-1257937557
Oleg1963
2009-11-11 14:05
2010.01.03
Компонент в цикле





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский