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 +7 -0
- data/lib/tic_tac_toe_master/board.rb +50 -0
- data/lib/tic_tac_toe_master/game.rb +40 -0
- data/lib/tic_tac_toe_master/player.rb +13 -0
- data/lib/tic_tac_toe_master/ui/console_ui.rb +42 -0
- data/lib/tic_tac_toe_master/version.rb +5 -0
- data/lib/tic_tac_toe_master.rb +58 -0
- metadata +51 -0
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,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,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: []
|