Skip to content

Instantly share code, notes, and snippets.

@miyucy
Created June 8, 2009 15:10
Show Gist options
  • Save miyucy/125872 to your computer and use it in GitHub Desktop.
Save miyucy/125872 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby -wKU
# -*- coding: utf-8 -*-
require 'pp'
module Tictactoe
class Game
def initialize player1, player2, size=3
@board = Board.new(size)
@players = [player1, player2,]
@players.map{ |p| p.board = @board }
@turn = 0
end
def start
while @board.finish?
color = step
return color if color != :next
end
:draw
end
private
def step
player = @players[@turn]
if @board.check(*player.think)
return player.color
end
@turn ^= 1
:next
end
end
class Board
attr_reader :size
def initialize size=3
@size = size
@board = Array.new(@size**2){ |e| nil }
@pattern = pattern
end
def checked? x, y
@board[x + y * @size] != nil
end
def check x, y, color
@board[x + y * @size] = color
won? color
end
def finish?
not @board.grep(nil).empty?
end
def empty
@board.grep(nil)
end
private
def won? color
@pattern.each do |ptn|
return color if @board.values_at(*ptn).all?{ |e| e == color }
end
false
end
def pattern
board = (0...@size**2).to_a
pattern = []
# 横方向
0.step(board.size - 1, @size){ |i| pattern << board[i, @size] }
# 縦方向
(0...@size).each{ |i| pattern << board.select{ |e| e if e % @size == i } }
# 斜め方向
tmp = []
(0...@size).inject(0){ |r,v| tmp << r; r+= @size + 1; }
pattern << tmp
tmp = []
(0...@size).inject(0){ |r,v| tmp << r += @size - 1; r }
pattern << tmp
end
end
class Player
attr_accessor :board
attr_reader :color
def initialize color
@color = color
end
def think
loop do
x, y = rand(@board.size), rand(@board.size)
unless @board.checked?(x, y)
return [x, y, @color]
end
end
end
end
end
total = {}
(0...10000).step do
game = Tictactoe::Game.new(Tictactoe::Player.new(:red), Tictactoe::Player.new(:blue))
result = game.start
total[result]||= 0
total[result] += 1
end
p total
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment