Skip to content

Commit

Permalink
Version 0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
rchastain committed Dec 26, 2019
1 parent 7f95779 commit e46e740
Show file tree
Hide file tree
Showing 13 changed files with 1,152 additions and 607 deletions.
Binary file added Nouveau dossier compressé.zip
Binary file not shown.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Moustique
# Moustique (JSSchach UCI)


UCI chess engine built on Jürgen Schlottke's didactic chess program.
Jürgen Schlottke's didactic chess program, with a basic UCI interface.

![alt text](https://github.com/rchastain/moustique/blob/master/Farman%20F455%20Moustique.bmp)

Download Moustique 0.2 for Windows:
https://sites.google.com/view/eschecs/moustique
Moustique 0.3 uses the small [Polyglot book](http://www.open-aurec.com/chesswar/download.html) by Olivier Deville.
506 changes: 506 additions & 0 deletions book.pas

Large diffs are not rendered by default.

249 changes: 129 additions & 120 deletions chessplayer.pas
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ TChessPlayer = class
public
constructor Create;
destructor Destroy; override;
procedure SetPosition(const aPos: string);
function PlayMove(const aMove: string): boolean;
function BestMoveIndex(const aBestValue: integer): integer;
function BestMove(out aCode: TExitCode): string; overload;
function BestMove(): string; overload;
function BoardAsText(const aPretty: boolean = TRUE): string;
function FEN(): string;
function SetPosition_(const aPos: string; const aMoves: array of string): string;
procedure SetPosition(const APos: string);
function PlayMove(const AMove: string): boolean;
function BestMoveIndex(const ABestValue: integer): integer;
function BestMove(out ACode: TExitCode): string; overload;
function BestMove: string; overload;
function BoardAsText(const APretty: boolean = TRUE): string;
function FEN: string;
function SetPositionFromMoves(const APos: string; const AMoves: array of string): string;
end;

implementation
Expand All @@ -57,214 +57,223 @@ destructor TChessPlayer.Destroy;
inherited Destroy;
end;

procedure TChessPlayer.SetPosition(const aPos: string);
procedure TChessPlayer.SetPosition(const APos: string);

function GetMoveCount(const aPos: string): integer;
function GetMoveCount(const APos: string): integer;
var
lst: TStringList;
LFields: TStringList;
begin
lst := TStringList.Create;
ExtractStrings([' '], [], pchar(aPos), lst);
if lst.Count = 6 then
result := 2 * Pred(StrToInt(lst[5])) + Ord(lst[1] = 'b')
LFields := TStringList.Create;
ExtractStrings([' '], [], pchar(APos), LFields);
if LFields.Count = 6 then
result := 2 * Pred(StrToInt(LFields[5])) + Ord(LFields[1] = 'b')
else
result := 0;
lst.Free;
LFields.Free;
end;

begin
FCurPos.SetPosition(aPos);
FHalfmovesCount := GetMoveCount(aPos);
FCurPos.SetPosition(APos);
FHalfmovesCount := GetMoveCount(APos);
end;

function TChessPlayer.PlayMove(const aMove: string): boolean;
function TChessPlayer.PlayMove(const AMove: string): boolean;
var
aux: TChessPosition;
iMove, iPromo, iFromSquare, iToSquare: integer;
LAuxPos: TChessPosition;
LMove, LPromo, LFrom, LTo: integer;
begin
MoveToInt(aMove, iMove, iPromo);
iFromSquare := iMove div 100;
iToSquare := iMove mod 100;
MoveToInt(AMove, LMove, LPromo);
LFrom := LMove div 100;
LTo := LMove mod 100;
FCurPos.GenerateMoves;
result := FCurPos.IsLegal(iMove);
result := FCurPos.IsLegal(LMove);
if result then
begin
aux := TChessPosition.Create;
aux.SetPosition(FCurPos);
aux.MovePiece(iFromSquare, iToSquare, iPromo);
aux.activeColor := cBlack * aux.activeColor;
if aux.Check then
LAuxPos := TChessPosition.Create;
LAuxPos.SetPosition(FCurPos);
LAuxPos.MovePiece(LFrom, LTo, LPromo);
LAuxPos.activeColor := CBlack * LAuxPos.activeColor;
if LAuxPos.Check then
result := FALSE
else
begin
FCurPos.MovePiece(iFromSquare, iToSquare, iPromo);
FCurPos.MovePiece(LFrom, LTo, LPromo);
Inc(FHalfmovesCount);
end;
aux.Free;
LAuxPos.Free;
end;
end;

function TChessPlayer.BestMoveIndex(const aBestValue: integer): integer;
function TChessPlayer.BestMoveIndex(const ABestValue: integer): integer;
var
aux: TChessPosition;
LAuxPos: TChessPosition;
LMaxValue: integer;
LSecondListCount: integer;
i, j: integer;
maxValue: integer;
secondListCount: integer;
LLine1, LLine2: string;
begin
aux := TChessPosition.Create;
LAuxPos := TChessPosition.Create;

with FCurPos do
begin
secondListCount := 0;
LSecondListCount := 0;
for i := 1 to moveCount do
if firstList[i].v = aBestValue then
if firstList[i].FValue = ABestValue then
begin
Inc(secondListCount);
FSecondList[secondListCount].f := firstList[i].f;
FSecondList[secondListCount].t := firstList[i].t;
FSecondList[secondListCount].v := 0
Inc(LSecondListCount);
FSecondList[LSecondListCount].FFrom := firstList[i].FFrom;
FSecondList[LSecondListCount].FTo := firstList[i].FTo;
FSecondList[LSecondListCount].FValue := 0
end;
end;

maxValue := Low(integer);
LMaxValue := Low(integer);
result := 0;

for i := 1 to secondListCount do
LLine1 := '';
LLine2 := '';

for i := 1 to LSecondListCount do
begin
aux.SetPosition(FCurPos);
LAuxPos.SetPosition(FCurPos);

with aux do
with LAuxPos do
begin
if chessboard[FSecondList[i].f] = FIniPos.chessboard[FSecondList[i].f] then
if chessboard[FSecondList[i].FFrom] = FIniPos.chessboard[FSecondList[i].FFrom] then
begin
Inc(FSecondList[i].v, 5);
if chessboard[FSecondList[i].f] * activeColor = cPawn then
Inc(FSecondList[i].v, 2);
Inc(FSecondList[i].FValue, 5);
if chessboard[FSecondList[i].FFrom] * activeColor = CPawn then
Inc(FSecondList[i].FValue, 2);
end;

if chessboard[FSecondList[i].f] * activeColor = cKing then
if Abs(FSecondList[i].t - FSecondList[i].f) = 20 then
Inc(FSecondList[i].v, 20)
if chessboard[FSecondList[i].FFrom] * activeColor = CKing then
if Abs(FSecondList[i].FTo - FSecondList[i].FFrom) = 20 then
Inc(FSecondList[i].FValue, 20)
else
Dec(FSecondList[i].v, 10);

if (FHalfmovesCount < 32) and (chessboard[FSecondList[i].f] * activeColor in [cPawn, cBishop, cKnight]) then
Inc(FSecondList[i].v, 20);

if (FSecondList[i].f div 10 = 1)
or (FSecondList[i].f div 10 = 8)
or (FSecondList[i].f mod 10 = 1)
or (FSecondList[i].f mod 10 = 8) then
Inc(FSecondList[i].v, 2);

if (FSecondList[i].t div 10 = 1)
or (FSecondList[i].t div 10 = 8)
or (FSecondList[i].t mod 10 = 1)
or (FSecondList[i].t mod 10 = 8) then
Dec(FSecondList[i].v, 2);
Dec(FSecondList[i].FValue, 10);

if (FHalfmovesCount < 32) and (chessboard[FSecondList[i].FFrom] * activeColor in [CPawn, CBishop, CKnight]) then
Inc(FSecondList[i].FValue, 20);

if (FSecondList[i].FFrom div 10 = 1)
or (FSecondList[i].FFrom div 10 = 8)
or (FSecondList[i].FFrom mod 10 = 1)
or (FSecondList[i].FFrom mod 10 = 8) then
Inc(FSecondList[i].FValue, 2);

if (FSecondList[i].FTo div 10 = 1)
or (FSecondList[i].FTo div 10 = 8)
or (FSecondList[i].FTo mod 10 = 1)
or (FSecondList[i].FTo mod 10 = 8) then
Dec(FSecondList[i].FValue, 2);
end;

aux.SetPosition(FCurPos);
aux.MovePiece(FSecondList[i].f, FSecondList[i].t, cQueen);
LAuxPos.SetPosition(FCurPos);
LAuxPos.MovePiece(FSecondList[i].FFrom, FSecondList[i].FTo, CQueen);

if aux.chessboard[FSecondList[i].t] = FIniPos.chessboard[FSecondList[i].t] then
Dec(FSecondList[i].v, 10);
if LAuxPos.chessboard[FSecondList[i].FTo] = FIniPos.chessboard[FSecondList[i].FTo] then
Dec(FSecondList[i].FValue, 10);

aux.activeColor := cBlack * aux.activeColor;
aux.GenerateSimpleMoves;
LAuxPos.activeColor := CBlack * LAuxPos.activeColor;
LAuxPos.GenerateSimpleMoves;

with aux do
with LAuxPos do
for j := 1 to moveCount do
begin
Inc(FSecondList[i].v);
if chessboard[firstList[j].t] <> cNil then
Inc(FSecondList[i].v);
Inc(FSecondList[i].FValue);
if chessboard[firstList[j].FTo] <> CNil then
Inc(FSecondList[i].FValue);
end;

aux.activeColor := cBlack * aux.activeColor;
aux.GenerateSimpleMoves;
LAuxPos.activeColor := CBlack * LAuxPos.activeColor;
LAuxPos.GenerateSimpleMoves;

with aux do
with LAuxPos do
for j := 1 to moveCount do
begin
Dec(FSecondList[i].v);
if chessboard[firstList[j].t] <> cNil then
Dec(FSecondList[i].v);
Dec(FSecondList[i].FValue);
if chessboard[firstList[j].FTo] <> CNil then
Dec(FSecondList[i].FValue);
end;
{$IFDEF DEBUG}
with FSecondList[i] do Write(MoveToStr(100 * f + t), '(', v, ') ');
with FSecondList[i] do
begin
LLine1 := LLine1 + Format('%6s', [MoveToStr(100 * FFrom + FTo)]);
LLine2 := LLine2 + Format('%6d', [FValue]);
end;
{$ENDIF}
if FSecondList[i].v >= maxValue then
if FSecondList[i].FValue >= LMaxValue then
begin
maxValue := FSecondList[i].v;
LMaxValue := FSecondList[i].FValue;
result := i;
end;
end;
{$IFDEF DEBUG}
WriteLn;
TLog.Append(LLine1);
TLog.Append(LLine2);
{$ENDIF}
aux.Free;
LAuxPos.Free;
end;

function TChessPlayer.BestMove(out aCode: TExitCode): string;
function TChessPlayer.BestMove(out ACode: TExitCode): string;
const
CCodeIllegalMove: array[boolean] of TExitCode = (ecStalemate, ecCheckmate);
CCodeLegalMove: array[boolean] of TExitCode = (ecSuccess, ecCheck);
CCodeIllegal: array[boolean] of TExitCode = (ecStalemate, ecCheckmate);
CCodeLegal: array[boolean] of TExitCode = (ecSuccess, ecCheck);
var
i: integer;
checkBefore, prom: boolean;
LCheckBefore, LPromo: boolean;
begin
result := '0000';
i := FCurPos.BestEval(FCurPos.activeColor, 1, 32000);
i := BestMoveIndex(i);
if i > 0 then
begin
Inc(FHalfmovesCount);
checkBefore := FCurPos.Check;
LCheckBefore := FCurPos.Check;
with FSecondList[i] do
prom := FCurPos.MovePiece(f, t, cQueen);
FCurPos.activeColor := cBlack * FCurPos.activeColor;
LPromo := FCurPos.MovePiece(FFrom, FTo, CQueen);
FCurPos.activeColor := CBlack * FCurPos.activeColor;
if FCurPos.Check then
aCode := CCodeIllegalMove[checkBefore]
ACode := CCodeIllegal[LCheckBefore]
else
begin
with FSecondList[i] do
result := MoveToStr(100 * f + t);
if prom then result := result + 'q';
FCurPos.activeColor := cBlack * FCurPos.activeColor;
aCode := CCodeLegalMove[FCurPos.Check];
result := MoveToStr(100 * FFrom + FTo);
if LPromo then
result := result + 'q';
FCurPos.activeColor := CBlack * FCurPos.activeColor;
ACode := CCodeLegal[FCurPos.Check];
end;
end else
aCode := ecError;
if not (aCode in [ecSuccess, ecCheck]) then
TLog.Append(Format('bestmove exit code %d'#13#10'%s', [aCode, BoardAsText(TRUE)]));
ACode := ecError;
if not (ACode in [ecSuccess, ecCheck]) then
TLog.Append(Format('bestmove function exit code %d', [ACode]));
end;

function TChessPlayer.BestMove(): string;
function TChessPlayer.BestMove: string;
var
_: TExitCode;
LCode: TExitCode;
begin
result := BestMove(_);
result := BestMove(LCode);
end;

function TChessPlayer.BoardAsText(const aPretty: boolean): string;
function TChessPlayer.BoardAsText(const APretty: boolean): string;
begin
result := FCurPos.BoardAsText(aPretty);
result := FCurPos.BoardAsText(APretty);
end;

function TChessPlayer.FEN(): string;
function TChessPlayer.FEN: string;
begin
result := FCurPos.FEN();
result := FCurPos.FEN;
end;

function TChessPlayer.SetPosition_(const aPos: string; const aMoves: array of string): string;
function TChessPlayer.SetPositionFromMoves(const APos: string; const AMoves: array of string): string;
var
vIndex: integer;
i: integer;
begin
SetPosition(aPos);
for vIndex := Low(aMoves) to High(aMoves) do
PlayMove(aMoves[vIndex]);
result := FEN();
SetPosition(APos);
for i := Low(AMoves) to High(AMoves) do
PlayMove(AMoves[i]);
result := FEN;
end;

end.
Loading

0 comments on commit e46e740

Please sign in to comment.