www.pudn.com > 推箱子源码.rar > Cboxword.pas


unit Cboxword; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  Grids, Menus, ComCtrls, ExtCtrls, ImgList, StdCtrls; 
const 
   utimes=88; 
type 
  TForm1 = class(TForm) 
    DrawGrid1: TDrawGrid; 
    MainMenu1: TMainMenu; 
    G1: TMenuItem; 
    Undo1: TMenuItem; 
    N1: TMenuItem; 
    Retry1: TMenuItem; 
    N2: TMenuItem; 
    BeepOff1: TMenuItem; 
    N3: TMenuItem; 
    GotoToWorld1: TMenuItem; 
    StatusBar1: TStatusBar; 
    ImageList1: TImageList; 
    Timer1: TTimer; 
    H1: TMenuItem; 
    N5: TMenuItem; 
    N6: TMenuItem; 
    A1: TMenuItem; 
    N4: TMenuItem; 
    exit1: TMenuItem; 
    procedure FormCreate(Sender: TObject); 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
    procedure DrawGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; 
      var CanSelect: Boolean); 
    procedure Timer1Timer(Sender: TObject); 
    procedure DrawGrid1KeyDown(Sender: TObject; var Key: Word; 
      Shift: TShiftState); 
    procedure DrawGrid1KeyUp(Sender: TObject; var Key: Word; 
      Shift: TShiftState); 
    procedure Undo1Click(Sender: TObject); 
    procedure BeepOff1Click(Sender: TObject); 
    procedure Retry1Click(Sender: TObject); 
    procedure GotoToWorld1Click(Sender: TObject); 
    procedure exit1Click(Sender: TObject); 
    procedure DrawGrid1MouseUp(Sender: TObject; Button: TMouseButton; 
      Shift: TShiftState; X, Y: Integer); 
    procedure FormPaint(Sender: TObject); 
  private 
    { Private declarations } 
    protime:integer; 
    hightscore:integer; 
    swinpath:string; 
    imagetemp:tbitmap; 
    manindex:integer; 
    undotimes:integer; 
    undoclick:integer; 
    tssystem:tstrings; 
    movedstep:integer; 
    username:string; 
    oldstateXY:array[0..13,0..15] of integer; 
    undostateXY:array[0..13,0..15,0..utimes] of integer; 
    undooldstateXY:array[0..13,0..15,0..utimes] of integer; 
    undomanindex:array[0..utimes] of integer; 
    undorow,undocol:array[0..utimes] of integer; 
    procedure setstateXY(oldx,oldy:integer); 
    procedure setboxstate(x,y,x1,y1,stay:integer;var canselt:boolean); 
    function iswin:boolean; 
    procedure startnewone; 
    function getfield(s:string;idx:integer):string; 
  public 
    { Public declarations } 
    curstate:integer; 
    stateXY:array[0..13,0..15] of integer; 
    procedure initnewstate(state:integer); 
    procedure readblockfromfile(fname,sname:string;ts:tstrings); 
  end; 
 
var 
  Form1: TForm1; 
 
implementation 
 
uses Chelp,cabout, Cdesign; 
 
{$R *.DFM} 
 
procedure TForm1.FormCreate(Sender: TObject); 
var 
   state:integer; 
   s:string; 
   buf:array[0..60] of char; 
begin 
    protime:=0; 
    username:=''; 
    tssystem:=tstringlist.create; 
    getwindowsdirectory(buf,sizeof(buf)); 
    swinpath:=buf+'\'; 
    if not fileexists(swinpath+'gxglcy.ini') then begin 
        tssystem.Append('curstate=1'); 
        tssystem.SaveToFile(swinpath+'gxglcy.ini'); 
    end; 
    form1.ClientHeight:=442; 
    form1.ClientWidth:=482; 
    undotimes:=0; 
    undoclick:=0; 
    tssystem.loadfromfile(swinpath+'gxglcy.ini'); 
    drawgrid1.Canvas.Pen.color:=clblack; 
    drawgrid1.Canvas.brush.color:=clblack; 
    imagetemp:=tbitmap.Create; 
    state:=1; 
    s:=trim(tssystem.values['curstate']); 
    if s<>'' then begin 
        try 
            state:=strtoint(s); 
        except 
            state:=1; 
        end; 
    end; 
    curstate:=state; 
    beepoff1.Checked:=tssystem.Values['nosound']='1'; 
    initnewstate(state); 
