畠山くんのdelphi教室
■ このスレッドは過去ログ倉庫に格納されています
0001畠山 幸助
NGNGまずはテキストエディターなどからよろしくお願いします。
あ、ほんとに初心者なのでやさしくしてくださいね♪
ゆくゆくはファイル操作などまでできるようになりたいです。
0111デフォルトの名無しさん
NGNG0112デフォルトの名無しさん
NGNG0113デフォルトの名無しさん
NGNG0114デフォルトの名無しさん
NGNG0115鼻山
NGNGまずは、型の宣言だな。やっぱりな。抽象化が必要だよな?
じゃ、駒からだ。
type TKOMA=(koNone,koWhite,koBlack);
どうだこの素晴らしい抽象化。 何も置いてないときは koNone、白黒は、koWhiteに koBllackだよ。
これはもう完璧な型宣言だろう。だからinterface部、 uses のすぐ後に書いてやろう。
0116鼻山
NGNGこれはもう、配列しかないだろ? な? じゃあこうだろ?
type TBAN =array [0..7,0..7]of TKOMA;
盤は駒が8x8に置けるんだからこれしかないよな?
0117デフォルトの名無しさん
NGNG沈め!沈め!
0118鼻山
NGNG次は、表示だ。 Delphiには DrawGridって便利なコンポーネントがある。
これを貼り付けて、 そうだな。サイズが変更されても追従するように、
初期化はフォームのOnResizeでやろう。
procedure TForm1.FormResize(Sender: TObject);
begin
with DrawGrid1 do begin
ScrollBars:=ssNone;
ColCount:=8;
RowCount:=8;
DefaultColWidth:=Width div ColCount;
DefaultRowHeight:=Height div RowCount;
FixedCols:=0;
FixedRows:=0;
end;
end;
よし、実行っと・・・・ありゃ? ssNoneが無いって?
ヘルプ出すと StdCtrls にあるのか 何で StdCtrlsが自動的にusesされないんだ?
まあいいや、 uses に StdCtrlsを追加すりゃいいだけだろ。よしよし、とりあえず枠は表示されたと。
0119鼻山
NGNGまあ、メソッドの方が格好いいかもしれないけど、とりあえず手続きでやって必要になってから変えりゃいいや。
procedure InitBAN(var BAN:TBAN);
var x,y:Integer;
begin
for x:=Low(BAN) to High(BAN) do
for y:=Low(BAN[x]) to High(BAN[x]) do
BAN[x,y]:=koNone;
BAN[3,3]:=koWhite;
BAN[4,4]:=koWhite;
BAN[3,4]:=koBlack;
BAN[4,3]:=koBlack;
end;
こんなもんだな。
これをフォームのOnCreateで呼び出せばいいだろ。
procedure TForm1.FormCreate(Sender: TObject);
begin
InitBAN(BAN);
end;
0120鼻山
NGNG一つあればいいんだから、グローバル変数でもいいけど、
とりあえず、これもフォームの public部でいいか。
ここに置く時はvar は不要だから、
TForm1 = class(TForm)
DrawGrid1: TDrawGrid;
procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
public
BAN:TBAN;
end;
0121鼻山
NGNGこれはDrawGridのOnDrawCell に書けばいい筈。
えい、まずは力技で、
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
DrawGrid1 .Canvas.Pen.Color:=clBlack;
case BAN[ACol,ARow] of
koWhite:DrawGrid1. Canvas.Brush.Color:=clWhite;
koBlack:DrawGrid1 .Canvas.Brush.Color:=clBlack;
end;
case BAN[ACol,ARow] of
koWhite,koBlack: DrawGrid1.Canvas.Ellipse(Rect);
end;
end;
これでどうだ。とりあえず表示されたぞ。
0122鼻山
NGNG自動的に駒も描画されやがる。
ちくしょう、可愛いやつめ。
0123鼻山
NGNGその為には、置けるかどうか検査する処理が必要だぞ。
それは関数だな。 引数は盤と駒と、その位置だから
function okeruka(const BAN:TBAN;K:TKOMA;x,y:Integer)
で、帰り値は 論理型でいいだろ。
0124鼻山
NGNGどういう場合に駒が置けるか? どういう場合に駒が置けないのか?
まずは、既にに駒があったら置けないな
盤のx,y位置が空である事が条件だ。
Result:=BAN[x,y]=koNone; if not Result then exit;
って事だな。
それから、相手の駒を挟めないと置けない。
これはチョット考えないといけないぞ。
0125鼻山
NGNGまず相手の駒を返す関数を作ろうか。
function AiteNoKoma(K:TKOMA):TKOMA;
begin
result:=koNone;
case K of
koWhite: Result:=koBlack;
koBlack: Result:=koWhite;
end;
end;
0126鼻山
NGNG1、最初の隣が相手の駒でないとダメ
2、次の駒が相手の駒ならさらに検索、空白か盤を超えたらダメ
3、自分の駒が見つかれば置ける
って感じで調べたらいい。
8方向は ステップ dx,dyで表現、位置はx,yで表現しよう。
0127鼻山
NGNG関数 okerukaはこうだ。
置ける場所があって、置ける駒であって、8方向どこかで相手を挟める事
begin
Result:=BAN[x,y]=koNone; if not Result then exit;
Result:=K<>koNone; if not Result then exit;
Result:=Check( 0, 1,x,y); if Result then exit;
Result:=Check( 1, 0,x,y); if Result then exit;
Result:=Check( 0,-1,x,y); if Result then exit;
Result:=Check(-1, 0,x,y); if Result then exit;
Result:=Check( 1, 1,x,y); if Result then exit;
Result:=Check( 1,-1,x,y); if Result then exit;
Result:=Check(-1,-1,x,y); if Result then exit;
Result:=Check(-1, 1,x,y);
end;
2つの条件は満たさなければならないからif NOT 、8つの条件はどれか一つだだから if だ。
0128鼻山
NGNG駒の隣と、その後では別けなきゃいけないから、さらに関数内関数を呼ぼう。
function okeruka(const BAN:TBAN;K:TKOMA;x,y:Integer):boolean;
function Check(dx,dy,x,y:Integer):boolean;
function Check1:boolean;
begin
x:=x+dx;
y:=y+dy;
Result:= x >=LOW(BAN); if not Result then exit;
Result:= x <=HIGH(BAN); if not Result then exit;
Result:= y >=LOW(BAN[x]); if not Result then exit;
Result:= y <=HIGH(BAN[x]); if not Result then exit;
Result:= BAN[x,y]=AiteNoKoma(K) ;
end;
function Check2:boolean;
begin
x:=x+dx;
y:=y+dy;
Result:= x >=LOW(BAN); if not Result then exit;
Result:= x <=HIGH(BAN); if not Result then exit;
Result:= y >=LOW(BAN[x]); if not Result then exit;
Result:= y <=HIGH(BAN[x]); if not Result then exit;
if BAN[x,y]=AiteNoKoma(K) then Result:= Check2;
result:= BAN[x,y]=K;
end;
begin
Result:=Check1; if not Result then exit;
Result:=Check2;
end;
0129鼻山
NGNG0130デフォルトの名無しさん
NGNG面白かったよ。いい意味で
0131デフォルトの名無しさん
NGNGレスつけんなよ
0132鼻山
NGNGとりあえず、もう少しオセロらしく動くようにしてから止める事にする。
まずは、>>128は同じ事をCheclk1 Check2でやってるんでそれをマトメテおこう。
0133鼻山
NGNGfunction Check(dx,dy,x,y:Integer):boolean;
function Check0:boolean;
begin x:=x+dx; y:=y+dy;
Result:= x >=LOW(BAN); if not Result then exit;
Result:= x <=HIGH(BAN); if not Result then exit;
Result:= y >=LOW(BAN[x]); if not Result then exit;
Result:= y <=HIGH(BAN[x]); if not Result then exit;
end;
function Check1:boolean;
begin Result:= Check0; if not Result then exit;
Result:= BAN[x,y]=AiteNoKoma(K) ;
end;
function Check2:boolean;
begin Result:= Check0; if not Result then exit;
if BAN[x,y]=AiteNoKoma(K)
then Result:= Check2
else result:= BAN[x,y]=K;
end;
begin Result:=Check1; if not Result then exit; Result:=Check2;
end;
0134鼻山
NGNGbegin
Result:=BAN[x,y]=koNone; if not Result then exit;
Result:=K<>koNone; if not Result then exit;
Result:=Check( 0, 1,x,y); if Result then exit;
Result:=Check( 1, 0,x,y); if Result then exit;
Result:=Check( 0,-1,x,y); if Result then exit;
Result:=Check(-1, 0,x,y); if Result then exit;
Result:=Check( 1, 1,x,y); if Result then exit;
Result:=Check( 1,-1,x,y); if Result then exit;
Result:=Check(-1,-1,x,y); if Result then exit;
Result:=Check(-1, 1,x,y);
end;
0135鼻山
NGNGfunction KomaWoOku(var BAN:TBAN;var K:TKOMA;x,y:Integer):boolean;
今度はBAN K は参照型って奴にした。 これで、呼び出した方の変数が変更される筈だ。
置けたら置いて、相手の手番にして終わるという処理をする為には K も参照型にしなくちゃな。
begin
Result:=False;
if okeruka(BAN,K,x,y) then begin
Result:=Flip( 0, 1,x,y);
Result:=Flip( 1, 0,x,y);
Result:=Flip( 0,-1,x,y);
Result:=Flip(-1, 0,x,y);
Result:=Flip( 1, 1,x,y);
Result:=Flip( 1,-1,x,y);
Result:=Flip(-1,-1,x,y);
Result:=Flip(-1, 1,x,y);
BAN[x,y]:=K;
K:=AiteNoKoma(K);
Result:=True;
end;
end;
Flipは駒をヒックリ返す処理のつもりだ。
0136鼻山
NGNGこの駒をヒックリ返す処理が問題か。
前の置けるかどうかの判定で、再帰を使ったけど、判定に成功したら再帰で
帰ってくる時のループを使えば簡単じゃないかな?
判定に成功したらisOKって変数をTrueにしてやればいい。
って事で、判定ルーチンからコピペしてくる。
0137鼻山
NGNGvar isOK:boolean;
function Check0:boolean;
begin
x:=x+dx; y:=y+dy;
Result:= x >=LOW(BAN); if not Result then exit;
Result:= x <=HIGH(BAN); if not Result then exit;
Result:= y >=LOW(BAN[x]); if not Result then exit;
Result:= y <=HIGH(BAN[x]); if not Result then exit;
end;
function Check1:boolean;
begin Check0; if not Result then exit;
Result:= BAN[x,y]=AiteNoKoma(K) ;
end;
procedure Flip2;
begin
if not Check0 then exit;
if BAN[x,y]=AiteNoKoma(K)
then Flip2
else isOK:= BAN[x,y]=K;
if isOK then begin
x:=x-dx;
y:=y-dy;
BAN[x,y]:=K;
end;
end;
begin
isOK:=false;
Result:=Check1; if not Result then exit;
Flip2;
end;
0138鼻山
NGNGで、それから帰る時に isOKがTrueだったら 座標を戻して、その駒を自分の駒にしながら帰れば、
おお、ちゃんと勘定が合う。
・・・・当然か。
0139鼻山
NGNGまあとりあえず、OnSelectCellに入れちゃえ。
procedure TForm1.DrawGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
begin
KomaWoOku(BAN,TEBAN, ACol, ARow);
DrawGrid1.Invalidate;
end;
ヘヘ、とりあえず動いてるな。 満足だ。
次はパスだな。 置けない場合にパスが出来なくちゃな。
それには、どこにも置けないって判定が必要だな。
0140鼻山
NGNG簡単にやっつけるには、盤を全部 okeruka でチェックすりゃいいんだろうが、
それって格好悪くないか?
・・・
っと思ったが、実行しても大した時間かからんな。 これでいいのか?
いいんだよな?
0141鼻山
NGNGfunction isPass(const BAN:TBAN;K:TKOMA):boolean;
var x,y:Integer;
begin
Result:=false;
for x:=Low(BAN) to High(BAN) do
for y:=Low(BAN[x]) to High(BAN[x]) do
if okeruka(BAN,K,x,y) then
exit;
Result:=True;
end;
こりゃ、なんかテストする方法考えないとダメだな。
0142デフォルトの名無しさん
NGNG0143デフォルトの名無しさん
NGNGよくみたら「鼻」山だ!
0144デフォルトの名無しさん
NGNG0145デフォルトの名無しさん
NGNG期待あげ
0146鼻山
NGNGオセロプログラムのテストを、そのプログラム自身にやらせるにはどうやったらいいか
考えてたらそっちが面白くなったというか、行き詰まったというか・・・
0147デフォルトの名無しさん
NGNG>考えてたらそっちが面白くなったというか、行き詰まったというか・・・
・・・ん??
白黒ハッキリしてくださいよ!
ガンガレ期待してます
0148デフォルトの名無しさん
NGNGうまい
0149デフォルトの名無しさん
NGNGうまい
0150デフォルトの名無しさん
NGNGうまい
0153デフォルトの名無しさん
NGNG期待あげ
0154デフォルトの名無しさん
NGNG個人的にはCPUのロジックの手順が早く知りたいな
0155Socket775
NGNG付録のチュートリアルの内容が、そのものズバリ
「テキストエディタの作り方」だ。
説明の通りやってけば誰でもできる。
0156デフォルトの名無しさん
NGNGそのチュートリアルはPersonal版では進められないわけだが。
0157デフォルトの名無しさん
NGNG先に日本語勉強しような
0158デフォルトの名無しさん
NGNG0159デフォルトの名無しさん
NGNG0160デフォルトの名無しさん
NGNG0161デフォルトの名無しさん
NGNGワロタ
■ このスレッドは過去ログ倉庫に格納されています