|
Вопрос # 1 192/ вопрос открыт / |
|
Здравствуйте!
Пишу шахматы и не как не могу сообразить, как мне реализовать ход и соответственно его проверку?
Все писал руками - по заданию, написать шахматы без использования визуального моделирования в Delphi (т.е. нельзя визуально вставлять на форму панели, рисунки, кнопки), при компиляции приложения форма должна быть пустая)
Осталось написать следующее:
- реализовать ход
- соответственно проверку хода (чтоб фигуры как попало не ходили)
- некое подобие искусственного интелекта, но это я уже нашел и постараюсь сам прикрутить.
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, ExtCtrls;
-
- type
- TForm1 = class(TForm)
- ImgFigure: TImage;
- procedure FormCreate(Sender: TObject);
-
-
-
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- TFigure = Class(TObject)
- private
- TFigColor:boolean;
- TypeFigure:String;
- ImgFigure:TImage;
- Function GetCoordFigure:TPanel;
- Procedure SetCoordFigure(const Value:Tpanel);
- constructor Fcreate (cvet:Boolean);virtual;abstract;
- public
- Procedure HodFigure(a:TPanel); Virtual;
- Protected
- DestroyFigure:Boolean;
- OcheredHodaFigure:Boolean;
-
- end;
-
- TKing = class(TFigure)
- Constructor Fcreate(cvet:Boolean); Override;
- Procedure HodFigure(a:TPanel); Override;
- end;
-
- TPeshka = class(TFigure)
- Width, Height : integer;
- Constructor Fcreate(cvet:Boolean); Override;
- Procedure HodFigure(a:TPanel); Override;
- end;
-
- TFerz = Class(TFigure)
- Width, Height : integer;
- Constructor Fcreate (cvet:Boolean);Override;
- Procedure HodFigure(a:TPanel); Override;
- end;
-
- TLoshad = Class (TFigure)
- Width, Height : integer;
- Constructor Fcreate (cvet:Boolean); Override;
- Procedure HodFigure(a:TPanel); Override;
- end;
-
- TSlon = Class (TFigure)
- Width, Height : integer;
- Constructor Fcreate (cvet:Boolean); Override;
- Procedure HodFigure(a:TPanel); Override;
- end;
-
- TLadya = Class (TFigure)
- Width, Height : integer;
- Constructor Fcreate(cvet:Boolean); Override;
- Procedure HodFigure(a:TPanel); Override;
- end;
-
- var
- Form1: TForm1;
- a: array [1..8,1..8] of Tpanel;
- b: array [1..8,1..8] of Tpanel;
- c: array [1..8] of String[1]=('A','B','C','D','E','F','G','H');
- d: array [1..8] of String[1]=('1','2','3','4','5','6','7','8');
- i,j,t,r,y,u,m,n: integer;
- K: array [1..2,1..2] of TKing;
- P: array [1..2,1..8] of TPeshka;
- F: array [1..2,1..2] of TFerz;
- L: array [1..2,1..4] of TLoshad;
- S: array [1..2,1..4] of TSlon;
- Lad: array [1..2,1..4] of TLadya;
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- for i:=1 to 8 do
- for j:=1 to 8 do
- begin
- a[i,j]:= TPanel.create(Form1);
- a[i,j].parent:= Form1;
- a[i,j].Left:=(i-1)*50+51;
- a[i,j].Top:=(j-1)*50+1;
- a[i,j].Width:=50;
- a[i,j].Height:=50;
- a[i,j].BevelOuter:=bvNone;
- a[i,j].Color:=clSkyBlue;
- if odd (i+j) then
- a[i,j].Color:=clGray else
- a[i,j].Color:=clInfobk;
- end;
-
- for i:=1 to 1 do
- for j:=1 to 8 do
- begin
- b[i,j]:= Tpanel.Create(Form1);
- b[i,j].Parent:= Form1;
- b[i,j].Left:=0;
- b[i,j].Top:=((j-1)*50+1);
- b[i,j].Width:=50;
- b[i,j].Height:=50;
- b[i,j].BevelOuter:=bvNone;
- b[i,j].Caption:=d[j];
- end;
-
- for i:=1 to 8 do
- for j:=1 to 1 do
- begin
- b[i,j]:= Tpanel.Create(Form1);
- b[i,j].Parent:= Form1;
- b[i,j].Left:=((i-1)*50+1)+50;
- b[i,j].Top:=400;
- b[i,j].Width:=50;
- b[i,j].Height:=50;
- b[i,j].BevelOuter:=bvNone;
- b[i,j].Caption:=c[i];
- end;
- //================PESHKA========================
- for t:=1 to 2 do
- for r:=1 to 8 do
- begin
- if t=1 then begin
- P[t,r]:=TPeshka.Fcreate(true);
- P[t,r].ImgFigure.Parent:=a[r,2];
- end
- else begin
- P[t,r]:=TPeshka.Fcreate(false);
- P[t,r].ImgFigure.Parent:=a[r,7];
- end;
- //================KING===========================
- for m:=1 to 2 do
- for n:=1 to 2 do
- if n=1 then begin
- K[m,n]:=TKing.Fcreate(true);
- K[m,n].ImgFigure.Parent:=a[4,1];
- end
- else begin
- K[m,n]:=TKing.Fcreate(false);
- K[m,n].ImgFigure.Parent:=a[5,8];
- end;
-
- //================FERZ=========================
- for m:=1 to 2 do
- for n:=1 to 4 do
- if n=1 then begin
- F[m,n]:=TFerz.Fcreate(true);
- F[m,n].ImgFigure.Parent:=a[5,1];
- end
- else begin
- F[m,n]:=TFerz.Fcreate(false);
- F[m,n].ImgFigure.Parent:=a[4,8];
- end;
-
- //================LOSHAD========================
- for m:=2 to 2 do
- for n:=2 to 4 do
- if n=3 then begin
- L[m,n]:=TLoshad.Fcreate(true);
- L[m,n].ImgFigure.Parent:=a[n,1];
- end
- else begin
- L[m,n]:=TLoshad.Fcreate(false);
- L[m,n].ImgFigure.Parent:=a[3,8];
- end;
-
- //===============================================
- for m:=1 to 2 do
- for n:=1 to 8 do
- if n=6 then begin
- L[m,n]:=TLoshad.Fcreate(true);
- L[m,n].ImgFigure.Parent:=a[6,1];
- end
- else begin
- L[m,n]:=TLoshad.Fcreate(false);
- L[m,n].ImgFigure.Parent:=a[6,8];
- end;
-
- //================LOSHAD=======================
- //================SLON=========================
- for m:=1 to 2 do
- for n:=1 to 8 do
- if n=1 then begin
- S[m,n]:=TSlon.Fcreate(true);
- S[m,n].ImgFigure.Parent:=a[7,1];
- end
- else begin
- S[m,n]:=TSlon.Fcreate(false);
- S[m,n].ImgFigure.Parent:=a[7,8];
- end;
-
- //================================
- for m:=1 to 2 do
- for n:=1 to 8 do
- if n=1 then begin
- S[m,n]:=TSlon.Fcreate(true);
- S[m,n].ImgFigure.Parent:=a[2,1];
- end
- else begin
- S[m,n]:=TSlon.Fcreate(false);
- S[m,n].ImgFigure.Parent:=a[2,8];
- end;
-
- //================LADYA=========================
- for m:=1 to 2 do
- for n:=1 to 8 do
- if n=1 then begin
- Lad[m,n]:=TLadya.Fcreate(true);
- Lad[m,n].ImgFigure.Parent:=a[8,1];
- end
- else begin
- Lad[m,n]:=TLadya.Fcreate(false);
- Lad[m,n].ImgFigure.Parent:=a[8,8];
- end;
-
- //================================
- for m:=1 to 2 do
- for n:=1 to 8 do
- if n=1 then begin
- Lad[m,n]:=TLadya.Fcreate(true);
- Lad[m,n].ImgFigure.Parent:=a[1,1];
- end
- else begin
- Lad[m,n]:=TLadya.Fcreate(false);
- Lad[m,n].ImgFigure.Parent:=a[1,8];
- end;
- end;
- end;
- //======================LADYA=========================
- //====================================================
- Function TFigure.GetCoordFigure:TPanel;
- begin
- end;
- Procedure TFigure.SetCoordFigure(const Value:Tpanel);
- begin
- end;
- //=====================================================
- Procedure TFigure.HodFigure(a:TPanel);
- begin
- end;
- //=====================================================
-
-
- Procedure TKing.HodFigure(a:TPanel);
- begin
- end;
- Constructor TKing.Fcreate;
- begin
- create;
- ImgFigure:=TImage.Create(a[1,1]);
- if cvet then
- begin ImgFigure.picture.LoadFromFile('BKing.bmp');
-
- end
- else
- begin
- ImgFigure.picture.LoadFromFile('WKing.bmp');
- ImgFigure.Transparent:=true;
- end;
- end;
- //===============================================================
- Procedure TPeshka.HodFigure(a:TPanel);
- begin
- end;
- Constructor TPeshka.Fcreate(cvet:boolean);
- begin
- create;
- ImgFigure:=TImage.Create(a[2,1]);
- if cvet then
- begin
- ImgFigure.picture.LoadFromFile('BPeshka.bmp');
- ImgFigure.Transparent:=true;
- end
- else
- begin
- ImgFigure.picture.LoadFromFile('WPeshka.bmp');
- ImgFigure.Transparent:=true;
- end;
- end;
- //================================================================
- Procedure TFerz.HodFigure(a:TPanel);
- begin
- end;
- Constructor TFerz.Fcreate;
- begin
- create;
- ImgFigure:=TImage.Create(a[2,1]);
- if cvet then
- begin
- ImgFigure.picture.LoadFromFile('BFerz.bmp');
- ImgFigure.Transparent:=true;
- end
- else
- begin
- ImgFigure.picture.LoadFromFile('WFerz.bmp');
- ImgFigure.Transparent:=true;
- end;
- end;
- //===================================================================
- Procedure TLoshad.HodFigure(a:TPanel);
- begin
- end;
- Constructor TLoshad.Fcreate;
- begin
- create;
- ImgFigure:=TImage.Create(a[2,1]);
- if cvet then
- begin
- ImgFigure.picture.LoadFromFile('BLoshad.bmp');
- ImgFigure.Transparent:=true;
- end
- else
- begin
- ImgFigure.picture.LoadFromFile('WLoshad.bmp');
- ImgFigure.Transparent:=true;
- end;
- end;
- //=============================================================================
- Procedure TSlon.HodFigure(a:TPanel);
- begin
- end;
- Constructor TSlon.Fcreate;
- begin
- create;
- ImgFigure:=TImage.Create(a[2,1]);
- if cvet then
- begin
- ImgFigure.picture.LoadFromFile('BSlon.bmp');
- ImgFigure.Transparent:=true;
- end
- else
- begin
- ImgFigure.picture.LoadFromFile('WSlon.bmp');
- ImgFigure.Transparent:=true;
- end;
- end;
- //============================================================================
- Procedure TLadya.HodFigure(a:TPanel);
- begin
- end;
- Constructor TLadya.Fcreate;
- begin
- create;
- ImgFigure:=TImage.Create(a[2,1]);
- if cvet then
- begin
- ImgFigure.picture.LoadFromFile('BLadya.bmp');
- ImgFigure.Transparent:=true;
- end
- else
- begin
- ImgFigure.picture.LoadFromFile('WLadya.bmp');
- ImgFigure.Transparent:=true;
- end;
- end;
- //=============================================================================
-
-
- end.
-
-
 |
