LoginSignup
0
0

More than 3 years have passed since last update.

Tick-Tack-Toe(どう書く)

Last updated at Posted at 2020-11-29

問題

http://nabetani.sakura.ne.jp/hena/1/

三目並べ( tick-tack-toe )の手を入力とし、勝敗を出力する。

  • 先攻がo、後攻がx
  • すでに打ってある場所に打った場合、反則負け。 x が反則をした場合、「Foul : o won.」と出力
  • 縦横斜めのいずれかで一列揃ったら、揃えた方の勝ち。 x が揃えた場合、「x won.」と出力
  • 9マス埋まっても揃わなかったら引き分け。 「Draw game.」と出力
  • 勝敗が決した後の手は無視する
  • 入力文字列は、先攻から順に打った位置を示す。盤上の位置と数の対応は下表を参照。
  • 入力文字列が「91593」の場合、「oが9の位置、xが1の位置、oが5の位置、xが9の位置→xの反則負け(最後の3は無視)」となる。
  • 以下の様なケースは考慮しなくてよい。 入力が 1〜9 以外の文字を含んでいる。 入力が不足していて、ゲームの勝敗が決まらない。
1 2 3
4 5 6
7 8 9

コード

Ruby
class TickTackToe
  WinPattern = %W(123 456 789 147 258 369 159 357)
  def initialize(input)
    @input = input.chars.map(&:to_i)
    @field = Array.new(10)
    @turn = 0    #o
    @ptns = WinPattern.map {|pt| pt.chars.map(&:to_i)}
  end

  def solve
    @input.each do |i|
      if @field[i]
        return "Foul : #{output_turn(false)} won."
      else
        @field[i] = @turn
        if settle?
          return "#{output_turn} won."
        elsif @field[1..9].all?
          return "Draw game."  
        else
          @turn = 1 - @turn
        end
      end
    end
  end

  def settle?
    @ptns.any? do |pt|
      a = pt.map {|i| @field[i]}.join
      a == "000" || a == "111"
    end
  end

  def output_turn(t = true)
    %W(o x)[t ? @turn : 1 - @turn]
  end

  def self.solve(input)
    new(input).solve
  end
end


if $0 == __FILE__
  data = [79538246, 35497162193, 61978543, 254961323121, 6134278187, 4319581,
   9625663381, 7975662, 2368799597, 18652368566, 965715, 38745796, 371929,
   758698769, 42683953, 618843927, 36535224, 882973, 653675681, 9729934662,
   972651483927, 5439126787, 142583697, 42198637563, 657391482]

  data.each do |d|
    puts TickTackToe.solve(d.to_s)
  end
end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0