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