oxo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 57d6bbd4f6bdd8eefcd5c93ec1db4645b9ee8cc3
4
+ data.tar.gz: 1a5f97f7dbb659b20951af02d1bddc5852b518f3
5
+ SHA512:
6
+ metadata.gz: 31d6af29d95dfd648649b8f55906d1909b86fa4b8f1ef1fa9ce8160c36fc75b3cebb7eafa2e7a2f4171742e48be48ad380ee618e7e2971594fdddb3e9b016302
7
+ data.tar.gz: 475eb3b11dc66209b9c5d4ca76be472dbdd7de717f081191b6de95057f20f349f41e85ec263a12151cb9a7c3af07b27ef7951a6739f705e46cc651be5807377e
@@ -0,0 +1,42 @@
1
+ oxo
2
+ ===
3
+
4
+ `oxo` is a command line Tic-tac-toe game written in [Ruby][ruby].
5
+
6
+ ## Getting Started
7
+
8
+ Start a game with
9
+
10
+ ``` sh
11
+ $ oxo
12
+ ```
13
+
14
+ and have fun!
15
+
16
+ ## Documentation
17
+
18
+ Use `oxo --help` to display a brief help message.
19
+
20
+ ## Installation
21
+
22
+ Use `gem install oxo` to install from RubyGems.org.
23
+
24
+ ## Requirements
25
+
26
+ - [Ruby][ruby] 2.0.0 or higher
27
+
28
+ ## Reporting Bugs
29
+
30
+ Report bugs on the `oxo` home page: <https://github.com/stomar/oxo/>
31
+
32
+ ## License
33
+
34
+ Copyright &copy; 2016 Marcus Stollsteimer
35
+
36
+ `oxo` is free software: you can redistribute it and/or modify it under
37
+ the terms of the GNU General Public License version 3 or later (GPLv3+),
38
+ see [www.gnu.org/licenses/gpl.html](http://www.gnu.org/licenses/gpl.html).
39
+ There is NO WARRANTY, to the extent permitted by law.
40
+
41
+
42
+ [ruby]: https://www.ruby-lang.org/
@@ -0,0 +1,27 @@
1
+ require "rake/testtask"
2
+
3
+
4
+ def gemspec_file
5
+ "oxo.gemspec"
6
+ end
7
+
8
+
9
+ task :default => [:test]
10
+
11
+ Rake::TestTask.new do |t|
12
+ t.pattern = "test/**/test_*.rb"
13
+ t.verbose = true
14
+ t.warning = true
15
+ end
16
+
17
+
18
+ desc "Build gem"
19
+ task :build do
20
+ sh "gem build #{gemspec_file}"
21
+ end
22
+
23
+
24
+ desc "Remove generated files"
25
+ task :clean do
26
+ FileUtils.rm(Dir.glob("*.gem"))
27
+ end
data/bin/oxo ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "oxo"
4
+
5
+ OXO::Application.new.run
@@ -0,0 +1,175 @@
1
+ require "optparse"
2
+
3
+ require "oxo/version"
4
+ require "oxo/board"
5
+ require "oxo/computer"
6
+ require "oxo/human"
7
+
8
+ # == Name
9
+ #
10
+ # oxo - a command line Tic-tac-toe game
11
+ #
12
+ # == See also
13
+ #
14
+ # Use <tt>oxo --help</tt> to display a brief help message.
15
+ #
16
+ # The full documentation for +oxo+ is available on the
17
+ # project home page.
18
+ #
19
+ # == Author
20
+ #
21
+ # Copyright (C) 2016 Marcus Stollsteimer
22
+ #
23
+ # License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
24
+ #
25
+ module OXO
26
+
27
+ PROGNAME = "oxo"
28
+
29
+ COPYRIGHT = <<-copyright.gsub(/^ +/, "")
30
+ Copyright (C) 2016 Marcus Stollsteimer.
31
+ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
32
+ This is free software: you are free to change and redistribute it.
33
+ There is NO WARRANTY, to the extent permitted by law.
34
+ copyright
35
+
36
+
37
+ class Optionparser
38
+
39
+ # Parses the command line options from +argv+.
40
+ # (+argv+ is cleared).
41
+ # Might print out help or version information.
42
+ #
43
+ # +argv+ - array with the command line options
44
+ #
45
+ # Returns a hash containing the option parameters.
46
+ def self.parse!(argv)
47
+
48
+ options = {
49
+ :delay => 0
50
+ }
51
+
52
+ opt_parser = OptionParser.new do |opt|
53
+ opt.banner = "Usage: #{PROGNAME} [options]"
54
+ opt.separator %q{
55
+ oxo is a command line Tic-tac-toe game.
56
+
57
+ Options:
58
+ }.gsub(/^ +/, "")
59
+
60
+ # process --version and --help first,
61
+ # exit successfully (GNU Coding Standards)
62
+ opt.on_tail("-h", "--help", "Print a brief help message and exit.") do
63
+ puts opt_parser
64
+ puts "\nReport bugs on the #{PROGNAME} home page: <#{HOMEPAGE}>"
65
+ exit
66
+ end
67
+
68
+ opt.on_tail("-v", "--version",
69
+ "Print a brief version information and exit.") do
70
+ puts "#{PROGNAME} #{VERSION}"
71
+ puts COPYRIGHT
72
+ exit
73
+ end
74
+
75
+ opt.on("-d", "--delay SECONDS", Float,
76
+ "Set delay time for oxo's moves.") do |d|
77
+ options[:delay] = d
78
+ end
79
+
80
+ opt.separator ""
81
+ end
82
+ opt_parser.parse!(argv)
83
+
84
+ # nothing should be left in argv
85
+ raise(ArgumentError, "wrong number of arguments") unless argv.empty?
86
+
87
+ options
88
+ end
89
+ end
90
+
91
+
92
+ class Application
93
+
94
+ ERRORCODE = {:general => 1, :usage => 2}
95
+
96
+ def initialize
97
+ begin
98
+ options = Optionparser.parse!(ARGV)
99
+ rescue => e
100
+ usage_fail(e.message)
101
+ end
102
+
103
+ @delay = options[:delay]
104
+ end
105
+
106
+ def run
107
+ board = Board.new
108
+
109
+ case beginning_side
110
+ when :quit
111
+ return
112
+ when :human
113
+ players = [Human.new(:X), Computer.new(:O, delay: @delay)]
114
+ puts board
115
+ when :computer
116
+ players = [Computer.new(:X, delay: @delay), Human.new(:O)]
117
+ end
118
+
119
+ game_over = false
120
+
121
+ until game_over
122
+ player = players.first
123
+ move = player.make_move(board)
124
+
125
+ break if move == :quit
126
+
127
+ board.place(player.color, move[0], move[1])
128
+
129
+ puts board
130
+ puts "Move of #{player.name} was: #{(move[0] - 1) * 3 + move[1]}"
131
+
132
+ if board.win?(player.color)
133
+ puts "#{player.name} wins!"
134
+ game_over = true
135
+ elsif board.full?
136
+ puts "It's a draw."
137
+ game_over = true
138
+ end
139
+
140
+ players.rotate!
141
+ end
142
+ end
143
+
144
+ private
145
+
146
+ def beginning_side
147
+ choices = {
148
+ "1" => :human, "" => :human,
149
+ "2" => :computer,
150
+ "0" => :quit, "q" => :quit
151
+ }
152
+
153
+ answer = nil
154
+ until choices.keys.include?(answer)
155
+ print "Beginning side (1=Human, 2=Computer, 0/q=quit)? "
156
+ answer = gets.chomp
157
+ end
158
+
159
+ choices[answer]
160
+ end
161
+
162
+ # Prints an error message and exits.
163
+ def general_fail(message)
164
+ warn "#{PROGNAME}: #{message}"
165
+ exit ERRORCODE[:general]
166
+ end
167
+
168
+ # Prints an error message and a short help information, then exits.
169
+ def usage_fail(message)
170
+ warn "#{PROGNAME}: #{message}"
171
+ warn "Use `#{PROGNAME} --help' for valid options."
172
+ exit ERRORCODE[:usage]
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,72 @@
1
+ module OXO
2
+ class Board
3
+
4
+ attr_accessor :rows, :cols
5
+
6
+ def initialize
7
+ @rows, @cols = 3, 3
8
+ @board = Array.new(@rows) { Array.new(@cols) }
9
+ end
10
+
11
+ def legal_move?(row, col)
12
+ on_board?(row, col) && !piece_at(row, col)
13
+ end
14
+
15
+ def place(color, row, col)
16
+ return unless legal_move?(row, col)
17
+ @board[row-1][col-1] = color
18
+ end
19
+
20
+ def legal_moves
21
+ empty_squares = []
22
+
23
+ 1.upto(rows) do |row|
24
+ 1.upto(cols) do |col|
25
+ empty_squares << [row, col] unless piece_at(row, col)
26
+ end
27
+ end
28
+
29
+ empty_squares
30
+ end
31
+
32
+ def full?
33
+ !@board.flatten.include? nil
34
+ end
35
+
36
+ def win?(color)
37
+ @board.each {|row| return true if row.uniq == [color] }
38
+ @board.transpose.each {|col| return true if col.uniq == [color] }
39
+ return true if @board.flatten.values_at(0, 4, 8).uniq == [color]
40
+ return true if @board.flatten.values_at(2, 4, 6).uniq == [color]
41
+
42
+ false
43
+ end
44
+
45
+ def to_s
46
+ output = "\n"
47
+ hline = "+---" * @cols << "+\n"
48
+
49
+ characters = @board.map {|row| row.map {|pos| pos.to_s.ljust(1) } }
50
+
51
+ output << hline
52
+ characters.each do |row|
53
+ output << "| " << row.join(" | ") << " |" << "\n"
54
+ output << hline
55
+ end
56
+
57
+ output + "\n"
58
+ end
59
+
60
+ private
61
+
62
+ def on_board?(row, col)
63
+ (1..@rows).include?(row) && (1..@cols).include?(col)
64
+ end
65
+
66
+ def piece_at(row, col)
67
+ return unless on_board?(row, col)
68
+
69
+ @board[row-1][col-1]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,21 @@
1
+ module OXO
2
+ class Computer
3
+
4
+ attr_reader :color
5
+
6
+ def initialize(color, delay: 0)
7
+ @color = color
8
+ @delay = delay
9
+ end
10
+
11
+ def name
12
+ "oxo"
13
+ end
14
+
15
+ def make_move(board)
16
+ sleep @delay
17
+
18
+ board.legal_moves.sample
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,46 @@
1
+ module OXO
2
+ class Human
3
+
4
+ attr_reader :color
5
+
6
+ def initialize(color)
7
+ @color = color
8
+ end
9
+
10
+ def name
11
+ "Human"
12
+ end
13
+
14
+ def make_move(board)
15
+ move = :illegal
16
+
17
+ while move == :illegal
18
+ print "Your move (1...9, 0/q=quit)? "
19
+ answer = gets.chomp
20
+
21
+ move = parse_answer(answer, board)
22
+
23
+ puts "Illegal move: #{answer}" if move == :illegal
24
+ end
25
+
26
+ move
27
+ end
28
+
29
+ private
30
+
31
+ def parse_answer(answer, board)
32
+ case answer
33
+ when "0", "q", "quit"
34
+ :quit
35
+ when /\d/
36
+ number = answer.to_i
37
+ row = (number - 1) / board.rows + 1
38
+ col = (number - 1) % board.cols + 1
39
+
40
+ board.legal_move?(row, col) ? [row, col] : :illegal
41
+ else
42
+ :illegal
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ module OXO
2
+ VERSION = "0.1.0"
3
+ DATE = "2016-04-27"
4
+ HOMEPAGE = "https://github.com/stomar/oxo/"
5
+ end
@@ -0,0 +1,40 @@
1
+ require_relative "lib/oxo/version"
2
+
3
+ version = OXO::VERSION
4
+ date = OXO::DATE
5
+ homepage = OXO::HOMEPAGE
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "oxo"
9
+ s.version = version
10
+ s.date = date
11
+
12
+ s.summary = "oxo is a command line Tic-tac-toe game."
13
+ s.description = s.summary
14
+
15
+ s.authors = ["Marcus Stollsteimer"]
16
+ s.email = "sto.mar@web.de"
17
+ s.homepage = homepage
18
+
19
+ s.license = "GPL-3.0"
20
+
21
+ s.required_ruby_version = ">= 2.0.0"
22
+
23
+ s.add_development_dependency "rake", "~> 11.1"
24
+ s.add_development_dependency "minitest", "~> 5.8"
25
+
26
+ s.executables = ["oxo"]
27
+ s.bindir = "bin"
28
+
29
+ s.require_paths = ["lib"]
30
+
31
+ s.files = %w[
32
+ oxo.gemspec
33
+ README.md
34
+ Rakefile
35
+ ] +
36
+ Dir.glob("{bin,lib,test}/**/*")
37
+
38
+ s.extra_rdoc_files = %w[README.md]
39
+ s.rdoc_options = ["--charset=UTF-8", "--main=README.md"]
40
+ end
@@ -0,0 +1,15 @@
1
+ require "minitest/autorun"
2
+ require "oxo/board"
3
+
4
+
5
+ describe OXO::Board do
6
+
7
+ before do
8
+ @board = OXO::Board.new
9
+ end
10
+
11
+ it "should have the correct size" do
12
+ @board.rows.must_equal 3
13
+ @board.cols.must_equal 3
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oxo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Marcus Stollsteimer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '11.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '11.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.8'
41
+ description: oxo is a command line Tic-tac-toe game.
42
+ email: sto.mar@web.de
43
+ executables:
44
+ - oxo
45
+ extensions: []
46
+ extra_rdoc_files:
47
+ - README.md
48
+ files:
49
+ - README.md
50
+ - Rakefile
51
+ - bin/oxo
52
+ - lib/oxo.rb
53
+ - lib/oxo/board.rb
54
+ - lib/oxo/computer.rb
55
+ - lib/oxo/human.rb
56
+ - lib/oxo/version.rb
57
+ - oxo.gemspec
58
+ - test/test_board.rb
59
+ homepage: https://github.com/stomar/oxo/
60
+ licenses:
61
+ - GPL-3.0
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options:
65
+ - "--charset=UTF-8"
66
+ - "--main=README.md"
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 2.0.0
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.5.1
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: oxo is a command line Tic-tac-toe game.
85
+ test_files: []