2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Шахматы. Ход пешки
Сообщение18.05.2012, 06:53 


20/05/11
22
Шахматы на Делфи. Помогите, пожалуйста, найти ошибки в ходе пешки. :oops: Не работает(((
Код:
unit Unit1;

interface

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

  type
  TChess = class(TForm)
    procedure FormCreate(Sender: TObject);
    private
     A: Array [1..8,1..8] of TShape;
    Number: Array [1..4, 1..8] of TLabel;
    { Private declarations }
    Function Shah(color : boolean) : boolean;
    procedure OnImageDrop(Sender, Source: TObject; X, Y: Integer);
    procedure OnImageOver(Sender, Source: TObject; X, Y: Integer;
    State: TDragState; var Accept: Boolean);
  public
    { Public declarations }
  end;

   Coordinaty=array [1..2] of integer;
  TFigura=Class (TImage)
  private
  Public
    FPlace: Coordinaty;
    FColor: boolean;
    Procedure SetPlace (const a:coordinaty);
    Property Place: coordinaty read FPlace write SetPlace;
    Property color: boolean read FColor;
    protected
    constructor  OOO(value:Coordinaty);
    Function Hod ( x : coordinaty): boolean; virtual; abstract;
    Function pryg (x: coordinaty): boolean;

  End;
// подклассы
TPAWN = class(TFigura)
  private
    Function Hod(X : coordinaty): boolean; override;
  end;
TRook = class(TFigura)
  private
    Function Hod(X : coordinaty): boolean; override;
  end;
TKING = class(TFigura)
  private
    Function Hod(X : coordinaty): boolean; override;
  end;
TBishop = class(TFigura)
  private
    Function Hod(X : coordinaty): boolean; override;
  end;
TQueen = class(TFigura)
  private
    Function Hod(X : coordinaty): boolean; override;
  end;
TKnight = class(TFigura)
  private
    Function Hod(X : coordinaty): boolean; override;
  end;



var
  Chess: TChess;
    Figures: array[1..32] of TFigura;
    ColorHOD: boolean;
    Nextturn:boolean;
implementation

{$R *.dfm}
{$R Picture.res}

procedure TChess.FormCreate(Sender: TObject);
var i, j: byte;
    polog:Coordinaty;
begin
Nextturn:=true;
  ClientHeight := 65*8+50;
  ClientWidth := 65*8+50;
  BorderStyle := bsSingle;

for j:=1 to 8 do
for i:=1 to 8 do
  begin
    a[i,9-j]:=TShape.Create(Chess);
    a[i,9-j].Parent:=Chess;
    a[i,9-j].Height:=65;
    a[i,9-j].Width:=65;
    a[i,9-j].Tag:=i*10+j;
    a[i,9-j].Left:=(i-1)*a[i,9-j].Height+20;
    a[i,9-j].Top:=(j-1)*a[i,9-j].Height+20;
    a[i,9-j].OnDragDrop:=Chess.OnImageDrop;
    a[i,9-j].OnDragOver:=Chess.OnImageOver;
    if odd(i+j) then a[i,9-j].Brush.Color:=clBtnShadow;
    end;
for i:=1 to 4 do
  for j:=1 to 8 do
    begin
    Number[i,j]:=TLabel.Create(Chess);
    Number[i,j].Parent:=Chess;
    case i of
    1, 2:
      begin
        Number[i,j].Caption := Chr(Ord('A')+j-1);
        Number[i,j].Left:=(j)*65-15;
        Number[i,j].Top:= 4 +550*(i-1);
      end;
    3, 4:
      begin
        Number[i,j].Caption := IntToStr(9-j);
        Number[i,j].Top:=(j)*65-15;
        Number[i,j].Left:= 4 +550*(i-3);
      end;
    end;

    end;
    polog[1]:=1;
    polog[2]:=5;
    Figures[1]:=TKING.OOO(polog);
    polog[1]:=1;
    polog[2]:=4;
    Figures[2]:=TQUEEN.OOO(polog);
    polog[1]:=1;
    polog[2]:=3;
    Figures[3]:=TBISHOP.OOO(polog);
    polog[1]:=1;
    polog[2]:=6;
    Figures[4]:=TBISHOP.OOO(polog);
    polog[1]:=1;
    polog[2]:=2;
    Figures[5]:=TKNIGHT.OOO(polog);
    polog[1]:=1;
    polog[2]:=7;
    Figures[6]:=TKNIGHT.OOO(polog);
    polog[1]:=1;
    polog[2]:=1;
    Figures[7]:=TROOK.OOO(polog);
    polog[1]:=1;
    polog[2]:=8;
    Figures[8]:=TROOK.OOO(polog);
    polog[1]:=2;
    polog[2]:=1;
    for i:=1 to 8 do begin
    Figures[8+i]:=Tpawn.OOO(polog);
    polog[2]:=polog[2]+1;
    end;
    polog[1]:=8;
    polog[2]:=5;
    Figures[17]:=TKING.OOO(polog);
    polog[1]:=8;
    polog[2]:=4;
    Figures[18]:=TQUEEN.OOO(polog);
    polog[1]:=8;
    polog[2]:=3;
    Figures[19]:=TBISHOP.OOO(polog);
    polog[1]:=8;
    polog[2]:=6;
    Figures[20]:=TBISHOP.OOO(polog);
    polog[1]:=8;
    polog[2]:=2;
    Figures[21]:=TKNIGHT.OOO(polog);
    polog[1]:=8;
    polog[2]:=7;
    Figures[22]:=TKNIGHT.OOO(polog);
    polog[1]:=8;
    polog[2]:=1;
    Figures[23]:=TROOK.OOO(polog);
    polog[1]:=8;
    polog[2]:=8;
    Figures[24]:=TROOK.OOO(polog);
    polog[1]:=7;
    polog[2]:=1;
    for i:=1 to 8 do begin
    Figures[24+i]:=Tpawn.OOO(polog);
    polog[2]:=polog[2]+1;
    end;



end;

{ TFigura }


constructor TFigura.OOO(value:Coordinaty);
begin
Create(Chess);
parent := Chess;
DragMode:=dmAutomatic;
OnDragDrop:=Chess.OnImageDrop;
OnDragOver:=Chess.OnImageOver;
if value[1] < 4
  then
    begin
      Picture.Bitmap.LoadFromResourceName(HInstance, 'BLACK_'
        + Self.ClassName);
      Fcolor:= false;
    end
  else
    begin
      Picture.Bitmap.LoadFromResourceName(HInstance, 'WHITE_'
        + Self.ClassName);
      Fcolor := true;
    end;
Width := 40; //указываем высоту нашей картинки
Height := 40; //Указываем ширину нашей картинки
transparent:=True;
Place:=value;

end;

function TFigura.pryg(x: coordinaty): boolean;
var i:byte;
begin
Result :=true; {С этой строки начинается весь метод. Она необходима для начального присваивания значения результат функции. Таким образом, мы изначально разрешаем ход, а в случае найденной занятой клетки - запрещаем.}
//вертикаль
{проверка на ход по вертикали}
if self.Place[1] = x[1] then
for i:= 1 to 32 do //цикл по всем фигурам
{ищем несрубленную фигуру, координата X которой совпадает с нашей}
if  (Figures[i] <> nil)
and ( Figures[i].Place[1] = self.Place[1]) then
{если такая найдена, то проверим находится ли она в промежутке движения фигуры}
if (Figures[i].Place[2] > self.Place[2])
and (Figures[i].Place[2] < x[2])
or (Figures[i].Place[2] < self.Place[2])
and (Figures[i].Place[2] > x[2])
then
{если и это условие выполнено, то занятая клетка найдена - ход запрещаем}
Result := false;

if self.Place[2] = x[2] then
for i:= 1 to 32 do //цикл по всем фигурам
{ищем несрубленную фигуру, координата X которой совпадает с нашей}
if   (Figures[i] <> nil)
and (Figures[i].Place[2] = self.Place[2])then
{если такая найдена, то проверим находится ли она в промежутке движения фигуры}
if (Figures[i].Place[1] > self.Place[1])
and (Figures[i].Place[1] < x[1])
or (Figures[i].Place[1] < self.Place[1])
and (Figures[i].Place[1] > x[1])
then
{если и это условие выполнено, то занятая клетка найдена - ход запрещаем}
Result := false;

if abs(Self.Place[2] - x[2]) = abs(Self.FPlace[1] - x[1])
      then
      for i:= 1 to 32 do
      if (Figures[i] <> nil) and
        (((Figures[i].Place[1] > Self.Place[1]) and
            (Figures[i].Place[1] < x[1])) or
          ((Figures[i].Place[1] < Self.Place[1]) and
            (Figures[i].Place[1] > x[1]))) and
        (((Figures[i].Place[2] > Self.Place[2]) and
            (Figures[i].Place[2] < x[2])) or
          ((Figures[i].Place[2] < Self.Place[2]) and
            (Figures[i].Place[2] > x[2]))) and
        (abs(Figures[i].Place[2] - x[2]) = abs
          (Figures[i].Place[1] - x[1])) then
        result := false;

end;

procedure TFigura.SetPlace(const a: coordinaty);
begin
FPlace:=a;
Top:=(a[1]-1)*65+30;
Left:=(a[2]-1)*65+30;
end;


{ TPawn }

function TPawn.Hod(X: coordinaty): boolean;
var
  fd: Boolean;
  i: Byte;
begin
fd := true;
  for i := 1 to 32 do
  begin
    if (Figures[i] <> nil) and (Figures[i].Color <> Self.Color) and
      (Figures[i].Place[1] = X[1]) and (X[2] = Figures[i].Place[2]) then
      fd := false;
  end;
if (fd) then
  begin
    result := false;
    if (Color) then
    begin
      if (self.Place[2] = 7) then
        if((self.Place[2] - X[2] = 1) or (self.Place[2] - X[2] = 2))
        and (self.Place[1] = X[1]) then
        hod:=true
      else
        if(self.Place[2] - X[2] = 1) and (self.Place[1] = X[1]) then
        hod:=true;
    end
    else
    begin
      if (self.Place[2] = 2) then
        if ((X[2] - self.Place[2] = 1) or (X[2] - self.Place[2] = 2))
        and (self.Place[1] = X[1])then
        hod:=true
      else
        if (X[2] - self.Place[2] = 1) and (self.Place[1] = X[1])then
        hod:=true;
    end;
   // if () then
   //   result := false;
  end
  else
  begin
    if (Color) then
      result := (abs(self.Place[1] - X[1]) = 1) and (self.Place[2] - X[2] = 1)
    else
      result := (abs(self.Place[1] - X[1]) = 1) and (X[2] - self.Place[2] = 1)}
  end;
{if self.place[2] = x[2] then
Hod:=true else Hod:=false;
  end; }
end;

{ TRook }

function TRook.Hod(X: coordinaty): boolean;
begin
if (self.place[1] = x[1])
or (self.place[2] = x[2])
then
Hod:=true
else
Hod:=false;
end;

{ TKing }

function TKing.Hod(X: coordinaty): boolean;
begin
if(abs(self.place[1]*10+self.place[2]-x[1]*10-x[2])=1) or (abs(self.place[1]*10+self.place[2]-x[1]*10-x[2])=11) or
(abs(self.place[1]*10+self.place[2]-x[1]*10-x[2])=10) or (abs(self.place[1]*10+self.place[2]-x[1]*10-x[2])=9) then
Hod:=true else Hod:=False;
end;

{ TBishop }

function TBishop.Hod(X: coordinaty): boolean;
begin
if abs(self.place[1]-x[1])=abs(self.place[2]-x[2])
then Hod:=true
else Hod:=false;
end;

{ TQueen }

function TQueen.Hod(X: coordinaty): boolean;
begin
if (self.Place[1] = X[1])
or (self.Place[2] = X[2])
or (abs(self.Place[1] - X[1]) = abs(self.Place[2] - X[2]))
then
Result := true
else
Result := false;
end;

{ TKnight }

function TKnight.Hod(X: coordinaty): boolean;
begin
if (abs(self.place[1]-x[1])+abs(self.place[2]-x[2])=3) and
(abs(self.place[1]-x[1])>0) and (abs(self.place[2]-x[2])>0) then
Hod:=True else Hod:=False;
end;

procedure TChess.OnImageDrop(Sender, Source: TObject; X, Y: Integer);
var
Pos: coordinaty;
OldPos: coordinaty;
begin
if Sender is TShape then begin
Pos[1]:=TShape(Sender).Tag mod 10;
Pos[2]:=TShape(Sender).Tag div 10;
if (TFigura(Source).Hod(Pos)) and (TFigura(Source).pryg(Pos)) and (TFigura(Source).Fcolor = Nextturn) then
begin
Pos[1]:=TShape(Sender).Tag mod 10;
Pos[2]:=TShape(Sender).Tag div 10;
if NextTurn = true then
  NextTurn :=false
  else NextTurn:=true
  end else pos:=TFigura(Source).place;
end;
if Sender is TFigura then
begin
pos:=TFigura(Sender).place;
OldPos:=TFigura(Source).place;
if (TFigura(Source).Hod(Pos))
and (TFigura(Source).pryg(Pos))
and (TFigura(Source).Fcolor = Nextturn)
and (TFigura(Sender).FColor<>NextTurn) then
begin
  pos:=TFigura(Sender).place;
  TFigura(Sender).Free;
  if NextTurn = true then
  NextTurn :=false else NextTurn :=true;
  end else pos:=TFigura(Source).place;
end;
TFigura(Source).Place:=Pos;
{Shah(NextTurn);
if NextTurn = true
then
NextTurn := false
else
NextTurn := true              }


end;

procedure TChess.OnImageOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
Accept := true;
end;

function TChess.Shah(color: boolean): boolean;
var I: byte;
King: integer;
begin
Result := false;
//найдем необходимого короля
for i := 1 to 32 do
if (Figures[i] is TKing)
and (Figures[i].Fcolor <> color)
then
King := i;
//проверим выполняемость всех описанных выше условий
for I := 1 to 32 do
if Figures[i]<>nil then
if (Figures[i].Fcolor<>Figures[king].Fcolor)
and Figures[i].Hod(Figures[king].place)
and Figures[i].pryg(Figures[king].place) then begin
ShowMessage('шах!');
Result := true;
end;

end;



end.

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение18.05.2012, 08:04 


20/05/11
22
Спасибо, разобралась, подскажите, пожалуйста, куда прописать рокировку.

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение18.05.2012, 08:04 


20/05/11
22
Спасибо, разобралась, подскажите, пожалуйста, куда прописать рокировку.

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение18.05.2012, 09:17 


20/05/11
22
Помогите, пожалуйста, как и куда лучше прописать рокировку и в каком месте в процедуре TChess.OnImageDrop вызвать процедуру Sash :oops:

-- Пт май 18, 2012 12:47:56 --

Я вставила вот так:
Код:
procedure TChess.OnImageDrop(Sender, Source: TObject; X, Y: Integer);
var
Pos: coordinaty;
OldPos: coordinaty;
begin
if Sender is TShape then begin
Pos[1]:=TShape(Sender).Tag mod 10;
Pos[2]:=TShape(Sender).Tag div 10;
if (TFigura(Source).Hod(Pos)) and (TFigura(Source).pryg(Pos)) and (TFigura(Source).Fcolor = Nextturn) then
begin
{Pos[1]:=TShape(Sender).Tag mod 10;
Pos[2]:=TShape(Sender).Tag div 10;}
if NextTurn = true then
  NextTurn :=false
  else NextTurn:=true
  end else pos:=TFigura(Source).place;
end;
if Sender is TFigura then
begin
pos:=TFigura(Sender).place;
OldPos:=TFigura(Source).place;
if (TFigura(Source).Hod(Pos))
and (TFigura(Source).pryg(Pos))
and (TFigura(Source).Fcolor = Nextturn)
and (TFigura(Sender).FColor<>NextTurn) then
begin
  pos:=TFigura(Sender).place;
  TFigura(Sender).Free;
  if NextTurn = true then
  NextTurn :=false else NextTurn :=true;
  end else pos:=TFigura(Source).place;
end;
TFigura(Source).Place:=Pos;
Shah(NextTurn);
end;

procedure TChess.OnImageOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
Accept := true;
end;

function TChess.Shah(color: boolean): boolean;
var i: byte;
King: integer;
begin
Result := false;
//найдем необходимого короля
for i := 1 to 32 do
if (Figures[i] is TKing)
and (Figures[i].Fcolor <> color)
then
King := i;
//проверим выполняемость всех описанных выше условий
for I := 1 to 32 do
if Figures[i]<>nil then
if (Figures[i].Fcolor<>Figures[king].Fcolor)
and Figures[i].Hod(Figures[king].place)
and Figures[i].pryg(Figures[king].place) then begin
ShowMessage('шах!');
Result := true;
end;

end;

Но при этом у меня получается, что когда король под шахом, фигуры все равно могут ходить.Надо сделать запрет хода, помогите, пожалуйста :oops:

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение18.05.2012, 23:46 
Заслуженный участник


27/04/09
28128
Радикальный совет переписать всё заново, как понимаю, не подойдёт? :-)

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение19.05.2012, 21:34 


20/05/11
22
Теперь все работает, кроме шаха. Когда фигуре шах, то выводится сообщение, но игру продолжить можно.Не подскажете, как запрерить ходить фигурам, если при этом остается королю шах

-- Вс май 20, 2012 00:35:29 --

arseniiv в сообщении #573109 писал(а):
Радикальный совет переписать всё заново, как понимаю, не подойдёт? :-)


