game-tictactoe-esegredo 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -0
- data/Rakefile +37 -0
- data/bin/tictactoe_game.rb +15 -0
- data/game-tictactoe-esegredo.gemspec +23 -0
- data/lib/game-tictactoe-esegredo.rb +36 -0
- data/lib/tictactoe/board.rb +105 -0
- data/lib/tictactoe/dumbplayer.rb +10 -0
- data/lib/tictactoe/humanplayer.rb +30 -0
- data/lib/tictactoe/minimaxplayer.rb +69 -0
- data/lib/tictactoe/player.rb +16 -0
- data/lib/tictactoe/smartplayer.rb +42 -0
- data/lib/tictactoe/version.rb +3 -0
- data/spec/dumbplayer_spec.rb +16 -0
- data/spec/humanplayer_spec.rb +15 -0
- data/spec/smartplayer_spec.rb +16 -0
- data/test/tc_dumbplayer.rb +16 -0
- data/test/tc_humanplayer.rb +16 -0
- data/test/tc_smartplayer.rb +16 -0
- metadata +107 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Eduardo Segredo
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Game::Tictactoe::Esegredo
|
2
|
+
|
3
|
+
Gem which implements the Tic-Tac-Toe game with different
|
4
|
+
kind of players.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'game-tictactoe-esegredo'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install game-tictactoe-esegredo
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
rake build # Build tictactoe-0.0.1.gem into the pkg directory
|
23
|
+
rake doc # Run rspec with --format documentation
|
24
|
+
rake dp_test # Run DumbPlayer tests
|
25
|
+
rake dumb # Run TicTacToe game vs dumb player
|
26
|
+
rake hp_test # Run HumanPlayer tests
|
27
|
+
rake install # Build and install tictactoe-0.0.1.gem into system gems
|
28
|
+
rake release # Create tag v0.0.1 and build and push tictactoe-0.0.1.gem to Rubygems
|
29
|
+
rake smart # Run TicTacToe game vs smart player
|
30
|
+
rake sp_test # Run SmartPlayer tests
|
31
|
+
rake spec # Run RSpec code examples
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + 'lib'
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
RSpec::Core::RakeTask.new
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
desc "Run TicTacToe game vs smart player"
|
10
|
+
task :smart do
|
11
|
+
sh "ruby -Ilib bin/tictactoe_game.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Run TicTacToe game vs dumb player"
|
15
|
+
task :dumb do
|
16
|
+
sh "ruby -Ilib bin/tictactoe_game.rb -d"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Run rspec with --format documentation"
|
20
|
+
task :doc do
|
21
|
+
sh "rspec -Ilib spec/*.rb --format documentation"
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Run HumanPlayer tests"
|
25
|
+
task :hp_test do
|
26
|
+
sh "ruby -Ilib test/tc_humanplayer.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "Run SmartPlayer tests"
|
30
|
+
task :sp_test do
|
31
|
+
sh "ruby -Ilib test/tc_smartplayer.rb"
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Run DumbPlayer tests"
|
35
|
+
task :dp_test do
|
36
|
+
sh "ruby -Ilib test/tc_dumbplayer.rb"
|
37
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
|
3
|
+
if __FILE__ == $0
|
4
|
+
if ARGV.size > 0 and ARGV[0] == "-d"
|
5
|
+
game = Tictactoe::Game.new Tictactoe::HumanPlayer,
|
6
|
+
Tictactoe::DumbPlayer
|
7
|
+
elsif ARGV.size > 0 and ARGV[0] == "-m"
|
8
|
+
game = Tictactoe::Game.new Tictactoe::HumanPlayer,
|
9
|
+
Tictactoe::MinimaxPlayer
|
10
|
+
else
|
11
|
+
game = Tictactoe::Game.new Tictactoe::HumanPlayer,
|
12
|
+
Tictactoe::SmartPlayer
|
13
|
+
end
|
14
|
+
game.play
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tictactoe/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "game-tictactoe-esegredo"
|
8
|
+
gem.version = Tictactoe::VERSION
|
9
|
+
gem.authors = ["Eduardo Segredo"]
|
10
|
+
gem.email = ["edusegre@gmail.com"]
|
11
|
+
gem.description = %q{Gem which implements the Tic-Tac-Toe game with different kind of players}
|
12
|
+
gem.summary = %q{Gem which implements the Tic-Tac-Toe game with different kind of players}
|
13
|
+
gem.homepage = "https://github.com/esegredo/pract10_tictactoe"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'rspec'
|
22
|
+
gem.add_development_dependency 'guard-rspec'
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "tictactoe/version"
|
2
|
+
require "tictactoe/humanplayer"
|
3
|
+
require "tictactoe/smartplayer"
|
4
|
+
require "tictactoe/minimaxplayer"
|
5
|
+
require "tictactoe/dumbplayer"
|
6
|
+
require "tictactoe/board"
|
7
|
+
|
8
|
+
module Tictactoe
|
9
|
+
class Game
|
10
|
+
def initialize( player1, player2, random = true )
|
11
|
+
if random and rand(2) == 1
|
12
|
+
@x_player = player2.new("X")
|
13
|
+
@o_player = player1.new("O")
|
14
|
+
else
|
15
|
+
@x_player = player1.new("X")
|
16
|
+
@o_player = player2.new("O")
|
17
|
+
end
|
18
|
+
|
19
|
+
@board = Board.new([" "] * 9)
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :x_player, :o_player
|
23
|
+
|
24
|
+
def play
|
25
|
+
until @board.won?
|
26
|
+
@board[@x_player.move(@board)] = @x_player.mark
|
27
|
+
break if @board.won?
|
28
|
+
|
29
|
+
@board[@o_player.move(@board)] = @o_player.mark
|
30
|
+
end
|
31
|
+
|
32
|
+
@o_player.finish @board
|
33
|
+
@x_player.finish @board
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Tictactoe
|
2
|
+
module SquaresContainer
|
3
|
+
def []( index ) @squares[index] end
|
4
|
+
|
5
|
+
def blanks() @squares.find_all { |s| s == " " }.size end
|
6
|
+
def os() @squares.find_all { |s| s == "O" }.size end
|
7
|
+
def xs() @squares.find_all { |s| s == "X" }.size end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Board
|
11
|
+
attr_reader :squares
|
12
|
+
class Row
|
13
|
+
def initialize( squares, names )
|
14
|
+
@squares = squares
|
15
|
+
@names = names
|
16
|
+
end
|
17
|
+
|
18
|
+
include SquaresContainer
|
19
|
+
|
20
|
+
def to_board_name( index )
|
21
|
+
Board.index_to_name(@names[index])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
MOVES = %w{a1 a2 a3 b1 b2 b3 c1 c2 c3}
|
26
|
+
# Define constant INDICES
|
27
|
+
INDICES = Hash.new { |h, k| h[k] = MOVES.find_index(k) }
|
28
|
+
|
29
|
+
def self.name_to_index( name )# Receives "b2" and returns 4
|
30
|
+
INDICES[name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.index_to_name( index ) # Receives the index, like 4 and returns "b2"
|
34
|
+
MOVES[index]
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize( squares )
|
38
|
+
@squares = squares # An array of Strings: [ " ", " ", " ", " ", "X", " ", " ", " ", "O"]
|
39
|
+
end
|
40
|
+
|
41
|
+
include SquaresContainer
|
42
|
+
|
43
|
+
def []( *indices )
|
44
|
+
if indices.size == 2 # board[1,2] is @squares[7]
|
45
|
+
super indices[0] + indices[1] * 3 # calls SquaresContainer [] method
|
46
|
+
elsif indices[0].is_a? Fixnum # board[7]
|
47
|
+
super indices[0]
|
48
|
+
else # board["b2"]
|
49
|
+
super Board.name_to_index(indices[0].to_s)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def []=(indice, value) # board["b2"] = "X"
|
54
|
+
m = Board.name_to_index(indice)
|
55
|
+
@squares[m] = value
|
56
|
+
end
|
57
|
+
|
58
|
+
HORIZONTALS = [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ]
|
59
|
+
COLUMNS = [ [0, 3, 6], [1, 4, 7], [2, 5, 8] ]
|
60
|
+
DIAGONALS = [ [0, 4, 8], [2, 4, 6] ]
|
61
|
+
ROWS = HORIZONTALS + COLUMNS + DIAGONALS
|
62
|
+
|
63
|
+
def each_row
|
64
|
+
ROWS.each do |e|
|
65
|
+
yield Row.new(@squares.values_at(*e), e)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def moves
|
70
|
+
moves = [ ]
|
71
|
+
@squares.each_with_index do |s, i|
|
72
|
+
moves << Board.index_to_name(i) if s == " "
|
73
|
+
end
|
74
|
+
moves # returns the set of feasible moves [ "b3", "c2", ... ]
|
75
|
+
end
|
76
|
+
|
77
|
+
def won?
|
78
|
+
each_row do |row|
|
79
|
+
return "X" if row.xs == 3 # "X" wins
|
80
|
+
return "O" if row.os == 3 # "O" wins
|
81
|
+
end
|
82
|
+
return " " if blanks == 0 # tie
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
BOARD =<<EOS
|
87
|
+
|
88
|
+
+---+---+---+
|
89
|
+
a | 0 | 1 | 2 |
|
90
|
+
+---+---+---+
|
91
|
+
b | 3 | 4 | 5 |
|
92
|
+
+---+---+---+
|
93
|
+
c | 6 | 7 | 8 |
|
94
|
+
+---+---+---+
|
95
|
+
1 2 3
|
96
|
+
|
97
|
+
EOS
|
98
|
+
def to_s
|
99
|
+
BOARD.gsub(/(\d)(?= \|)/) { |i| @squares[i.to_i] }
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "tictactoe/player"
|
2
|
+
|
3
|
+
module Tictactoe
|
4
|
+
class HumanPlayer < Player
|
5
|
+
def move( board )
|
6
|
+
print board
|
7
|
+
|
8
|
+
moves = board.moves
|
9
|
+
print "Your move? (format: b3) "
|
10
|
+
move = $stdin.gets
|
11
|
+
until moves.include?(move.chomp.downcase)
|
12
|
+
print "Invalid move. Try again. "
|
13
|
+
move = $stdin.gets
|
14
|
+
end
|
15
|
+
move.chomp
|
16
|
+
end
|
17
|
+
|
18
|
+
def finish( final_board )
|
19
|
+
print final_board
|
20
|
+
|
21
|
+
if final_board.won? == @mark
|
22
|
+
print "Congratulations, you win.\n\n"
|
23
|
+
elsif final_board.won? == " "
|
24
|
+
print "Tie game.\n\n"
|
25
|
+
else
|
26
|
+
print "You lost tic-tac-toe?!\n\n"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "tictactoe/player"
|
2
|
+
|
3
|
+
module Tictactoe
|
4
|
+
class MinimaxPlayer < Player
|
5
|
+
def move( board )
|
6
|
+
# Obtains the available movements
|
7
|
+
moves = board.moves
|
8
|
+
|
9
|
+
# For each available movement
|
10
|
+
bestValue = -2
|
11
|
+
bestMove = ""
|
12
|
+
moves.each do |move|
|
13
|
+
newsquares = board.squares.dup
|
14
|
+
newboard = Board.new(newsquares)
|
15
|
+
value = search_best_move(newboard, move, self.mark, 1)
|
16
|
+
if (value >= bestValue)
|
17
|
+
bestValue = value
|
18
|
+
bestMove = move
|
19
|
+
end
|
20
|
+
end
|
21
|
+
bestMove
|
22
|
+
end
|
23
|
+
|
24
|
+
def search_best_move(board, move, mark, level)
|
25
|
+
# Puts the movement on the board
|
26
|
+
board[move] = mark
|
27
|
+
moves = board.moves
|
28
|
+
|
29
|
+
# Checks whether there is a winner or not
|
30
|
+
return 1 if (board.won? == self.mark)
|
31
|
+
return 0 if (board.won? == " ")
|
32
|
+
return -1 if (board.won? == opponent_mark)
|
33
|
+
|
34
|
+
# Max level
|
35
|
+
if ((level % 2 == 1) && (!board.won?))
|
36
|
+
bestValue = -2;
|
37
|
+
moves.each do |mov|
|
38
|
+
newsquares = board.squares.dup
|
39
|
+
newboard = Board.new(newsquares)
|
40
|
+
value = search_best_move(newboard, mov, opponent_mark, level + 1)
|
41
|
+
if (value >= bestValue)
|
42
|
+
bestValue = value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# Min level
|
46
|
+
elsif ((level % 2 == 0) && (!board.won?))
|
47
|
+
bestValue = 2;
|
48
|
+
moves.each do |mov|
|
49
|
+
newsquares = board.squares.dup
|
50
|
+
newboard = Board.new(newsquares)
|
51
|
+
value = search_best_move(newboard, mov, self.mark, level + 1)
|
52
|
+
if (value <= bestValue)
|
53
|
+
bestValue = value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
bestValue
|
58
|
+
end
|
59
|
+
|
60
|
+
def opponent_mark
|
61
|
+
if (self.mark == "X")
|
62
|
+
return "O"
|
63
|
+
else
|
64
|
+
return "X"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Tictactoe
|
2
|
+
class Player
|
3
|
+
def initialize( mark )
|
4
|
+
@mark = mark # "X" or "O" or " "
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :mark
|
8
|
+
|
9
|
+
def move( board )
|
10
|
+
raise NotImplementedError, "Player subclasses must define move()."
|
11
|
+
end
|
12
|
+
|
13
|
+
def finish( final_board )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "tictactoe/player"
|
2
|
+
|
3
|
+
module Tictactoe
|
4
|
+
class SmartPlayer < Player
|
5
|
+
def move( board )
|
6
|
+
moves = board.moves
|
7
|
+
|
8
|
+
# If I have a win, take it. If he is threatening to win, stop it.
|
9
|
+
board.each_row do |row|
|
10
|
+
if row.blanks == 1 and (row.xs == 2 or row.os == 2)
|
11
|
+
(0..2).each do |e|
|
12
|
+
return row.to_board_name(e) if row[e] == " "
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Take the center if open.
|
18
|
+
return "b2" if moves.include? "b2"
|
19
|
+
|
20
|
+
# Defend opposite corners.
|
21
|
+
if board[0] != @mark and board[0] != " " and board[8] == " "
|
22
|
+
return "c3"
|
23
|
+
elsif board[8] != @mark and board[8] != " " and board[0] == " "
|
24
|
+
return "a1"
|
25
|
+
elsif board[2] != @mark and board[2] != " " and board[6] == " "
|
26
|
+
return "c1"
|
27
|
+
elsif board[6] != @mark and board[6] != " " and board[2] == " "
|
28
|
+
return "a3"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Defend against the special case XOX on a diagonal.
|
32
|
+
if board.xs == 2 and board.os == 1 and board[4] == "O" and
|
33
|
+
(board[0] == "X" and board[8] == "X") or
|
34
|
+
(board[2] == "X" and board[6] == "X")
|
35
|
+
return %w{a2 b1 b3 c2}[rand(4)]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Or make a random move.
|
39
|
+
moves[rand(moves.size)]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
|
3
|
+
describe Tictactoe::DumbPlayer do
|
4
|
+
before :each do
|
5
|
+
@dp = Tictactoe::DumbPlayer.new("X")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "Debe existir un metodo move" do
|
9
|
+
@dp.respond_to?("move").should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "Debe existir un metodo finish" do
|
13
|
+
@dp.respond_to?("finish").should == true
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
|
3
|
+
describe Tictactoe::HumanPlayer do
|
4
|
+
before :each do
|
5
|
+
@hp = Tictactoe::HumanPlayer.new("X")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "Debe existir un metodo move" do
|
9
|
+
@hp.respond_to?("move").should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "Debe existir un metodo finish" do
|
13
|
+
@hp.respond_to?("finish").should == true
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
|
3
|
+
describe Tictactoe::SmartPlayer do
|
4
|
+
before :each do
|
5
|
+
@sp = Tictactoe::SmartPlayer.new("X")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "Debe existir un metodo move" do
|
9
|
+
@sp.respond_to?("move").should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "Debe existir un metodo finish" do
|
13
|
+
@sp.respond_to?("finish").should == true
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
class TestDumbPlayer < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@dp = Tictactoe::DumbPlayer.new("X")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_implements_move
|
10
|
+
assert_equal true, @dp.respond_to?("move")
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_implements_finish
|
14
|
+
assert_equal true, @dp.respond_to?("finish")
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
class TestHumanPlayer < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@hp = Tictactoe::HumanPlayer.new("X")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_implements_move
|
10
|
+
assert_equal true, @hp.respond_to?("move")
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_implements_finish
|
14
|
+
assert_equal true, @hp.respond_to?("finish")
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "game-tictactoe-esegredo"
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
class TestSmartPlayer < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@sp = Tictactoe::SmartPlayer.new("X")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_implements_move
|
10
|
+
assert_equal true, @sp.respond_to?("move")
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_implements_finish
|
14
|
+
assert_equal true, @sp.respond_to?("finish")
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: game-tictactoe-esegredo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eduardo Segredo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &21944360 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *21944360
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &21943600 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *21943600
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard-rspec
|
38
|
+
requirement: &21942600 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *21942600
|
47
|
+
description: Gem which implements the Tic-Tac-Toe game with different kind of players
|
48
|
+
email:
|
49
|
+
- edusegre@gmail.com
|
50
|
+
executables:
|
51
|
+
- tictactoe_game.rb
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- Guardfile
|
58
|
+
- LICENSE.txt
|
59
|
+
- README.md
|
60
|
+
- Rakefile
|
61
|
+
- bin/tictactoe_game.rb
|
62
|
+
- game-tictactoe-esegredo.gemspec
|
63
|
+
- lib/game-tictactoe-esegredo.rb
|
64
|
+
- lib/tictactoe/board.rb
|
65
|
+
- lib/tictactoe/dumbplayer.rb
|
66
|
+
- lib/tictactoe/humanplayer.rb
|
67
|
+
- lib/tictactoe/minimaxplayer.rb
|
68
|
+
- lib/tictactoe/player.rb
|
69
|
+
- lib/tictactoe/smartplayer.rb
|
70
|
+
- lib/tictactoe/version.rb
|
71
|
+
- spec/dumbplayer_spec.rb
|
72
|
+
- spec/humanplayer_spec.rb
|
73
|
+
- spec/smartplayer_spec.rb
|
74
|
+
- test/tc_dumbplayer.rb
|
75
|
+
- test/tc_humanplayer.rb
|
76
|
+
- test/tc_smartplayer.rb
|
77
|
+
homepage: https://github.com/esegredo/pract10_tictactoe
|
78
|
+
licenses: []
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.8.11
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: Gem which implements the Tic-Tac-Toe game with different kind of players
|
101
|
+
test_files:
|
102
|
+
- spec/dumbplayer_spec.rb
|
103
|
+
- spec/humanplayer_spec.rb
|
104
|
+
- spec/smartplayer_spec.rb
|
105
|
+
- test/tc_dumbplayer.rb
|
106
|
+
- test/tc_humanplayer.rb
|
107
|
+
- test/tc_smartplayer.rb
|