diff options
Diffstat (limited to 'plugins/Chess4Net/ChessBoardUnit.pas')
-rw-r--r-- | plugins/Chess4Net/ChessBoardUnit.pas | 1788 |
1 files changed, 889 insertions, 899 deletions
diff --git a/plugins/Chess4Net/ChessBoardUnit.pas b/plugins/Chess4Net/ChessBoardUnit.pas index 6b655058ad..8a7042f292 100644 --- a/plugins/Chess4Net/ChessBoardUnit.pas +++ b/plugins/Chess4Net/ChessBoardUnit.pas @@ -1,410 +1,396 @@ +////////////////////////////////////////////////////////////////////////////////
+// All code below is exclusively owned by author of Chess4Net - Pavel Perminov
+// (packpaul@mail.ru, packpaul1@gmail.com).
+// Any changes, modifications, borrowing and adaptation are a subject for
+// explicit permition from the owner.
+
unit ChessBoardUnit;
interface
uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, TntForms,
- Dialogs, StdCtrls, TntStdCtrls, ExtCtrls, Buttons,
- // Chess4net
- ChessBoardHeaderUnit, ChessRulesEngine, BitmapResUnit, LocalizerUnit;
+ Forms, ExtCtrls, Classes, Controls, Graphics, Types, Messages,
+ //
+ ChessRulesEngine, BitmapResUnit, PromotionUnit;
type
- TMode = (mView, mGame); // состояние доски
- TChessBoardEvent =
- (cbeMoved, cbeMate, cbeStaleMate, cbeInsuffMaterial, cbeKeyPressed,
- cbeClockSwitched, cbeTimeOut, cbeExit, cbeMenu, cbeActivate, cbeFormMoving,
- cbeRefreshAll); // возможно добавление новых событий
- // cbeRefreshAll сигнализирует, что были изменены глобальные опции.
+ TMode = (mView, mGame, mAnalyse, mEdit); // Board mode
+
+ TAnimation = (aNo, aSlow, aQuick);
+
+ TChessBoardEvent = (cbeMate, cbeStaleMate, cbeMoved, cbePosSet, cbeMenu);
TChessBoardHandler = procedure(e: TChessBoardEvent;
d1: pointer = nil; d2: pointer = nil) of object;
- TAnimation = (aNo, aSlow, aQuick);
-{$IFDEF THREADED_CHESSCLOCK}
- TChessBoard = class;
- TTimeLabelThread = class(TThread)
- private
- ChessBoard: TChessBoard;
- player_time: array[TFigureColor] of TDateTime;
- protected
- procedure Execute; override;
- public
- WhiteTime, BlackTime: string;
- constructor Create(ChessBoard: TChessBoard);
- end;
-{$ENDIF}
+ TChessBoardLayerBase = class;
- TChessBoard = class(TTntForm, ILocalizable, IChessRulesEngineable)
+ TChessBoard = class(TForm, IChessRulesEngineable)
PBoxBoard: TPaintBox;
- TimePanel: TPanel;
- WhiteLabel: TTntLabel;
- WhiteTimeLabel: TLabel;
- BlackLabel: TTntLabel;
- BlackTimeLabel: TLabel;
- GameTimer: TTimer;
AnimateTimer: TTimer;
- WhiteFlagButton: TSpeedButton;
- BlackFlagButton: TSpeedButton;
- WhitePanel: TPanel;
- BlackPanel: TPanel;
+
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
+ procedure FormCanResize(Sender: TObject; var NewWidth,
+ NewHeight: Integer; var Resize: Boolean);
+ procedure FormResize(Sender: TObject);
+ procedure AnimateTimerTimer(Sender: TObject);
procedure PBoxBoardPaint(Sender: TObject);
procedure PBoxBoardDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure PBoxBoardDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure PBoxBoardEndDrag(Sender, Target: TObject; X, Y: Integer);
- procedure PBoxBoardMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure PBoxBoardMouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
+ procedure PBoxBoardMouseDown(Sender: TObject;
+ Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+ procedure PBoxBoardMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure PBoxBoardMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
- procedure PBoxBoardStartDrag(Sender: TObject;
- var DragObject: TDragObject);
- procedure AnimateTimerTimer(Sender: TObject);
- procedure GameTimerTimer(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure FormActivate(Sender: TObject);
- procedure FlagButtonClick(Sender: TObject);
- procedure FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer;
- var Resize: Boolean);
- procedure FormResize(Sender: TObject);
- procedure TimePanelResize(Sender: TObject);
+ procedure PBoxBoardStartDrag(Sender: TObject; var DragObject: TDragObject);
private
m_ChessRulesEngine: TChessRulesEngine;
+ m_BitmapRes: TBitmapRes; // Manager for bitmaps
- m_i0, m_j0: integer;
- m_fig: TFigure;
+ FHandler: TChessBoardHandler;
- mode_var: TMode;
dx, dy: integer; // Расстояние от курсора до верхнего левого угла
x0, y0: integer; // Предыдущие координаты курсора
_flipped: boolean; // Доска перевёрнута или нет
- hilighted: boolean; // Подсветка делаемого хода
+ m_bHilighted: boolean; // Hilight the move that is being done
+ m_i0, m_j0: integer;
+ m_fig: TFigure;
+
+ m_Mode: TMode;
+ m_bViewGaming: boolean;
+
+ m_bmHiddenBoard: TBitmap;
m_bmChessBoard: TBitmap;
m_bmFigure: array[TFigure] of TBitmap;
m_bmBuf: TBitmap;
- Handler: TChessBoardHandler;
-
- m_animation: TAnimation; // скорость анимации
-
- anim_dx, anim_dy: real; // переменные для анимации перемещения фигуры
- anim_step, anim_step_num: integer; // количество шагов в анимации
- player_color: TFigureColor; // цвет игрока клиента
- dragged_moved: boolean; // индикатор включения перетаскивания
- last_hilight: boolean; // флаг подсветки последнего хода
- m_bFlash_move: boolean; // flag for flashing on icoming move
- coord_show: boolean; // флаг координат
+ m_iSquareSize: integer; // Size of one chess board field
- auto_flag: boolean; // индикатор автофлага
- player_time: array[TFigureColor] of TDateTime; // время белых и чёрных
- past_time: TDateTime; // время начала обдумывания хода
- unlimited_var: array[TFigureColor] of boolean; // партия без временного контроля
- clock_color: TFigureColor; // цвет анимируемой фигуры
+ m_animation: TAnimation; // Animation speed
+ m_iAnimStep, m_iPrevAnimStep, m_iAnimStepsCount: integer;
+ anim_dx, anim_dy: real; // Variables for animation of a dragged piece
- shuted: boolean; // индикатор внешнего закрытия окна
+ m_PlayerColor: TFigureColor; // Color of player client
+ m_bDraggedMoved: boolean; // Flag for switching of dragging
+ last_hilight: boolean; // Flag for hilighting of the last move done
+ coord_show: boolean; // Flag for showing coordinates
// Resizing
m_ResizingType: (rtNo, rtHoriz, rtVert);
m_iDeltaWidthHeight: integer;
- m_BitmapRes: TBitmapRes; // Manager for bitmaps
- m_iTimePanelInitialWidth: integer;
- m_iWhitePanelInitialLeft, m_iBlackPanelInitialLeft: integer;
- m_iWhitePanelInitialWidth, m_iBlackPanelInitialWidth: integer;
- m_TimeFont: TFont;
+ m_bDeltaWidthHeightFlag: boolean;
- m_bViewGaming: boolean;
+ m_PromotionForm: TPromotionForm;
+
+ m_EditPiece: TFigure;
-{$IFDEF THREADED_CHESSCLOCK}
- TimeLabelThread: TTimeLabelThread; // нить используется для борьбы с лагом в Миранде
-{$ENDIF}
+ m_iUpdateCounter: integer;
+
+ m_lstLayers: TList;
procedure HilightLastMove;
- procedure WhatSquare(const P: TPoint; var i: Integer; var j: Integer);
- procedure Animate(const i, j: integer); // Анимирует перемещение фигуры с (i0,j0) до (i,j)
- procedure SetMode(const m: TMode);
- procedure ShowTime(const c: TFigureColor);
- procedure SetPlayerColor(const color: TFigureColor);
- procedure SetTime(color: TFigureColor; const tm: TDateTime);
- function GetTime(color: TFigureColor): TDateTime;
- procedure SetUnlimited(color: TFigureColor; const unl: boolean);
- function GetUnlimited(color: TFigureColor): boolean;
procedure Evaluate;
- procedure SetHilightLastMove(const yes: boolean);
- procedure SetCoordinates(const yes: boolean);
- procedure SetFlipped(const f: boolean); // Переварачивает позицию при отображении
- function GetStayOnTop: boolean;
- procedure SetStayOnTop(onTop: boolean);
- procedure FCancelAnimationDragging; // отмена анимации и перетаскивания для удаления грязи при прорисовки
- procedure SetAutoFlag(auto_flag: boolean);
- procedure FFlashWindow;
- // Localization
- procedure ILocalizable.Localize = FLocalize;
- procedure FLocalize;
-
- procedure WMMoving(var Msg: TWMMoving); message WM_MOVING;
- procedure WMSizing(var Msg: TMessage); message WM_SIZING;
- function FGetPositinoColor: TFigureColor;
+ function FGetLastMove: PMoveAbs;
+ property lastMove: PMoveAbs read FGetLastMove;
+
function FGetPosition: PChessPosition;
+ property Position: PChessPosition read FGetPosition;
+
function AskPromotionFigure(FigureColor: TFigureColor): TFigureName;
- function FGetLastMove: PMoveAbs;
+ procedure FSetMode(const Value: TMode);
+
+ function FDoMove(i, j: integer; prom_fig: TFigureName = K): boolean;
+ procedure FOnAfterMoveDone;
+ procedure FOnAfterSetPosition;
+
+ procedure FAnimate(const i, j: integer); // Animates a disposition of a piece from (i0,j0) to (i,j)
+ procedure FDoAnimationStep;
+ procedure FEndAnimation;
+ procedure FWhatSquare(const P: TPoint; var i: Integer; var j: Integer);
+
+ procedure FSetPlayerColor(const Value: TFigureColor);
+ procedure FCancelAnimationDragging; // Caneling of animation and dragging for trace removal after draw
+ procedure FSetFlipped(Value: boolean); // Flips chess position
+ procedure FSetCoordinatesShown(Value: boolean);
+ procedure FSetLastMoveHilighted(Value: boolean);
function FGetPositionsList: TList;
+ function FGetPositionColor: TFigureColor;
+ function FGetMoveNotationFormat: TMoveNotationFormat;
+ procedure FSetMoveNotationFormat(Value: TMoveNotationFormat);
+ function FGetFENFormat: boolean;
+ procedure FSetFENFormat(bValue: boolean);
- procedure FOnAfterMoveDone;
+ procedure FDrawHiddenBoard;
+ function FGetHiddenBoardCanvas: TCanvas;
- property ChessRulesEngine: TChessRulesEngine read m_ChessRulesEngine;
- property Position: PChessPosition read FGetPosition;
+ procedure FDrawBoard;
+ procedure FOnDrawLayerUpdate(const ADrawLayer: TChessBoardLayerBase);
- property lastMove: PMoveAbs read FGetLastMove;
+ function FGetMovesOffset: integer;
+ function FGetColorStarts: TFigureColor;
- protected
- iSquareSize: integer; // Size of a chess board field
- bmHiddenBoard: TBitmap;
- procedure RDrawBoard;
+ procedure WMSizing(var Msg: TMessage); message WM_SIZING;
- procedure RDrawHiddenBoard; virtual;
- procedure ROnAfterSetPosition; virtual;
- function RDoMove(i, j: integer; prom_fig: TFigureName = K): boolean;
- procedure ROnAfterMoveDone; virtual;
+ procedure FDoHandler(e: TChessBoardEvent; d1: pointer = nil; d2: pointer = nil);
- property PositionsList: TList read FGetPositionsList;
+ property SquareSize: integer read m_iSquareSize;
+ property PositionsList: TList read FGetPositionsList;
public
- constructor Create(Owner: TComponent; h: TChessBoardHandler = nil); reintroduce;
+ constructor Create(Owner: TComponent; AHandler: TChessBoardHandler = nil); reintroduce;
- procedure TakeBack; // взятие хода обратно
- procedure SwitchClock(clock_color: TFigureColor);
+ function DoMove(const strMove: string): boolean;
+ procedure ResetMoveList;
+ function SetPosition(const strPosition: string): boolean;
+ function GetPosition: string;
procedure InitPosition;
procedure PPRandom;
- procedure StopClock;
+ procedure TakeBack;
+ function NMoveDone: integer;
+ function NPlysDone: integer;
- procedure ResetMoveList;
- function SetPosition(const posstr: string): boolean;
- function GetPosition: string;
- function NMoveDone: integer; // количество сделанных ходов
- function DoMove(move_str: string): boolean;
- procedure Shut;
-
- property Unlimited[color: TFigureColor]: boolean read GetUnlimited write SetUnlimited;
- property Time[color: TFigureColor]: TDateTime read GetTime write SetTime;
- property PlayerColor: TFigureColor read player_color write SetPlayerColor;
- property PositionColor: TFigureColor read FGetPositinoColor; // чей ход в текущей позиции
- property ClockColor: TFigureColor read clock_color;
- property Mode: TMode read mode_var write SetMode;
- property CoordinatesShown: boolean read coord_show write SetCoordinates;
-
- property flipped: boolean read _flipped write SetFlipped;
- property LastMoveHilighted: boolean read last_hilight write SetHilightLastMove;
- property FlashOnMove: boolean read m_bFlash_move write m_bFlash_move;
- property StayOnTop: boolean read GetStayOnTop write SetStayOnTop;
- property AutoFlag: boolean read auto_flag write SetAutoFlag;
- property animation: TAnimation read m_animation write m_animation;
+ function IsMoveAnimating: boolean;
+
+ procedure BeginUpdate;
+ procedure EndUpdate;
+
+ procedure AddLayer(const ALayer: TChessBoardLayerBase);
+ procedure RemoveLayer(const ALayer: TChessBoardLayerBase);
+
+ property PlayerColor: TFigureColor read m_PlayerColor write FSetPlayerColor;
+ property Mode: TMode read m_Mode write FSetMode;
+ property CoordinatesShown: boolean read coord_show write FSetCoordinatesShown;
+ property Flipped: boolean read _flipped write FSetFlipped;
+ property LastMoveHilighted: boolean read last_hilight write FSetLastMoveHilighted;
+ property Animation: TAnimation read m_animation write m_animation;
property ViewGaming: boolean read m_bViewGaming write m_bViewGaming;
+ property PositionColor: TFigureColor read FGetPositionColor; // Whos move it is in the current position
+ property MoveNotationFormat: TMoveNotationFormat
+ read FGetMoveNotationFormat write FSetMoveNotationFormat;
+ property MovesOffset: integer read FGetMovesOffset;
+ property FENFormat: boolean read FGetFENFormat write FSetFENFormat;
+ property EditPiece: TFigure read m_EditPiece write m_EditPiece;
end;
-implementation
-{$J+}
+ TChessBoardLayerBase = class
+ private
+ m_ChessBoard: TChessBoard;
+ function FGetSquareSize: integer;
+ function FGetCanvas: TCanvas;
+ function FGetPosition: PChessPosition;
+ function FGetPositionsList: TList;
+ protected
+ procedure RDraw; virtual; abstract;
+ function RGetColorStarts: TFigureColor;
+
+ procedure RDoUpdate;
+
+ procedure ROnAfterMoveDone; virtual;
+ procedure ROnAfterSetPosition; virtual;
+ procedure ROnAfterModeSet(const OldValue, NewValue: TMode); virtual;
+ procedure ROnResetMoveList; virtual;
+
+ property ChessBoard: TChessBoard read m_ChessBoard write m_ChessBoard;
+ property SquareSize: integer read FGetSquareSize;
+ property Canvas: TCanvas read FGetCanvas;
+ property Position: PChessPosition read FGetPosition;
+ property PositionsList: TList read FGetPositionsList;
+ end;
+
+implementation
{$R *.dfm}
uses
- StrUtils, Math, DateUtils,
- // Chess4Net
- PromotionUnit;
+ Math, SysUtils, Windows,
+ //
+ ChessBoardHeaderUnit;
const
HILIGHT_WIDTH = 1;
HILIGHT_COLOR: TColor = clRed;
HILIGHT_LAST_MOVE_WIDTH = 1;
HILIGHT_LAST_MOVE_COLOR: TColor = clBlue;
- ANIMATION_SLOW = 30; // Время анимации хода в фреймах >= 1
+ ANIMATION_SLOW = 30; // Time of animation in frames >= 1
ANIMATION_QUICK = 9;
CHB_WIDTH = 4;
- TIME_COLOR = clBlack;
-// FULL_TIME_FORMAT = 'h:n:s"."z';
- HOUR_TIME_FORMAT = 'h:nn:ss';
- MIN_TIME_FORMAT = 'n:ss';
- ZEITNOT_BOARDER = 10; // сек - цетйтнотная граница
- ZEITNOT_COLOR = clMaroon;
- ZEITNOT_FORMAT = 's"."zzz';
-// CHEAT_TIME_CONST = 1.5; // > 1
- WHITE_LONG_LABEL: WideString = 'White ';
- WHITE_MEDIUM_LABEL: WideString = 'White ';
- WHITE_SHORT_LABEL: WideString = 'W ';
- BLACK_LONG_LABEL: WideString = 'Black ';
- BLACK_MEDIUM_LABEL: WideString = 'Black ';
- BLACK_SHORT_LABEL: WideString = 'B ';
////////////////////////////////////////////////////////////////////////////////
-// Globals
+// TChessBoard
-function TChessBoard.DoMove(move_str: string): boolean;
+constructor TChessBoard.Create(Owner: TComponent; AHandler: TChessBoardHandler = nil);
begin
- // Отмена анимации
- if (AnimateTimer.Enabled) then
- begin
- AnimateTimer.Enabled := FALSE;
- anim_step := anim_step_num;
- AnimateTimerTimer(nil);
- end;
+ FHandler := AHandler;
+ inherited Create(Owner);
+end;
- Result := ChessRulesEngine.DoMove(move_str);
- if (Result) then
- begin
- FOnAfterMoveDone;
- Animate(lastMove.i, lastMove.j);
- SwitchClock(PositionColor);
- if (m_bFlash_move and (mode_var = mGame)) then
- FFlashWindow;
- end;
+procedure TChessBoard.AnimateTimerTimer(Sender: TObject);
+begin
+ FDoAnimationStep;
+ if (m_iAnimStep >= m_iAnimStepsCount) then
+ FEndAnimation;
end;
-procedure TChessBoard.ShowTime(const c: TFigureColor);
+procedure TChessBoard.FDoAnimationStep;
var
- time_label: TLabel;
+ iX, iY: integer;
+ rect: TRect;
begin
- if c = fcWhite then time_label:= WhiteTimeLabel
- else time_label:= BlackTimeLabel;
-
- if unlimited_var[c] then
- begin
- time_label.Caption:= '';
- exit;
- end;
+ if (m_iAnimStep < m_iAnimStepsCount) then
+ begin
+ inc(m_iAnimStep);
- time_label.Font.Color:= TIME_COLOR;
+ iX := round(x0 + anim_dx * m_iAnimStep);
+ iY := round(y0 + anim_dy * m_iAnimStep);
+ dx := iX - x0 - Round(anim_dx * m_iPrevAnimStep);
+ dy := iY - y0 - Round(anim_dy * m_iPrevAnimStep);
- LongTimeFormat:= MIN_TIME_FORMAT;
- if player_time[c] >= EncodeTime(1, 0, 0, 0) then
- LongTimeFormat:= HOUR_TIME_FORMAT
- else
- if (player_time[c] < EncodeTime(0, 0, ZEITNOT_BOARDER, 0)) and
- (player_time[c] > 0) then
- begin
- LongTimeFormat:= ZEITNOT_FORMAT;
- time_label.Font.Color:= ZEITNOT_COLOR;
- end;
+ // Восстановить фрагмент на m_bmHiddenBoard
+ m_bmHiddenBoard.Canvas.Draw(iX - dx, iY - dy, m_bmBuf);
+ // Копировать новый фрагмент в буфер
+ m_bmBuf.Canvas.CopyRect(Bounds(0, 0, m_iSquareSize, m_iSquareSize),
+ m_bmHiddenBoard.Canvas, Bounds(iX, iY, m_iSquareSize, m_iSquareSize));
+ // Нарисовать перетаскиваемую фигуру в новой позиции
+ m_bmHiddenBoard.Canvas.Draw(iX, iY, m_bmFigure[m_fig]);
+ // Перенести новый фрагмент на экран
+ rect := Bounds(Min(iX - dx, iX), Min(iY - dy, iY),
+ abs(dx) + m_iSquareSize, abs(dy) + m_iSquareSize);
+ PBoxBoard.Canvas.CopyRect(rect, m_bmHiddenBoard.Canvas, rect);
+ end;
- time_label.Caption:= TimeToStr(player_time[c]);
+ m_iPrevAnimStep := m_iAnimStep;
+
end;
-
-procedure TChessBoard.SetFlipped(const f: boolean);
+procedure TChessBoard.FEndAnimation;
begin
- // TODO: ???
- _flipped:= f;
- RDrawBoard;
-end;
+ AnimateTimer.Enabled := FALSE;
+ m_iAnimStep := m_iAnimStepsCount;
-procedure TChessBoard.ResetMoveList;
-begin
- ChessRulesEngine.ResetMoveList;
+ FDrawBoard;
+ HilightLastMove;
+ Evaluate;
end;
-function TChessBoard.SetPosition(const posstr: string): boolean;
+procedure TChessBoard.FDrawBoard;
+var
+ i: integer;
begin
- Result := ChessRulesEngine.SetPosition(posstr);
- if (not Result) then
+ if (csDestroying in ComponentState) then
exit;
- FCancelAnimationDragging;
- ROnAfterSetPosition;
- clock_color := Position.color;
- RDrawBoard;
-end;
+ if (m_iUpdateCounter > 0) then
+ exit;
+ FDrawHiddenBoard;
-function TChessBoard.GetPosition: string;
-begin
- Result := ChessRulesEngine.GetPosition;
+ for i := 0 to m_lstLayers.Count - 1 do
+ TChessBoardLayerBase(m_lstLayers[i]).RDraw;
+
+ PBoxBoardPaint(nil);
end;
-procedure TChessBoard.FormCreate(Sender: TObject);
+procedure TChessBoard.HilightLastMove;
+var
+ i, j, l,
+ _i0, _j0, x, y: integer;
begin
- m_iDeltaWidthHeight := Width - Height;
-
- m_iTimePanelInitialWidth := TimePanel.Width;
- m_iWhitePanelInitialLeft := WhitePanel.Left;
- m_iWhitePanelInitialWidth := WhitePanel.Width;
- m_iBlackPanelInitialLeft := BlackPanel.Left;
- m_iBlackPanelInitialWidth := BlackPanel.Width;
-
- m_TimeFont := TFont.Create;
- m_TimeFont.Assign(WhiteTimeLabel.Font);
-
- m_BitmapRes := TBitmapRes.Create(Size(PBoxBoard.Width, PBoxBoard.Height));
-
- BlackFlagButton.Glyph := WhiteFlagButton.Glyph; // чтоб не тащить лишнего
- coord_show:= TRUE;
- last_hilight:= FALSE;
- m_animation := aQuick;
-
- TLocalizer.Instance.AddSubscriber(self);
- FLocalize;
+ if (not (m_Mode in [mGame, mAnalyse])) then
+ exit;
+
+ // Output the last move done
+ if (last_hilight and (lastMove.i0 <> 0)) then
+ begin
+ if (_flipped) then
+ begin
+ _i0 := 9 - lastMove.i0;
+ _j0 := lastMove.j0;
+ i := 9 - lastMove.i;
+ j := lastMove.j;
+ end
+ else
+ begin
+ _i0 := lastMove.i0;
+ _j0 := 9 - lastMove.j0;
+ i := lastMove.i;
+ j := 9 - lastMove.j;
+ end;
- m_ChessRulesEngine := TChessRulesEngine.Create(self);
+ x := m_iSquareSize * (_i0 - 1) + CHB_X;
+ y := m_iSquareSize * (_j0 - 1) + CHB_Y;
+ m_bmHiddenBoard.Canvas.Pen.Color := HILIGHT_LAST_MOVE_COLOR;
+ m_bmHiddenBoard.Canvas.Pen.Width := HILIGHT_LAST_MOVE_WIDTH;
- // Clock initialization
- SetUnlimited(fcWhite, TRUE); SetUnlimited(fcBlack, TRUE);
+ for l := 1 to 2 do
+ with m_bmHiddenBoard.Canvas do
+ begin
+ MoveTo(x, y);
+ LineTo(x + m_iSquareSize - 1, y);
+ LineTo(x + m_iSquareSize - 1, y + m_iSquareSize - 1);
+ LineTo(x, y + m_iSquareSize - 1);
+ LineTo(x, y);
- InitPosition;
+ x := m_iSquareSize * (i - 1) + CHB_X;
+ y := m_iSquareSize * (j - 1) + CHB_Y;
+ end;
+ PBoxBoardPaint(nil);
+ end;
end;
-procedure TChessBoard.RDrawHiddenBoard;
+procedure TChessBoard.FDrawHiddenBoard;
var
i, j: integer;
x, y: integer;
begin
- if (not Assigned(bmHiddenBoard)) then
+ if (not Assigned(m_bmHiddenBoard)) then
exit;
// Copy empty board to the hidden one
- with bmHiddenBoard do
+ with m_bmHiddenBoard do
begin
Canvas.CopyRect(Bounds(0,0, Width,Height), m_bmChessBoard.Canvas, Bounds(0,0, Width,Height));
end;
// Draw coordinates
if (coord_show) then
- with bmHiddenBoard, bmHiddenBoard.Canvas do
+ with m_bmHiddenBoard, m_bmHiddenBoard.Canvas do
begin
- x:= CHB_X + iSquareSize div 2;
- y:= (bmHiddenBoard.Height + CHB_Y + 8 * iSquareSize + CHB_WIDTH) div 2;
+ x:= CHB_X + m_iSquareSize div 2;
+ y:= (m_bmHiddenBoard.Height + CHB_Y + 8 * m_iSquareSize + CHB_WIDTH) div 2;
if _flipped then j := ord('h')
else j:= ord('a');
for i:= 1 to 8 do // буквы
begin
TextOut(x - TextWidth(chr(j)) div 2,
y + 1 - TextHeight(chr(j)) div 2 , chr(j));
- x := x + iSquareSize;
+ x := x + m_iSquareSize;
if _flipped then dec(j)
else inc(j);
end;
x:= (CHB_X - CHB_WIDTH) div 2;
- y:= CHB_Y + iSquareSize div 2;
+ y:= CHB_Y + m_iSquareSize div 2;
if _flipped then j:= ord('1')
else j := ord('8');
for i := 1 to 8 do // цифры
begin
TextOut(x - TextWidth(chr(j)) div 2,
y - TextHeight(chr(j)) div 2, chr(j));
- y:= y + iSquareSize;
+ y:= y + m_iSquareSize;
if _flipped then inc(j)
else dec(j);
end;
@@ -417,45 +403,346 @@ begin if ((Position.board[i,j] = ES)) then
continue; // There's nothing to draw
if not _flipped then // Загрузить нужную фигуру из ресурса и нарисовать
- bmHiddenBoard.Canvas.Draw(CHB_X + iSquareSize * (i-1),
- CHB_Y + iSquareSize * (8-j),
+ m_bmHiddenBoard.Canvas.Draw(CHB_X + m_iSquareSize * (i-1),
+ CHB_Y + m_iSquareSize * (8-j),
m_bmFigure[Position.board[i,j]])
else // Black is below
- bmHiddenBoard.Canvas.Draw(CHB_X + iSquareSize * (8-i),
- CHB_Y + iSquareSize * (j-1),
+ m_bmHiddenBoard.Canvas.Draw(CHB_X + m_iSquareSize * (8-i),
+ CHB_Y + m_iSquareSize * (j-1),
m_bmFigure[Position.board[i,j]]);
end;
end;
-procedure TChessBoard.RDrawBoard;
+function TChessBoard.FGetHiddenBoardCanvas: TCanvas;
begin
- RDrawHiddenBoard;
- PBoxBoardPaint(nil);
+ if (Assigned(m_bmHiddenBoard)) then
+ Result := m_bmHiddenBoard.Canvas
+ else
+ Result := nil;
+end;
+
+
+procedure TChessBoard.Evaluate;
+begin
+ case m_ChessRulesEngine.GetEvaluation of
+ evMate:
+ FDoHandler(cbeMate, self);
+ evStaleMate:
+ FDoHandler(cbeStaleMate, self);
+ end;
end;
procedure TChessBoard.PBoxBoardPaint(Sender: TObject);
begin
- PBoxBoard.Canvas.Draw(0,0, bmHiddenBoard); // Вывод скрытой доски на форму
-// PBoxBoard.Canvas.StretchDraw(Bounds(0, 0, PBoxBoard.Width, PBoxBoard.Height), bmHiddenBoard);
+ PBoxBoard.Canvas.Draw(0, 0, m_bmHiddenBoard); // Draw hidden board on the form
+// PBoxBoard.Canvas.StretchDraw(Bounds(0, 0, PBoxBoard.Width, PBoxBoard.Height), m_bmHiddenBoard);
end;
-constructor TChessBoard.Create(Owner: TComponent; h: TChessBoardHandler);
+function TChessBoard.FGetLastMove: PMoveAbs;
begin
- inherited Create(Owner);
- Handler:= h;
+ Result := m_ChessRulesEngine.lastMove;
+end;
+
+
+function TChessBoard.FGetPosition: PChessPosition;
+begin
+ Result := m_ChessRulesEngine.Position;
+end;
+
+
+function TChessBoard.AskPromotionFigure(FigureColor: TFigureColor): TFigureName;
+var
+ frmOwner: TForm;
+begin
+ if (Owner is TForm) then
+ frmOwner := TForm(Owner)
+ else
+ frmOwner := self;
+
+ if (Showing) then
+ begin
+ m_PromotionForm := TPromotionForm.Create(frmOwner, m_BitmapRes);
+ try
+ Result := m_PromotionForm.ShowPromotion(FigureColor);
+ finally
+ FreeAndNil(m_PromotionForm);
+ end;
+ end
+ else
+ Result := Q;
+end;
+
+
+procedure TChessBoard.FSetPlayerColor(const Value: TFigureColor);
+begin
+ FCancelAnimationDragging;
+ m_PlayerColor := Value;
+ if (m_PlayerColor = fcWhite) then
+ FSetFlipped(FALSE)
+ else // fcBlack
+ FSetFlipped(TRUE);
+end;
+
+
+procedure TChessBoard.FCancelAnimationDragging;
+begin
+ // Cancel animation and dragging
+ if (AnimateTimer.Enabled) then
+ begin
+ AnimateTimer.Enabled := FALSE;
+ // iAnimStep := iAnimStepsCount;
+ // AnimateTimerTimer(nil);
+ end;
+
+ if (PBoxBoard.Dragging) then
+ begin
+ m_bDraggedMoved := FALSE;
+ PBoxBoard.EndDrag(FALSE);
+ end;
+end;
+
+
+procedure TChessBoard.FSetFlipped(Value: boolean);
+begin
+ // TODO: ???
+ _flipped := Value;
+ FDrawBoard;
+end;
+
+
+procedure TChessBoard.FSetMode(const Value: TMode);
+var
+ OldMode: TMode;
+ i: integer;
+begin
+ if (m_Mode = Value) then
+ exit;
+
+ OldMode := m_Mode;
+ m_Mode := Value;
+
+ if ((m_Mode in [mView, mEdit]) and (Assigned(m_PromotionForm))) then
+ m_PromotionForm.Close;
+
+ for i := 0 to m_lstLayers.Count - 1 do
+ TChessBoardLayerBase(m_lstLayers[i]).ROnAfterModeSet(OldMode, m_Mode);
+
+ FDrawBoard;
+ HilightLastMove;
+end;
+
+
+procedure TChessBoard.FSetCoordinatesShown(Value: boolean);
+begin
+ coord_show := Value;
+ FDrawBoard;
+ HilightLastMove;
+end;
+
+
+procedure TChessBoard.FSetLastMoveHilighted(Value: boolean);
+begin
+ last_hilight := Value;
+ FDrawBoard;
+ HilightLastMove;
+end;
+
+
+function TChessBoard.DoMove(const strMove: string): boolean;
+begin
+ Result := FALSE;
+
+ if (m_Mode = mEdit) then
+ exit;
+
+ // Animation canceling
+ if (AnimateTimer.Enabled) then
+ FEndAnimation;
+
+ Result := m_ChessRulesEngine.DoMove(strMove);
+
+ if (Result) then
+ begin
+ FOnAfterMoveDone;
+ FAnimate(lastMove.i, lastMove.j);
+ end;
+end;
+
+
+procedure TChessBoard.FOnAfterMoveDone;
+var
+ _fig: TFigure;
+ strLastMove: string;
+ i: integer;
+begin
+ m_i0 := lastMove.i0;
+ m_j0 := lastMove.j0;
+
+ _fig := Position.board[lastMove.i, lastMove.j];
+ if (lastMove.prom_fig in [Q, R, B, N]) then
+ begin
+ if (_fig < ES) then
+ m_fig := WP
+ else
+ m_fig := BP;
+ end
+ else
+ m_fig := _fig;
+
+ strLastMove := m_ChessRulesEngine.LastMoveStr;
+ FDoHandler(cbeMoved, @strLastMove, self);
+
+ if (m_Mode = mAnalyse) then
+ m_PlayerColor := PositionColor;
+
+ for i := 0 to m_lstLayers.Count - 1 do
+ TChessBoardLayerBase(m_lstLayers[i]).ROnAfterMoveDone;
+end;
+
+
+procedure TChessBoard.FAnimate(const i, j: integer);
+var
+ x, y: integer;
+begin
+ if (not Showing) then
+ exit;
+
+ if ((m_i0 = 0) or (m_j0 = 0)) then
+ exit;
+
+ if (AnimateTimer.Enabled) then
+ begin
+ m_iAnimStep := m_iAnimStepsCount;
+ exit;
+ end;
+
+ case animation of
+ aNo:
+ m_iAnimStepsCount := 1;
+ aSlow:
+ m_iAnimStepsCount := ANIMATION_SLOW;
+ aQuick:
+ m_iAnimStepsCount := ANIMATION_QUICK;
+ end;
+
+ if (_flipped) then
+ begin
+ x0 := (8 - m_i0) * m_iSquareSize + CHB_X;
+ y0 := (m_j0 - 1) * m_iSquareSize + CHB_Y;
+ x := (8 - i) * m_iSquareSize + CHB_X;
+ y := (j - 1) * m_iSquareSize + CHB_Y;
+ end
+ else
+ begin
+ x0 := (m_i0 - 1) * m_iSquareSize + CHB_X;
+ y0 := (8 - m_j0) * m_iSquareSize + CHB_Y;
+ x := (i - 1) * m_iSquareSize + CHB_X;
+ y := (8 - j) * m_iSquareSize + CHB_Y;
+ end;
+
+ anim_dx := (x - x0) / m_iAnimStepsCount;
+ anim_dy := (y - y0) / m_iAnimStepsCount;
+
+ m_iAnimStep := 0;
+ m_iPrevAnimStep := m_iAnimStep;
+
+ // Copy image of the empty square to m_bmBuf
+ m_bmBuf.Width := m_iSquareSize;
+ m_bmBuf.Height := m_iSquareSize;
+ if (((m_i0 + m_j0) and 1) <> 0) then
+ m_bmBuf.Canvas.CopyRect(Bounds(0, 0, m_iSquareSize, m_iSquareSize),
+ m_bmFigure[ES].Canvas, Bounds(0, 0, m_iSquareSize, m_iSquareSize))
+ else
+ m_bmBuf.Canvas.CopyRect(Bounds(0, 0, m_iSquareSize, m_iSquareSize),
+ m_bmFigure[ES].Canvas, Bounds(m_iSquareSize, 0, m_iSquareSize, m_iSquareSize));
+
+ AnimateTimer.Enabled := TRUE;
+end;
+
+
+procedure TChessBoard.ResetMoveList;
+var
+ i: integer;
+begin
+ m_ChessRulesEngine.ResetMoveList;
+
+ for i := 0 to m_lstLayers.Count - 1 do
+ TChessBoardLayerBase(m_lstLayers[i]).ROnResetMoveList;
+end;
+
+
+function TChessBoard.SetPosition(const strPosition: string): boolean;
+begin
+ Result := m_ChessRulesEngine.SetPosition(strPosition);
+ if (Result) then
+ begin
+ FCancelAnimationDragging;
+ FOnAfterSetPosition;
+ FDrawBoard;
+ end;
+end;
+
+
+function TChessBoard.GetPosition: string;
+begin
+ Result := m_ChessRulesEngine.GetPosition;
+end;
+
+
+procedure TChessBoard.FOnAfterSetPosition;
+var
+ strPosition: string;
+ i: integer;
+begin
+ case m_Mode of
+ mAnalyse:
+ m_PlayerColor := PositionColor;
+
+ mEdit:
+ ResetMoveList;
+ end;
+
+ m_i0 := 0;
+ m_j0 := 0;
+
+ strPosition := GetPosition;
+ FDoHandler(cbePosSet, @strPosition, self);
+
+ for i := 0 to m_lstLayers.Count - 1 do
+ TChessBoardLayerBase(m_lstLayers[i]).ROnAfterSetPosition;
+end;
+
+
+procedure TChessBoard.FormCreate(Sender: TObject);
+begin
+ // m_iDeltaWidthHeight := Width - Height;
+
+ m_BitmapRes := TBitmapRes.Create(Size(PBoxBoard.Width, PBoxBoard.Height));
+
+ coord_show:= TRUE;
+ last_hilight:= FALSE;
+ m_animation := aQuick;
+
+ m_ChessRulesEngine := TChessRulesEngine.Create(self);
+ m_lstLayers := TList.Create;
end;
procedure TChessBoard.FormDestroy(Sender: TObject);
var
_fig: TFigure;
+ i: integer;
begin
+ for i := m_lstLayers.Count - 1 downto 0 do
+ RemoveLayer(m_lstLayers[i]);
+ m_lstLayers.Free;
+
m_ChessRulesEngine.Free;
- bmHiddenBoard.Free;
+ m_bmHiddenBoard.Free;
m_bmBuf.Free;
for _fig := Low(TFigure) to High(TFigure) do
@@ -463,9 +750,6 @@ begin m_bmChessBoard.Free;
m_BitmapRes.Free;
- m_TimeFont.Free;
-
- TLocalizer.Instance.DeleteSubscriber(self);
end;
@@ -474,15 +758,41 @@ procedure TChessBoard.PBoxBoardDragDrop(Sender, Source: TObject; X, var
i, j: Integer;
begin
- WhatSquare(Point(X, Y), i, j);
- if (Mode = mGame) then
+ FWhatSquare(Point(X, Y), i, j);
+ case m_Mode of
+ mGame, mAnalyse:
+ begin
+ if (FDoMove(i, j)) then
+ m_bDraggedMoved := TRUE;
+ end;
+
+ mEdit:
+ m_bDraggedMoved := TRUE;
+ end;
+end;
+
+
+procedure TChessBoard.FWhatSquare(const P: TPoint;
+ var i: Integer; var j: Integer);
+begin
+ with P do
begin
- if (RDoMove(i, j)) then
+ i := (X - CHB_X + m_iSquareSize) div m_iSquareSize;
+ j := 8 - (Y - CHB_Y) div m_iSquareSize;
+ if (_flipped) then
begin
- SwitchClock(PositionColor);
- dragged_moved:= TRUE;
+ i := 9 - i;
+ j := 9 - j;
end;
- end; // if
+ end;
+end;
+
+
+function TChessBoard.FDoMove(i, j: integer; prom_fig: TFigureName = K): boolean;
+begin
+ Result := m_ChessRulesEngine.DoMove(m_i0, m_j0, i, j, prom_fig);
+ if (Result) then
+ FOnAfterMoveDone;
end;
@@ -494,25 +804,26 @@ var begin
case State of
dsDragEnter:
- hilighted:= FALSE;
+ m_bHilighted := FALSE;
+
dsDragMove:
begin
- // Восстановить фрагмент на bmHiddenBoard
- bmHiddenBoard.Canvas.Draw(x0 - dx, y0 - dy, m_bmBuf);
- // Копировать новый фрагмент в буфер
- m_bmBuf.Canvas.CopyRect(Bounds(0, 0, iSquareSize, iSquareSize),
- bmHiddenBoard.Canvas, Bounds(X - dx, Y - dy, iSquareSize, iSquareSize));
- // Нарисовать перетаскиваемую фигуру в новой позиции
- bmHiddenBoard.Canvas.Draw(X - dx, Y - dy, m_bmFigure[m_fig]);
- // Перенести новый фрагмент на экран
+ // Repaint a fragment on m_bmHiddenBoard
+ m_bmHiddenBoard.Canvas.Draw(x0 - dx, y0 - dy, m_bmBuf);
+ // Copy new fragment to the buffer
+ m_bmBuf.Canvas.CopyRect(Bounds(0, 0, m_iSquareSize, m_iSquareSize),
+ m_bmHiddenBoard.Canvas, Bounds(X - dx, Y - dy, m_iSquareSize, m_iSquareSize));
+ // Draw the dragging piece in a new position
+ m_bmHiddenBoard.Canvas.Draw(X - dx, Y - dy, m_bmFigure[m_fig]);
+ // Copy the new fragment to the screen
rect:= Bounds(Min(x0,X) - dx, Min(y0, Y) - dy,
- abs(X - x0) + iSquareSize, abs(Y - y0) + iSquareSize);
- PBoxBoard.Canvas.CopyRect(rect, bmHiddenBoard.Canvas, rect);
+ abs(X - x0) + m_iSquareSize, abs(Y - y0) + m_iSquareSize);
+ PBoxBoard.Canvas.CopyRect(rect, m_bmHiddenBoard.Canvas, rect);
x0 := X;
y0 := Y;
- WhatSquare(Point(X,Y), i,j);
+ FWhatSquare(Point(X,Y), i, j);
Accept := ((i in [1..8]) and (j in [1..8]));
end;
@@ -520,50 +831,64 @@ begin end;
-procedure TChessBoard.PBoxBoardEndDrag(Sender, Target: TObject; X,
- Y: Integer);
+procedure TChessBoard.PBoxBoardEndDrag(Sender, Target: TObject; X, Y: Integer);
+var
+ i, j: integer;
+ bRes: boolean;
begin
- if hilighted then
- with bmHiddenBoard.Canvas do
+ case m_Mode of
+ mGame, mAnalyse:
+ begin
+ if (m_bHilighted) then
begin
- Pen.Color:= HILIGHT_COLOR;
- Pen.Width := HILIGHT_WIDTH;
- x0:= x0 - dx;
- y0:= y0 - dy;
- MoveTo(x0,y0);
- LineTo(x0 + iSquareSize - 1, y0);
- LineTo(x0 + iSquareSize - 1, y0 + iSquareSize - 1);
- LineTo(x0, y0 + iSquareSize - 1);
- LineTo(x0,y0);
-
- PBoxBoardPaint(nil);
+ with m_bmHiddenBoard.Canvas do
+ begin
+ Pen.Color:= HILIGHT_COLOR;
+ Pen.Width := HILIGHT_WIDTH;
+ x0:= x0 - dx;
+ y0:= y0 - dy;
+ MoveTo(x0,y0);
+ LineTo(x0 + m_iSquareSize - 1, y0);
+ LineTo(x0 + m_iSquareSize - 1, y0 + m_iSquareSize - 1);
+ LineTo(x0, y0 + m_iSquareSize - 1);
+ LineTo(x0, y0);
+
+ PBoxBoardPaint(nil);
+ end;
end
- else
- begin
- RDrawBoard;
- if dragged_moved then
+ else
+ begin
+ if (AnimateTimer.Enabled) then
+ AnimateTimer.Enabled := FALSE;
+ FDrawBoard;
+ if (m_bDraggedMoved) then
begin
HilightLastMove;
Evaluate;
- dragged_moved:= FALSE;
+ m_bDraggedMoved := FALSE;
end;
+ end;
end;
-end;
-
-procedure TChessBoard.WhatSquare(const P: TPoint;
- var i: Integer; var j: Integer);
-begin
- with P do
+ mEdit:
begin
- i := (X - CHB_X + iSquareSize) div iSquareSize;
- j := 8 - (Y - CHB_Y) div iSquareSize;
- if (_flipped) then
+ if (m_bDraggedMoved) then
begin
- i := 9 - i;
- j := 9 - j;
+ FWhatSquare(Point(X, Y), i, j);
+ bRes := (((i <> m_i0) or (j <> m_j0)) and Position.SetPiece(i, j, m_fig));
+ end
+ else
+ bRes := TRUE;
+
+ if (bRes) then
+ begin
+ Position.SetPiece(m_i0, m_j0, ES);
+ FOnAfterSetPosition;
end;
- end;
+
+ FDrawBoard;
+ end;
+ end; // case
end;
@@ -573,58 +898,67 @@ var i, j: Integer;
f: TFigure;
begin
- WhatSquare(Point(X, Y), i, j);
+ if (Button <> mbLeft) then
+ exit;
+
+ FWhatSquare(Point(X, Y), i, j);
if (not ((i in [1..8]) and (j in [1..8]))) then
exit;
+ m_bDraggedMoved := FALSE;
+
f := Position.board[i,j];
- case Mode of
- mGame:
+ case m_Mode of
+ mGame, mAnalyse:
begin
- if (ViewGaming) then
+ if (m_bViewGaming) then
exit;
- if (Button <> mbLeft) or (Position.color <> player_color) or
- (((Position.color <> fcWhite) or (f >= ES)) and
- ((Position.color <> fcBlack) or (f <= ES))) then
+ if ((Position.color <> m_PlayerColor) or
+ (((Position.color <> fcWhite) or (f >= ES)) and
+ ((Position.color <> fcBlack) or (f <= ES)))) then
exit;
+
+ if ((i = m_i0) and (j = m_j0)) then
+ m_bHilighted := (m_bHilighted xor TRUE)
+ else
+ m_bHilighted := TRUE;
end;
- else
- exit;
- end;
- if (anim_step < anim_step_num) then
+ mEdit:
begin
- anim_step:= anim_step_num;
- AnimateTimerTimer(nil);
+ if (f = ES) then
+ exit;
end;
- if ((i = m_i0) and (j = m_j0)) then
- hilighted := (hilighted xor TRUE)
else
- hilighted:= TRUE;
+ exit;
+ end;
+
+ if (m_iAnimStep < m_iAnimStepsCount) then
+ FEndAnimation;
m_fig := f;
m_i0 := i;
m_j0 := j;
- dx := (X - CHB_X) mod iSquareSize;
- dy := (Y - CHB_Y) mod iSquareSize;
+ dx := (X - CHB_X) mod m_iSquareSize;
+ dy := (Y - CHB_Y) mod m_iSquareSize;
x0 := X;
y0 := Y;
- dragged_moved := TRUE;
+ m_bDraggedMoved := TRUE;
PBoxBoard.BeginDrag(FALSE);
end;
-procedure TChessBoard.PBoxBoardMouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
+procedure TChessBoard.PBoxBoardMouseMove(Sender: TObject; Shift: TShiftState;
+ X, Y: Integer);
var
f: TFigure;
i,j: Integer;
begin
- WhatSquare(Point(X,Y), i,j);
+ FWhatSquare(Point(X,Y), i,j);
if (not ((i in [1..8]) and (j in [1..8]))) then
begin
PBoxBoard.Cursor:= crDefault;
@@ -633,388 +967,185 @@ begin f := Position.board[i,j];
- case Mode of
- mGame:
+ case m_Mode of
+ mGame, mAnalyse:
begin
- if (ViewGaming) then
+ if (m_bViewGaming) then
exit;
-
- if (player_color = Position.color) and
+
+ if (m_PlayerColor = Position.color) and
(((Position.color = fcWhite) and (f < ES)) or
((Position.color = fcBlack) and (f > ES))) then
PBoxBoard.Cursor:= crHandPoint
else
PBoxBoard.Cursor:= crDefault;
- end;
-
- else
- PBoxBoard.Cursor:= crDefault;
- end;
-end;
-
-
-procedure TChessBoard.ROnAfterMoveDone;
-var
- strLastMove: string;
-begin
- if (Assigned(Handler) and
- ((Mode = mGame) and (Position.color <> player_color))) then
- begin
- strLastMove := ChessRulesEngine.LastMoveStr;
- Handler(cbeMoved, @strLastMove, self);
- end;
-end;
-
+ end;
-procedure TChessBoard.FOnAfterMoveDone;
-var
- _fig: TFigure;
-begin
- m_i0 := lastMove.i0;
- m_j0 := lastMove.j0;
+ mEdit:
+ begin
+ if (f <> ES) then
+ PBoxBoard.Cursor:= crHandPoint
+ else
+ PBoxBoard.Cursor:= crDefault;
+ end;
- _fig := Position.board[lastMove.i, lastMove.j];
- if (lastMove.prom_fig in [Q, R, B, N]) then
- begin
- if (_fig < ES) then
- m_fig := WP
- else
- m_fig := BP;
- end
else
- m_fig := _fig;
-
- ROnAfterMoveDone;
+ PBoxBoard.Cursor := crDefault;
+ end;
end;
-function TChessBoard.RDoMove(i, j: integer; prom_fig: TFigureName = K): boolean;
+function TChessBoard.FGetPositionsList: TList;
begin
- Result := ChessRulesEngine.DoMove(m_i0, m_j0, i, j, prom_fig);
- if (Result) then
- FOnAfterMoveDone;
+ Result := m_ChessRulesEngine.PositionsList;
end;
-function TChessBoard.FGetPositionsList: TList;
+function TChessBoard.FGetColorStarts: TFigureColor;
begin
- Result := ChessRulesEngine.PositionsList;
+ Result := m_ChessRulesEngine.GetColorStarts;
end;
-procedure TChessBoard.PBoxBoardMouseUp(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+procedure TChessBoard.PBoxBoardMouseUp(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
var
i, j: integer;
begin
case Button of
mbLeft:
- case Mode of
- mGame:
+ begin
+ case m_Mode of
+ mGame, mAnalyse:
+ begin
+ if (not m_bHilighted) then
+ exit;
+ FWhatSquare(Point(X, Y), i, j);
+ if (m_bDraggedMoved) then
+ FDrawBoard
+ else
begin
- if (not hilighted) then
- exit;
- WhatSquare(Point(X, Y), i, j);
- if (dragged_moved) then
- RDrawBoard
+ m_bHilighted := FALSE;
+ if (FDoMove(i, j)) then
+ FAnimate(i, j)
else
- begin
- hilighted:= FALSE;
- if (RDoMove(i, j)) then
- begin
- Animate(i, j);
- SwitchClock(PositionColor);
- end
- else
- RDrawBoard;
- end;
+ FDrawBoard;
end;
- end;
+ end;
+
+ mEdit:
+ begin
+ if (m_bDraggedMoved) then
+ exit;
+ // Assert(empty field)
+ FWhatSquare(Point(X, Y), i, j);
+ if (Position.SetPiece(i, j, m_EditPiece)) then
+ begin
+ FOnAfterSetPosition;
+ FDrawBoard;
+ end;
+ end;
+
+ end; // case
+ end;
mbRight:
- if (Assigned(Handler)) then
- Handler(cbeMenu, self);
+ begin
+ FDoHandler(cbeMenu, self);
+ end;
+
end;
end;
+
procedure TChessBoard.PBoxBoardStartDrag(Sender: TObject;
var DragObject: TDragObject);
begin
- // Копировать изображение пустого поля в m_bmBuf
- m_bmBuf.Width:= iSquareSize; m_bmBuf.Height:= iSquareSize;
+ // Copy image of an empty square to m_bmBuf
+ m_bmBuf.Width := m_iSquareSize;
+ m_bmBuf.Height:= m_iSquareSize;
if (((m_i0 + m_j0) and 1) <> 0) then
- m_bmBuf.Canvas.CopyRect(Bounds(0,0, iSquareSize, iSquareSize),
- m_bmFigure[ES].Canvas, Bounds(0,0, iSquareSize, iSquareSize))
+ m_bmBuf.Canvas.CopyRect(Bounds(0,0, m_iSquareSize, m_iSquareSize),
+ m_bmFigure[ES].Canvas, Bounds(0,0, m_iSquareSize, m_iSquareSize))
else
- m_bmBuf.Canvas.CopyRect(Bounds(0,0, iSquareSize, iSquareSize),
- m_bmFigure[ES].Canvas, Bounds(iSquareSize,0, iSquareSize, iSquareSize));
+ m_bmBuf.Canvas.CopyRect(Bounds(0,0, m_iSquareSize, m_iSquareSize),
+ m_bmFigure[ES].Canvas, Bounds(m_iSquareSize,0, m_iSquareSize, m_iSquareSize));
- dragged_moved:= FALSE;
-end;
-
-
-procedure TChessBoard.Animate(const i, j: integer);
-var
- x, y: integer;
-begin
- if not Showing then exit;
-
- case animation of
- aNo: anim_step_num:= 1;
- aSlow: anim_step_num:= ANIMATION_SLOW;
- aQuick: anim_step_num:= ANIMATION_QUICK;
- end;
-
- if (_flipped) then
- begin
- x0 := (8 - m_i0) * iSquareSize + CHB_X;
- y0 := (m_j0 - 1) * iSquareSize + CHB_Y;
- x := (8 - i) * iSquareSize + CHB_X;
- y := (j - 1) * iSquareSize + CHB_Y;
- end
- else
- begin
- x0:= (m_i0 - 1) * iSquareSize + CHB_X;
- y0:= (8 - m_j0) * iSquareSize + CHB_Y;
- x:= (i - 1) * iSquareSize + CHB_X;
- y:= (8 - j) * iSquareSize + CHB_Y;
- end;
-
- anim_dx:= (x-x0) / anim_step_num;
- anim_dy:= (y-y0) / anim_step_num;
-
- anim_step:= 0;
-
- // Копировать изображение пустого поля в m_bmBuf
- m_bmBuf.Width := iSquareSize;
- m_bmBuf.Height := iSquareSize;
- if (((m_i0 + m_j0) and 1) <> 0) then
- m_bmBuf.Canvas.CopyRect(Bounds(0, 0, iSquareSize, iSquareSize),
- m_bmFigure[ES].Canvas, Bounds(0, 0, iSquareSize, iSquareSize))
- else
- m_bmBuf.Canvas.CopyRect(Bounds(0, 0, iSquareSize, iSquareSize),
- m_bmFigure[ES].Canvas, Bounds(iSquareSize, 0, iSquareSize, iSquareSize));
-
- AnimateTimer.Enabled := TRUE;
-end;
-
-
-procedure TChessBoard.AnimateTimerTimer(Sender: TObject);
-var
- X,Y: integer;
- rect: TRect;
-begin
- inc(anim_step);
- if (anim_step < anim_step_num) then
- begin
- X := round(x0 + anim_dx * anim_step);
- Y := round(y0 + anim_dy * anim_step);
- dx := X - x0 - round(anim_dx * (anim_step - 1));
- dy := Y - y0 - round(anim_dy * (anim_step - 1));
-
- // Восстановить фрагмент на bmHiddenBoard
- bmHiddenBoard.Canvas.Draw(X - dx, Y - dy, m_bmBuf);
- // Копировать новый фрагмент в буфер
- m_bmBuf.Canvas.CopyRect(Bounds(0, 0, iSquareSize, iSquareSize),
- bmHiddenBoard.Canvas, Bounds(X, Y, iSquareSize, iSquareSize));
- // Нарисовать перетаскиваемую фигуру в новой позиции
- bmHiddenBoard.Canvas.Draw(X, Y, m_bmFigure[m_fig]);
- // Перенести новый фрагмент на экран
- rect := Bounds(Min(X - dx, X), Min(Y - dy, Y),
- abs(dx) + iSquareSize, abs(dy) + iSquareSize);
- PBoxBoard.Canvas.CopyRect(rect, bmHiddenBoard.Canvas, rect);
- end
- else
- begin
- AnimateTimer.Enabled := FALSE;
- RDrawBoard;
- HilightLastMove;
- Evaluate;
- end;
+ m_bDraggedMoved := FALSE;
end;
procedure TChessBoard.InitPosition;
begin
- ChessRulesEngine.InitNewGame;
- RDrawBoard;
-end;
+ m_ChessRulesEngine.InitNewGame;
+ FCancelAnimationDragging;
+ FOnAfterSetPosition;
-procedure TChessBoard.SetMode(const m: TMode);
-begin
- mode_var := m;
- RDrawBoard;
- HilightLastMove;
- if (mode_var <> mGame) then
- begin
- WhiteFlagButton.Visible := FALSE;
- BlackFlagButton.Visible := FALSE;
- end;
+ FDrawBoard;
end;
-procedure TChessBoard.SetTime(color: TFigureColor; const tm: TDateTime);
+procedure TChessBoard.PPRandom;
begin
- if (not Unlimited[color]) then
- begin
- if ((not auto_flag) and (not ViewGaming)) then
- begin
- case color of
- fcWhite:
- WhiteFlagButton.Visible := ((player_color = fcBlack) and (tm = 0.0));
- fcBlack:
- BlackFlagButton.Visible := ((player_color = fcWhite) and (tm = 0.0));
- end;
- end;
- player_time[color]:= tm;
- ShowTime(color);
- end;
-end;
+ m_ChessRulesEngine.InitNewPPRandomGame;
-
-function TChessBoard.GetTime(color: TFigureColor): TDateTime;
-begin
- Result:= player_time[color];
+ FCancelAnimationDragging;
+ FOnAfterSetPosition;
+
+ FDrawBoard;
end;
-procedure TChessBoard.GameTimerTimer(Sender: TObject);
+procedure TChessBoard.TakeBack;
begin
- if unlimited_var[clock_color] then
- begin
- GameTimer.Enabled := FALSE;
- exit;
- end;
- // TODO: cheating check
- player_time[clock_color] := player_time[clock_color] - (Now - past_time);
- if player_time[clock_color] <= 0.0 then
- begin
- player_time[clock_color] := 0.0;
- ShowTime(clock_color);
- if ((not auto_flag) and (player_color <> clock_color) and (not ViewGaming)) then
- begin
- case clock_color of
- fcWhite:
- WhiteFlagButton.Visible := TRUE;
- fcBlack:
- BlackFlagButton.Visible := TRUE;
- end;
- end;
- if ((player_color <> clock_color) and Assigned(Handler) and (Mode = mGame) and (auto_flag)) then
- Handler(cbeTimeOut, self);
- GameTimer.Enabled := FALSE;
- end;
-{$IFNDEF THREADED_CHESSCLOCK}
- ShowTime(clock_color);
-{$ENDIF}
-
- past_time:= Now;
-end;
+ if (m_Mode = mEdit) then
+ exit;
+ if (not m_ChessRulesEngine.TakeBack) then
+ exit;
-procedure TChessBoard.SetUnlimited(color: TFigureColor; const unl: boolean);
-begin
- unlimited_var[color]:= unl;
- ShowTime(color);
+ FOnAfterSetPosition;
+ // TODO: animation
+ FDrawBoard;
end;
-function TChessBoard.GetUnlimited(color: TFigureColor): boolean;
+function TChessBoard.NMoveDone: integer;
begin
- Result := unlimited_var[color];
+ Result := m_ChessRulesEngine.NMovesDone;
end;
-procedure TChessBoard.SwitchClock(clock_color: TFigureColor);
+function TChessBoard.NPlysDone: integer;
begin
- self.clock_color := clock_color;
- if (not GameTimer.Enabled) then
- begin
- past_time := Now;
- GameTimer.Enabled := TRUE;
- end;
- if (Assigned(Handler) and (Mode = mGame)) then
- Handler(cbeClockSwitched, self);
- ShowTime(clock_color);
-
-{$IFDEF THREADED_CHESSCLOCK}
- if (not Assigned(TimeLabelThread)) then
- TimeLabelThread := TTimeLabelThread.Create(self);
-{$ENDIF}
+ Result := m_ChessRulesEngine.NPlysDone;
end;
-procedure TChessBoard.HilightLastMove;
-var
- i, j, l,
- _i0, _j0, x, y: integer;
+function TChessBoard.FGetMovesOffset: integer;
begin
- // вывод последнего сделанного хода
- if (last_hilight and (lastMove.i0 <> 0)) then
- begin
- if (_flipped) then
- begin
- _i0 := 9 - lastMove.i0;
- _j0 := lastMove.j0;
- i := 9 - lastMove.i;
- j := lastMove.j;
- end
- else
- begin
- _i0 := lastMove.i0;
- _j0 := 9 - lastMove.j0;
- i := lastMove.i;
- j := 9 - lastMove.j;
- end;
-
- x := iSquareSize * (_i0 - 1) + CHB_X;
- y := iSquareSize * (_j0 - 1) + CHB_Y;
- bmHiddenBoard.Canvas.Pen.Color := HILIGHT_LAST_MOVE_COLOR;
- bmHiddenBoard.Canvas.Pen.Width := HILIGHT_LAST_MOVE_WIDTH;
-
- for l := 1 to 2 do
- with bmHiddenBoard.Canvas do
- begin
- MoveTo(x, y);
- LineTo(x + iSquareSize - 1, y);
- LineTo(x + iSquareSize - 1, y + iSquareSize - 1);
- LineTo(x, y + iSquareSize - 1);
- LineTo(x, y);
-
- x := iSquareSize * (i - 1) + CHB_X;
- y := iSquareSize * (j - 1) + CHB_Y;
- end;
- PBoxBoardPaint(nil);
- end;
+ Result := m_ChessRulesEngine.MovesOffset;
end;
-procedure TChessBoard.SetPlayerColor(const color: TFigureColor);
+function TChessBoard.FGetPositionColor: TFigureColor;
begin
- FCancelAnimationDragging;
- player_color:= color;
- if (player_color = fcWhite) then
- SetFlipped(FALSE)
- else
- SetFlipped(TRUE); // player_color = fcBlack
-end;
-
-
-procedure TChessBoard.StopClock;
-begin
- GameTimer.Enabled := FALSE;
- WhiteFlagButton.Visible := FALSE;
- BlackFlagButton.Visible := FALSE;
+ Result := Position.color;
end;
procedure TChessBoard.FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
var
-
NewBoardSize: TSize;
begin
+ if (not m_bDeltaWidthHeightFlag) then
+ begin
+ m_iDeltaWidthHeight := Width - Height;
+ m_bDeltaWidthHeightFlag := TRUE;
+ end;
+
Resize := (m_ResizingType <> rtNo);
if (not Resize) then
exit;
@@ -1037,355 +1168,214 @@ begin end;
-procedure TChessBoard.FormClose(Sender: TObject; var Action: TCloseAction);
-begin
- if ((not shuted) and Assigned(Handler)) then
- begin
- Handler(cbeExit, self);
- Action:= caNone;
- end
- else
- shuted := FALSE;
-end;
-
-
-procedure TChessBoard.Shut;
+procedure TChessBoard.FormResize(Sender: TObject);
+var
+ _fig: TFigure;
begin
- shuted:= TRUE;
- Close;
-end;
+ FreeAndNil(m_bmChessBoard);
+ m_BitmapRes.CreateBoardBitmap(Size(PBoxBoard.Width, PBoxBoard.Height), self.Color,
+ m_bmChessBoard);
+ m_iSquareSize := m_BitmapRes.SquareSize;
+ for _fig := Low(TFigure) to High(TFigure) do
+ begin
+ FreeAndNil(m_bmFigure[_fig]);
+ m_BitmapRes.CreateFigureBitmap(_fig, m_bmFigure[_fig]);
+ end;
-procedure TChessBoard.Evaluate;
-begin
- if (Assigned(Handler)) then
+ // Graphics initialization
+ if (not Assigned(m_bmHiddenBoard)) then
begin
- case ChessRulesEngine.GetEvaluation of
- evMate:
- Handler(cbeMate, self);
- evStaleMate:
- Handler(cbeStaleMate, self);
- end;
+ m_bmHiddenBoard := Graphics.TBitmap.Create;
+ m_bmHiddenBoard.Palette := m_bmChessBoard.Palette;
+ m_bmHiddenBoard.Canvas.Font := PBoxBoard.Font; // Характеристики шрифта координат задаются в инспекторе
+ m_bmHiddenBoard.Canvas.Brush.Style := bsClear;
end;
-end;
+ m_bmHiddenBoard.Width := m_bmChessBoard.Width;
+ m_bmHiddenBoard.Height := m_bmChessBoard.Height;
+ if (not Assigned(m_bmBuf)) then
+ begin
+ m_bmBuf := Graphics.TBitmap.Create;
+ m_bmBuf.Palette:= m_bmChessBoard.Palette;
+ end;
-procedure TChessBoard.PPRandom;
-begin
- ChessRulesEngine.InitNewPPRandomGame;
- RDrawBoard;
+ FDrawBoard;
end;
-procedure TChessBoard.TakeBack;
+procedure TChessBoard.WMSizing(var Msg: TMessage);
begin
- if (not ChessRulesEngine.TakeBack) then
- exit;
- ROnAfterSetPosition;
- // TODO: animation
- RDrawBoard;
+ case Msg.WParam of
+ WMSZ_RIGHT, WMSZ_LEFT, WMSZ_BOTTOMRIGHT, WMSZ_TOPLEFT:
+ m_ResizingType := rtHoriz;
+ WMSZ_BOTTOM, WMSZ_TOP:
+ m_ResizingType := rtVert;
+ else
+ begin
+ m_ResizingType := rtNo;
+ PRect(Msg.LParam).Left := Left;
+ PRect(Msg.LParam).Top := Top;
+ end;
+ end; // case
end;
-procedure TChessBoard.SetHilightLastMove(const yes: boolean);
+procedure TChessBoard.FDoHandler(e: TChessBoardEvent; d1: pointer = nil; d2: pointer = nil);
begin
- last_hilight := yes;
- RDrawBoard;
- HilightLastMove;
+ if (Assigned(FHandler)) then
+ FHandler(e, d1, d2);
end;
-procedure TChessBoard.SetCoordinates(const yes: boolean);
+function TChessBoard.FGetMoveNotationFormat: TMoveNotationFormat;
begin
- coord_show := yes;
- RDrawBoard;
- HilightLastMove;
+ Result := m_ChessRulesEngine.MoveNotationFormat;
end;
-function TChessBoard.NMoveDone: integer;
+procedure TChessBoard.FSetMoveNotationFormat(Value: TMoveNotationFormat);
begin
- Result := ChessRulesEngine.NMovesDone;
+ m_ChessRulesEngine.MoveNotationFormat := Value;
end;
-procedure TChessBoard.ROnAfterSetPosition;
-begin
-end;
-
-{$IFDEF THREADED_CHESSCLOCK}
-procedure TTimeLabelThread.Execute;
+function TChessBoard.FGetFENFormat: boolean;
begin
- while ChessBoard.GameTimer.Enabled do
- begin
- if self.player_time[fcWhite] <> ChessBoard.player_time[fcWhite] then
- ChessBoard.ShowTime(fcWhite);
- if self.player_time[fcBlack] <> ChessBoard.player_time[fcBlack] then
- ChessBoard.ShowTime(fcBlack);
- Sleep(ChessBoard.GameTimer.Interval div 2);
- end;
- ChessBoard.TimeLabelThread := nil;
+ Result := m_ChessRulesEngine.FENFormat;
end;
-constructor TTimeLabelThread.Create(ChessBoard: TChessBoard);
+procedure TChessBoard.FSetFENFormat(bValue: boolean);
begin
- self.ChessBoard := ChessBoard;
- self.player_time[fcWhite] := ChessBoard.player_time[fcWhite];
- self.player_time[fcBlack] := ChessBoard.player_time[fcBlack];
-
- inherited Create(TRUE);
-//Priority := tpNormal;
- FreeOnTerminate := TRUE;
- Resume;
-end;
-{$ENDIF}
-
-procedure TChessBoard.FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
-begin
- if Assigned(Handler) then
- Handler(cbeKeyPressed, Pointer(Key), self);
+ m_ChessRulesEngine.FENFormat := bValue;
end;
-function TChessBoard.GetStayOnTop: boolean;
+procedure TChessBoard.BeginUpdate;
begin
- Result := (self.FormStyle = fsStayOnTop);
+ inc(m_iUpdateCounter);
end;
-procedure TChessBoard.SetStayOnTop(onTop: boolean);
+procedure TChessBoard.EndUpdate;
begin
- if (onTop) then
- self.FormStyle := fsStayOnTop
- else
- self.FormStyle := fsNormal;
+ if (m_iUpdateCounter > 0) then
+ begin
+ dec(m_iUpdateCounter);
+ if (m_iUpdateCounter = 0) then
+ FDrawBoard;
+ end;
end;
-procedure TChessBoard.FormActivate(Sender: TObject);
+procedure TChessBoard.FOnDrawLayerUpdate(const ADrawLayer: TChessBoardLayerBase);
begin
- if Assigned(Handler) then
- Handler(cbeActivate, self);
+ if (not AnimateTimer.Enabled) then
+ FDrawBoard;
end;
-procedure TChessBoard.WMMoving(var Msg: TWMMoving);
+procedure TChessBoard.AddLayer(const ALayer: TChessBoardLayerBase);
begin
- // TODO: it's possible to handle if form is outside of the screen
- if Assigned(Handler) then
- Handler(cbeFormMoving, Pointer(Msg.DragRect.Left - Left), Pointer(Msg.DragRect.Top - Top));
- inherited;
-end;
+ if (m_lstLayers.IndexOf(ALayer) >= 0) then
+ exit;
+ ALayer.ChessBoard := self;
+ m_lstLayers.Add(ALayer);
-procedure TChessBoard.WMSizing(var Msg: TMessage);
-begin
- case Msg.WParam of
- WMSZ_RIGHT, WMSZ_LEFT, WMSZ_BOTTOMRIGHT, WMSZ_TOPLEFT:
- m_ResizingType := rtHoriz;
- WMSZ_BOTTOM, WMSZ_TOP:
- m_ResizingType := rtVert;
- else
- begin
- m_ResizingType := rtNo;
- PRect(Msg.LParam).Left := Left;
- PRect(Msg.LParam).Top := Top;
- end;
- end; { case }
+ FOnDrawLayerUpdate(ALayer);
end;
-function TChessBoard.FGetPositinoColor: TFigureColor;
+procedure TChessBoard.RemoveLayer(const ALayer: TChessBoardLayerBase);
begin
- Result := Position.color;
-end;
-
+ if (m_lstLayers.Remove(ALayer) >= 0) then
+ begin
+ ALayer.ChessBoard := nil;
-function TChessBoard.FGetPosition: PChessPosition;
-begin
- Result := ChessRulesEngine.Position;
+ FOnDrawLayerUpdate(ALayer);
+ end;
end;
-function TChessBoard.AskPromotionFigure(FigureColor: TFigureColor): TFigureName;
+function TChessBoard.IsMoveAnimating: boolean;
begin
- if (Showing) then
- begin
- with TPromotionForm.Create(self, m_BitmapRes) do
- try
- Result := ShowPromotion(FigureColor);
- finally
- Free;
- end;
- end
- else
- Result := Q;
+ Result := AnimateTimer.Enabled;
end;
+////////////////////////////////////////////////////////////////////////////////
+// TChessBoardDrawBase
-function TChessBoard.FGetLastMove: PMoveAbs;
+procedure TChessBoardLayerBase.RDoUpdate;
begin
- Result := ChessRulesEngine.lastMove;
+ if (Assigned(m_ChessBoard)) then
+ m_ChessBoard.FOnDrawLayerUpdate(self);
end;
-procedure TChessBoard.FCancelAnimationDragging;
+function TChessBoardLayerBase.FGetSquareSize: integer;
begin
- // Отмена анимации и перетаскивания
- if (AnimateTimer.Enabled) then
- begin
- AnimateTimer.Enabled := FALSE;
- // anim_step := anim_step_num;
- // AnimateTimerTimer(nil);
- end;
- if (PBoxBoard.Dragging) then
- begin
- dragged_moved := FALSE;
- PBoxBoard.EndDrag(FALSE);
- end;
+ if (Assigned(m_ChessBoard)) then
+ Result := m_ChessBoard.SquareSize
+ else
+ Result := 0;
end;
-procedure TChessBoard.FlagButtonClick(Sender: TObject);
+function TChessBoardLayerBase.FGetCanvas: TCanvas;
begin
- if Assigned(Handler) and (Mode = mGame) then
- Handler(cbeTimeOut, self);
+ if (Assigned(m_ChessBoard)) then
+ Result := m_ChessBoard.FGetHiddenBoardCanvas
+ else
+ Result := nil;
end;
-procedure TChessBoard.SetAutoFlag(auto_flag: boolean);
+function TChessBoardLayerBase.FGetPosition: PChessPosition;
begin
- self.auto_flag := auto_flag;
- if (auto_flag) then
- begin
- WhiteFlagButton.Visible := FALSE;
- BlackFlagButton.Visible := FALSE;
- end;
+ if (Assigned(m_ChessBoard)) then
+ Result := m_ChessBoard.Position
+ else
+ Result := nil;
end;
-procedure TChessBoard.FormResize(Sender: TObject);
-var
- _fig: TFigure;
+function TChessBoardLayerBase.RGetColorStarts: TFigureColor;
begin
- FreeAndNil(m_bmChessBoard);
- m_BitmapRes.CreateBoardBitmap(Size(PBoxBoard.Width, PBoxBoard.Height), self.Color,
- m_bmChessBoard);
- iSquareSize := m_BitmapRes.SquareSize;
-
- for _fig := Low(TFigure) to High(TFigure) do
- begin
- FreeAndNil(m_bmFigure[_fig]);
- m_BitmapRes.CreateFigureBitmap(_fig, m_bmFigure[_fig]);
- end;
-
- // Graphics initialization
- if (not Assigned(bmHiddenBoard)) then
- begin
- bmHiddenBoard := TBitmap.Create;
- bmHiddenBoard.Palette := m_bmChessBoard.Palette;
- bmHiddenBoard.Canvas.Font := PBoxBoard.Font; // Характеристики шрифта координат задаются в инспекторе
- bmHiddenBoard.Canvas.Brush.Style := bsClear;
- end;
- bmHiddenBoard.Width := m_bmChessBoard.Width;
- bmHiddenBoard.Height := m_bmChessBoard.Height;
-
- if (not Assigned(m_bmBuf)) then
- begin
- m_bmBuf := TBitmap.Create;
- m_bmBuf.Palette:= m_bmChessBoard.Palette;
- end;
-
- RDrawBoard;
+ if (Assigned(m_ChessBoard)) then
+ Result := m_ChessBoard.FGetColorStarts
+ else
+ Result := fcWhite;
end;
-procedure TChessBoard.TimePanelResize(Sender: TObject);
-var
- rRatio: real;
+function TChessBoardLayerBase.FGetPositionsList: TList;
begin
- // Adjust panels on TimePanel
- rRatio := TimePanel.Width / m_iTimePanelInitialWidth;
- WhitePanel.Left := Round(rRatio * m_iWhitePanelInitialLeft);
- WhitePanel.Width := m_iWhitePanelInitialWidth;
- BlackPanel.Left := Round(rRatio * m_iBlackPanelInitialLeft);
- BlackPanel.Width := m_iBlackPanelInitialWidth;
-
-
- WhiteTimeLabel.Font.Assign(m_TimeFont);
- BlackTimeLabel.Font.Assign(m_TimeFont);
- if (WhitePanel.Left + WhitePanel.Width < BlackPanel.Left) then
- begin
- WhiteLabel.Caption := WHITE_LONG_LABEL;
- BlackLabel.Caption := BLACK_LONG_LABEL;
- end
+ if (Assigned(m_ChessBoard)) then
+ Result := m_ChessBoard.PositionsList
else
- begin
- WhitePanel.Left := 4;
- WhitePanel.Width := TimePanel.Width div 2;
- BlackPanel.Left := TimePanel.Width div 2;
- BlackPanel.Width := TimePanel.Width div 2 - 4;
+ Result := nil;
+end;
- WhiteLabel.Caption := WHITE_MEDIUM_LABEL;
- BlackLabel.Caption := BLACK_MEDIUM_LABEL;
- end;
- // Adjust color labels
- if ((WhiteTimeLabel.Left + WhiteTimeLabel.Width > WhitePanel.Width) or
- (BlackTimeLabel.Left + BlackTimeLabel.Width > BlackPanel.Width)) then
- begin
- WhiteTimeLabel.Font.Size := WhiteTimeLabel.Font.Size - 4;
- BlackTimeLabel.Font.Size := BlackTimeLabel.Font.Size - 4;
- WhiteLabel.Caption := WHITE_SHORT_LABEL;
- BlackLabel.Caption := BLACK_SHORT_LABEL;
- end;
+procedure TChessBoardLayerBase.ROnAfterMoveDone;
+begin
end;
-procedure TChessBoard.FFlashWindow;
-var
- flushWindowInfo: TFlashWInfo;
+procedure TChessBoardLayerBase.ROnAfterSetPosition;
begin
- // Flash with taskbar
- flushWindowInfo.cbSize := SizeOf(flushWindowInfo);
- flushWindowInfo.hwnd := Application.Handle;
- flushWindowInfo.dwflags := FLASHW_TRAY; // FLASHW_ALL; //FLASHW_TRAY;
- flushWindowInfo.ucount := 3; // Flash times
- flushWindowInfo.dwtimeout := 0; // speed in msec, 0 - frequency of cursor flashing
- FlashWindowEx(flushWindowInfo);
-
- if (self.Focused) then
- exit;
- // Flash window
- flushWindowInfo.hwnd := self.Handle; // handle of the flashing window
- flushWindowInfo.dwflags := FLASHW_CAPTION; // FLASHW_TRAY; // FLASHW_ALL; //FLASHW_TRAY;
- FlashWindowEx(flushWindowInfo);
end;
-procedure TChessBoard.FLocalize;
+procedure TChessBoardLayerBase.ROnAfterModeSet(const OldValue, NewValue: TMode);
begin
- with TLocalizer.Instance do
- begin
- WHITE_LONG_LABEL := GetLabel(13);
- WHITE_MEDIUM_LABEL := GetLabel(14);
- WHITE_SHORT_LABEL := GetLabel(15);
- BLACK_LONG_LABEL := GetLabel(16);
- BLACK_MEDIUM_LABEL := GetLabel(17);
- BLACK_SHORT_LABEL := GetLabel(18);
- end;
-
- TimePanelResize(nil);
end;
-initialization
+procedure TChessBoardLayerBase.ROnResetMoveList;
begin
- Randomize; // для PP Random
end;
-finalization
-
end.
|