end; 
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
timer1.Enabled:=false; 
form1.OnPaint:=nil; 
imagetemp.free; 
tssystem.free; 
end; 
 
procedure TForm1.DrawGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; 
  var CanSelect: Boolean); 
var 
    currow,curcol:integer; 
    isin:boolean; 
begin 
if not form2.visible then begin 
   with drawgrid1 do begin 
      if acol<>col then begin 
          if acol>col then begin 
              manindex:=10; 
              stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                curcol:=col; 
                isin:=false; 
              while (((stateXY[row,curcol+1]=1)or(stateXY[row,curcol+1]=2))and(curcol<=acol-1)) do begin 
                  curcol:=curcol+1; 
                  isin:=true; 
              end; 
//              if curcol>acol then curcol:=acol; 
              if isin then curcol:=curcol-1; 
          end 
          else begin 
              manindex:=8; 
              stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                curcol:=col; 
                isin:=false; 
              while (((stateXY[row,curcol-1]=1)or(stateXY[row,curcol-1]=2))and(curcol>=acol+1)) do begin 
                  curcol:=curcol-1; 
                  isin:=true; 
              end; 
//                if curcolrow then begin 
          if arow>row then begin 
               manindex:=6; 
               stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                currow:=row; 
                isin:=false; 
              while (((stateXY[currow+1,curcol]=1)or(stateXY[currow+1,curcol]=2))and(currow<=arow-1)) do begin 
                  currow:=currow+1; 
                  isin:=true; 
              end; 
//                if currow>arow then currow:=arow; 
                if isin then currow:=currow-1; 
          end 
          else begin 
               manindex:=12; 
               stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                 currow:=row; 
                 isin:=false; 
              while (((stateXY[currow-1,curcol]=1)or(stateXY[currow-1,curcol]=2))and(currow>=arow+1)) do begin 
                  currow:=currow-1; 
                  isin:=true; 
              end; 
//                if currowrow then begin 
          if arow>row then begin 
              manindex:=6; 
              stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                currow:=row; 
                isin:=false; 
              while (((stateXY[currow+1,curcol]=1)or(stateXY[currow+1,curcol]=2))and(currow<=arow-1)) do begin 
                  currow:=currow+1; 
                  isin:=true; 
              end; 
//                if currow>arow then currow:=arow; 
                if isin then currow:=currow-1; 
          end 
          else begin 
               manindex:=12; 
               stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                 currow:=row; 
                 isin:=false; 
              while (((stateXY[currow-1,curcol]=1)or(stateXY[currow-1,curcol]=2))and(currow>=arow+1)) do begin 
                  currow:=currow-1; 
                  isin:=true; 
              end; 
//                if currowcol then begin 
          if acol>col then begin 
              manindex:=10; 
              stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                curcol:=col; 
                isin:=false; 
              while (((stateXY[currow,curcol+1]=1)or(stateXY[currow,curcol+1]=2))and(curcol<=acol-1)) do begin 
                  curcol:=curcol+1; 
                  isin:=true; 
              end; 
//              if curcol>acol then curcol:=acol; 
              if isin then curcol:=curcol-1; 
          end 
          else begin 
              manindex:=8; 
              stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
                curcol:=col; 
                isin:=false; 
              while (((stateXY[currow,curcol-1]=1)or(stateXY[currow,curcol-1]=2))and(curcol>=acol+1)) do begin 
                  curcol:=curcol-1; 
                  isin:=true; 
              end; 
//                if curcolcurrow then begin 
       manindex:=6; 
       stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
   end; 
   if arowcurcol then begin 
       manindex:=10; 
       stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex; 
   end; 
   if acolacol then begin 
              if curcol>acol then begin 
                  setboxstate(arow,acol-1,arow,acol,1,canselect); 
              end 
              else begin 
                  setboxstate(arow,acol+1,arow,acol,1,canselect); 
              end; 
            end; 
          end 
          else begin 
            if currow<>arow then begin 
              if currow>arow then begin 
                  setboxstate(arow-1,acol,arow,acol,1,canselect); 
              end 
              else begin 
                  setboxstate(arow+1,acol,arow,acol,1,canselect); 
              end; 
            end; 
          end; 
      end; 
 
    4:begin 
          if currow=arow then begin 
            if curcol<>acol then begin 
              if curcol>acol then begin 
                  setboxstate(arow,acol-1,arow,acol,2,canselect); 
              end 
              else begin 
                  setboxstate(arow,acol+1,arow,acol,2,canselect); 
              end; 
            end; 
          end 
          else begin 
            if currow<>arow then begin 
              if currow>arow then begin 
                  setboxstate(arow-1,acol,arow,acol,2,canselect); 
              end 
              else begin 
                  setboxstate(arow+1,acol,arow,acol,2,canselect); 
              end; 
            end; 
          end; 
      end; 
  end; 
