Skip to content

Commit

Permalink
TicTacToe
Browse files Browse the repository at this point in the history
  • Loading branch information
Amey-Thakur committed Aug 29, 2022
1 parent 41b5d76 commit 566884a
Show file tree
Hide file tree
Showing 14 changed files with 576 additions and 0 deletions.
2 changes: 2 additions & 0 deletions TicTacToe/.replit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language = "ruby"
run = "ruby lib/main.rb"
3 changes: 3 additions & 0 deletions TicTacToe/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--color
--require spec_helper
--format documentation
5 changes: 5 additions & 0 deletions TicTacToe/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
AllCops:
NewCops: enable
Exclude:
- 'spec/*'

9 changes: 9 additions & 0 deletions TicTacToe/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

source 'https://rubygems.org'

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
gem 'reek', '6.0.1'
gem 'rubocop', '0.82.0'
37 changes: 37 additions & 0 deletions TicTacToe/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.1)
jaro_winkler (1.5.4)
kwalify (0.7.2)
parallel (1.19.2)
parser (2.7.1.4)
ast (~> 2.4.1)
psych (3.1.0)
rainbow (3.0.0)
reek (6.0.1)
kwalify (~> 0.7.0)
parser (>= 2.5.0.0, < 2.8, != 2.5.1.1)
psych (~> 3.1.0)
rainbow (>= 2.0, < 4.0)
rexml (3.2.4)
rubocop (0.82.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
rexml
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
ruby-progressbar (1.10.1)
unicode-display_width (1.7.0)

PLATFORMS
ruby

DEPENDENCIES
reek (= 6.0.1)
rubocop (= 0.82.0)

BUNDLED WITH
2.1.4
4 changes: 4 additions & 0 deletions TicTacToe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# ruby_TicTacToe
This project is from [The Odin Project](https://www.theodinproject.com/courses/ruby-programming/lessons/oop)

[![Run on Repl.it](https://repl.it/badge/github/rlmoser99/ruby_TicTacToe)](https://repl.it/github/rlmoser99/ruby_TicTacToe)
47 changes: 47 additions & 0 deletions TicTacToe/lib/board.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

# Tic-Tac-Toe Board
class Board
attr_reader :cells

WINNING_COMBOS = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6],
[1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]
].freeze

def initialize
@cells = [1, 2, 3, 4, 5, 6, 7, 8, 9]
end

# rubocop:disable Metrics/AbcSize
def show
puts <<-HEREDOC
#{cells[0]} | #{cells[1]} | #{cells[2]}
---+---+---
#{cells[3]} | #{cells[4]} | #{cells[5]}
---+---+---
#{cells[6]} | #{cells[7]} | #{cells[8]}
HEREDOC
end
# rubocop:enable Metrics/AbcSize

def update_board(number, symbol)
@cells[number] = symbol
end

def valid_move?(number)
cells[number - 1] == number
end

def full?
cells.all? { |cell| cell =~ /[^0-9]/ }
end

def game_over?
WINNING_COMBOS.any? do |combo|
[cells[combo[0]], cells[combo[1]], cells[combo[2]]].uniq.length == 1
end
end
end
39 changes: 39 additions & 0 deletions TicTacToe/lib/display.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

# rubocop:disable Layout/LineLength

# Text needed to Tic-Tac-Toe
module Display
def display_intro
"Let's play a simple Tic-Tac-Toe game in the console! \n\n"
end

def display_name_prompt(number)
"What is the name of player ##{number}?"
end

def display_symbol_prompt
'What 1 letter (or special character) would you like to be your game marker?'
end

def display_first_symbol(duplicate)
"It can not be '#{duplicate}'"
end

def display_input_warning
"\e[31mSorry, that is an invalid answer. Please, try again.\e[0m"
end

def display_player_turn(name, symbol)
"#{name}, please enter a number (1-9) that is available to place an '#{symbol}'"
end

def display_winner(player)
"GAME OVER! #{player} is the winner!"
end

def display_tie
"It's a draw"
end
end
# rubocop:enable Layout/LineLength
93 changes: 93 additions & 0 deletions TicTacToe/lib/game.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# frozen_string_literal: true

require_relative 'display.rb'

# Contains the logic to play the game
class Game
include Display
attr_reader :first_player, :second_player, :board, :current_player

def initialize
@board = Board.new
@first_player = nil
@second_player = nil
@current_player = nil
end

def play
game_set_up
board.show
player_turns
conclusion
end

def create_player(number, duplicate_symbol = nil)
puts display_name_prompt(number)
name = gets.chomp
symbol = symbol_input(duplicate_symbol)
Player.new(name, symbol)
end

def turn(player)
cell = turn_input(player)
board.update_board(cell - 1, player.symbol)
board.show
end

private

def game_set_up
puts display_intro
@first_player = create_player(1)
@second_player = create_player(2, first_player.symbol)
end

def symbol_input(duplicate)
player_symbol_prompts(duplicate)
input = gets.chomp
return input if input.match?(/^[^0-9]$/) && input != duplicate

puts display_input_warning
symbol_input(duplicate)
end

def player_symbol_prompts(duplicate)
puts display_symbol_prompt
puts display_first_symbol(duplicate) if duplicate
end

def player_turns
@current_player = first_player
until board.full?
turn(current_player)
break if board.game_over?

@current_player = switch_current_player
end
end

def turn_input(player)
puts display_player_turn(player.name, player.symbol)
number = gets.chomp.to_i
return number if board.valid_move?(number)

puts display_input_warning
turn_input(player)
end

def switch_current_player
if current_player == first_player
second_player
else
first_player
end
end

def conclusion
if board.game_over?
puts display_winner(current_player.name)
else
puts display_tie
end
end
end
24 changes: 24 additions & 0 deletions TicTacToe/lib/main.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

require_relative 'board.rb'
require_relative 'player.rb'
require_relative 'game.rb'
require_relative 'display.rb'

def play_game
game = Game.new
game.play
repeat_game
end

def repeat_game
puts "Would you like to play a new game? Press 'y' for yes or 'n' for no."
repeat_input = gets.chomp.downcase
if repeat_input == 'y'
play_game
else
puts 'Thanks for playing!'
end
end

play_game
11 changes: 11 additions & 0 deletions TicTacToe/lib/player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

# Game need two players
class Player
attr_reader :name, :symbol

def initialize(name, symbol)
@name = name
@symbol = symbol
end
end
Loading

0 comments on commit 566884a

Please sign in to comment.