jdl_tictactoe 0.0.5 → 0.0.6
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/lib/jdl_tictactoe/board.rb +96 -94
- data/lib/jdl_tictactoe/game.rb +31 -29
- metadata +1 -1
data/lib/jdl_tictactoe/board.rb
CHANGED
@@ -1,95 +1,97 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
1
|
+
module JdlTicTacToe
|
2
|
+
class Board
|
3
|
+
|
4
|
+
attr_reader :size, :squares
|
5
|
+
|
6
|
+
def initialize(size=3)
|
7
|
+
@size = size
|
8
|
+
@squares = initialize_squares(size)
|
9
|
+
end
|
10
|
+
|
11
|
+
def mark_square(square_index, marker)
|
12
|
+
row, column = translate_index(square_index)
|
13
|
+
squares[row][column] = marker
|
14
|
+
end
|
15
|
+
|
16
|
+
def undo_move(square_index)
|
17
|
+
row, column = translate_index(square_index)
|
18
|
+
squares[row][column] = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def value_at(square_index)
|
22
|
+
row, column = translate_index(square_index)
|
23
|
+
squares[row][column]
|
24
|
+
end
|
25
|
+
|
26
|
+
def winner?(mark)
|
27
|
+
horizontal_winner?(mark) || vertical_winner?(mark) || first_diagonal_winner?(mark) || second_diagonal_winner?(mark)
|
28
|
+
end
|
29
|
+
|
30
|
+
def draw?(player)
|
31
|
+
return true if empty_squares.length == 0 && ( !winner?(player.mark) || !winner?(player.opponent.mark) )
|
32
|
+
end
|
33
|
+
|
34
|
+
def empty_squares
|
35
|
+
@squares.flatten.each_with_index.collect { |sq, i| i+1 if sq == nil}.compact
|
36
|
+
end
|
37
|
+
|
38
|
+
def score(player)
|
39
|
+
return 1 if winner?(player.mark)
|
40
|
+
return -1 if winner?(player.opponent.mark)
|
41
|
+
return 0 if draw?(player)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def first_diagonal_winner?(mark)
|
47
|
+
diagonal = []
|
48
|
+
size.times do |row|
|
49
|
+
diagonal << squares[row][row]
|
50
|
+
end
|
51
|
+
winner_in_collection?(diagonal, mark)
|
52
|
+
end
|
53
|
+
|
54
|
+
def second_diagonal_winner?(mark)
|
55
|
+
diagonal = []
|
56
|
+
size.times do |row|
|
57
|
+
diagonal << squares[row][size - row - 1]
|
58
|
+
end
|
59
|
+
winner_in_collection?(diagonal, mark)
|
60
|
+
end
|
61
|
+
|
62
|
+
def vertical_winner?(mark)
|
63
|
+
size.times do |index|
|
64
|
+
column = []
|
65
|
+
size.times do |row|
|
66
|
+
column << squares[row][index]
|
67
|
+
end
|
68
|
+
return true if winner_in_collection?(column, mark)
|
69
|
+
end
|
70
|
+
false
|
71
|
+
end
|
72
|
+
|
73
|
+
def horizontal_winner?(mark)
|
74
|
+
squares.reduce(false) do |winner, row|
|
75
|
+
winner || winner_in_collection?(row, mark)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def winner_in_collection?(collection, mark)
|
80
|
+
!collection.include?(nil) && collection.uniq.size == 1 && collection.include?(mark)
|
81
|
+
end
|
82
|
+
|
83
|
+
def initialize_squares(size)
|
84
|
+
squares = []
|
85
|
+
size.times { squares << ([nil]*size) }
|
86
|
+
return squares
|
87
|
+
end
|
88
|
+
|
89
|
+
def translate_index(square_index)
|
90
|
+
square_index -= 1
|
91
|
+
row = square_index / size
|
92
|
+
column = square_index % size
|
93
|
+
return row, column
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
95
97
|
end
|
data/lib/jdl_tictactoe/game.rb
CHANGED
@@ -1,39 +1,41 @@
|
|
1
|
-
|
1
|
+
module JdlTicTacToe
|
2
|
+
class Game
|
2
3
|
|
3
|
-
|
4
|
+
attr_accessor :player1, :player2, :turn, :board
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
def initialize(player1, player2, size=3)
|
7
|
+
@player1 = player1
|
8
|
+
@player2 = player2
|
9
|
+
@turn = :player1
|
10
|
+
@board = Board.new(size)
|
11
|
+
set_opponents(@player1, @player2)
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def switch_turn(turn)
|
15
|
+
@turn = :player2 if turn == :player1
|
16
|
+
@turn = :player1 if turn == :player2
|
17
|
+
return @turn
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def over?
|
21
|
+
return true if winner?(@player1.mark) || winner?(@player2.mark) || empty_squares.count == 0
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
+
private
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
def set_opponents(player1, player2)
|
27
|
+
player1.opponent = player2
|
28
|
+
player2.opponent = player1
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
def method_missing(method_name, *args)
|
32
|
+
delegated_methods = [:empty_squares, :winner?, :mark_square, :undo_move]
|
33
|
+
if delegated_methods.include?(method_name)
|
34
|
+
self.board.send(method_name, *args)
|
35
|
+
else
|
36
|
+
raise NoMethodError.new("Undefined method #{method_name} called on Game")
|
37
|
+
end
|
36
38
|
end
|
37
|
-
end
|
38
39
|
|
40
|
+
end
|
39
41
|
end
|