Вопрос задал: jawwwik (статус: Посетитель)
Вопрос отправлен: 11 декабря 2007, 13:05
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: Матвеев Игорь Владимирович
Здравствуйте, jawwwik!
Касательно самого подхода - действительно, нужен абстрактный класс-фигура, от которого наследуются все реальные фигуры (пешки, слоны, короли и т.д.) как Вы это и делаете. Далее нужен класс-доста, это будет удобнее, например, чтобы определить возможна ли сейчас рокировка (такую возможность определяет доска, фигуры только "спрашивают"). Нужет класс-ход и класс-список ходов. Так каждая фигура должна уметь получать список доступных для нее ходов. В классе-ходе, помимо собственно хода должено быть значение ценности этого хода.
Далее, можно оценить все фигуры статически (скажем пешка стоит 1 у.е. конь 3 у.е. и т.д., кстати в шахматах на самом беле есть подобные веса для всех фигур), но подобный подход не даст качественной игры (все зависит от Ваших целей, или сдать курсовую, или написать прилично играющие шахматы). Второй случай - фигура сама определяет свою ценность в зависимости от положения на доске, от числа возможных ходов, от близости к вражескому королю, от числа и типа фигур, которым она угрожает, от наличия шаха на доске и др. условий.
Теперь, имеется ситуация на доске, нужно сделать ход одной из сторон (первый ход можно вообще не считать, а выбрать из дву-трех типа E2-E4). Для этого нужно определить все возможные ходы этим цветом. Далее нужно оценить каждый из этих ходов и ситуацию на доске вцелом (или просто сумма ценностей фигур, или какая-то функция от суммы).
Теперь нужна виртуальная доска. На ней делается один из возможных ходов, и ищется список всех возможных ответов со стороны противника, затем все возможные ответы с нашей стороны и т.д. до некоторого уровня вложенности. Таким образом получаем дерево где для каждого хода есть список возможных ответов. На каждом этапе считается ценность комбинации на доске, значит и ценность хода. Поскольку на каждый ход может быть сразу много ответов дерево начнет разрастаться очень быстро. Чтобы ускорить процесс обхода дерева примените алгоритм сокрашенного перебора (альфа-бета отсечения).
В итоге получите дерево с ценностями, из этого дерева выбираете лучший путь, т.е. чтобы вконце Вы получили значительное приемущество.
В этой задаче очень много тонкостей, см. home.uic.tula.ru/~kv200874/addons/rus/prog01.htm.
Мини-форум вопроса
Мини-форум пуст.
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|