разве все так плохо?

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение20.05.2012, 18:15 
Заслуженный участник


27/04/09
28128
Natalya23 в сообщении #573434 писал(а):
разве все так плохо?
По-моему.

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение20.05.2012, 21:24 


20/05/11
22
а можно конкретнее

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение20.05.2012, 21:29 


01/07/08
836
Киев
arseniiv в сообщении #573109 писал(а):
Радикальный совет переписать всё заново, как понимаю, не подойдёт? :-)


В принципе, если у ТС не поднимается рука, можно применять метод перевода операторов в комментарий. Например в
Код:
procedure TChess.FormCreate(Sender: TObject);
var i, j: byte;
    polog:Coordinaty;
begin
Nextturn:=true;
  ClientHeight := 65*8+50;
  ClientWidth := 65*8+50;
  BorderStyle := bsSingle;

for j:=1 to 8 do
for i:=1 to 8 do
  begin
    a[i,9-j]:=TShape.Create(Chess);
    a[i,9-j].Parent:=Chess;
    a[i,9-j].Height:=65;
    a[i,9-j].Width:=65;
    a[i,9-j].Tag:=i*10+j;
    a[i,9-j].Left:=(i-1)*a[i,9-j].Height+20;
    a[i,9-j].Top:=(j-1)*a[i,9-j].Height+20;
    a[i,9-j].OnDragDrop:=Chess.OnImageDrop;
    a[i,9-j].OnDragOver:=Chess.OnImageOver;
    if odd(i+j) then a[i,9-j].Brush.Color:=clBtnShadow;
    end;
