Create a gist now

Instantly share code, notes, and snippets.

com対戦できるオセロ
# -*- 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
#モード番号
COM = 1
HUMAN = 2
WATCH = 3
#新しい盤の作成
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")
phase
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 phase
turnable_cells = get_turnable_cells #石を置くことができるマスの一覧の取得
if turnable_cells.size == 0
print("パスしました\n")
@pass_count += 1
@stone_color = -@stone_color
else
print("#{@turn+1}手目: ")
case @mode
when COM #COM戦の場合
if @stone_color == @player_color
human(turnable_cells)
else
com(turnable_cells)
end
when HUMAN #対人戦の場合
human(turnable_cells)
when WATCH #観戦の場合
com(turnable_cells)
end
end
end
def human(turnable_cells) #人が石を置く操作
cell_list = ""
turnable_cells.each do |val|
cell_list += "(" + ROW_NUM.key(val[1]) + COL_NUM.key(val[0]) + ")"
end
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) #指定されたマスが置くことができるマスの時
put_stone(cell)
else
print("そのマスには打つことはできません\n")
print("打てるマスは#{cell_list}です\n")
phase
end
else
print("正しいマスを指定してください\n")
phase
end
end
def com(turnable_cells) #COMの場合
cell = turnable_cells.sample
col = COL_NUM.key(cell[0])
row = ROW_NUM.key(cell[1])
print(row + col)
put_stone(cell)
end
#石を置く
def put_stone(cell)
col = cell[0]
row = cell[1]
@board[col][row] = @stone_color
reverse_stone(col, row)
@stone_color = -@stone_color #処理が終わったら色を変える
@turn += 1
@pass_count = 0
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
#メインメニュー
def menu
while true
print("COMと対戦: 1\n")
print("二人で対戦: 2\n")
print("観戦: 3\n")
print("終了: 4\n\n")
mode = gets.chomp!
if mode.to_i == 4
break
end
if mode =~ /[1-3]/
@mode = mode.to_i
case @mode
when COM
print("手番を選択してください\n")
print("1: 先手(黒), 2: 後手(白)")
player = gets.chomp!.to_i
case player
when 1
print("あなたの先手で始めます\n")
@player_color = BLACK
when 2
print("comの先手で始めます\n")
@player_color = WHITE
end
end
start_game
else
print("1~4で選択してください\n\n")
menu
end
end
end
menu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment