tic_tac_toe_master 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 351d57128ecff0b1e7863f2ef9b19deee6682ce88034d37ca1dadc84d221c724
4
+ data.tar.gz: a5ad2103845661007da9d62b74db2195c2b137ed326dd75e90a9a5b979cd889e
5
+ SHA512:
6
+ metadata.gz: 0e3901d3c0ddfe7161b359e22cb9fa7a0860a0dcb359e64b6031c3f278eba5e86e6d3eaf02010563215412fac66ecf20b8b399fceb29d5ac0ca4c42040b5e0f4
7
+ data.tar.gz: 3f8c37708cec0f31dae1b8868ab92e4ad85b5cc24afb7d043c0ee3d5eebc59605c10ea3352cd64eea0dd8f37fbd4753958ac63a0afa8b3d0bb982297f07701cd
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TicTacToeMaster
4
+ # Represents the game board for Tic Tac Toe
5
+ class Board
6
+ attr_reader :grid
7
+
8
+ FIELD_SIZE = (1..9)
9
+
10
+ WIN_CONBINATIONS = [
11
+ [0, 1, 2], [3, 4, 5], [6, 7, 8],
12
+ [0, 3, 6], [1, 4, 7], [2, 5, 8],
13
+ [0, 4, 8], [2, 4, 6]
14
+ ].freeze
15
+
16
+ def initialize
17
+ @grid = FIELD_SIZE.to_a
18
+ end
19
+
20
+ def draw
21
+ puts '-----------'
22
+
23
+ grid.each_slice(3) do |row|
24
+ puts " #{row.join(' | ')} "
25
+ puts '-----------'
26
+ end
27
+ end
28
+
29
+ def place(position, symbol)
30
+ return false unless valid_position?(position)
31
+
32
+ grid[position - 1] = symbol
33
+ true
34
+ end
35
+
36
+ def valid_position?(position)
37
+ FIELD_SIZE.cover?(position) && grid[position - 1].is_a?(Integer)
38
+ end
39
+
40
+ def full?
41
+ grid.none?(Integer)
42
+ end
43
+
44
+ def winner?(symbol)
45
+ WIN_CONBINATIONS.any? do |combo|
46
+ combo.all? { |index| grid[index] == symbol }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TicTacToeMaster
4
+ # Controls the main game flow
5
+ class Game
6
+ attr_reader :player1, :player2, :current_player, :board
7
+
8
+ def initialize(player1_name:, player2_name:)
9
+ @player1 = Player.new(player1_name, 'X')
10
+ @player2 = Player.new(player2_name, 'O')
11
+ @board = Board.new
12
+ @current_player = @player1
13
+ end
14
+
15
+ # Makes a move for the current player at the given position.
16
+ # Returns:
17
+ # :invalid - if the move is invalid
18
+ # :win - if the current player wins
19
+ # :draw - if the board is full (draw)
20
+ # :next_turn - if the game should continue
21
+ def make_move(position)
22
+ return :invalid unless board.place(position, current_player.symbol)
23
+
24
+ if board.winner?(current_player.symbol)
25
+ :win
26
+ elsif board.full?
27
+ :draw
28
+ else
29
+ switch_player
30
+ :next_turn
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def switch_player
37
+ @current_player = current_player == player1 ? player2 : player1
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TicTacToeMaster
4
+ # Represents a Player with name and symbol(X or O)
5
+ class Player
6
+ attr_reader :name, :symbol
7
+
8
+ def initialize(name, symbol)
9
+ @name = name
10
+ @symbol = symbol
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TicTacToeMaster
4
+ module UI
5
+ # Console interface display option
6
+ class ConsoleUI
7
+ def initialize(game)
8
+ @game = game
9
+ end
10
+
11
+ def start
12
+ puts 'šŸŽ® Welcome to Tic Tac Toe!'
13
+
14
+ loop do
15
+ @game.board.draw
16
+
17
+ case @game.make_move(ask_for_move)
18
+ when :invalid
19
+ puts 'āŒ Invalid move, try again.'
20
+ when :win
21
+ @game.board.draw
22
+ puts "šŸ† #{@game.current_player.name} wins!"
23
+ break
24
+ when :draw
25
+ @game.board.draw
26
+ puts "šŸ¤ It's a draw!"
27
+ break
28
+ end
29
+ end
30
+ puts "\nšŸ‘‹ Game over!"
31
+ end
32
+
33
+ private
34
+
35
+ def ask_for_move
36
+ print "\n#{@game.current_player.name} #{@game.current_player.symbol}, " \
37
+ "choose a position #{TicTacToeMaster::Board::FIELD_SIZE}: "
38
+ gets.to_i
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TicTacToeMaster
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tic_tac_toe_master/version'
4
+ require_relative 'tic_tac_toe_master/game'
5
+ require_relative 'tic_tac_toe_master/board'
6
+ require_relative 'tic_tac_toe_master/player'
7
+ require_relative 'tic_tac_toe_master/ui/console_ui'
8
+
9
+ # Main namespace for TicTacToeMaster gem.
10
+ # Provides an entry point to start the Tic Tac Toe game
11
+ # using different UI implementations (e.g., ConsoleUI, WebUI).
12
+ module TicTacToeMaster
13
+ class << self
14
+ # Starts the Tic Tac Toe game.
15
+ #
16
+ # Options:
17
+ # ui_class - the UI class to use (default: UI::ConsoleUI)
18
+ # player1_name, player2_name - optional names for players
19
+ #
20
+ # Examples:
21
+ # TicTacToeMaster.start
22
+ # TicTacToeMaster.start(ui_class: UI::ConsoleUI, player1_name: 'Alice', player2_name: 'Bob')
23
+ def start(ui_class: UI::ConsoleUI, player1_name: nil, player2_name: nil)
24
+ player1_name, player2_name = resolve_player_names(ui_class, player1_name, player2_name)
25
+
26
+ game = Game.new(player1_name: player1_name, player2_name: player2_name)
27
+ ui_class.new(game).start
28
+ end
29
+
30
+ private
31
+
32
+ # Determines or asks for player names depending on the UI type.
33
+ # For ConsoleUI, it prompts for names if not provided.
34
+ # For other UIs, both names must be passed explicitly.
35
+ #
36
+ # Returns an array: [player1_name, player2_name]
37
+ def resolve_player_names(ui_class, player1_name, player2_name)
38
+ if ui_class == UI::ConsoleUI
39
+ player1_name ||= ask_for_name('Player 1 (X)')
40
+ player2_name ||= ask_for_name('Player 2 (O)')
41
+ else
42
+ unless player1_name && player2_name
43
+ raise ArgumentError, 'player1_name and player2_name are required for non-console UI'
44
+ end
45
+ end
46
+
47
+ [player1_name, player2_name]
48
+ end
49
+
50
+ # Prompts the user to enter a name for the given player.
51
+ #
52
+ # Returns the entered string (stripped of whitespace).
53
+ def ask_for_name(label)
54
+ print "Enter name for #{label}: "
55
+ gets.strip
56
+ end
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tic_tac_toe_master
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Vitalii Matseiko
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-11-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: TicTacToeMaster is a gem that allows you to play Tic Tac Toe in the console.
14
+ email:
15
+ - realnatisk@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/tic_tac_toe_master.rb
21
+ - lib/tic_tac_toe_master/board.rb
22
+ - lib/tic_tac_toe_master/game.rb
23
+ - lib/tic_tac_toe_master/player.rb
24
+ - lib/tic_tac_toe_master/ui/console_ui.rb
25
+ - lib/tic_tac_toe_master/version.rb
26
+ homepage: https://github.com/Natisk/tic_tac_toe_master
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ allowed_push_host: https://rubygems.org
31
+ homepage_uri: https://github.com/Natisk/tic_tac_toe_master
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.5.16
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: A simple Tic Tac Toe game implemented in Ruby.
51
+ test_files: []