Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Практический курс математического и компьютерного моделирования. Учебно-практическое пособие
.pdf
II. Программная реализация математической модели
board.refresh;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end. // конец файла figure.pas
Этот абстрактный класс содержит поле ID — идентификатор
фигуры, включающий ее номер (№0 — фигура отсутствует на
доске, №1 — король, №2 — ферзь, №3 — ладья и т.
д.), коорди-
наты на шахматной доске, цвет и объект board — «шахматная
доска» (объявления класса Tboard и всех типов вынесены в отдельный модуль board.pas, см. ниже). Класс Tboard предназна-
чен для поддержки графики и интерфейса с шахматными фигурами и, помимо прочего, содержит поле fig_board — массив 8
×
идентификаторов фигур. Фигура «делает ход», посылая сообщение объекту board отметить ее положение в этом массиве.
Поэтому кроме конструктора и деструктора этот класс имеет
метод move, который осуществляет «ход» фигуры — посылает
сообщение стереть запись своего текущего положения на доске
и записать новые координаты в массив fig_board, предварительно проверив допустимость
данного хода. Правильность хода
проверяет логическая функция can_move. Поскольку эта функция индивидуальна для каждой фигуры, она объявлена абстрактной и перекрывается в соответствующих классах.
// файл queen.pas
unit queen;
interface
uses figure, board;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Type Tqueen = class( Tfigure ) // класс Ферзь
protected
function can_move( to_position: Tposition ): Boolean; override;
public
constructor Init( ident: Tid; chessBoard: Tboard );
destructor delete;
end;
8
41

Математическое и компьютерное моделирование
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// может ли ферзь идти в to_position
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function Tqueen.can_move( to_position: Tposition ): Boolean;
begin
result := ( ID.pos.x = to_position.x )
OR ( ID.pos.y = to_position.y )
OR ( Abs( ID.pos.y - to_position.y ) =
Abs( ord( ID.pos.x ) - ord( to_position.x ) ) );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
constructor Tqueen.Init( ident: Tid; chessBoard: Tboard );
begin
inherited Init( ident, chessBoard );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - destructor Tqueen.delete;
begin
inherited delete;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end. // конец файла queen.pas
// файл rook.pas
unit rook;
interface
uses figure, board;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Type Trook = class( Tfigure ) // класс Ладья
protected
function can_move( to_position: Tposition ): Boolean; override;
public
constructor Init( ident: Tid; chessBoard: Tboard );
destructor delete;
end;
42

II. Программная реализация математической модели
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // может ли ладья идти в to_position
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function Trook.can_move( to_position: Tposition ): Boolean;
begin
result := ( ID.pos.x = to_position.x ) OR ( ID.pos.y = to_position.y );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - constructor Trook.Init( ident: Tid; chessBoard: Tboard );
begin
inherited Init( ident, chessBoard );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
destructor Trook.delete;
begin
inherited delete;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end. // конец файла rook.pas
В заключение приведем листинги остальной части программы, назначение всех процедур и функций должно быть
вполне понятным из комментариев.
// файл board.pas
unit board;
interface
uses Forms, Graphics,Types;
Type Tletter = ( _a, _b, _c, _d, _e, _f, _g, _h );
Type Tposition = record
x : Tletter; // координаты шахматных
y : 1..8; // фигур на доске;
end;
Type Tfigcolor = ( black, white ); // цвет фигур;
43

Математическое и компьютерное моделирование
4
Type Tid = record // идентификатор фигуры;
pos : Tposition; // положение;
color : Tfigcolor; // цвет фигуры;
number: 0..16; // № фигуры: 0 - отсутствует,
// 1 - король, 2 - ферзь,...
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // поддержка графики и интерфейс для шахмат
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Type Tboard = class
protected
Forma : TForm; // форма, куда все рисуется;
whiteCell : Tcolor; // цвета клетки
blackCell : Tcolor; // шахматной доски;
hCell : word; // длина стороны клетки;
fig_board : array[1..8, 1..8] of Tid;
function get_color_cell( i, j: word ): boolean;
procedure draw;
function search_rect( pos: Tposition ): TRect;
procedure show_figures;
// рисование фигур:
procedure draw_queen( pos : TPosition; color : Tfigcolor );
procedure draw_rook( pos : TPosition; color : Tfigcolor );
//////// здесь могут быть другие фигуры.../////////////////////////////
public
function search_pos( X, Y: word ): Tposition;
procedure entry_fig_board( ID: Tid );
procedure refresh;
constructor init( white_cell, black_cell: Tcolor;
h_cell : word; form : TForm );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // определяет цвет клетки доски по ее координатам,
// возвращает TRUE, если клетка белая
4

II. Программная реализация математической модели
5
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Tboard.get_color_cell( i, j: word ): boolean;
begin
if odd(i) then result := odd( j )
else result := not odd( j );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // рисует доску без фигур
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Tboard.draw;
var i, j: word; sq: TRect;
begin
for i := 1 to 8 do
begin
for j := 1 to 8 do
begin
if ( get_color_cell( i, j ) )
then Forma.Canvas.brush.color := whiteCell
else Forma.Canvas.brush.color := blackCell;
Sq := Rect( hCell*i, hCell*j, hCell*(i + 1), hCell*(j + 1) );
Forma.Canvas.Fillrect( Sq );
end;
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // занесение фигуры с идентификатором ID в массив fig_board
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Tboard.entry_fig_board( ID: Tid );
begin
fig_board[ ord( ID.pos.x ) + 1, ID.pos.y ] := ID;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // расстановка фигур на доске
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Tboard.show_figures; var i, j : word; figID : Tid;
begin
4