end 
else begin 
               canselect:=false; 
             if not beepoff1.Checked then begin 
                 beep; 
             end; 
end; 
end 
else begin 
    stateXY[arow,acol]:=form2.wutype; 
    form1.Repaint; 
end; 
end; 
 
procedure TForm1.Timer1Timer(Sender: TObject); 
begin 
    protime:=protime+1; 
    if protime>=6 then begin 
       if not form2.visible then begin 
         stateXY[drawgrid1.Row,drawgrid1.Col]:=stateXY[drawgrid1.Row,drawgrid1.Col]+1; 
           if stateXY[drawgrid1.Row,drawgrid1.Col]>manindex then begin 
               stateXY[drawgrid1.Row,drawgrid1.Col]:=manindex-1; 
           end; 
       end; 
 
       protime:=0; 
    end; 
    form1.Repaint; 
end; 
 
procedure TForm1.DrawGrid1KeyDown(Sender: TObject; var Key: Word; 
  Shift: TShiftState); 
var 
   i,j:integer; 
begin 
if not form2.visible then begin 
     case key of 
         71:begin 
                if ssctrl in shift then begin 
                    undo1.Enabled:=false; 
                    retry1.enabled:=false; 
                    gototoworld1.enabled:=false; 
                           for i:=0 to 13 do begin 
                               for j:=0 to 15 do begin 
                                   stateXY[i,j]:=-1; 
                               end; 
                           end; 
                    drawgrid1.Canvas.Rectangle(0,0,drawgrid1.width,drawgrid1.Height); 
                    form2.left:=10; 
                    form2.top:=30; 
                    form1.Repaint; 
                    form2.show; 
                end; 
            end; 
     end; 
end; 
end; 
 
procedure TForm1.setstateXY(oldx,oldy:integer); 
begin 
          if oldstateXY[oldx,oldy]=5 then begin 
              stateXY[oldx,oldy]:=1; 
              oldstateXY[oldx,oldy]:=1; 
          end 
          else begin 
              if oldstateXY[oldx,oldy]=6 then begin 
                  stateXY[oldx,oldy]:=2; 
                  oldstateXY[oldx,oldy]:=2; 
              end 
              else begin 
                  stateXY[oldx,oldy]:=oldstateXY[oldx,oldy]; 
              end; 
          end; 
end; 
procedure TForm1.setboxstate(x,y,x1,y1,stay:integer;var canselt:boolean); 
var 
   i,j:integer; 
