program TicTacToe3; {チックタックトウ(○×ゲーム)} {学生証番号 氏名} {$APPTYPE CONSOLE} uses SysUtils; type TBangou = 1..9; // 部分範囲型 // 3×3の枡につけた1〜9の通し番号 TYouso = (Kara,Maru,Batu); // 列挙型 // 枡の要素=(空,○,×) TBan = array [TBangou] of TYouso; // 配列 // 盤=9つの枡(3×3) TPlayer = Maru..Batu; // 部分範囲型 // 選手=(○,×) var Ban : TBan; procedure BanSyokika; {盤を初期化する} var N : TBangou; begin for N := 1 to 9 do Ban[N] := Kara; end; {BanSyokika} procedure YousoWoKaku(N : TBangou); {Ban[N]の要素を書く} begin case Ban[N] of Maru : Write('○':2); Batu : Write('×':2); Kara : Write(' ':2); end; end; {YousoWoKaku} procedure BanWoKaku; {盤を書く} var N : TBangou; begin WriteLn('+−+−+−+'); for N := 1 to 9 do begin Write('|'); YousoWoKaku(N); if N mod 3 = 0 then begin WriteLn('|'); WriteLn('+−+−+−+'); end; end; end; {BanWoKaku} function OkuBasyo : TBangou; {どこに置くか人に訊く} var N : TBangou; begin 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; end; {OkuBasyo} procedure TebanKoutai(var Player : TPlayer); {手番を交代する} begin case Player of Maru : begin Player := Batu; WriteLn('×の番です'); end; Batu : begin Player := Maru; WriteLn('○の番です'); end; end; end; {TebanKoutai} function Onaji(I,J,K : TBangou) : Boolean; {Ban[I],Ban[J],Ban[K] に同じマークが入っているか調べる} begin Result := (Ban[J] = Ban[I]) and (Ban[K] = Ban[I]); end; {Onaji} function Naranda(N : TBangou) : Boolean; {N 番を含む列に同じマークが3つ並んだか調べる} begin case N of 1 : Result := Onaji(1,2,3) or Onaji(1,4,7) or Onaji(1,5,9); 2 : Result := Onaji(1,2,3) or Onaji(2,5,8); 3 : Result := Onaji(1,2,3) or Onaji(3,6,9) or Onaji(3,5,7); 4 : Result := Onaji(4,5,6) or Onaji(1,4,7); 5 : Result := Onaji(4,5,6) or Onaji(2,5,8) or Onaji(1,5,9) or Onaji(3,5,7); 6 : Result := Onaji(4,5,6) or Onaji(3,6,9); 7 : Result := Onaji(7,8,9) or Onaji(1,4,7) or Onaji(3,5,7); 8 : Result := Onaji(7,8,9) or Onaji(2,5,8); 9 : Result := Onaji(7,8,9) or Onaji(3,6,9) or Onaji(1,5,9); end; end; {Naranda} var Tesuu : Integer; Teban : TPlayer; Basyo : TBangou; Katta : Boolean; begin BanSyokika; BanWoKaku; Tesuu := 0; // 手数を0に初期化する Teban := Batu; // 手番を×(後手)とする repeat Inc(Tesuu); // 手数を+1する WriteLn; Write(Tesuu, '手目: '); TebanKoutai(Teban); // 手番を交代する Basyo := OkuBasyo; // 置く場所を訊く Ban[Basyo] := Teban; // 置く BanWoKaku; // 盤を書く Katta := Naranda(Basyo); // 勝ったかどうか調べる until (Tesuu = 9) or Katta; if Katta then WriteLn('勝ちました') else WriteLn('引き分けです'); ReadLn; end.