Skip to content

Instantly share code, notes, and snippets.

@umaz
Created February 9, 2017 08:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save umaz/ace7dd1f204574e6eb7cd1dde8e42f33 to your computer and use it in GitHub Desktop.
Save umaz/ace7dd1f204574e6eb7cd1dde8e42f33 to your computer and use it in GitHub Desktop.
対人対戦できるオセロ
# -*- coding: utf-8 -*-
#定数の定義
MAX_TURN = 60 #最大ターン数
BOARD_SIZE = 8 #盤のサイズ(8*8)
EMPTY = 0 #空きマス
BLACK = 1 #黒石のマス
WHITE = -1 #白石のマス
WALL = 2 #番兵(ひっくり返すときに使う)
ROW_NUM = {"a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6, "g" => 7, "h" => 8} #列番号
COL_NUM = {"1" => 1, "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8} #行番号
COLOR = {BLACK => "黒", WHITE => "白"} #色
#ひっくり返せる方向
UPPER_LEFT = 1
UPPER = 2
UPPER_RIGHT = 3
RIGHT = 4
LOWER_RIGHT = 5
LOWER = 6
LOWER_LEFT = 7
LEFT = 8
#新しい盤の作成
def new_board
#盤面を表す二重配列の作成
@board = Array.new(BOARD_SIZE+2){Array.new(BOARD_SIZE+2,EMPTY)}
#壁の配置
@board[0].fill(WALL)
@board[9].fill(WALL)
@board.each do |col|
col[0] = WALL
col[9] = WALL
end
#石の初期配置
@board[4][4] = WHITE
@board[5][5] = WHITE
@board[5][4] = BLACK
@board[4][5] = BLACK
end
#現在の盤の状態を表示
def show_board
print("\n\n #{ROW_NUM.keys.join(" ")}\n") #列番号の表示
@board.slice(1...-1).each_with_index do |col, i|
print(COL_NUM[(i+1).to_s]) #行番号の表示
col.each do |row| #マスの表示
case row
when EMPTY
print "\e[32m"
print(" □")
print "\e[0m"
when BLACK
print(" ○")
when WHITE
print(" ●")
end
end
print("\n")
end
print("\n")
end
#ゲームの進行
def start_game
new_board
show_board
@turn = 0
@pass_count = 0
@stone_color = BLACK #黒石からスタート
while true
print("#{COLOR[@stone_color]}の手番です\n")
put_stone
show_board
stone_count = count
print("\n 黒:#{count[0]}, 白:#{count[1]}\n\n")
#ゲームの終了
if @turn == MAX_TURN
break
end
if @pass_count == 2
break
end
end
judge
end
def turnable_direction(col, row) #返せるかどうかの判定とその方向の取得
direction = []
#左上
if @board[col-1][row-1] == -@stone_color #相手の色がある場合
i = 2
while @board[col-i][row-i] == -@stone_color #相手の色が続くまで
i += 1
end
if @board[col-i][row-i] == @stone_color #相手の色に続くのが自分の色の場合
direction.push(UPPER_LEFT)
end
end
if @board[col-1][row] == -@stone_color #上
i = 2
while @board[col-i][row] == -@stone_color
i += 1
end
if @board[col-i][row] == @stone_color
direction.push(UPPER)
end
end
if @board[col-1][row+1] == -@stone_color #右上
i = 2
while @board[col-i][row+i] == -@stone_color
i += 1
end
if @board[col-i][row+i] == @stone_color
direction.push(UPPER_RIGHT)
end
end
if @board[col][row+1] == -@stone_color #右
i = 2
while @board[col][row+i] == -@stone_color
i += 1
end
if @board[col][row+i] == @stone_color
direction.push(RIGHT)
end
end
if @board[col+1][row+1] == -@stone_color #右下
i = 2
while @board[col+i][row+i] == -@stone_color
i += 1
end
if @board[col+i][row+i] == @stone_color
direction.push(LOWER_RIGHT)
end
end
if @board[col+1][row] == -@stone_color #下
i = 2
while @board[col+i][row] == -@stone_color
i += 1
end
if @board[col+i][row] == @stone_color
direction.push(LOWER)
end
end
if @board[col+1][row-1] == -@stone_color #左下
i = 2
while @board[col+i][row-i] == -@stone_color
i += 1
end
if @board[col+i][row-i] == @stone_color
direction.push(LOWER_LEFT)
end
end
if @board[col][row-1] == -@stone_color #左
i = 2
while @board[col][row-i] == -@stone_color
i += 1
end
if @board[col][row-i] == @stone_color
direction.push(LEFT)
end
end
return direction
end
#石を置くことができるマスの取得
def get_turnable_cells
turnable_cells = []
@board.each_with_index do |col, i|
col.each_with_index do |row, j|
if row == EMPTY #空きマス
turnable_direction = turnable_direction(i,j) #返せる方向の取得
if turnable_direction.size != 0 #ひっくり返せる方向が存在する=石を置けるマス
turnable_cells.push([i,j]) #座標を格納
end
end
end
end
return turnable_cells
end
#石を置く
def put_stone
turnable_cells = get_turnable_cells #石を置くことができるマスの一覧の取得
cell_list = "" #石を置くことができるマスの一覧の作成
turnable_cells.each do |val|
cell_list += "(" + ROW_NUM.key(val[1]) + COL_NUM.key(val[0]) + ")"
end
if turnable_cells.size == 0
print("パスしました\n\n")
@pass_count += 1
@stone_color = -@stone_color
else
print("#{@turn+1}手目: ")
move = gets.chomp!
if move =~ /[a-h][1-8]/
cell = move.split("")
col = COL_NUM[cell[1]]
row = ROW_NUM[cell[0]]
cell = [col, row]
if turnable_cells.include?(cell) #指定されたマスが置くことができるマスの時
@board[col][row] = @stone_color
reverse_stone(col, row)
@stone_color = -@stone_color
@turn += 1
@pass_count = 0
else
print("そのマスには打つことはできません\n")
print("打てるマスは#{cell_list}です\n")
put_stone
end
else
print("正しいマスを指定してください\n")
put_stone
end
end
end
#石をひっくり返す
def reverse_stone(col, row) #石をおいた位置
turn_direction = turnable_direction(col, row) #方向と数を取得
turn_direction.each do |direction|
case direction
when UPPER_LEFT
i = 1
while @board[col-i][row-i] == -@stone_color #相手の色が続くまで
@board[col-i][row-i] = @stone_color
i += 1
end
when UPPER
i = 1
while @board[col-i][row] == -@stone_color
@board[col-i][row] = @stone_color
i += 1
end
when UPPER_RIGHT
i = 1
while @board[col-i][row+i] == -@stone_color
@board[col-i][row+i] = @stone_color
i += 1
end
when RIGHT
i = 1
while @board[col][row+i] == -@stone_color
@board[col][row+i] = @stone_color
i += 1
end
when LOWER_RIGHT
i = 1
while @board[col+i][row+i] == -@stone_color
@board[col+i][row+i] = @stone_color
i += 1
end
when LOWER
i = 1
while @board[col+i][row] == -@stone_color
@board[col+i][row] = @stone_color
i += 1
end
when LOWER_LEFT
i = 1
while @board[col+i][row-i] == -@stone_color
@board[col+i][row-i] = @stone_color
i += 1
end
when LEFT
i = 1
while @board[col][row-i] == -@stone_color
@board[col][row-i] = @stone_color
i += 1
end
end
end
end
#石の数を数える
def count
black = 0
white = 0
@board.each do |col|
col.each do |row|
case row
when BLACK
black += 1
when WHITE
white += 1
end
end
end
count = [black, white]
return count
end
#勝敗の判定
def judge
stone_count = count
black = count[0]
white = count[1]
if black > white
print("\n黒:#{black} 対 白:#{white} で黒の勝ち\n\n")
elsif white > black
print("\n黒:#{black} 対 白:#{white} で白の勝ち\n\n")
else
print("\n黒:#{black} 対 白:#{white} で引き分け\n\n")
end
end
start_game
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment