library SudoScan;
{$mode objfpc}{$H+}
uses
Classes, strutils, sysutils, character
{ you can add units after this };
//Fonction InStr renvoie la position d'une sous-chaine Needle dans une chaine Chaine
// On peut préciser la position de départ Debut dans la chaine.
// Renvoie 0 si Needle non trouvée.
Function InStr(Debut: Integer; Chaine: AnsiString; Needle: AnsiString): Integer;
var
f: PChar;
res: Integer;
begin
f := @Chaine[Debut];
res := Pos(Needle, f);
if res = 0 then
result := 0
else
Result := res + Debut - 1;
end;
//Fonction blktfr transfère un bloc de caractères orig vers un pointeur de caractères dest
Function blktfr(dest: PChar; orig: AnsiString): PChar;
var
c: Integer;
begin
for c:=1 to length(orig) do begin
dest^ := orig[c]; dest := dest + 1;
end;
Result := dest;
end;
//Effectue l'analyse de la page web codeSource et rempli Reponse avec le résultat de l'analyse
// Reponse est un tableau de caractères de 400 caractères initialisé à chr(0) fourni par l'application appelante
procedure procedeEsudoku(codeSource: AnsiString; var Reponse:Array of char);
var
k: Char;
tablo: array[0..80] of char;
m, col, lig: Integer;
posi, situetd, situevalue, offset, lastp: Integer;
q: PChar;
txprem, txinput, txtd, txvalue, txsudoku, txnumero, txdiv: AnsiString;
txAnnul: AnsiString;
begin
for m:=0 to 80 do tablo[m]:='0';
txAnnul:='0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,';
txAnnul:= txAnnul + '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,';
txAnnul := txAnnul + 'page web sudoku inconnue'; //variable à renvoyer en cas d'incompréhension;
if Instr(1, codeSource, 'class=tableau') <> 0 then txprem := 'class=tableau'
else if Instr(1, codeSource, 'class="tableau"') <> 0 then txprem := 'class="tableau"'
else if Instr(1, codeSource, 'id=grille') <> 0 then txprem := 'id=grille'
else if Instr(1, codeSource, 'id="grille"') <> 0 then txprem := 'id="grille"'
else if Instr(1, codeSource, 'id="grille-sudoku"') <> 0 then txprem := 'id="grille-sudoku"'
else begin blktfr(Reponse, txAnnul); exit; end; //Tiens! un nouveau qu'on ne connait pas?
posi := Instr(1, codeSource, txprem); // lancer la recherche du tableau
if Instr(posi, codeSource, 'value="') <> 0 then begin // et initialise...
txvalue := 'value="'; offset := 7; end
else begin txvalue := 'value='; offset := 6; end; //... quelques variables
if Instr(posi, codeSource, ' 0 then txinput := ' 0 then txtd := ' 0 then begin
posi := Instr(posi, codeSource, txinput); // Recherche la position de 0) and (situevalue < situetd) then begin
k := codeSource[situevalue + offset];
if k = '"' then k:='0'; // prévoir le cas : value=""
situevalue := Instr(posi, codeSource, txsudoku); // rech sudoku[l][c]
lig := StrToInt(codeSource[situevalue + 7]);
col := StrToInt(codesource[situevalue + 10]);
tablo[lig * 9 + col] := k;
end;
posi := Instr(posi+1, CodeSource, txinput); //rech du 0 then txdiv := ' 0 then txnumero := 'id="numero"'
else if Instr(lastp, codeSource, 'id=numero') <> 0 then txnumero := 'id=numero'
else begin blktfr(q, 'e-sudoku-Numéro_inconnu'); exit; end;
posi := Instr(lastp, codeSource, txnumero); //rech id=numero
while not IsNumber(codeSource[posi]) do Inc(posi); //rech du 1er car numérique
situetd := Instr(posi, codeSource, txdiv); //on limite le texte à la rencontre de