mic-mac-moe 0.2.0
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/bin/tictactoe.rb +39 -0
- data/config/environment.rb +6 -0
- data/lib/board.rb +67 -0
- data/lib/game.rb +95 -0
- data/lib/player.rb +12 -0
- data/lib/players/computer.rb +75 -0
- data/lib/players/human.rb +11 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 89acda3dad9b3d6f30aa0a463bee6ca15598439750c5c50cf1b091bc86ffe068
|
4
|
+
data.tar.gz: f4157046928f05d9742f4836b104e3c5754358585aec13c1d60bb1813ce6d8de
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6acdc0c331a5222dcdcab5b23b5d7491f530b33a52be016bf7b2ead0b1a291eb70e823c976cabc81dce0cfb3597a2c6025e468988bc2b69ddbe6f403c79e881b
|
7
|
+
data.tar.gz: 19779df3fd59899b7a8d29d9edf27aeb666d706971c15eed5c47c0fe318135be6016fdaacb337db405c308dc94f16a7a0cd99a36da09ffb3cff6f62650260cbf
|
data/bin/tictactoe.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "./config/environment.rb"
|
4
|
+
|
5
|
+
puts "\n***** Welcome to Tic Tac Toe! *****".blue
|
6
|
+
|
7
|
+
def load_mode
|
8
|
+
puts "\nWhat mode would you like to play?".blue
|
9
|
+
puts "For 0 player, type '0'"
|
10
|
+
puts "For 1 player, type '1'"
|
11
|
+
puts "For 2 player, type '2'"
|
12
|
+
mode = gets.strip
|
13
|
+
case mode
|
14
|
+
when "0"
|
15
|
+
game = Game.new(Players::Computer.new("X"), Players::Computer.new("O"))
|
16
|
+
when "1"
|
17
|
+
game = Game.new(Players::Computer.new("X"), Players::Human.new("O"))
|
18
|
+
when "2"
|
19
|
+
game = Game.new(Players::Human.new("X"), Players::Human.new("O"))
|
20
|
+
else
|
21
|
+
puts "\nError - please choose a mode.".blue
|
22
|
+
game = load_mode
|
23
|
+
end
|
24
|
+
game
|
25
|
+
end
|
26
|
+
|
27
|
+
def play
|
28
|
+
puts "\nDo you want to play? Type 'Y or N'".blue
|
29
|
+
answer = gets.strip.upcase
|
30
|
+
while answer != "N"
|
31
|
+
game = load_mode
|
32
|
+
game.play
|
33
|
+
puts "\nDo you want to play? Type 'Y or N'".blue
|
34
|
+
answer = gets.strip.upcase
|
35
|
+
end
|
36
|
+
puts "\nThanks for playing - goodbye.".blue
|
37
|
+
end
|
38
|
+
|
39
|
+
play
|
data/lib/board.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require "pry"
|
2
|
+
class Board
|
3
|
+
attr_accessor :cells
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@cells = Array.new(9, " ")
|
8
|
+
end
|
9
|
+
|
10
|
+
def reset!
|
11
|
+
@cells = Array.new(9, " ")
|
12
|
+
end
|
13
|
+
|
14
|
+
def input=(input)
|
15
|
+
@input = gets.strip
|
16
|
+
@input.to_i
|
17
|
+
end
|
18
|
+
|
19
|
+
def display
|
20
|
+
puts " #{@cells[0]} | #{@cells[1]} | #{@cells[2]} "
|
21
|
+
puts "-----------"
|
22
|
+
puts " #{@cells[3]} | #{@cells[4]} | #{@cells[5]} "
|
23
|
+
puts "-----------"
|
24
|
+
puts " #{@cells[6]} | #{@cells[7]} | #{@cells[8]} "
|
25
|
+
end
|
26
|
+
|
27
|
+
def position(input)
|
28
|
+
index = (input.to_i - 1)
|
29
|
+
@cells[index]
|
30
|
+
end
|
31
|
+
|
32
|
+
def full?
|
33
|
+
@cells.include?(" " || "" || nil) ? false : true
|
34
|
+
end
|
35
|
+
|
36
|
+
def turn_count
|
37
|
+
x_turns = @cells.count("X")
|
38
|
+
o_turns = @cells.count("O")
|
39
|
+
turn_count = x_turns + o_turns
|
40
|
+
return turn_count
|
41
|
+
end
|
42
|
+
|
43
|
+
def taken?(input)
|
44
|
+
if position(input) == "X"
|
45
|
+
true
|
46
|
+
elsif position(input) == "O"
|
47
|
+
true
|
48
|
+
else
|
49
|
+
false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def valid_move?(input)
|
54
|
+
if (input.to_i.between?(1,9) == true) && (taken?(input.to_i) == false)
|
55
|
+
return true
|
56
|
+
else
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def update(position, player)
|
62
|
+
index = (position.to_i - 1)
|
63
|
+
@cells[index] = player.token
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
data/lib/game.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
class Game
|
2
|
+
require "pry"
|
3
|
+
|
4
|
+
attr_accessor :board, :player_1, :player_2
|
5
|
+
WIN_COMBINATIONS =
|
6
|
+
[[0,1,2],
|
7
|
+
[3,4,5],
|
8
|
+
[6,7,8],
|
9
|
+
[0,3,6],
|
10
|
+
[1,4,7],
|
11
|
+
[2,5,8],
|
12
|
+
[0,4,8],
|
13
|
+
[2,4,6]]
|
14
|
+
|
15
|
+
def initialize(player_1 = Players::Human.new("X"), player_2 = Players::Human.new("O"), board = Board.new)
|
16
|
+
@board = board
|
17
|
+
@player_1 = player_1
|
18
|
+
@player_2 = player_2
|
19
|
+
end
|
20
|
+
|
21
|
+
def current_player
|
22
|
+
self.board.turn_count.even? ? self.player_1 : self.player_2
|
23
|
+
end
|
24
|
+
|
25
|
+
def won?
|
26
|
+
#binding.pry
|
27
|
+
result = nil
|
28
|
+
WIN_COMBINATIONS.each do |sub_array|
|
29
|
+
index_1 = sub_array[0]
|
30
|
+
index_2 = sub_array[1]
|
31
|
+
index_3 = sub_array[2]
|
32
|
+
|
33
|
+
board_index_1 = self.board.cells[index_1]
|
34
|
+
board_index_2 = self.board.cells[index_2]
|
35
|
+
board_index_3 = self.board.cells[index_3]
|
36
|
+
if (board_index_1 == "X" && board_index_2 == "X" && board_index_3 == "X") || (board_index_1 == "O" && board_index_2 == "O" && board_index_3 == "O")
|
37
|
+
result = sub_array
|
38
|
+
end
|
39
|
+
end
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
def draw?
|
44
|
+
if won?
|
45
|
+
false
|
46
|
+
elsif !self.board.full?
|
47
|
+
false
|
48
|
+
else
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def over?
|
54
|
+
if draw?
|
55
|
+
return true
|
56
|
+
elsif won?
|
57
|
+
return true
|
58
|
+
else
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def winner
|
64
|
+
sub_array = won?
|
65
|
+
if won? == nil
|
66
|
+
nil
|
67
|
+
elsif self.board.cells[sub_array[1]] == "X"
|
68
|
+
"X"
|
69
|
+
elsif self.board.cells[sub_array[1]] == "O"
|
70
|
+
"O"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def turn
|
75
|
+
input = self.current_player.move(self.board).to_i
|
76
|
+
player = current_player
|
77
|
+
if self.board.valid_move?(input)
|
78
|
+
self.board.update(input, player)
|
79
|
+
self.board.display
|
80
|
+
else
|
81
|
+
turn
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def play
|
87
|
+
turn until over?
|
88
|
+
if draw?
|
89
|
+
puts "\n>>>Cat's Game!<<<".red
|
90
|
+
elsif over?
|
91
|
+
puts "\n>>>Congratulations #{winner}!<<<".blue
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
data/lib/player.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
module Players
|
2
|
+
class Computer < Player
|
3
|
+
|
4
|
+
require "pry"
|
5
|
+
|
6
|
+
CLOSE_COMBINATIONS =
|
7
|
+
[[0,1,2],
|
8
|
+
[3,4,5],
|
9
|
+
[6,7,8],
|
10
|
+
[0,3,6],
|
11
|
+
[1,4,7],
|
12
|
+
[2,5,8],
|
13
|
+
[0,4,8],
|
14
|
+
[2,4,6]]
|
15
|
+
|
16
|
+
def move(board)
|
17
|
+
#binding.pry
|
18
|
+
puts "\nPlayer #{self.token} - Please input a #1-9.".blue
|
19
|
+
input = "#{psuedo_gets(board)}"
|
20
|
+
input
|
21
|
+
end
|
22
|
+
|
23
|
+
def psuedo_gets(board)
|
24
|
+
gets_position = 0
|
25
|
+
positions = []
|
26
|
+
if close(board) != []
|
27
|
+
close(board).each do |sub_array|
|
28
|
+
sub_array.each do |value|
|
29
|
+
test = value+1
|
30
|
+
if board.valid_move?(test)
|
31
|
+
positions << test
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
gets_position = positions.sample
|
36
|
+
else
|
37
|
+
board.cells.each_with_index do |v, i|
|
38
|
+
test = i+1
|
39
|
+
if board.taken?(test) == false
|
40
|
+
positions << test
|
41
|
+
end
|
42
|
+
end
|
43
|
+
gets_position = positions.sample
|
44
|
+
end
|
45
|
+
puts gets_position
|
46
|
+
gets_position
|
47
|
+
end
|
48
|
+
|
49
|
+
def close(board)
|
50
|
+
#binding.pry
|
51
|
+
result = []
|
52
|
+
CLOSE_COMBINATIONS.each_with_index do |sub_array, index|
|
53
|
+
#these return the numbers/indexes associated with a winning combination
|
54
|
+
number_1 = sub_array[0]
|
55
|
+
number_2 = sub_array[1]
|
56
|
+
number_3 = sub_array[2]
|
57
|
+
|
58
|
+
#these tell you the values associated with an index
|
59
|
+
board_index_1 = board.cells[number_1]
|
60
|
+
board_index_2 = board.cells[number_2]
|
61
|
+
board_index_3 = board.cells[number_3]
|
62
|
+
|
63
|
+
#this checks to see if 2 of the values are the same, and if the last value is open && valid
|
64
|
+
if ((board_index_1 == "X" || board_index_1 == "O") && board_index_1 == board_index_2 && board.valid_move?(number_3+1)) ||
|
65
|
+
((board_index_2 == "X" || board_index_2 == "O") && board_index_2 == board_index_3 && board.valid_move?(number_1+1)) ||
|
66
|
+
((board_index_1 == "X" || board_index_1 == "O") && board_index_1 == board_index_3 && board.valid_move?(number_2+1))
|
67
|
+
result << sub_array
|
68
|
+
end
|
69
|
+
end
|
70
|
+
result
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mic-mac-moe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mackenzie Moore
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: require_all
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: colorize
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: TicTacToe with AI! Play against the computer, against a friend, or watch
|
84
|
+
the computers duke it out.
|
85
|
+
email:
|
86
|
+
- macmoore@ucdavis.edu
|
87
|
+
executables:
|
88
|
+
- tictactoe.rb
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- bin/tictactoe.rb
|
93
|
+
- config/environment.rb
|
94
|
+
- lib/board.rb
|
95
|
+
- lib/game.rb
|
96
|
+
- lib/player.rb
|
97
|
+
- lib/players/computer.rb
|
98
|
+
- lib/players/human.rb
|
99
|
+
homepage: https://github.com/mackenzie-km/mic-mac-moe.git
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata:
|
103
|
+
homepage_uri: https://github.com/mackenzie-km/mic-mac-moe.git
|
104
|
+
source_code_uri: https://github.com/mackenzie-km/mic-mac-moe.git
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubygems_version: 3.0.3
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: "{TicTacToe with AI!}"
|
124
|
+
test_files: []
|