Created
February 9, 2017 08:10
-
-
Save umaz/ace7dd1f204574e6eb7cd1dde8e42f33 to your computer and use it in GitHub Desktop.
対人対戦できるオセロ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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