📄 moves.pas
字号:
unit moves;
{*
* Based on The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 X-Watch Software, Sven K黱zler. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* X-Watch Software (http://www.xwatch.de/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Slider" and "X-Watch" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact svenk@gmx.net.
*
* 5. Products derived from this software may not be called "Slider",
* nor may "Slider" appear in their name, without prior written
* permission of X-Watch Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL X-WATCH SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*}
interface
// Die Puzzleteile sind von 1 bis 8 durchnummeriert,
// der leere Platz mit 0 bezeichnet
Const bdEmptySlot=0;
Type TBoard = Array[0..8] of Integer;
TMove=Class
private
Pred: TMove;
Public
Board: TBoard;
Tiefe: Integer;
Constructor Create(b: TBoard);
Destructor Destroy;override;
Function IsSolve: Boolean;
Function NextCount: Integer;
Function EmptySlot: Integer;
Function GetNext(index: Integer): TMove;
Function GetID: LongInt;
Function Distance: Integer;
Property Predecessor: TMove read Pred;
End;
implementation
Constructor TMove.Create(b: TBoard);
Begin
Move(b,Board,SizeOf(TBoard));
Pred:=Nil;
End;
Destructor TMove.Destroy;
Begin
inherited Destroy;
End;
Function TMove.IsSolve: Boolean;
Var i: Integer;
Begin
Result:=True;
For i:=0 to 7 Do
If Board[i]<>(i+1) Then
Begin
Result:=False;
Break;
End;
End;
Function TMove.NextCount: Integer;
var tmp: Integer;
Begin
tmp:=EmptySlot;
if(tmp=4) then Result:=4 Else
If odd(tmp) Then Result:=3 Else Result:=2;
End;
Function TMove.EmptySlot: Integer;
var slot: Integer;
Begin
slot:=0;
while(slot<9) Do If Board[slot]=0 Then Break Else Inc(slot);
Result:=slot;
End;
Function TMove.GetNext(index: Integer): TMove;
var tmpCount, tmpSlot: Integer;
var tmpMove: TMove;
Begin
if Index>=NextCount Then
Begin
Result:=nil;
exit;
End;
tmpCount:=0;
tmpSlot:=EmptySlot;
// Von oben nach unten schieben
If(EmptySlot>2) Then
Begin
Inc(tmpCount);
If(tmpCount=(index+1)) Then
Begin
tmpMove:=TMove.Create(Board);
tmpMove.Board[tmpSlot]:=tmpMove.Board[tmpSlot-3];
tmpMove.Board[tmpSlot-3]:=0;
tmpMove.Pred:=Self;
tmpMove.Tiefe:=Self.Tiefe+1;
Result:=tmpMove;
exit;
End;
End;
// Von links nach rechts schieben
If(EmptySlot Mod 3>0) Then
Begin
Inc(tmpCount);
If(tmpCount=(index+1)) Then
Begin
tmpMove:=TMove.Create(Board);
tmpMove.Board[tmpSlot]:=tmpMove.Board[tmpSlot-1];
tmpMove.Board[tmpSlot-1]:=0;
tmpMove.Pred:=Self;
tmpMove.Tiefe:=Self.Tiefe+1;
Result:=tmpMove;
exit;
End;
End;
// Von rechts nach links schieben
If(EmptySlot Mod 3<2) Then
Begin
Inc(tmpCount);
If(tmpCount=(index+1)) Then
Begin
tmpMove:=TMove.Create(Board);
tmpMove.Board[tmpSlot]:=tmpMove.Board[tmpSlot+1];
tmpMove.Board[tmpSlot+1]:=0;
tmpMove.Pred:=Self;
tmpMove.Tiefe:=Self.Tiefe+1;
Result:=tmpMove;
exit;
End;
End;
// Von unten nach oben schieben
If(EmptySlot<6) Then
Begin
Inc(tmpCount);
If(tmpCount=(index+1)) Then
Begin
tmpMove:=TMove.Create(Board);
tmpMove.Board[tmpSlot]:=tmpMove.Board[tmpSlot+3];
tmpMove.Board[tmpSlot+3]:=0;
tmpMove.Pred:=Self;
tmpMove.Tiefe:=Self.Tiefe+1;
Result:=tmpMove;
exit;
End;
End;
Result:=nil;
End;
Function TMove.GetID: LongInt;
Var tmp: LongInt;
I: Integer;
Begin
tmp:=0;
For i:=0 To 8 Do tmp:=tmp*10+Board[i];
Result:=tmp;
End;
// Diese Methode f黨rt eine Bewertung des aktuellen
// Zuges durch.
// Der Algorithmus stammt aus einem
// Java-Applet von Geert-Jan van Opdorp,
// Copyright (c) 1995 AI Engineering.
Function TMove.Distance: Integer;
var i, sx,sy,g,gx,gy, tmp: Integer;
const dx=3;
dy=3;
Begin
i:= -1;
tmp:=0;
for sy:= 0 to dy-1 Do
for sx:= 0 to dx-1 Do
Begin
Inc(i);
g:= Board[i]-1;
if (g = -1) Then continue;
gx:= g Mod dx;
gy:= g Div dx;
tmp:=tmp+abs(gy - sy) +abs(gx - sx);
End;
Result:=tmp;
End;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -