ruby_terminal_games 0.1.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33a5a845ad2fa70bcfb583e07de91e99365c6166
4
- data.tar.gz: 71a0188aca20407a84d330fcc146eee7e0fd1c2c
3
+ metadata.gz: daca2f7a086e3e6efb02744675de934890622b86
4
+ data.tar.gz: 643e9c2bff3684d7b92216db2201c787b8f889c9
5
5
  SHA512:
6
- metadata.gz: d8290f1216a58bd49934b890c0583797ea65e370502a4d1b784902d6f4f6ede849cf09fa9d19eb92c0af40c0aade950afe2379b3cd3ee01039c39994a069ca11
7
- data.tar.gz: f74ba59d7a52048571bbfb7951efea69b81389c1d99aad6451bc47b4b8e87bba537730504416523d19b21ded48822e33ca8a6af4be55a594072770cdfc023eff
6
+ metadata.gz: 28f69c1ec650b408448ceabbe874aaccea983d82b20194352eaa4e95227457ee2159dbda7b4ca4afcb964e1c242986e5a270bdebfc3acf9b352737a46e236b9a
7
+ data.tar.gz: 88d4f3e4bb29d61df49e62b566d19fabafeba42fba533afe488d53c17065cf44dcb1cbaf5f5f13aa5f8ff537d253ce3ec5baed6372def84e718c453bc501c385
data/README.md CHANGED
@@ -3,7 +3,8 @@
3
3
  The idea of the gem is provide some basic games to play on Terminal. Currently the gem has the games below:
4
4
 
5
5
  - [x] Snake
6
- - [ ] Hangman
6
+ - [x] Hangman
7
+ - [ ] Sudoku
7
8
  - Any suggestions?
8
9
 
9
10
  ## Installation
@@ -17,6 +17,7 @@ if command =~ /list/
17
17
  Games:
18
18
  - Snake (play snake)
19
19
  - Hangman (play hangman)
20
+ - Sudoku (play sudoku)
20
21
  EOT
21
22
  exit
22
23
  end
@@ -31,6 +32,8 @@ when /snake/
31
32
  RubyTerminalGames::Snake::Game.new
32
33
  when /hangman/
33
34
  RubyTerminalGames::Hangman::Game.new
35
+ when /sudoku/
36
+ RubyTerminalGames::Sudoku::Game.new
34
37
  end
35
38
 
36
39
  if game
@@ -3,7 +3,7 @@ require_relative 'word'
3
3
 
4
4
  module RubyTerminalGames
5
5
  module Hangman
6
- class Game
6
+ class Game < RubyTerminalGames::Game
7
7
  attr_reader :word, :guess_total, :board, :input_index,
8
8
  :wrong_guesses
9
9
 
@@ -48,7 +48,7 @@ module RubyTerminalGames
48
48
  end
49
49
 
50
50
  def game_interval!
51
- sleep(0.05)
51
+ sleep(0.1)
52
52
  end
53
53
  end
54
54
  end
@@ -32,7 +32,7 @@ module RubyTerminalGames
32
32
 
33
33
  def draw_apple!(apple)
34
34
  row, col = apple.position
35
- write("❤", row: row, col: col)
35
+ write("❤".red, row: row, col: col)
36
36
  end
37
37
 
38
38
  def draw_snake!(snake_state, direction)
@@ -0,0 +1,117 @@
1
+ module RubyTerminalGames
2
+ module Sudoku
3
+ class Board < RubyTerminalGames::Board
4
+ def print_board(game)
5
+ clear!
6
+ print_top_border!
7
+ print_middle_borders!
8
+ print_bottom_border!
9
+ print_instructions!
10
+
11
+ user_inputs = game.user_inputs
12
+ user_input_index = game.user_input_index
13
+ state = game.puzzle.state
14
+
15
+ user_inputs.each_with_index do |input, index|
16
+ highlight = (input == user_inputs[user_input_index])
17
+ row, col = input
18
+ number = (state[index] || " ").to_s
19
+
20
+ if game.puzzle.locked_position?(index)
21
+ if highlight
22
+ output = number.colorize(
23
+ background: :green,
24
+ color: :white
25
+ )
26
+ else
27
+ output = number.colorize(color: :green)
28
+ end
29
+ else
30
+ output = number
31
+
32
+ if highlight
33
+ output = number
34
+ .colorize(background: :light_yellow, color: :black)
35
+ end
36
+ end
37
+
38
+ write(output, row: row, col: col)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def corner_cols
45
+ [
46
+ 2, 3, 4, 5, 6, 8,
47
+ 9, 10, 11, 12, 14,
48
+ 15, 16, 17, 18
49
+ ]
50
+ end
51
+
52
+ def middle_rows
53
+ [
54
+ 2, 3, 4, 5, 6,
55
+ 8, 9, 10, 11, 12,
56
+ 14, 15, 16, 17, 18
57
+ ]
58
+ end
59
+
60
+ def middle_columns
61
+ [
62
+ 2, 3, 4,
63
+ 6, 7, 8,
64
+ 10, 11, 12
65
+ ]
66
+ end
67
+
68
+ def print_top_border!
69
+ write("┌", row: 1, col: 1)
70
+ write("┬", row: 1, col: 7)
71
+ write("┬", row: 1, col: 13)
72
+ write("┐", row: 1, col: 19)
73
+ end
74
+
75
+ def print_middle_borders!
76
+ write("├", row: 5, col: 1)
77
+ write("┼", row: 5, col: 7)
78
+ write("┼", row: 5, col: 13)
79
+ write("┤", row: 5, col: 19)
80
+ write("├", row: 9, col: 1)
81
+ write("┼", row: 9, col: 7)
82
+ write("┼", row: 9, col: 13)
83
+ write("┤", row: 9, col: 19)
84
+
85
+ middle_rows.each do |col|
86
+ write("┈", row: 5, col: col)
87
+ write("┈", row: 9, col: col)
88
+ end
89
+
90
+ middle_columns.each do |row|
91
+ write("┊", row: row, col: 7)
92
+ write("┊", row: row, col: 13)
93
+ end
94
+ end
95
+
96
+ def print_bottom_border!
97
+ write("└", row: 13, col: 1)
98
+ write("┴", row: 13, col: 7)
99
+ write("┴", row: 13, col: 13)
100
+ write("┘", row: 13, col: 19)
101
+ end
102
+
103
+ def print_bottom_line!
104
+ write("─"*width, row: 14, col: 1)
105
+ end
106
+
107
+ def print_instructions!
108
+ print_bottom_line!
109
+ text = 'Use 0 to clear input'
110
+ write(text, row: 15, col: 1)
111
+
112
+ exit_text = 'Press Q to exit'
113
+ write(exit_text, row: 15, col: width - exit_text.length)
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,77 @@
1
+ require_relative 'puzzle'
2
+ require_relative 'board'
3
+
4
+ module RubyTerminalGames
5
+ module Sudoku
6
+ class Game < RubyTerminalGames::Game
7
+ attr_reader :board, :puzzle, :user_input_index, :user_input
8
+ def initialize
9
+ @puzzle = Puzzle.new
10
+ @board = Board.new
11
+ @user_input_index = 0
12
+ end
13
+
14
+ def play!
15
+ @playing = true
16
+ Keyboard.capture(detect_direction: true) do |key|
17
+ begin
18
+ @playing = false if key =~ /q/
19
+ if direction_key?(key)
20
+ move_user_input(key)
21
+ else
22
+ if allowed_input?(key)
23
+ add_user_input(key.to_i)
24
+ end
25
+ end
26
+ rescue
27
+ Keyboard.stop_capture
28
+ @playing = false
29
+ end
30
+ end
31
+
32
+ while @playing
33
+ board.print_board(self)
34
+ sleep(0.1)
35
+ end
36
+ end
37
+
38
+ def user_inputs
39
+ @user_inputs ||= begin
40
+ inputs = []
41
+ [2, 3, 4, 6, 7, 8, 10, 11, 12].each do |row|
42
+ [2, 4, 6, 8, 10, 12, 14, 16, 18].each do |col|
43
+ inputs << [row, col]
44
+ end
45
+ end
46
+ inputs
47
+ end
48
+ end
49
+
50
+ def direction_key?(key)
51
+ [UP, LEFT, RIGHT, DOWN].include?(key)
52
+ end
53
+
54
+ def move_user_input(key)
55
+ moved = case key
56
+ when UP
57
+ [user_input_index - 9, 0].max
58
+ when RIGHT
59
+ [user_input_index + 1, 80].min
60
+ when LEFT
61
+ [user_input_index - 1, 0].max
62
+ when DOWN
63
+ [user_input_index + 9, 80].min
64
+ end
65
+ @user_input_index = moved
66
+ end
67
+
68
+ def allowed_input?(key)
69
+ ('0'..'9').include?(key)
70
+ end
71
+
72
+ def add_user_input(input)
73
+ puzzle.add_input(input, user_input_index)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,105 @@
1
+ module RubyTerminalGames
2
+ module Sudoku
3
+ class Puzzle
4
+ attr_reader :state, :locked_positions
5
+ def initialize
6
+ @locked_positions = []
7
+ @state = build_puzzle
8
+ end
9
+
10
+ def add_input(input, user_input_index)
11
+ return if locked_position?(user_input_index)
12
+ input = nil if input.zero?
13
+ previous = state[user_input_index]
14
+ @state[user_input_index] = input
15
+ return true if valid?
16
+ @state[user_input_index] = previous
17
+ false
18
+ end
19
+
20
+ def locked_position?(user_input_index)
21
+ locked_positions.include?(user_input_index)
22
+ end
23
+
24
+ private
25
+
26
+ def puzzle_string
27
+ path = File.expand_path(
28
+ File.join(File.dirname(__FILE__), "puzzles.txt"))
29
+
30
+ File.readlines(path)
31
+ .map { |line|
32
+ line.strip
33
+ }.reject { |w| w.empty? }.sample
34
+ end
35
+
36
+ def build_puzzle
37
+ puzzle_string.chars.each_with_index.map do |char, index|
38
+ number = char.to_i
39
+ @locked_positions << index unless number.zero?
40
+ number.zero? ? nil : number
41
+ end
42
+ end
43
+
44
+ def valid?
45
+ valid_rows? && valid_columns? && valid_squares?
46
+ end
47
+
48
+ def valid_rows?
49
+ rows.each do |row|
50
+ return false if row.compact.size != row.compact.uniq.size
51
+ end
52
+ true
53
+ end
54
+
55
+ def valid_columns?
56
+ columns.each do |col|
57
+ return false if col.compact.size != col.compact.uniq.size
58
+ end
59
+ true
60
+ end
61
+
62
+ def valid_squares?
63
+ squares.each do |square|
64
+ return false if square.compact.size != square.compact.uniq.size
65
+ end
66
+ true
67
+ end
68
+
69
+ def rows
70
+ (0..8).map do |i|
71
+ start = i * 9
72
+ (start..start+8).map { |j| state[j] }
73
+ end
74
+ end
75
+
76
+ def columns
77
+ (0..8).map do |i|
78
+ (0..9).map do |n|
79
+ state[n*9 + i]
80
+ end
81
+ end
82
+ end
83
+
84
+ def squares
85
+ [
86
+ [0, 1, 2],
87
+ [3, 4, 5],
88
+ [6, 7, 8],
89
+ [27, 28, 29],
90
+ [30, 31, 32],
91
+ [33, 34, 35],
92
+ [54, 55, 56],
93
+ [57, 58, 59],
94
+ [60, 61, 62]
95
+ ].map do |group|
96
+ group.map { |i|
97
+ [0, 9, 18].map { |j|
98
+ state[i + j]
99
+ }.flatten
100
+ }.flatten
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,5 @@
1
+ 009006080000457210021389465150802937090003801873005604980534006400701398300068540
2
+ 630100009700030600490607130050300090947865000103000400829000570060798301071056000
3
+ 810000000000100304050706018140300062005009800000000000020900405093810700406500000
4
+ 008003000301000200029005000200070000000506400100040008000020000000090100000000800
5
+ 000000700000000600300000100000006000000010000000070001000060500000000000000000000
@@ -0,0 +1,5 @@
1
+ module RubyTerminalGames
2
+ module Sudoku
3
+ end
4
+ end
5
+ require_relative 'sudoku/game'
@@ -1,3 +1,3 @@
1
1
  module RubyTerminalGames
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -14,3 +14,4 @@ require_relative 'ruby_terminal_games/board'
14
14
  require_relative 'ruby_terminal_games/keyboard'
15
15
  require_relative 'ruby_terminal_games/snake'
16
16
  require_relative 'ruby_terminal_games/hangman'
17
+ require_relative 'ruby_terminal_games/sudoku'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_terminal_games
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Alves
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-18 00:00:00.000000000 Z
11
+ date: 2015-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -89,6 +89,11 @@ files:
89
89
  - lib/ruby_terminal_games/snake/board.rb
90
90
  - lib/ruby_terminal_games/snake/game.rb
91
91
  - lib/ruby_terminal_games/snake/snake.rb
92
+ - lib/ruby_terminal_games/sudoku.rb
93
+ - lib/ruby_terminal_games/sudoku/board.rb
94
+ - lib/ruby_terminal_games/sudoku/game.rb
95
+ - lib/ruby_terminal_games/sudoku/puzzle.rb
96
+ - lib/ruby_terminal_games/sudoku/puzzles.txt
92
97
  - lib/ruby_terminal_games/version.rb
93
98
  homepage: https://github.com/alvesdan/ruby_terminal_games
94
99
  licenses:
@@ -110,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
115
  version: '0'
111
116
  requirements: []
112
117
  rubyforge_project:
113
- rubygems_version: 2.4.5
118
+ rubygems_version: 2.2.2
114
119
  signing_key:
115
120
  specification_version: 4
116
121
  summary: Ruby Terminal Games