begin 
          with form1 do begin 
                  case stateXY[x,y] of 
                      -1,0,3,4:begin 
                                  canselt:=false; 
                                  if not beepoff1.Checked then begin 
                                      beep; 
                                  end; 
                               end; 
                      1:begin 
                            for i:=0 to 13 do begin 
                                for j:=0 to 15 do begin 
                                    undostateXY[i,j,undotimes]:=stateXY[i,j]; 
                                    undooldstateXY[i,j,undotimes]:=oldstateXY[i,j]; 
                                end; 
                            end; 
                            undomanindex[undotimes]:=manindex; 
                            undorow[undotimes]:=drawgrid1.row; 
                            undocol[undotimes]:=drawgrid1.col; 
                            undoclick:=undoclick+1; 
                            undo1.Enabled:=undoclick>0; 
                            undotimes:=undotimes+1; 
                            if undotimes>utimes then begin 
                                undotimes:=0; 
                            end; 
                            stateXY[x,y]:=3; 
                            oldstateXY[x,y]:=3; 
                            stateXY[x1,y1]:=manindex-1; 
                            oldstateXY[x1,y1]:=stay; 
                            setstateXY(drawgrid1.row,drawgrid1.col); 
                            movedstep:=movedstep+1; 
                            statusbar1.Panels[0].text:='已移动步数:'+inttostr(movedstep); 
                            form1.Repaint; 
                        end; 
                      2:begin 
                            for i:=0 to 13 do begin 
                                for j:=0 to 15 do begin 
                                    undostateXY[i,j,undotimes]:=stateXY[i,j]; 
                                    undooldstateXY[i,j,undotimes]:=oldstateXY[i,j]; 
                                end; 
                            end; 
                            undomanindex[undotimes]:=manindex; 
                            undorow[undotimes]:=drawgrid1.row; 
                            undocol[undotimes]:=drawgrid1.col; 
                            undoclick:=undoclick+1; 
                            undo1.Enabled:=undoclick>0; 
                            undotimes:=undotimes+1; 
                            if undotimes>utimes then begin 
                                undotimes:=0; 
                            end; 
                            stateXY[x,y]:=4; 
                            oldstateXY[x,y]:=4; 
                            stateXY[x1,y1]:=manindex-1; 
                            oldstateXY[x1,y1]:=stay; 
                            setstateXY(drawgrid1.row,drawgrid1.col); 
                            movedstep:=movedstep+1; 
                            statusbar1.Panels[0].text:='已移动步数:'+inttostr(movedstep); 
                            form1.Repaint; 
                        end; 
                  end; 
          end; 
end; 
 
procedure Tform1.initnewstate(state:integer); 
var 
   i,j:integer; 
   imgindex:integer; 
   tslevel:tstrings; 
   s,ss:string; 
begin 
    movedstep:=0; 
    undotimes:=0; 
    undoclick:=0; 
    undo1.Enabled:=false; 
    timer1.enabled:=false; 
    drawgrid1.OnSelectCell:=nil; 
    drawgrid1.Canvas.Rectangle(0,0,drawgrid1.width,drawgrid1.Height); 
    drawgrid1.Refresh; 
    manindex:=6; 
    tslevel:=tstringlist.Create; 
    while tslevel.count=0 do begin 
        readblockfromfile('boxworld.ini',inttostr(state),tslevel); 
        state:=state-1; 
    end; 
       curstate:=state+1; 
       for i:=0 to 13 do begin 
           for j:=1 to 16 do begin 
             imgindex:=strtoint(tslevel.Strings[i][j])-1; 
             stateXY[i,j-1]:=imgindex; 
             oldstateXY[i,j-1]:=imgindex; 
             if imgindex>=5 then begin 
                 drawgrid1.col:=j-1; 
                 drawgrid1.row:=i; 
             end; 
           end; 
       end; 
     tslevel.free; 
     form1.caption:='推箱子--第'+inttostr(curstate)+'关'; 
     statusbar1.Panels[0].text:='已移动步数:0'; 
     s:=''; 
     s:=tssystem.Values[inttostr(curstate)]; 
     if s='' then begin 
         ss:='无'; 
         hightscore:=maxint; 
     end 
     else begin 
         ss:=getfield(s,0)+'用了'+getfield(s,1)+'步!'; 
         hightscore:=strtoint(getfield(s,1)); 
     end; 
     statusbar1.Panels[1].text:='本局最高记录:'+ss; 
     tssystem.Values['curstate']:=inttostr(curstate); 
     tssystem.SaveToFile(swinpath+'gxglcy.ini'); 
     drawgrid1.OnSelectCell:=DrawGrid1SelectCell; 
     timer1.enabled:=true; 
end; 
 
procedure Tform1.readblockfromfile(fname,sname:string;ts:tstrings); 
var 
   i:integer; 
   tsfile:tstrings; 
   fromidx:integer; 
   s:string; 
begin 
    ts.clear; 
    if fileexists(fname) then begin 
        tsfile:=tstringlist.create; 
        tsfile.LoadFromFile(fname); 
        fromidx:=tsfile.IndexOf('['+sname+']'); 
        if fromidx<0 then begin 
            fromidx:=tsfile.count; 
        end; 
        for i:=fromidx+1 to tsfile.count-1 do begin 
            s:=trim(tsfile.strings[i]); 
            if s<>'' then begin 
                if s[1]<>'[' then begin 
                   ts.Append(s); 
                end 
                else begin 
                   break; 
                end; 
            end; 
        end; 
        tsfile.free; 
    end 
    else begin 
        ts.clear; 
    end; 
