プログラミングⅡ 第3回 TicTacToe のバージョンアップ TicTacToe4 コンピュータ VS 人 の対戦型にする 先手をどちらにするか訊いて決める コンピュータの手をランダムに決める メインルーチンを変更 今までメインルーチンのすぐ上にあった変数宣言を, 最上部の他の変数宣言と一緒にまとめる. コンピュータが先手(○)か後手(×)かを示す変数 Computer : TPlayer を追加する. var Ban Tesuu Teban Basyo Katta Computer : : : : : : TBan; Integer; TPlayer; TBangou; Boolean; TPlayer; // コンピュータ(が○か×か) メインルーチンを変更 begin {Main} SenteWoKimeru; BanSyokika; BanWoKaku; Tesuu := 0; Teban := Batu; repeat Inc(Tesuu); WriteLn; Write(Tesuu, '手目: '); TebanKoutai(Teban); if Teban = Computer then Basyo := ComputerNoTe else Basyo := OkuBasyo; Ban[Basyo] := Teban; BanWoKaku; Katta := Naranda(Basyo); until (Tesuu = 9) or Katta; if Katta then WriteLn('勝ちました') else WriteLn('引き分けです'); ReadLn; end. // どちらが先手か決める // 手数を0に初期化する // 手番を×(後手)とする // 手数を+1する // 手番を交代する // // // // // 置く場所をコンピュータが決める 置く場所を訊く 置く 盤を書く 勝ったかどうか調べる 注意 これ以降,プロシージャやファンクションを追加 していきますが,どこに書くか考えて正しい位 置に追加してください. プロシージャ SenteWoKimeru コンピュータを先手にするか後手にするか,人に選んでもらう. 後手を選ぶことが多いので, 先手を選ぶときは y 後手を選ぶときは y以外 を入れればよいようにする. procedure SenteWoKimeru; (* どちらが先手か決める *) var YesNo : String; begin Write('コンピュータを先手(○)にしますか [y(Yes) / y以外(No)] ? '); ReadLn(YesNo); if YesNo = 'y' then Computer := Maru else Computer := Batu; end; {SenteWoKimeru} ファンクション ComputerNoTe コンピュータが置く場所を決める. とりあえず,ランダムに空桝を選ぶ. function ComputerNoTe : TBangou; {置く場所をコンピュータが選ぶ} begin Result := DetarameNiErabu; end; {ComputerNoTe} ファンクション DetarameNiErabu 1~n(残っている空桝の個数) の乱数をrとする. 1番目から桝を調べていき,空ならrを1減らす. rが0になったときの桝を選ぶ. function DetarameNiErabu : TBangou; {でたらめに選ぶ} var R,K : TBangou; begin R := Random(10-Tesuu)+1; K := 0; repeat Inc(K); if Ban[K] = Kara then Dec(R); until R = 0; Result := K; end; {DetarameNiErabu} // r=1~空枡の個数 の乱数 // 空枡のうちr番目を選ぼう // k=0に初期設定する // kを1増やす(次の枡を調べる) // 空枡だったらrを1減らす // r=0になるまで繰り返す // Ban[k]がr番目の空枡 ファンクション DetarameNiErabu 前ページのプログラムの中で,変数 K,R の値が0にな ることがあります. 0は実際の番号ではないのですが,TBangou に含め ることにします. type TBangou TYouso TBan TPlayer = = = = 0..9; (Kara,Maru,Batu); array [1..9] of TYouso; Maru..Batu; // // // // 枡につけた通し番号,0は便宜上 枡の要素=(空,○,×) 盤=9つの枡(3×3) 選手=(○,×) 実行する コンピュータはでたらめに置いていくので弱いでしょう. ところで何回やってもコンピュータは同じ置き方をするのに気が つきましたか. 「でたらめ」というのに変ですね. いつも同じ乱数系列を使うからなのです. 乱数系列を変える Randomize をメインルーチンに追加します. begin {Main} Randomize; SenteWoKimeru; // どちらが先手か決める TicTacToe5 3つ並ぶ場合を考慮して決める 優先度 1. 自分のこまが3つ並ぶように置ける場所があ ればそこを選ぶ-勝つ手 2. 相手のこまが3つ並ぶように置ける場所があ ればそこを選ぶ-負けない手 3. ランダムに選ぶ プロシージャ TebanKoutai 配列定数 Aite を使って簡単にする. 定数を定義する. type TBangou TYouso TBan TPlayer = = = = 0..9; // (Kara,Maru,Batu); // array [TBangou] of TYouso; // Maru..Batu; // const Aite : array [TPlayer] of TPlayer = (Batu,Maru); 枡の通し番号,0は特殊 枡の要素=(空,○,×) 盤=9つの枡(3×3) 選手=(○,×) // 配列定数 // Aite[Maru]=Batu, // Aite[Batu]=Maru プロシージャ TebanKoutai 配列定数 Aite を使って簡単にする. TebanKoutai を変更する procedure TebanKoutai(var Player : TPlayer); {手番を交代する} begin Player := Aite[Player]; if Player = Batu then WriteLn('×の番です') else WriteLn('○の番です'); end; {TebanKoutai} ファンクション ComputerNoTe 善い手を選ぶようにする. function ComputerNoTe : TBangou; {置く場所をコンピュータが選ぶ} var YoiBasyo : TBangou; begin YoiBasyo := YoiBasyoWoSagasu; if YoiBasyo > 0 then Result := YoiBasyo else Result := DetarameNiErabu; end; {ComputerNoTe} ファンクション YoiBasyoWoSagasu 勝つあるいは負けを防ぐ場所を探して, あったらその場所を答えます. なかったら0を答えます. function YoiBasyoWoSagasu : TBangou; {善い場所を探す} var Katu : TBangou; // 自分のこまが3つ並ぶ場所 Makenai : TBangou; // 相手のこまが3つ並ぶ場所(を防ぐ) Basyo : TBangou; begin Katu := 0; Makenai := 0; Basyo := 0; repeat Inc(Basyo); if Ban[Basyo] = Kara then begin Ban[Basyo] := Computer; // 自分のこまを置いてみる if Naranda(Basyo) // 3つ並べば勝ち then Katu := Basyo; Ban[Basyo] := Aite[Computer]; // 相手のこまを置いてみる if Naranda(Basyo) // 3つ並べば負け then Makenai := Basyo; Ban[Basyo] := Kara; // 元に戻す end; until (Basyo = 9) or (Katu > 0); // 勝つ手が見つかれば終わる if Katu > 0 then Result := Katu else Result := Makenai; // 負けない手もなければ0 end; {YoiBasyoWoSagasu} 実行 このゲームは両者が最善手を選べば引き分け になります. しかし,コンピュータは最善手を選ぶようには なっていないので,人が勝つ可能性がありま す. さあ,あなたはどのくらい勝てるでしょうか. まさか負けることはないでしょうね. 問題 繰り返し実行できるように,メインルーチンを変 更してください. 1回ゲームが終わったら 終了しますか [y(Yes) / y以外(No)] ? と訊いて,y以外を入れたら繰り返すようにしてく ださい. 問題 勝負がついたとき(引き分けでないとき),今は, 勝ちました と,主語(手番の選手)を省略して書きますが, あなたが勝ちました または あなたが負けました と,人を主語にして書くように変更してください.
© Copyright 2024 ExpyDoc