読者です 読者をやめる 読者になる 読者になる

TomoProgの技術書

底辺プログラマーが達人プログラマーになるまで

Rubyでオセロを作ってみた

皆さん
こんにちは、こんばんは
TomoProgです。

今回はRubyを使ってオセロを作ってみたので、
その工程を書いておきます。

それでは頑張っていきましょう。

オセロの手順を整理する

まずはオセロを作る前に簡単にオセロの手順を整理しておきます。

  1. 盤面を表示
  2. 石を置く
  3. 裏返す
  4. 相手のターンに移る

大体こんな手順でしょう。
この手順をお互いが石が置けなくなるまで延々と繰り返すようにすれば、オセロを作れそうです。

盤面の表示

手順も頭に入れたので、早速作っていきます。

まずは、盤面の表示ですが、盤面がないと表示も出来ないので盤面を作ります。

オセロの盤面である8×8のマスを作成する関数です。

BLANK = "" # 置き石無し
BLACK = "" # 黒
WHITE = "" # 白
WALL  = "" # 終端
MAX_ROW = 10 # 行
MAX_COL = 10 # 列

def make_field
  field = []

  # 置き石無しの状態に初期化
  MAX_ROW.times do
    row = []
    MAX_COL.times do
      row << BLANK
    end
    field << row
  end

  # 壁を作る
  0.upto(MAX_COL - 1) do |i|
    field[0][i] = WALL
    field[MAX_ROW - 1][i] = WALL
  end
  0.upto(MAX_ROW - 1) do |i|
    field[i][0] = WALL
    field[i][MAX_COL - 1] = WALL
  end

  # 中央に石を置く
  field[4][4] = WHITE
  field[5][5] = WHITE
  field[4][5] = BLACK
  field[5][4] = BLACK
end

あとは作った盤面(field変数)を表示するだけです。
field変数を一行ずつ表示することで、盤面を表示します。

def print_field
  for i in 0..MAX_ROW - 1
    print i.to_s
    row = field[i]
    row.each do |stone|
      print stone
    end
    print "\n"
  end
end

これで盤面の表示は完了です。

石を置く

次に石を置く処理を書いていきます。

rubyではgetsを使えばキーボードからの入力を取得できます。
行と列をカンマ区切りで入力するということにしましょう。

# キーボードからの入力を取得
put_pos = gets

# 改行を取り除き、カンマで区切る
put_pos = put_pos.chomp.split(",")

# 行、列を取得
row = put_pos[0]
col = put_pos[1]

# 指定された行、列から盤面に石を置く
field[row][col] = my_stone

裏返す

さて、オセロの一番重要な部分である裏返す処理を作ります。

手順としては、

  1. 置いた石の周りの相手の石を探す
  2. 相手の石を見つけた方向に自分の石を探す
  3. 自分の石の間にある相手の石をすべて自分の石にする

この手順で石を裏返していきます。

# 時計回りに方向を定義
directions = [[-1,0], [-1,1], [0,1], [1,1], [1,0], [1,-1], [0,-1], [-1,-1]]

# 置いた石の周りに相手の石があるか確認
directions.each do |direction|
  reverse_pos = []
  reverse_row = put_row + direction[0]
  reverse_col = put_col + direction[1]

  # 相手の石でない場合は次の方向を確認
  if field[reverse_row][reverse_col] != enemy
    next
  end

  reverse_flag = false
  reverse_pos << [reverse_row, reverse_col]

  # 見つけた方向を捜査していく
  while true
    reverse_row += direction[0]
    reverse_col += direction[1]
    if field[reverse_row][reverse_col] == enemy
      reverse_pos << [reverse_row, reverse_col]
    elsif field[reverse_row][reverse_col] == my_stone
      reverse_flag = true
      break
    else
      break
    end
  end

  # 間にあった相手の石を裏返す
  if reverse_flag
    reverse_pos.each do |pos|
      field[pos[0]][pos[1]] = my_stone
    end
  end
end

これで裏返しの処理は完了です。

あとは交互における場所がなくなるまで繰り返すだけです。

完成!

上記の処理をまとめて、オセロ完成です!
github.com

今回はRubyでオセロを作ってみました。

もしよければ遊んでみてください。

それではまた。

TomoProg

GitHub
TomoProg (TomoProg) · GitHub

Twitter
TomoProg (@TomoHelloxxx) | Twitter