unit main; {* BINGO_Checker version 0.1.0.0 CopyRight hironori KANEMITSU BINGO CARDをチェックするソフトです。 Creative Farmで開催されるビンゴゲームに対応しています(これが作る目的でした)。 自作のBINGO_Makerで作成されたBINGO CARDにも対応しています(当然ですよね)。 *} interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, ComCtrls, ToolWin, StdCtrls, Buttons; type TForm1 = class(TForm) ToolBar1: TToolBar; StatusBar1: TStatusBar; DrawGrid1: TDrawGrid; SpeedButton1: TSpeedButton; OpenDialog1: TOpenDialog; SpeedButton2: TSpeedButton; Edit1: TEdit; SpeedButton3: TSpeedButton; ToolButton1: TToolButton; SaveDialog1: TSaveDialog; procedure FormCreate(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure SpeedButton2Click(Sender: TObject); procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure FormPaint(Sender: TObject); procedure SpeedButton3Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private 宣言 } public { Public 宣言 } procedure CellMark(aCol, aRow : integer ; rColor, cColor: TColor ; aSTR : string); procedure InitStatusBar; procedure SizeChange(aColCnt, aRowCnt : integer); end; function dlnSTR (aRow : integer) : string; function nthCopy(const aBP, aSTR : string ; nth : integer) : string; function mCount (const aBP, aSTR : string) : integer; var Form1: TForm1; {* globals *} gCell : array of array of string; gColCnt : integer; gRowCnt : integer; gDrawFlag : boolean; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); {* Initialize all *} begin InitStatusBar; gColCnt := 0; gRowCnt := 0; SizeChange(gColCnt, gRowCnt); Edit1.Clear; gDrawFlag := False; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); {* Exit *} begin {* dynamic arrayを解放する *} gCell := nil; end; procedure TForm1.CellMark(aCol, aRow : integer ; rColor, cColor : TColor ; aSTR : string); var aRect : TRect; aX : integer; aY : integer; aR : integer; begin {* get a RECT of (aCol,aRow) *} aRect := DrawGrid1.CellRect(aCol, aRow); with DrawGrid1.Canvas do begin {* draw rect *} Pen.Color := rColor; Brush.Color := rColor; FillRect(aRect); {* draw circle *} Pen.Color := cColor; Brush.Color := cColor; aX := aRect.Left + (DrawGrid1.DefaultColWidth div 2); aY := aRect.Top + (DrawGrid1.DefaultRowHeight div 2); aR := DrawGrid1.DefaultColWidth div 2 - 2; Ellipse(aX - aR, aY - aR, aX + aR , aY + aR); {* draw string *} Pen.Color := clBlack; Font.Height := DrawGrid1.DefaultRowHeight div 2; aX := aRect.Left + (DrawGrid1.DefaultColWidth div 4); aY := aRect.Top + (DrawGrid1.DefaultRowHeight div 4); if Length(aSTR)=1 then aSTR := ' '+ aSTR; TextOut(aX, aY, aSTR); end; end; procedure TForm1.InitStatusBar; begin {* StatusBarの初期設定 *} with StatusBar1 do begin Panels[0].Width := Form1.Width div 2; Panels[1].Width := Form1.Width div 2; end; end; procedure TForm1.SizeChange(aColCnt, aRowCnt : integer); begin {* ビンゴカードの大きさを変更する *} with DrawGrid1 do begin ColCount := aColCnt; RowCount := aRowCnt; {* Formの大きさも変更する *} Form1.Width := (ColCount+1) * GridLineWidth + ColCount*DefaultColWidth + 8; Form1.Height := (RowCount+1) * GridLineWidth + RowCount*DefaultRowHeight + 74; end; {* StatusBarの大きさも変更する *} InitStatusBar; end; procedure TForm1.FormPaint(Sender: TObject); begin gDrawFlag := True; end; procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); {* 再描画の際に実行される *} var i, j : integer; begin {* gCellの値に基づいてセルを表示する *} if gDrawFlag then begin for i:=0 to gColCnt-1 do begin for j:=0 to gRowCnt-1 do begin if (Trim(gCell[i,j])='**') or (Trim(gCell[i,j])='FREE') then CellMark(i,j,clRed,clBlack,'') else CellMark(i,j,clRed,clWhite,Trim(gCell[i,j])); end; end; end; gDrawFlag := False; end; procedure TForm1.SpeedButton1Click(Sender: TObject); {* BINGO TXT FILEを読みこむ *} var aTXT : TextFile; c, i, j : integer; tmpSTR : string; wrkSTR : array of string; begin if OpenDialog1.Execute then try AssignFile(aTXT, OpenDialog1.FileName); ReSet(aTXT); {* まずTextFileからビンゴカードの行数を得る *} c:=0; while not EOF(aTXT) do begin Readln(aTXT,tmpSTR); {* |を含む行はtmpSTR->wrkSTRとする *} if Pos('|',tmpSTR)>0 then Inc(c); end; gRowCnt := c; gColCnt := c; {* ビンゴカードの大きさを変更する *} SizeChange(gColCnt, gRowCnt); {* wrkSTR の大きさを変更する *} SetLength(wrkSTR,gRowCnt); {* wrkSTRに行を読む込む *} ReSet(aTXT); c:=0; while not EOF(aTXT) do begin Readln(aTXT, tmpSTR); if Pos('|', tmpSTR)>0 then begin wrkSTR[c] := tmpSTR; Inc(c); end; end; {* gCellの大きさを変更する *} SetLength(gCell, gColCnt, gRowCnt); {* gCellにwrkSTRを代入する *} for i:=0 to gColCnt-1 do begin for j:=0 to gRowCnt-1 do begin gCell[i,j] := Copy(wrkSTR[j],2+i*5,4); end; end; finally gDrawFlag := True; DrawGrid1.Repaint; CloseFile(aTXT); end; end; procedure TForm1.SpeedButton2Click(Sender: TObject); {* 現在の状態を保存する *} var aTXT : TextFile; i, j : integer; wrkSTR : string; const dSTR = '|'; begin if SaveDialog1.Execute then try AssignFile(aTXT, SaveDialog1.FileName); ReWrite(aTXT); WriteLn(aTXT, dlnSTR(gRowCnt)); for j:=0 to gRowCnt-1 do begin wrkSTR := ''; for i:=0 to gColCnt-1 do begin wrkSTR := wrkSTR + dSTR + gCell[i,j]; end; wrkSTR := wrkSTR + dSTR; WriteLn(aTXT, wrkSTR); WriteLn(aTXT, dlnSTR(gRowCnt)); end; finally gDrawFlag := True; CloseFile(aTXT); end; end; procedure TForm1.SpeedButton3Click(Sender: TObject); {* Editの数字を調べる *} var tmpSTR : string; wrkSTR : string; cntFIG : integer; i, j, k : integer; begin tmpSTR := Edit1.Text; tmpSTR := ','+tmpSTR+','; cntFIG := mCount(',', tmpSTR)-1; StatusBar1.Panels[0].Text := 'checked '; StatusBar1.Panels[1].Text := 'hit '; for k:=0 to cntFIG-1 do begin wrkSTR := nthCopy(',', tmpSTR, k+1); StatusBar1.Panels[0].Text := StatusBar1.Panels[0].Text + ' ' + wrkSTR; for i:=0 to gColCnt-1 do begin for j:=0 to gRowCnt-1 do begin if Trim(wrkSTR)=Trim(gCell[i,j]) then begin gCell[i,j] := ' ** '; CellMark(i,j,clRed,clBlack,''); StatusBar1.Panels[1].Text := StatusBar1.Panels[1].Text + ' '+ wrkSTR; end end; end; end; gDrawFlag := True; end; function dlnSTR(aRow : integer) : string; {* 区切り行を作成する(長さがaRow個単位) *} var i : integer; const dSTR = '+'; begin Result := dSTR; for i:=0 to aRow-1 do begin Result := Result + '----+'; end; end; function nthCopy(const aBP, aSTR : string ; nth : integer) : string; {* 区切り文字列aBPで囲まれたnth番目の文字列を返す *} var c, mCnt, i : integer; sp, ep : integer; begin mCnt := Length(aSTR); {* spを求める *} c := 0; i := 1; while (c < nth) and (i <= mCnt) do begin if aSTR[i] = aBP then Inc(c); Inc(i); end; sp := i ; {* ep を求める*} c := 0; i := 1; while (c < (nth + 1)) and (i <= mCnt) do begin if aSTR[i] = aBP then Inc(c); Inc(i); end; ep := i - 2; Result := Copy(aSTR, sp , ep - sp + 1); end; function mCount(const aBP, aSTR : string) : integer; {* 文字列aSTRの中に区切り文字列aBPが何個含まれているか計算する *} var i : integer; mCnt : integer; begin Result := 0; mCnt := Length(aSTR); for i:=1 to mCnt do begin if aSTR[i] = aBP then Inc(Result); end; end; end.