end; 
 
function Tform1.iswin:boolean; 
var 
   i,j:integer; 
begin 
    result:=true; 
    for i:=0 to 13 do begin 
        for j:=0 to 15 do begin 
            if stateXY[i,j]=3 then begin 
                result:=false; 
                break; 
            end; 
        end; 
    end; 
 
end; 
 
procedure TForm1.DrawGrid1KeyUp(Sender: TObject; var Key: Word; 
  Shift: TShiftState); 
begin 
if not form2.visible then begin 
  case key of 
   37,38,39,40:begin 
                   startnewone; 
               end; 
  end; 
end; 
end; 
////////////////////////////////////////////////////////////////////////////////////////// 
procedure TForm1.Undo1Click(Sender: TObject); 
var 
   i,j:integer; 
begin 
    undoclick:=undoclick-1; 
    undo1.Enabled:=undoclick>0; 
    drawgrid1.OnSelectCell:=nil; 
                            undotimes:=undotimes-1; 
                            if undotimes<0 then begin 
                                undotimes:=utimes; 
                            end; 
                            for i:=0 to 13 do begin 
                                for j:=0 to 15 do begin 
                                    stateXY[i,j]:=undostateXY[i,j,undotimes]; 
                                    oldstateXY[i,j]:=undooldstateXY[i,j,undotimes]; 
                                end; 
                            end; 
     drawgrid1.row:=undorow[undotimes]; 
     drawgrid1.col:=undocol[undotimes]; 
     manindex:=undomanindex[undotimes]; 
     movedstep:=movedstep-1; 
     statusbar1.Panels[0].text:='已移动步数:'+inttostr(movedstep); 
     drawgrid1.OnSelectCell:=DrawGrid1SelectCell; 
     form1.Repaint; 
end; 
 
procedure TForm1.BeepOff1Click(Sender: TObject); 
begin 
  beepoff1.Checked:=not beepoff1.checked; 
  if beepoff1.Checked then tssystem.Values['nosound']:='1' 
  else tssystem.Values['nosound']:='0'; 
  tssystem.SaveToFile(swinpath+'gxglcy.ini'); 
end; 
 
procedure TForm1.Retry1Click(Sender: TObject); 
begin 
    initnewstate(curstate); 
end; 
 
procedure TForm1.GotoToWorld1Click(Sender: TObject); 
var 
   s:string; 
begin 
s:=''; 
s:=trim(inputbox('选择另一局','请输入局数:',inttostr(curstate))); 
    if (s<>'')and(s<>inttostr(curstate)) then begin 
        try 
            curstate:=strtoint(s); 
            initnewstate(curstate); 
        except 
        end; 
    end; 
end; 
 
procedure TForm1.exit1Click(Sender: TObject); 
begin 
timer1.Enabled:=false; 
imagetemp.free; 
tssystem.free; 
application.Terminate; 
end; 
 
procedure Tform1.startnewone; 
begin 
  if iswin then begin 
    if movedstep'' then begin 
        if result[1]='|' then begin 
            delete(result,1,1); 
        end; 
    end; 
    if result<>'' then begin 
        if result[length(result)]='|' then begin 
            delete(result,length(result),1); 
        end; 
    end; 
end; 
 
procedure TForm1.DrawGrid1MouseUp(Sender: TObject; Button: TMouseButton; 
  Shift: TShiftState; X, Y: Integer); 
begin 
  if not form2.visible then startnewone; 
end; 
 
procedure TForm1.FormPaint(Sender: TObject); 
var 
   i,j:integer; 
   imgindex:integer; 
begin 
   with drawgrid1,drawgrid1.canvas do begin 
       for i:=0 to 13 do begin 
           for j:=1 to 16 do begin 
               imgindex:=stateXY[i,j-1]; 
               if imgindex>=0 then begin 
                   imagelist1.GetBitmap(imgindex,imagetemp); 
                   draw(CellRect(j-1,i).left,CellRect(j-1,i).top,imagetemp); 
               end 
               else begin 
                   Rectangle(CellRect(j-1,i).left,CellRect(j-1,i).top,CellRect(j-1,i).right,CellRect(j-1,i).bottom); 
               end; 
           end; 
       end; 
   end; 
end; 
 
end.