tic-tac-toe-with-ai 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.
- checksums.yaml +7 -0
- data/lib/computer_player/computer_player.rb +61 -0
- data/lib/tic_tac_toe/board.rb +58 -0
- data/lib/tic_tac_toe/game.rb +57 -0
- data/lib/tic_tac_toe/rules.rb +41 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a9f495aa72d65eac7567d162d13adef817ddeb50
|
4
|
+
data.tar.gz: dc3d6ee57e3354f212e52988a8807aba58d32581
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d88e9b6cf18d235506a46e5c3f7de45dd997c0cf5f72de31cf996531095c9861b20ba7c25dd0315d1519eaaba8ad0ea718db4209edeca213ceb1ccf09a71c085
|
7
|
+
data.tar.gz: db8e1789fb5a32ac9ba5edf45912354d0878ad8f75890d2689fdbcb546b896cbe724f790f1e2005bcdec7bdf981228981490349b52a9cef08aa45ec0832b4b98
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module TicTacToe
|
2
|
+
|
3
|
+
class ComputerPlayer
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@triples = [ [1,2,3], [4,5,6], [7,8,9], [1,4,7], [2,5,8], [3,6,9], [1,5,9], [3,5,7] ]
|
7
|
+
end
|
8
|
+
|
9
|
+
def decide_move(board)
|
10
|
+
return find_winning_cell(board, "O") if find_winning_cell(board, "O") != nil
|
11
|
+
return find_winning_cell(board, "X") if find_winning_cell(board, "X") != nil
|
12
|
+
return random_move(board)
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_winning_cell(board, mark)
|
16
|
+
return find_cell(board, mark) if find_cell(board, mark) != nil
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def random_move(board)
|
21
|
+
while(true)
|
22
|
+
trial_number = rand(9) + 1
|
23
|
+
if board[trial_number-1] == nil
|
24
|
+
return trial_number
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def find_cell(board, mark)
|
32
|
+
@triples.each do |triplet|
|
33
|
+
define_permutation(triplet[0], triplet[1], triplet[2]).each do |triple|
|
34
|
+
return triple[2] if it_finds_a_winning_triple(board, mark, triple[0], triple[1], triple[2])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def define_permutation(cell_one, cell_two, cell_three)
|
41
|
+
return [cell_one, cell_two, cell_three].permutation.to_a
|
42
|
+
end
|
43
|
+
|
44
|
+
def it_finds_a_winning_triple(board, mark, filled_spot_one, filled_spot_two, potential_move)
|
45
|
+
if board[filled_spot_one-1] == mark && board[filled_spot_two-1] == mark && spot_is_empty?(board, potential_move-1)
|
46
|
+
return true
|
47
|
+
else
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def spot_is_empty?(board, position)
|
53
|
+
["X", "O"].each do |mark|
|
54
|
+
return false if board[position] == mark
|
55
|
+
end
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module TicTacToe
|
2
|
+
|
3
|
+
class Board
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@board_positions = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_mark(mark, position)
|
10
|
+
@board_positions[position] = mark
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_mark_at(position)
|
14
|
+
@board_positions[position]
|
15
|
+
end
|
16
|
+
|
17
|
+
def return_entire_board
|
18
|
+
return [get_mark_at(1), get_mark_at(2), get_mark_at(3),
|
19
|
+
get_mark_at(4), get_mark_at(5), get_mark_at(6),
|
20
|
+
get_mark_at(7), get_mark_at(8), get_mark_at(9)]
|
21
|
+
end
|
22
|
+
|
23
|
+
def rows
|
24
|
+
position_groups_to_marks([
|
25
|
+
[1, 2, 3],
|
26
|
+
[4, 5, 6],
|
27
|
+
[7, 8, 9]
|
28
|
+
])
|
29
|
+
end
|
30
|
+
|
31
|
+
def columns
|
32
|
+
position_groups_to_marks([
|
33
|
+
[1, 4, 7],
|
34
|
+
[2, 5, 8],
|
35
|
+
[3, 6, 9]
|
36
|
+
])
|
37
|
+
end
|
38
|
+
|
39
|
+
def diagonals
|
40
|
+
position_groups_to_marks([
|
41
|
+
[1, 5, 9],
|
42
|
+
[3, 5, 7]
|
43
|
+
])
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def position_groups_to_marks(position_groups)
|
49
|
+
position_groups.collect do |positions|
|
50
|
+
positions.collect do |position|
|
51
|
+
get_mark_at(position)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module TicTacToe
|
2
|
+
class Game
|
3
|
+
|
4
|
+
attr_reader :computer_player, :board
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@board = Board.new
|
8
|
+
@rules = Rules.new(@board)
|
9
|
+
@computer_player = ComputerPlayer.new
|
10
|
+
@marks = ["X", "O"]
|
11
|
+
end
|
12
|
+
|
13
|
+
def in_progress?
|
14
|
+
return false if winner_exists?
|
15
|
+
return false if tie_exists?
|
16
|
+
return true
|
17
|
+
end
|
18
|
+
|
19
|
+
def move(position)
|
20
|
+
board.set_mark(current_mark, position)
|
21
|
+
change_current_mark
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_mark_at(position)
|
25
|
+
board.get_mark_at(position)
|
26
|
+
end
|
27
|
+
|
28
|
+
def winner
|
29
|
+
rules.winner
|
30
|
+
end
|
31
|
+
|
32
|
+
def tie
|
33
|
+
rules.tie
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_reader :marks, :rules
|
39
|
+
|
40
|
+
def current_mark
|
41
|
+
marks.first
|
42
|
+
end
|
43
|
+
|
44
|
+
def change_current_mark
|
45
|
+
marks.reverse!
|
46
|
+
end
|
47
|
+
|
48
|
+
def winner_exists?
|
49
|
+
!winner.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def tie_exists?
|
53
|
+
tie
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module TicTacToe
|
2
|
+
class Rules
|
3
|
+
|
4
|
+
def initialize(board)
|
5
|
+
@board = board
|
6
|
+
end
|
7
|
+
|
8
|
+
def winner
|
9
|
+
return "tie" if tie
|
10
|
+
["X", "O"].detect do |mark|
|
11
|
+
winning_mark?(mark)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def tie
|
16
|
+
(1..9).each do |position|
|
17
|
+
return false if @board.get_mark_at(position) == nil
|
18
|
+
end
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def winning_mark?(mark)
|
25
|
+
potential_winning_combinations.any? do |marks|
|
26
|
+
winning_marks?(marks, mark)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def potential_winning_combinations
|
31
|
+
board.rows + board.columns + board.diagonals
|
32
|
+
end
|
33
|
+
|
34
|
+
def winning_marks?(marks, mark)
|
35
|
+
marks == [mark] * 3
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :board
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tic-tac-toe-with-ai
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cyrus Vandrevala
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A tic-tac-toe-app with an unbeatable AI.
|
14
|
+
email: cyrus.vandrevala@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/computer_player/computer_player.rb
|
20
|
+
- lib/tic_tac_toe/board.rb
|
21
|
+
- lib/tic_tac_toe/game.rb
|
22
|
+
- lib/tic_tac_toe/rules.rb
|
23
|
+
homepage:
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.4.1
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: A simple tic-tac-toe app with an unbeatable AI.
|
47
|
+
test_files: []
|