for i:=1 to 4 do
  for j:=1 to 8 do
    begin
    Number[i,j]:=TLabel.Create(Chess);
    Number[i,j].Parent:=Chess;
    case i of
    1, 2:
      begin
        Number[i,j].Caption := Chr(Ord('A')+j-1);
        Number[i,j].Left:=(j)*65-15;
        Number[i,j].Top:= 4 +550*(i-1);
      end;
    3, 4:
      begin
        Number[i,j].Caption := IntToStr(9-j);
        Number[i,j].Top:=(j)*65-15;
        Number[i,j].Left:= 4 +550*(i-3);
      end;
    end;

    end;
    polog[1]:=1;
    polog[2]:=5;
    Figures[1]:=TKING.OOO(polog);
{    polog[1]:=1;
    polog[2]:=4;
    Figures[2]:=TQUEEN.OOO(polog);
    polog[1]:=1;
    polog[2]:=3;
    Figures[3]:=TBISHOP.OOO(polog);
    polog[1]:=1;
    polog[2]:=6;
    Figures[4]:=TBISHOP.OOO(polog);
    polog[1]:=1;
    polog[2]:=2;
    Figures[5]:=TKNIGHT.OOO(polog);
    polog[1]:=1;
    polog[2]:=7;
    Figures[6]:=TKNIGHT.OOO(polog);
    polog[1]:=1;
    polog[2]:=1;
    Figures[7]:=TROOK.OOO(polog);
    polog[1]:=1;
    polog[2]:=8;
    Figures[8]:=TROOK.OOO(polog);
    polog[1]:=2;
    polog[2]:=1;
    for i:=1 to 8 do begin
    Figures[8+i]:=Tpawn.OOO(polog);
    polog[2]:=polog[2]+1;
    end;
}   polog[1]:=8;
    polog[2]:=5;
    Figures[17]:=TKING.OOO(polog);
  {  polog[1]:=8;
    polog[2]:=4;
    Figures[18]:=TQUEEN.OOO(polog);
    polog[1]:=8;
    polog[2]:=3;
    Figures[19]:=TBISHOP.OOO(polog);
    polog[1]:=8;
    polog[2]:=6;
    Figures[20]:=TBISHOP.OOO(polog);
    polog[1]:=8;
    polog[2]:=2;
    Figures[21]:=TKNIGHT.OOO(polog);
    polog[1]:=8;
    polog[2]:=7;
    Figures[22]:=TKNIGHT.OOO(polog);
    polog[1]:=8;
    polog[2]:=1;
    Figures[23]:=TROOK.OOO(polog);
    polog[1]:=8;
    polog[2]:=8;
    Figures[24]:=TROOK.OOO(polog);
    polog[1]:=7;
    polog[2]:=1;
    for i:=1 to 8 do begin
    Figures[24+i]:=Tpawn.OOO(polog);
    polog[2]:=polog[2]+1;
    end;
}


end;


На доске два короля. Попытка перевести короля на соседнюю клетку приводит к непредсказуемым скачкам. Получается очень забавная игра, перевести белого короля в гости к черному. :D Возможна задача о погоне.
Таким образом можно будет обучить ходить любую фигуру.
Код
Код:
a[i,9-j]
можно записать
Код:
a[i,j]
. Что бы это увидеть в двойном цикле инициализации клеток доски перед $end$ вставьте
Код:
if i>2 and j>3 then exit;
Меняйте ограничители и увидите от чего зависит заполнение доски.
Зря вы занялись установкой стандартной исходной позиции. Очень полезно устанавливать заданную позицию( задачи,этюды) С уважением,

 Профиль  
                  
 
 Re: Шахматы. Ход пешки
Сообщение20.05.2012, 23:42 
Заслуженный участник


27/04/09
28128
Natalya23 в сообщении #573859 писал(а):
а можно конкретнее
Код слишком длинён, и потому никак. Много причин.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: YandexBot [bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group