You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1872 8e941d3f-bd1b-0410-a28a-d453659cc2b4
329 lines
13 KiB
Plaintext
329 lines
13 KiB
Plaintext
{****************************************************************************}
|
|
{* SETUP.PAS: This file contains the routines to either put the board in *}
|
|
{* its normal start of game setup or a custom user defined setup. *}
|
|
{****************************************************************************}
|
|
|
|
{****************************************************************************}
|
|
{* Default Board Set Pieces: Puts the pieces on the board for the normal *}
|
|
{* initial configuration. *}
|
|
{****************************************************************************}
|
|
procedure DefaultBoardSetPieces;
|
|
var row, col : RowColType;
|
|
begin
|
|
{*** put in the row of pawns for each player ***}
|
|
for col := 1 to BOARD_SIZE do begin
|
|
Board[2,col].image := PAWN;
|
|
Board[7,col].image := PAWN;
|
|
end;
|
|
|
|
{*** blank out the middle of the board ***}
|
|
for row := 3 to 6 do
|
|
for col := 1 to BOARD_SIZE do
|
|
Board[row,col].image := BLANK;
|
|
|
|
{*** put in white's major pieces and then copy for black ***}
|
|
Board[1,1].image := ROOK;
|
|
Board[1,2].image := KNIGHT;
|
|
Board[1,3].image := BISHOP;
|
|
Board[1,4].image := QUEEN;
|
|
Board[1,5].image := KING;
|
|
Board[1,6].image := BISHOP;
|
|
Board[1,7].image := KNIGHT;
|
|
Board[1,8].image := ROOK;
|
|
for col := 1 to BOARD_SIZE do
|
|
Board[8,col] := Board[1,col];
|
|
|
|
{*** set the piece colors for each side ***}
|
|
for row := 1 to 4 do
|
|
for col := 1 to BOARD_SIZE do begin
|
|
Board[row,col].color := C_WHITE;
|
|
Board[row,col].HasMoved := false;
|
|
Board[row+4,col].color := C_BLACK;
|
|
Board[row+4,col].HasMoved := false;
|
|
end;
|
|
end; {DefaultBoardSetPieces}
|
|
|
|
{****************************************************************************}
|
|
{* Default Board: Sets the pieces in their default positions and sets *}
|
|
{* some of the player attributes to their defaults. Some of the *}
|
|
{* attributes of the game are also set to their startup values. *}
|
|
{****************************************************************************}
|
|
procedure DefaultBoard;
|
|
var row,col : RowColType;
|
|
begin
|
|
DefaultBoardSetPieces;
|
|
|
|
{*** player attributes ***}
|
|
with Player[C_WHITE] do begin
|
|
CursorRow := 2;
|
|
CursorCol := 4;
|
|
InCheck := false;
|
|
KingRow := 1;
|
|
KingCol := 5;
|
|
ElapsedTime := 0;
|
|
LastMove.FromRow := NULL_MOVE;
|
|
end;
|
|
|
|
with Player[C_BLACK] do begin
|
|
CursorRow := 7;
|
|
CursorCol := 4;
|
|
InCheck := false;
|
|
KingRow := 8;
|
|
KingCol := 5;
|
|
ElapsedTime := 0;
|
|
LastMove.FromRow := NULL_MOVE;
|
|
end;
|
|
|
|
{*** game attributes ***}
|
|
Game.MoveNum := 1;
|
|
Game.MovesStored := 0;
|
|
Game.GameFinished := false;
|
|
Game.MovesPointer := 0;
|
|
Game.InCheck[0] := false;
|
|
Game.NonDevMoveCount[0] := 0;
|
|
end; {DefaultBoard}
|
|
|
|
{****************************************************************************}
|
|
{* Setup Board: Input a custom configuration of the pieces on the board *}
|
|
{* from the user. Will anyone actually read these comments. The user *}
|
|
{* moves the cursor to the square to be changed, and presses the key to *}
|
|
{* select the piece to put there. The standards K Q R B N P select a *}
|
|
{* piece and SPACE blanks out the square. The user can also clear the *}
|
|
{* board or ask for the default setup. RETURN saves the changes and asks *}
|
|
{* the user for the move number to continue the game from. ESCAPE *}
|
|
{* restores the setup upon entry to this routine and exits back to the *}
|
|
{* main menu. This routine is called from the main menu. *}
|
|
{****************************************************************************}
|
|
{$ifdef FPCHESS_DISPLAY_ON}
|
|
procedure SetupBoard;
|
|
var row, col, ClearRow, ClearCol : RowColType;
|
|
key : char;
|
|
image : PieceImageType;
|
|
LegalKey, InvalidSetup : boolean;
|
|
KingCount, Attacked, _Protected, Error, NewMoveNum : integer;
|
|
TempStr : string80;
|
|
SaveGame : GameType;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ Put Piece On Board: Puts the global Image onto the board at the cursor }
|
|
{ position. If the image is not a blank, then the user is asked for the }
|
|
{ color (B or W). If the piece is a rook or king being placed in the }
|
|
{ piece's startup position, the user is asked if the piece has been moved }
|
|
{ since the start of the game. }
|
|
{----------------------------------------------------------------------------}
|
|
procedure PutPieceOnBoard;
|
|
var KingHomeRow, PawnHomeRow : RowColType;
|
|
begin
|
|
Board[row,col].image := image;
|
|
if (image = BLANK) then begin
|
|
Board[row,col].color := C_WHITE;
|
|
Board[row,col].HasMoved := false;
|
|
end else begin
|
|
{*** get color ***}
|
|
DisplayInstructions (INS_SETUP_COLOR);
|
|
repeat
|
|
key := GetKey;
|
|
until (key = 'B') or (key = 'W');
|
|
|
|
{*** check if piece has moved ***}
|
|
if key = 'W' then begin
|
|
Board[row,col].color := C_WHITE;
|
|
KingHomeRow := 1;
|
|
PawnHomeRow := 2;
|
|
end else begin
|
|
Board[row,col].color := C_BLACK;
|
|
KingHomeRow := 8;
|
|
PawnHomeRow := 7;
|
|
end;
|
|
{*** may have to ask if piece has been moved ***}
|
|
if ((image = KING) and (row = KingHomeRow) and (col = 5))
|
|
or ((image = ROOK) and (row = KingHomeRow) and ((col = 1) or (col = 8))) then begin
|
|
DisplayInstructions (INS_SETUP_MOVED);
|
|
repeat
|
|
key := GetKey;
|
|
until (key = 'Y') or (key = 'N');
|
|
Board[row,col].HasMoved := key = 'Y';
|
|
end else
|
|
Board[row, col].HasMoved := not ((image = PAWN) and (row = PawnHomeRow));
|
|
DisplaySquare (row, col, false);
|
|
DisplayInstructions (INS_SETUP);
|
|
end;
|
|
end; {PutPieceOnBoard}
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ Check Valid Setup: Makes sure that each player has exactly one king on }
|
|
{ the board and updates the Player's King location attributes. Both kings }
|
|
{ cannot be in check. The other relevant player attributes are set to. }
|
|
{----------------------------------------------------------------------------}
|
|
procedure CheckValidSetup;
|
|
const NULL_ROW = NULL_MOVE;
|
|
var row, col : RowColType;
|
|
begin
|
|
{*** locate kings ***}
|
|
Player[C_WHITE].KingRow := NULL_ROW;
|
|
Player[C_BLACK].KingRow := NULL_ROW;
|
|
KingCount := 0;
|
|
for row := 1 to BOARD_SIZE do
|
|
for col := 1 to BOARD_SIZE do
|
|
if (Board[row, col].image = KING) then begin
|
|
KingCount := KingCount + 1;
|
|
Player[Board[row, col].color].KingRow := row;
|
|
Player[Board[row, col].color].KingCol := col;
|
|
end;
|
|
InvalidSetup := (KingCount <> 2) or (Player[C_WHITE].KingRow = NULL_ROW)
|
|
or (Player[C_BLACK].KingRow = NULL_ROW);
|
|
|
|
{*** make sure both kings are not in check ***}
|
|
if not InvalidSetup then begin
|
|
AttackedBy (Player[C_WHITE].KingRow, Player[C_WHITE].KingCol, Attacked, _Protected);
|
|
Player[C_WHITE].InCheck := (Attacked <> 0);
|
|
AttackedBy (Player[C_BLACK].KingRow, Player[C_BLACK].KingCol, Attacked, _Protected);
|
|
Player[C_BLACK].InCheck := (Attacked <> 0);
|
|
InvalidSetup := (Player[C_WHITE].InCheck) and (Player[C_BLACK].InCheck);
|
|
end;
|
|
|
|
{*** set other player attributes ***}
|
|
Game.GameFinished := false;
|
|
with Player[C_WHITE] do begin
|
|
CursorRow := 2;
|
|
CursorCol := 4;
|
|
LastMove.FromRow := NULL_MOVE;
|
|
end;
|
|
with Player[C_BLACK] do begin
|
|
CursorRow := 7;
|
|
CursorCol := 4;
|
|
LastMove.FromRow := NULL_MOVE;
|
|
end;
|
|
DisplayConversationArea;
|
|
|
|
{*** report invalid setup ***}
|
|
if InvalidSetup then begin
|
|
SetColor (White);
|
|
SetFillStyle (SolidFill, Black);
|
|
Bar (0,INSTR_LINE, GetMaxX, GetMaxY);
|
|
SetTextStyle (TriplexFont, HorizDir, 3);
|
|
OutTextXY (0,INSTR_LINE, 'Illegal Setup - King(s) not set correctly. Press Key.');
|
|
MakeSound (false);
|
|
while GetKey = 'n' do ;
|
|
DisplayInstructions (INS_SETUP);
|
|
end;
|
|
end; {CheckValidSetup}
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ Get Move Num: Asks the user for the next move number of the game and }
|
|
{ whose turn it is to move next. If one of the players is in check, then }
|
|
{ that player is the one who must move next and the latter question is not }
|
|
{ asked. }
|
|
{----------------------------------------------------------------------------}
|
|
procedure GetMoveNum;
|
|
const ex = 190; ey = 40;
|
|
var cx, cy : integer;
|
|
begin
|
|
DisplayInstructions (INS_SETUP_MOVENUM);
|
|
Game.MovesStored := 0;
|
|
Game.MovesPointer := 0;
|
|
Game.InCheck[0] := (Player[C_WHITE].InCheck) or (Player[C_BLACK].InCheck);
|
|
|
|
{*** open up 'window' ***}
|
|
cx := (BOARD_X1 + BOARD_X2) div 2;
|
|
cy := (BOARD_Y1 + BOARD_Y2) div 2;
|
|
SetFillStyle (SolidFill, DarkGray);
|
|
Bar (cx - ex, cy - ey, cx + ex, cy + ey);
|
|
|
|
{*** ask for move number ***}
|
|
SetTextStyle (DefaultFont, HorizDir, 2);
|
|
SetColor (Yellow);
|
|
Str ((Game.MoveNum + 1) div 2, TempStr);
|
|
UserInput (67, cy - 18, 4, 'Move Number: ', TempStr);
|
|
Val (TempStr, NewMoveNum, Error);
|
|
if Error <> 0 then
|
|
NewMoveNum := 1
|
|
else
|
|
NewMoveNum := NewMoveNum * 2 - 1;
|
|
|
|
{*** ask for whose turn to move next if not in check ***}
|
|
if Game.InCheck[0] then begin
|
|
if Player[C_BLACK].InCheck then NewMoveNum := NewMoveNum + 1
|
|
end else begin
|
|
if Game.MoveNum mod 2 = 1 then
|
|
TempStr := 'W'
|
|
else
|
|
TempStr := 'B';
|
|
UserInput (67, cy + 4, 1, 'Next Player (B/W): ', TempStr);
|
|
if TempStr = 'B' then NewMoveNum := NewMoveNum + 1;
|
|
end;
|
|
|
|
Game.MoveNum := NewMoveNum;
|
|
Game.NonDevMoveCount[0] := 0;
|
|
DisplayWhoseMove;
|
|
end; {GetMoveNum}
|
|
|
|
{----------------------------------------------------------------------------}
|
|
begin {SetupBoard}
|
|
DisplayInstructions (INS_SETUP);
|
|
{*** remember old setup incase of escape ***}
|
|
SaveGame := Game;
|
|
SaveGame.Player := Player;
|
|
SaveGame.FinalBoard := Board;
|
|
row := 4;
|
|
col := 4;
|
|
repeat
|
|
repeat
|
|
{*** move cursor and get key ***}
|
|
MoveCursor (row, col, C_WHITE, false, key);
|
|
LegalKey := true;
|
|
{*** interpret key ***}
|
|
case key of
|
|
'K': image := KING;
|
|
'Q': image := QUEEN;
|
|
'R': image := ROOK;
|
|
'B': image := BISHOP;
|
|
'N': image := KNIGHT;
|
|
'P': begin
|
|
image := PAWN;
|
|
if (row = 1) or (row = 8) then begin
|
|
LegalKey := false;
|
|
MakeSound (false);
|
|
end;
|
|
end;
|
|
' ': image := BLANK;
|
|
{*** clear board ***}
|
|
'C': begin
|
|
for ClearRow := 1 to BOARD_SIZE do
|
|
for ClearCol := 1 to BOARD_SIZE do
|
|
Board[ClearRow, ClearCol].image := BLANK;
|
|
DisplayBoard;
|
|
LegalKey := false;
|
|
end;
|
|
{*** default setup of pieces ***}
|
|
'D': begin
|
|
DefaultBoardSetPieces;
|
|
DisplayBoard;
|
|
LegalKey := false;
|
|
end;
|
|
else LegalKey := false;
|
|
end;
|
|
if LegalKey then PutPieceOnBoard;
|
|
until (key = 'e') or (key = 'x');
|
|
|
|
{*** make sure setup is valid and repeat above if not ***}
|
|
if (key = 'x') then
|
|
InvalidSetup := false
|
|
else
|
|
CheckValidSetup;
|
|
until not InvalidSetup;
|
|
|
|
if (key = 'x') then begin
|
|
{*** restore the old setup if user presses escape ***}
|
|
Game := SaveGame;
|
|
Player := SaveGame.Player;
|
|
Board := SaveGame.FinalBoard;
|
|
end else
|
|
GetMoveNum;
|
|
DisplayBoard;
|
|
end; {SetupBoard}
|
|
{$endif}
|
|
|
|
{*** end of SETUP.PAS include file ***}
|
|
|