Математическое и компьютерное моделирование
6
for i := 1 to 8 do
begin
for j := 1 to 8 do
begin
figID := fig_board[ i, j ];
case ( figID.number ) of
2 : draw_queen( figID.pos, figID.color );
3 : draw_rook( figID.pos, figID.color );
// и другие фигуры...
end;
end;
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // обновление доски со всеми фигурами
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Tboard.refresh;
begin
draw;
show_figures;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // поиск положения клетки доски по ее экранным координатам
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function Tboard.search_pos( X, Y: word ): Tposition;
var j : word; _x: Tletter;
pos, pos0 : Tposition; R : TRect;
begin
pos0.x := _a;
pos0.y := 8;
for _x := _a to _h do
begin
for j := 1 to 8 do
begin
pos.x := _x;
pos.y := j;
4

II. Программная реализация математической модели
7
R := search_rect( pos );
if ( ( X <= R.Right ) AND ( X >= R.Left ) AND
( Y >= R.Top ) AND ( Y <= R.Bottom ) )
then pos0 := pos;
end;
end;
result := pos0;
end;
//====================================================
// рисование шахматных фигур:
//====================================================
// возвращает координаты экранного прямоугольника углов
// клетки, соответствующей позиции pos
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function Tboard.search_rect( pos: TPosition ): TRect;
begin
Result := Rect( (ord( pos.x ) + 1 )*hCell, pos.y *hCell,
(ord( pos.x ) + 2 )*hCell, ( pos.y +1 )*hCell );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // рисует ферзя в позиции pos
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Tboard.draw_queen( pos: TPosition; color: Tfigcolor );
var R: TRect; h, h_2: word;
begin
with Forma.canvas do
begin
brush.Style := bsClear;
if ( color = black )
then pen.Color := clBlack
else pen.Color := clWhite;
pen.Width := 3;
R := search_rect( pos );
h := hCell;
h_2 := hCell div 2;
rectangle( R.Left + 4, R.Top + 3*h div 4, R.Right - 4, R.Bottom - 3 );
4

Математическое и компьютерное моделирование
rectangle( R.Left + 6, R.Top + h div 2,
R.Right - 6, R.Bottom - h div 3 + 1 );
polyline( [ point( R.Left + 6, R.Top + h div 2 – 2 ),
point( R.Left + 2 , R.Top + 4 ),
point( R.Left + h div 3, R.Top + h div 2 – 2 ),
point( R.Left + h_2 , R.Top + 4 ),
point( R.Left + 2*h div 3, R.Top + h div 2 – 2 ),
point( R.Right - 2 , R.Top + 4 ),
point( R.Right - 6, R.Top + h div 2 – 3 ) ] );
end; // with
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // рисует ладью в позиции pos
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Tboard.draw_rook( pos: TPosition; color: Tfigcolor );
var R: TRect; h: word;
begin
with Forma.canvas do
begin
brush.Style := bsClear;
if ( color = black )
then pen.Color := clBlack
else pen.Color := clWhite;
pen.Width := 3;
R := search_rect( pos );
h := hCell;
rectangle( R.Left + 4, R.Top + 3*h div 4, R.Right - 4, R.Bottom - 3 );
rectangle( R.Left + 6, R.Top + h div 2, R.Right - 6,
R.Bottom - h div 3 + 1 );
polyline( [ point( R.Left + 6, R.Top + h div 2 – 2 ),
point( R.Left + 2, R.Top + 4 ),
point( R.Right - 2, R.Top + 4 ),
point( R.Right - 6, R.Top + h div 2 – 3 ) ] );
end; // with
end;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// здесь можно добавить код для рисования других фигур
48

II. Программная реализация математической модели
// инициализация "доски"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - constructor Tboard.init( white_cell, black_cell: Tcolor;
h_cell: word; form: TForm );
var i, j: word;
begin
for i := 1 to 8 do
for j := 1 to 8 do fig_board[ i, j ].number := 0;
whiteCell := white_cell;
blackCell := black_cell;
hCell := h_cell;
Forma := form;
end;
end. // конец файла board.pas
// файл chessMain.pas
unit chessMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, figure, queen, rook, board, StdCtrls,
ComCtrls, Menus, ExtCtrls;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type TForm1 = class( TForm )
StatusBar1 : TStatusBar;
MainMenu1 : TMainMenu;
menuFile : TMenuItem;
MenuExit : TMenuItem;
menuAbout0 : TMenuItem;
menuAbout : TMenuItem;
RadioGroup1 : TRadioGroup;
procedure FormActivate( Sender: TObject );
procedure FormMouseMove( Sender : TObject;
Shift : TShiftState;
X, Y : Integer );
49

Математическое и компьютерное моделирование
0
procedure FormMouseDown( Sender : TObject;
Button : TMouseButton;
Shift : TShiftState;
X, Y : Integer );
procedure MenuExitClick( Sender: TObject );
procedure menuAboutClick( Sender: TObject );
procedure RadioGroup1Click( Sender: TObject );
private
{ Private declarations }
public
{ Public declarations }
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var Form1 : TForm1;
h : word; // ширина клетки доски;
chess_board : Tboard; // объект Шахматная доска;
queen : Tqueen; // объект Ферзь;
rook : Trook; // объект Ладья;
ID : Tid; // идентификатор фигуры;
const whiteCell = clSilver; // цвета клеток
blackCell = clGray; // шахматной доски;
implementation
{$R *.dfm}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // инициализация ферзя ( ID.number ферзя равен 2 )
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure init_queen;
begin
if ( ID.number = 2 ) then exit;
if ( ID.number = 3 ) then rook.delete;
ID.number := 2;
queen := Tqueen.Init( ID, chess_board );
queen.move( ID.pos );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // инициализация ладьи ( ID.number ладьи равен 3 )
5
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
