{ - uzavreni formulare - test blizkosti kralu } unit ChessboardForm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, inifiles, ChessBoard, StdCtrls, ImgList, ChessMan, Sockets; type TGameRec = record x, y, col, typ : integer; end; type TFormChessboard = class(TForm) PBChessboard: TPaintBox; ImageList1: TImageList; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure PBChessboardPaint(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure PBChessboardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private ChessMans : array of TChessMan; SelectRecX, SelectRecY : integer; Selected : boolean; posX,posY : integer; black,white : boolean; procedure MoveAction; procedure CreateAllFigures; function FigureAtPosition(x,y : integer) : integer; procedure TakeFigure(i : integer); function PathIsClear(startx,starty,endx,endy : integer): boolean; function KingsTest(x,y : integer) : boolean; procedure PawnToQueen(i : integer); procedure SaveGame; procedure DeleteGame; procedure LoadFigure; // metody osetrujici pohyb jednotlivych figurek function BishopMove(i : integer): boolean; function RookMove(i : integer): boolean; function KnightMove(i : integer): boolean; function KingMove(i : integer): boolean; function QueenMove(i : integer): boolean; function PawnMove(i : integer): boolean; { Private declarations } public Chessboard : TChessboard; playername : string; win : integer; procedure isLoad(load : boolean); { Public declarations } end; var FormChessboard: TFormChessboard; implementation {$R *.dfm} procedure TFormChessboard.isLoad(load : boolean); begin // vytvoreni figurek if load then LoadFigure else CreateAllFigures; end; function TFormChessboard.BishopMove(i : integer): boolean; var x,y,temp : integer; begin BishopMove := false; chessmans[i].GetPosition(x,y); // test zda lze takto tahnout if (abs(posX+1-x)=abs(posY+1-y)) then if PathIsClear(x,y,posX+1,posY+1) then begin // cilove pole je prazdne temp := FigureAtPosition(posX+1,posY+1); if temp=-1 then begin chessmans[i].SetPosition(posX+1,posY+1); BishopMove := true; exit; end else begin // obsazene pole if ((chessmans[temp].GetColor=clBlack)and(chessboard.GetTurnSide))or ((chessmans[temp].GetColor=clWhite)and not (chessboard.GetTurnSide)) then begin TakeFigure(temp); chessmans[i].SetPosition(posX+1,posY+1); BishopMove := true; exit; end; end; end; ShowMessage('Neplatný tah!'); end; function TFormChessBoard.RookMove(i : integer): boolean; var x,y,temp : integer; begin RookMove := false; chessmans[i].GetPosition(x,y); // je to mozny tah pro vez if (posX+1=x)or(posY+1=y) then if PathIsClear(x,y,posX+1,posY+1) then begin // prazdne pole temp := FigureAtPosition(posX+1,posY+1); if temp=-1 then begin chessmans[i].SetPosition(posX+1,posY+1); RookMove := true; exit; end else begin // obsazene pole if ((chessmans[temp].GetColor=clBlack)and(chessboard.GetTurnSide))or ((chessmans[temp].GetColor=clWhite)and not (chessboard.GetTurnSide)) then begin TakeFigure(temp); chessmans[i].SetPosition(posX+1,posY+1); RookMove := true; exit; end; end; end; ShowMessage('Neplatný tah!'); end; function TFormChessBoard.KnightMove(i : integer): boolean; var x,y,temp : integer; begin KnightMove := false; chessmans[i].GetPosition(x,y); // test spravnosti tahu if ((posX+1=x-2)and(posY+1=y-1))or((posX+1=x-1)and(posY+1=y-2))or ((posX+1=x+1)and(posY+1=y-2))or((posX+1=x+2)and(posY+1=y-1))or ((posX+1=x+2)and(posY+1=y+1))or((posX+1=x+1)and(posY+1=y+2))or ((posX+1=x-1)and(posY+1=y+2))or((posX+1=x-2)and(posY+1=y+1)) then begin // prazdne pole temp := FigureAtPosition(posX+1,posY+1); if temp=-1 then begin chessmans[i].SetPosition(posX+1,posY+1); KnightMove := true; exit; end else begin // obsazene pole if ((chessmans[temp].GetColor=clBlack)and(chessboard.GetTurnSide))or ((chessmans[temp].GetColor=clWhite)and not (chessboard.GetTurnSide)) then begin TakeFigure(temp); chessmans[i].SetPosition(posX+1,posY+1); KnightMove := true; exit; end; end; end; ShowMessage('Neplatný tah!'); end; function TFormChessBoard.KingMove(i : integer): boolean; var x,y,temp : integer; begin KingMove := false; chessmans[i].GetPosition(x,y); // je to mozny tah pro krale if ((posX+1=x)and(posY+1=y-1))or((posX+1=x)and(posY+1=y+1))or ((posX+1=x-1)and(posY+1=y-1))or((posX+1=x-1)and(posY+1=y))or ((posX+1=x-1)and(posY+1=y+1))or((posX+1=x+1)and(posY+1=y-1))or ((posX+1=x+1)and(posY+1=y))or((posX+1=x+1)and(posY+1=y+1)) then begin // je dana pozice volna if (FigureAtPosition(posX+1,posY+1)=-1)and(KingsTest(posX+1,posY+1)) then begin chessmans[i].SetPosition(posX+1,posY+1); KingMove := true; exit; end; // dana pozice je okupovana nepritelem temp := FigureAtPosition(posX+1,posY+1); if (temp<>-1)and(KingsTest(posX+1,posY+1)) then if ((chessmans[i].GetColor=clWhite)and(chessmans[temp].GetColor<>clWhite))or ((chessmans[i].GetColor=clBlack)and(chessmans[temp].GetColor<>clBlack)) then begin TakeFigure(temp); chessmans[i].SetPosition(posX+1,posY+1); KingMove := true; exit; end; end; ShowMessage('Neplatný tah!') end; function TFormChessBoard.QueenMove(i : integer): boolean; var x,y,temp : integer; begin QueenMove := false; chessmans[i].GetPosition(x,y); // test moznosti tahu if (abs(posX+1-x)=abs(posY+1-y))or((posX+1=x)or(posY+1=y)) then if PathIsClear(x,y,posX+1,posY+1) then begin // prazdne pole temp := FigureAtPosition(posX+1,posY+1); if temp=-1 then begin chessmans[i].SetPosition(posX+1,posY+1); QueenMove := true; exit; end else begin // obsazene pole if ((chessmans[temp].GetColor=clBlack)and(chessboard.GetTurnSide))or ((chessmans[temp].GetColor=clWhite)and not (chessboard.GetTurnSide)) then begin TakeFigure(temp); chessmans[i].SetPosition(posX+1,posY+1); QueenMove := true; exit; end; end; end; ShowMessage('Neplatný tah!'); end; function TFormChessBoard.PawnMove(i : integer): boolean; var x,y,pos : integer; begin PawnMove := false; chessmans[i].GetPosition(x,y); // test na moznost tohoto tahu if ChessBoard.GetTurnSide then begin // tahne bily // 1 tah utoku na nepritele if (PosX+1=x-1)and(PosY+1=y+1) then begin pos := FigureAtPosition(x-1,y+1); if (pos<>-1)and(chessmans[pos].GetColor<>clWhite) then begin TakeFigure(pos); chessmans[i].SetPosition(x-1,y+1); PawnMove := true; PawnToQueen(i); exit; end; end; // 2 tah utoku na nepritele if (PosX+1=x+1)and(PosY+1=y+1) then begin pos := FigureAtPosition(x+1,y+1); if (pos<>-1)and(chessmans[pos].GetColor<>clWhite) then begin TakeFigure(pos); chessmans[i].SetPosition(x+1,y+1); PawnMove := true; PawnToQueen(i); exit; end; end; // pohyb vpred if (PosY+1=y+1)and(PosX+1=x)and(FigureAtPosition(x,y+1)=-1) then begin chessmans[i].SetPosition(x,y+1); PawnMove := true; PawnToQueen(i); exit; end; // pohyb vpred z vychozi pozice o dve if (PosY+1=y+2)and(PosX+1=x)and PathIsClear(x,y,x,y+2)and(y=2) and(FigureAtPosition(x,y+2)=-1) then begin chessmans[i].SetPosition(x,y+2); PawnMove := true; exit; end; ShowMessage('Neplatný tah!'); end else begin // tahne cerny // 1 tah utoku na nepritele if (PosX+1=x-1)and(PosY+1=y-1) then begin pos := FigureAtPosition(x-1,y-1); if (pos<>-1)and(chessmans[pos].GetColor<>clBlack) then begin TakeFigure(pos); chessmans[i].SetPosition(x-1,y-1); PawnMove := true; PawnToQueen(i); exit; end; end; // 2 tah utoku na nepritele if (PosX+1=x+1)and(PosY+1=y-1) then begin pos := FigureAtPosition(x+1,y-1); if (pos<>-1)and(chessmans[pos].GetColor<>clBlack) then begin TakeFigure(pos); chessmans[i].SetPosition(x+1,y-1); PawnMove := true; PawnToQueen(i); exit; end; end; // pohyb vpred if (PosY+1=y-1)and(PosX+1=x)and(FigureAtPosition(x,y-1)=-1) then begin chessmans[i].SetPosition(x,y-1); PawnMove := true; PawnToQueen(i); exit; end; // pohyb vpred z vychozi pozice o dve if (PosY+1=y-2)and(PosX+1=x)and PathIsClear(x,y,x,y-2)and(y=7) and(FigureAtPosition(x,y-2)=-1) then begin chessmans[i].SetPosition(x,y-2); PawnMove := true; exit; end; ShowMessage('Neplatný tah!'); end; end; procedure TFormChessBoard.SaveGame; var gamefile : file of TGameRec; temp : TGameRec; i : integer; begin AssignFile(gamefile,playername+'.dat'); Rewrite(gamefile); for i := 0 to high(chessmans) do begin chessmans[i].GetPosition(temp.x,temp.y); temp.col := chessmans[i].GetColor; temp.typ := chessmans[i].GetName; Write(gamefile,temp); end; CloseFile(gamefile); end; procedure TFormChessBoard.DeleteGame; var gamefile : file; begin if FileExists(playername+'.dat') then begin AssignFile(gamefile,playername+'.dat'); Erase(gamefile); end; end; function TFormChessBoard.KingsTest(x: Integer; y: Integer): boolean; begin KingsTest := true; // DODELAT!!! end; function TFormChessboard.PathIsClear(startx: Integer; starty: Integer; endx: Integer; endy: Integer): boolean; var i,j : integer; begin // testuje zda je cesta pro pohyb figurky volna PathIsClear := true; // pohyb v ose y if startx=endx then begin if starty>endy then begin for i := starty-1 downto endy+1 do if FigureAtPosition(startx,i)<>-1 then begin PathIsClear := false; exit; end; end else begin for j := (starty+1) to endy-1 do if FigureAtPosition(startx,j)<>-1 then begin PathIsClear := false; exit; end; end; end; // pohyb v ose x if starty=endy then begin if startx>endx then begin for i := startx-1 downto endx+1 do if FigureAtPosition(i,starty)<>-1 then begin PathIsClear := false; exit; end; end else begin for j := (startx+1) to endx-1 do if FigureAtPosition(j,starty)<>-1 then begin PathIsClear := false; exit; end end; end; // pohyb po diagonalach if (startxendy) then begin for i := 1 to endx-startx-1 do if FigureAtPosition(endx-i,endx+i)<>-1 then begin PathIsClear := false; exit; end; end; if (startx>endx)and(starty-1 then begin PathIsClear := false; exit; end; end; if (startx-1 then begin PathIsClear := false; exit; end; end; if (startx>endx)and(starty>endy) then begin for i := 1 to startx-endx-1 do if FigureAtPosition(startx-i,starty-i)<>-1 then begin PathIsClear := false; exit; end; end; end; procedure TFormChessboard.PawnToQueen(i: Integer); var x,y : integer; temp : TQueen; begin chessmans[i].GetPosition(x,y); if (y=1)or(y=8) then begin temp := TQueen.Create; temp.SetPosition(x,y); temp.SetColor(chessmans[i].GetColor); chessmans[i].Free; chessmans[i] := temp; end; end; procedure TFormChessboard.TakeFigure(i: Integer); var j : integer; begin chessmans[i].Free; chessmans[i] := chessmans[high(chessmans)]; SetLength(chessmans,high(chessmans)); // pokud jeden hrac nema figurky prohral j :=0; black := false; white := false; while jSelectRecX)or(posY<>SelectRecY)) then begin Selected := false; // akce MoveAction; end else begin Selected := true; SelectRecX := posX; SelectRecY := posY; end; end; end; // prekresleni PBChessboard.Repaint; end; procedure TFormChessboard.PBChessboardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var newX,newY : integer; begin // posun vyberoveho tlacitka mysi if Button=mbLeft then begin newX := X div 70; newY := Y div 70; if (posX=newX)and(posY=newY)and not Selected then begin Selected := true; SelectRecX := newX; SelectRecY := newY; end else begin if (posX=newX)and(posY=newY)and Selected and ((newX<>SelectRecX)or(newY<>SelectRecY)) then begin Selected := false; // akce MoveAction; end else if (posX=newX)and(posY=newY)and Selected and ((newX=SelectRecX)or(newY=SelectRecY)) then Selected := false else begin posX := newX; posY := newY; end; end; PBChessBoard.Repaint; end; end; procedure TFormChessboard.PBChessboardPaint(Sender: TObject); var i,j,k : integer; temp : TChessMan; begin // vykresleni sachovnice na canvas PBChessboard.Canvas.Pen.Width := 0; PBChessboard.Canvas.Pen.Color := Chessboard.GetColor1; PBChessboard.Canvas.Brush.Color := Chessboard.GetColor1; PBChessboard.Canvas.Rectangle(0,0,self.ClientWidth,self.ClientHeight); PBChessboard.Canvas.Pen.Color := Chessboard.GetColor2; PBChessboard.Canvas.Brush.Color := Chessboard.GetColor2; k := PBChessboard.Width div 8; for i := 0 to 7 do for j := 0 to 3 do begin //rozliseni sudych a lichych radku if not odd(i) then PBChessboard.Canvas.Rectangle(0+j*k*2,0+i*k,k+j*k*2,k+i*k) else PBChessboard.Canvas.Rectangle(k+j*k*2,0+i*k,2*k+j*k*2,k+i*k); end; // vykresleni figurek for i := 0 to high(chessmans) do begin temp := chessmans[i]; temp.GetPosition(j,k); if temp.GetColor=clBlack then Imagelist1.Draw(PBChessBoard.Canvas,70*(j-1),70*(k-1),temp.GetName,true) else Imagelist1.Draw(PBChessBoard.Canvas,70*(j-1),70*(k-1),temp.GetName+6,true); end; // vykresleni vyberoveho okenka PBChessboard.Canvas.Pen.Width := 4; PBChessboard.Canvas.Pen.Color := clBlue; PBChessboard.Canvas.Brush.Style := bsClear; PBChessboard.Canvas.Rectangle(posX*70+3,posY*70+3, posX*70+70-3,posY*70+70-3); // vykresleni vybraneho okenka if Selected then begin PBChessboard.Canvas.Pen.Color := clRed; PBChessboard.Canvas.Rectangle(SelectRecX*70+3,SelectRecY*70+3, SelectRecX*70+70-3,SelectRecY*70+70-3); end; end; end.