board.pas
来自「用于开发税务票据管理的软件」· PAS 代码 · 共 1,705 行 · 第 1/5 页
PAS
1,705 行
procedure ChangeGridLineWidth(const NewVal: Cardinal);
procedure ChangeHighlightWidth(const NewVal: Cardinal);
procedure ChangeDrawGridLines(const NewVal: Boolean);
procedure ChangePic(const NewVal: TPicture);
procedure ChangePieceFilter(const NewVal: ShortString);
procedure ChangeShowHints(const NewVal: Boolean);
procedure ChangeShowSquareHighlights(const NewVal: Boolean);
procedure ChangeSmoothPieces(const NewVal: Boolean);
procedure ChangeSquareSize(const NewVal: Cardinal);
procedure ChangeStretch(const NewVal: Boolean);
procedure ChangeStretchPic(const NewVal: Boolean);
procedure ChangeUndoLimit(const NewVal: Byte);
procedure ChangeWhiteSquareColour(const NewVal: TColor);
procedure ClearPieces;
procedure DeletePiece(const Which: TPiece);
procedure DrawGridlines(DrawCanvas: TCanvas);
procedure DropUndoRecords(const HowMany: Byte);
procedure EraseSquare(const Where: TPoint; const p: TPiece);
procedure HighlightBoardSquare(const Where: TPoint; const MovingEnemy: Boolean);
procedure HighlightSquares(const HowMany: Cardinal; const MovingEnemy: Boolean);
procedure InitialisePieces;
procedure PromotePawn(LuckyPawn: TPawn); // gets piece type, calls PromotePawnToPiece
procedure PromotePawnToPiece(LuckyPawn: TPawn; const PieceType: TPromotedPiece);
procedure ResetPieceBits;
procedure SendEndTurnEvent;
procedure SetupPieces;
procedure ShowMeMessage2(const NewVal: ShortString);
// procedure SortBoard;
procedure UncapturePiece(UncapturedPiece: TPiece);
procedure UpdateGameTime(Sender: TObject);
procedure UpdateUndoRecords(const From, WhereTo: TPoint; const PositionMove: Boolean);
procedure UndrawGridLines(DrawCanvas: TCanvas);
// function CalculateHash(const p: TPoint): Cardinal;
function CanRedo: Boolean;
function CanUndo: Boolean;
function CheckCastling(const NumberOfSquares: Cardinal): Boolean;
function CheckForCheckmate: Boolean;
function CheckForGameEnd: Boolean;
function CheckForRepetition: Boolean;
function CheckForStalemate: Boolean;
function CheckPieceCounts(const A: TPiecesCountArray): Boolean;
function CheckForDefaultPieces: Boolean;
function ComparePoints(const P1, P2: TPoint): Boolean;
function CompareUndoRecords(const R1, R2: TUndoRecordPtr): Boolean;
function FindKing(var pKing: TPiece; const WhichColour: TColour): TPoint;
function FindNewLocation(const X,Y: Cardinal): TPoint; register;
function FindPiece(var ReturnThis: TPiece; const Where: TPoint): Boolean; register;
function GetPieceFilter: ShortString;
function GetPointsBlack: Byte;
function GetPointsWhite: Byte;
function GetSquareColour(Where: TPoint): TColor;
function InBounds(const Where: TPoint): Boolean;
//function KingInCheck(WhichColour: TColour): Boolean; // not used. Maybe use with AI evaluate() function
function MoveAndCheck(FromPiece, WhereToPiece: TPiece;
const KingLocation: TPoint; const EnemyColour: TColour ): Boolean;
function MovePiece(var P: TPiece; const WhereTo: TPoint): Boolean;
procedure MovePieceToSquare(P: TPiece; const WhereTo: TPoint);
function PieceCanAttackSquare(const p: TPiece; const Where: TPoint): Boolean;
function PiecesAttackingSquare(const WhereTo: TPoint; const WhatColour: TColour): Cardinal;
function PiecesInWay(const From, WhereTo: TPoint): Boolean;
function ShowMeMessage1: ShortString;
function ValidMove(const From, WhereTo: TPoint): Boolean;
protected
{ Protected declarations }
procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
// I handle these directly to do drag-n-drop, for display purposes
procedure WMBeginDrag(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMMouseMove(var Msg: TWMMouseMove); message WM_MOUSEMOVE;
procedure WMStopDrag(var Msg: TWMLButtonUp); message WM_LBUTTONUP;
// These are used when positioning mode is set to true
procedure PositionMove(const MoveTo: TPoint);
procedure PositionDrop(const DropLocation: TPoint);
procedure ShowValidMoves(const PieceWhere: TPiece);
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Paint; override;
function LoadGame(const FileName: String): Boolean;
function SaveGame(const FileName: String): Boolean;
procedure ForceRedraw;
procedure FinishCurrentGame;
procedure Pause;
procedure Redo;
procedure ResetBoard;
procedure Unpause;
function DrawCapturedPieces(Bmp: TBitmap; WhatColour: TColour;
pprow, w,h: Byte): Byte;
function GetBoardCount: Cardinal;
function GetPointsTotal(Colour: TColour): Cardinal;
function Undo: Boolean;
property Check: Boolean Read FCheck;
property GameRunning: Boolean Read FGameRunning;
property PointsBlack: Byte Read GetPointsBlack;
property PointsWhite: Byte Read GetPointsWhite;
property PositionMode: Boolean Read FPositionMode Write FPositionMode;
property Turn: byte Read FTurn;
property TurnNumber: Cardinal Read FTurnNumber;
property UndoPossible: Boolean Read CanUndo;
property RedoPossible: Boolean Read CanRedo;
published
{ Published declarations }
property Author: ShortString Read ShowMeMessage1 Write ShowMeMessage2;
property BackgroundColour: TColor Read FBackgroundC Write ChangeBackgroundColour;
property BlackSquareColour: TColor Read FBlackC Write ChangeBlackSquareColour default clGray;
property DrawLines: Boolean Read FDrawLines Write ChangeDrawGridLines default True;
property GridLineColour: TColor Read FGridLineColour Write ChangeGridLineColour;
property GridLineWidth: Cardinal Read FGridlineWidth Write ChangeGridlineWidth;
property HighlightCaptureColour: TColor Read FHighlightCaptureColour Write FHighlightCaptureColour default clLime;
property HighlightColour: TColor Read FHighlightColour Write FHighlightColour default clYellow;
property HighlightEnemyColour: TColor Read FHighlightEnemyColour Write FHighlightEnemyColour default clRed;
property HighlightStartSquare: Boolean Read FHighlightStartSquare Write FHighlightStartSquare default True;
property HighlightWidth: Cardinal Read FHighlightWidth Write ChangeHighlightWidth;
property Picture: TPicture Read FPic Write ChangePic;
property PieceFilter: ShortString Read GetPieceFilter Write ChangePieceFilter;
property ShowPieceHints: Boolean Read FShowHints Write ChangeShowHints default True;
property ShowSquareHighlights: Boolean Read FShowSquareHighlights Write ChangeShowSquareHighlights default True;
property ShowValidMovesMode: Boolean Read FShowValidMoves Write FShowValidMoves;
property SmoothPieces: Boolean Read FSmoothPieces Write ChangeSmoothPieces;
property StartDragColour: TColor Read FStartDragColour Write FStartDragColour default clYellow;
property Stretch: Boolean Read FStretch Write ChangeStretch default True;
property StretchPicture: Boolean Read FStretchPic Write ChangeStretchPic default True;
property TimeBlack: Cardinal Read FTimeBlack;
property TimeLimit: Cardinal Read FTimeLimit Write FTimeLimit;
property TimeLimitEnabled: Boolean Read FTimerEnabled Write FTimerEnabled;
property TimeWhite: Cardinal Read FTimeWhite;
property UndoLimit: Byte Read FUndoLimit Write ChangeUndoLimit;
property ValidMoveDragColour: TColor Read FValidMoveDragColour Write FValidMoveDragColour default clGreen;
property WhiteSquareColour: TColor Read FWhiteC Write ChangeWhiteSquareColour default clSilver;
property WidthOfSquares: Cardinal Read FSquareSize Write ChangeSquareSize;
// NOTE: The above "WidthOfSquares" was originally called the more logical
// "SquareSize". However, it must come after "Stretch" alphabetically or
// setting it at design-time doesn't work right! You previously had to set
// "SquareSize" at run-time to get it working!
property OnCheckmate: TNotifyCheckmate Read FOnCheckMate Write FOnCheckMate default nil;
property OnDraw: TNotifyDraw Read FOnDraw Write FOnDraw default nil;
property OnEndTurn: TNotifyEndTurn Read FOnEndTurn Write FOnEndTurn default nil;
property OnPositionMove: TNotifyPositionMove Read FOnPositionMove Write FOnPositionMove default nil;
property OnTimeLoss: TNotifyTimeLoss Read FOnTimeLoss Write FOnTimeLoss default nil;
{ Republish some properties }
property Align;
property Cursor;
property DragCursor;
property DragMode;
property Enabled;
property Hint;
property OnClick;
property OnDblClick;
property OnDragOver;
property OnDragDrop;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
end;
procedure Register;
const
crNoMove = 1;
crYesMove = 2;
implementation
{$R CURSORS.RES}
constructor TChessboard.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Screen.Cursors[crNoMove] := LoadCursor(hInstance, 'NOMOVE');
Screen.Cursors[crYesMove] := LoadCursor(hInstance, 'YESMOVE');
FLastPawnMoved := nil;
FLoading := False;
ControlStyle := ControlStyle + [csOpaque]; // reduces flicker
FPic := TPicture.Create;
FPic.Assign(nil);
FBitmap := TBitmap.Create;//TDIBUltra.Create(Screen.Width, Screen.Height, dupf16, nil);
// FBitmap.GDIStyle := False;
FBitmap.PixelFormat := pf16bit;
FBitmap.Width := Width;
FBitmap.Height := Height;
UndoList := TList.Create;
FUndoCount := 0;
FTimerClock := TRXTimer.Create(Self);
FTimeLimit := 300; // 5 mins for each side
FTimerClock.OnTimer := UpdateGameTime;
FBackgroundC := clBtnFace;
FHighlightColour := clYellow;
FHighlightEnemyColour := clRed;
FHighlightCaptureColour := clLime;
FStartDragColour := clYellow;
FValidMoveDragColour := clGreen;
FWhiteC := clSilver;
FBlackC := clGray;
FGridLineColour := clBlack;
FHighlightSquare := TList.Create;
Align := alClient;
FDrawLines := True;
FShowHints := True;
FStretch := True;
FStretchPic := True;
FTurn := 1;
FGridlineWidth := 1;
FHighlightWidth := 2;
FShowSquareHighlights := True;
FSquaresHighlighted := TBits.Create;
FSquaresHighlighted.Size := 64;
FPiecesInSquares := TBits.Create;
FPiecesInSquares.Size := 64;
FHighlightStartSquare := True;
FPicChanged := True;
FPositionDropChanged := False;
FSquareSize := Min(Width,Height) shr 3; // div 8
//if Width > Height then FSquareSize := Height shr 3 else FSquareSize := Width shr 3;
FillChar(Board, sizeof(Board), 0);
ResetBoard;
end;
destructor TChessboard.Destroy;
begin
FTimerClock.Enabled := False;
FTimerClock.Free;
ClearPieces;
FPic.Free;
FHighlightSquare.Free;
UndoList.Free;
FBitmap.Free;
FSquaresHighlighted.Free;
FPiecesInSquares.Free;
inherited Destroy;
end;
{ Handle WM_ERASEBKGND to stop Windows causing flickering }
procedure TChessboard.WMEraseBkgnd(var Msg: TMessage);
begin
Msg.Result := 1; // Stop Windows erasing the background manually - will reduce flicker
end;
{ Handle WM_LBUTTONDOWN for when the user starts a left mouse button drag }
procedure TChessboard.WMBeginDrag(var Msg: TWMLButtonDown);
var
CurrPiecePtr: TPiece;
CurrentMousePos: TPoint;
i: Integer;
OldColour: TColor; // for temp. swapping of highlight colours
begin
if not FGameRunning then
begin
inherited;
Exit;
end;
// Reset the old drag location (arbitrary value not on the board is used here)
FOldDragLoc := Point(-1, -1);
CurrPiecePtr := nil;
// Reset all square highlighting bits in FSquaresHighlighted to false
for i := 0 to FSquaresHighlighted.Size - 1 do
FSquaresHighlighted[i] := False;
// convert x & y pos to board square
CurrentMousePos := FindNewLocation(msg.XPos, msg.YPos);
// Detect if user is attempting to drag a piece, and set up the square
// highlighting appropriately
if FindPiece(CurrPiecePtr , CurrentMousePos) then
begin
if FShowValidMoves then
ShowValidMoves(CurrPiecePtr);
FDraggedPiece := CurrPiecePtr;
FLastValidMoveLoc := FDraggedPiece.Location;
FDragging := True;
Screen.Cursor := crNoMove;
Assert(InBounds(CurrPiecePtr.Location));
if FHighlightStartSquare then
begin
// Highlight the dragged piece's square
OldColour := FHighlightColour;
FHighlightColour := FStartDragColour;
HighlightBoardSquare(CurrPiecePtr.Location, Ord(CurrPiecePtr.Colour) = Turn);
FHighlightColour := OldColour;
end;
end;
inherited;
end;
{ Handle WM_LBUTTONUP, to determine what happens when the user lets the left
mouse button up after dragging across the board. }
procedure TChessboard.WMStopDrag(var Msg: TWMLButtonUp);
var
Curr,
GetPos: TPoint;
CurrPiecePtr: TPiece;
begin
if not FGameRunning then
begin
inherited;
Exit;
end;
CurrPiecePtr := nil;
// The user has stopped dragging a piece, so clear any square highlights
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?