tic-tac-toe-with-ai 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|