プログラミングⅡ 第2回 第1回(プログラミングⅠの復習) の解説 プログラムの作り方 いきなり完全版を作るのではなく,だんだんふく らませていきます. TicTacToe1 プログラムの作り方 いきなり完全版を作るのではなく,だんだんふく らませていく. TicTacToe1 TicTacToe2 プログラムの作り方 いきなり完全版を作るのではなく,だんだんふく らませていく. TicTacToe1 TicTacToe2 TicTacToe3 盤のデータ構造 2次元配列で表す場合 type TBan = array [1..3,1..3] of ~; 1,1 1,2 1,3 2,1 2,2 2,3 3,1 3,2 3,3 盤のデータ構造 1次元配列で表す場合 type TBan = array [1..9] of ~; 1 2 3 4 5 6 7 8 9 盤のデータ構造 今回は1次元配列を使うことにします. 盤の枡を指す番号は 1~9 で,integer 型のほん の一部に過ぎません. 一部の範囲だけを動くデータのために,固有の 型名をつけると,わかりやすくなります. type TBangou = 1..9; これを部分範囲型といいます. 盤のデータ構造 から 盤の枡の状態は,空,○,× の3つあります. それぞれを 0,1,2 で表すことにして type TYouso = 0..2; としてもよいのですが, 名前で表すとわかりやすくなります. type TYouso = (Kara,Maru,Batu); これを列挙型といいます. 盤のデータ構造 合わせて次のようになります. type TBangou = 1..9; TYouso = (Kara,Maru,Batu); TBan = array [TBangou] of TYouso; var Ban : TBan; 盤の表示 枠の線を +-|を使って書きます. +-+-+-+ | |×| | +-+-+-+ | |○| | +-+-+-+ |○| | | +-+-+-+ 1行目 2行目 3行目 4行目 5行目 6行目 7行目 盤の表示 9つの空の枡を一直線に書くのは簡単です. for N := 1 to 9 do begin Write(‘|’); //左の線 Write(‘ ’); end; WriteLn(‘|’); //最後の線 実行すると | | | | | | | | | | 盤の表示 空白の代わりにN番目の要素を書くようにします. for N := 1 to 9 do begin Write(‘|’); YousoWoKaku(N); end; WriteLn(‘|’); 実行すると | |×| | |○| |○| | | 盤の表示 3枡書いたら右の線を書いて改行 するようにします. for N := 1 to 9 do begin Write(‘|’); YousoWoKaku(N); if N mod 3 = 0 then WriteLn(‘|’); end; 実行すると | |×| | |○| |○| | | | | 盤の表示 横の線を書くようにします. WriteLn(‘+-+-+-+’); for N := 1 to 9 do begin Write(‘|’); YousoWoKaku(N); if N mod 3 = 0 then begin WriteLn(‘|’); WriteLn(‘+-+-+-+’); end; end; 実行すると +-+-+-+ | |×| | +-+-+-+ | |○| | +-+-+-+ |○| | | +-+-+-+ 要素を書く 要素は3種類あるので,場合分け(case分岐) を使います. case Ban[N] of Kara : Write(‘ ’); Maru : Write(‘○’); Batu : Write(‘×’); end; どこに置くか 手番のプレイヤーに,どこに置くか訊きます. 正しい番号を入れるまで,繰り返し訊かないと いけません. どこに置くか repeatループを使った例 repeat Write(‘どこに置きますか [1~9] ? ’); ReadLn(N); until (N in [1..9]) and (Ban[N] = Kara); Result := N; 実行すると どこに置きますか [1~9] ? 0 どこに置きますか [1~9] ? どこに置くか whileループを使った例 Write(‘どこに置きますか [1~9] ? ’); ReadLn(N); while not (N in [1..9]) or (Ban[N] <> Kara) do begin WriteLn(‘そこは置けません’); Write(‘どこに置きますか [1~9] ? ’); ReadLn(N); end; Result := N; 実行すると どこに置きますか [1~9] ? 0 そこは置けません どこに置きますか [1~9] ? 集合を使うと便利 整数Nが 1~9 の数であるかの判定. 不等式を使うと (1 <= N) and (N <= 9) 集合を使うと N in [1..9] これは,数学での式 N ∈ {1,2,3,4,5,6,7,8,9} と同じ意味です. 集合を使うと便利 「M月が大の月(31日まである月)か」を 不等式で書くと (M=1) or (M=3) or (M=5) or (M=7) or (M=8) or (M=10) or (M=12) ですが,集合で書くと M in [1,3,5,7,8,10,12] と簡潔でわかりやすくなります. 集合を使うと便利 「M月とN月が両方とも大の月か」を 不等式で書くと,とても長くなります. 集合で書くと [M,N] <= [1,3,5,7,8,10,12] と簡単です. これは,数学での式 {M,N}⊆{1,3,5,7,8,10,12} と同じ意味です. 繰り返しの条件 repeatループでは終了条件を書き, whileループでは継続条件を書きます. ちょうど反対(否定)になります. repeat ~ until (N in [1..9]) and (Ban[N] = Kara); while not (N in [1..9]) or (Ban[N] <> Kara) do begin ~ end; ゲームの終了条件 とりあえず,勝敗は気にしないで,すべての 枡が埋まるまで(9手)続けるとします. Tesuu := 0; repeat Inc(Tesuu); // Tesuu := Tesuu+1; と同じ ~ until Tesuu = 9; Boolean(論理値) 次のプログラムを実行してみてください. var Tesuu : Integer; begin {Main} Tesuu := 0; repeat Inc(Tesuu); WriteLn(Tesuu:2, (Tesuu=9):6); until Tesuu=9; ReadLn; end. Boolean(論理値) 実行しましたか. Tesuu の値は Tesuu=9 の値は 1 2 …9 9=1 9=2 … 9=9 で,整数値(Integer)です. すなわち False False … True で,論理値(Boolean)です. ゲームの終了条件 勝敗は,今○か×を置いたことによって,それ が3つ並んだら「勝った」とわかります. 変数 Katta : Boolean を使うことにします. Tesuu := 0; repeat Inc(Tesuu); ~ Katta := Naranda(Basyo); until (Tesuu = 9) or Katta; ゲームの終了条件 function Naranda(N : TBangou) : Boolean; は,今 Ban[N] に○か×を置いたところで,それ が3つ並んだか調べる論理値関数です. Nによって並ぶ筋が異なるので場合分けして調べ ます. case N of 1 : Onaji(1,2,3) or Onaji(1,4,7) or Onaji(1,5,9); ~ end; ゲームの終了条件 関数 Naranda を完成させてください. 問題 procedure TebanKoutai(var Player : TPlayer); は case分岐を使っていますが,二分岐なので if分岐でも書けます. if分岐に書き換えてください. 問題 盤の線を罫線(┌ ─ など)を使うともっときれいに 書けます. ┌─┬─┬─┐ | |×| | ├─┼─┼─┤ | |○| | ├─┼─┼─┤ |○| | | └─┴─┴─┘ 1行目 2行目 3行目 4行目 5行目 6行目 7行目 罫線を使うように改良してください. 「けいせん」を変換していろいろな線が選べます. 7行目が3,5行目と異なるので,ちょっと工夫しないと いけません.
© Copyright 2025 ExpyDoc