Created
September 6, 2013 00:59
-
-
Save steven-ferguson/6458243 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Board | |
def initialize(grid_length) | |
@spaces = [] | |
@grid_length = grid_length | |
create_spaces | |
end | |
attr_reader :spaces, :grid_length | |
def create_spaces | |
number_counter = 1 | |
(0...@grid_length).each do |row| | |
(0...@grid_length).each do |column| | |
@spaces << Space.new(number_counter, column, row) | |
number_counter += 1 | |
end | |
end | |
end | |
def get_row(row_number) | |
@spaces.select do |space| | |
space.row == row_number | |
end | |
end | |
def get_column(column_number) | |
@spaces.select do |space| | |
space.column == column_number | |
end | |
end | |
def get_negative_slope_diagonal | |
@spaces.select do |space| | |
space.column == space.row | |
end | |
end | |
def get_positive_slope_diagonal | |
@spaces.select do |space| | |
space.column + space.row == @grid_length - 1 | |
end | |
end | |
def has_winning_combination? | |
winning_row? || winning_column? || winning_diagonal? | |
end | |
def winning_row? | |
(0...@grid_length).any? do |row_number| | |
row = get_row(row_number) | |
row.all? do |space| | |
space.occupying_player == row[0].occupying_player && !row[0].occupying_player.nil? | |
end | |
end | |
end | |
def winning_column? | |
(0...@grid_length).any? do |column_number| | |
column = get_column(column_number) | |
column.all? do |space| | |
space.occupying_player == column[0].occupying_player && !column[0].occupying_player.nil? | |
end | |
end | |
end | |
def winning_diagonal? | |
diagonals = [get_negative_slope_diagonal, get_positive_slope_diagonal] | |
diagonals.any? do |diagonal| | |
diagonal.all? do |space| | |
space.occupying_player == diagonal[0].occupying_player && !diagonal[0].occupying_player.nil? | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'game' | |
require 'player' | |
require 'board' | |
require 'space' | |
describe Board do | |
it 'intializes with a grid length' do | |
board = Board.new(3) | |
board.should be_an_instance_of Board | |
end | |
it 'creates spaces based on the board size' do | |
board = Board.new(4) | |
board.spaces.length.should eq 16 | |
end | |
it 'creates spaces with the right number, column, and row' do | |
board = Board.new(3) | |
board.spaces[4].number.should eq 5 | |
board.spaces[4].column.should eq 1 | |
board.spaces[4].row.should eq 1 | |
end | |
describe 'get_row' do | |
it 'gets all the spaces from a specified row' do | |
board = Board.new(3) | |
row = board.get_row(0) | |
row[0].number.should eq 1 | |
row[1].number.should eq 2 | |
row[2].number.should eq 3 | |
end | |
end | |
describe 'get_column' do | |
it 'gets all the spaces from a specified column' do | |
board = Board.new(3) | |
column = board.get_column(0) | |
column[0].number.should eq 1 | |
column[1].number.should eq 4 | |
column[2].number.should eq 7 | |
end | |
end | |
describe 'get_negative_slope_diagonal' do | |
it 'gets all the spaces in the diagonal' do | |
board = Board.new(3) | |
diagonal = board.get_negative_slope_diagonal | |
diagonal[0].number.should eq 1 | |
diagonal[1].number.should eq 5 | |
diagonal[2].number.should eq 9 | |
end | |
end | |
describe 'get_positive_slope_diagonal' do | |
it 'gets all the spaces of the diagonal' do | |
board = Board.new(3) | |
diagonal = board.get_positive_slope_diagonal | |
diagonal[0].number.should eq 3 | |
diagonal[1].number.should eq 5 | |
diagonal[2].number.should eq 7 | |
end | |
end | |
describe 'winning_row?' do | |
it 'is false if all the spaces in a row are not occupied by the same player' do | |
board = Board.new(3) | |
board.winning_row?.should eq false | |
end | |
it 'is true if all the spaces in a row are occupied by the same player' do | |
board = Board.new(4) | |
player = Player.new('X') | |
board.spaces[0].occupy(player) | |
board.spaces[1].occupy(player) | |
board.spaces[2].occupy(player) | |
board.spaces[3].occupy(player) | |
board.winning_row?.should eq true | |
end | |
end | |
describe 'winning_column?' do | |
it 'is false if all the spaces in a column are not occupied by the same player' do | |
board = Board.new(3) | |
board.winning_column?.should eq false | |
end | |
it 'is true if all the spaces in a column are occupied by the same player' do | |
board = Board.new(4) | |
player = Player.new('X') | |
board.spaces[0].occupy(player) | |
board.spaces[4].occupy(player) | |
board.spaces[8].occupy(player) | |
board.spaces[12].occupy(player) | |
board.winning_column?.should eq true | |
end | |
end | |
describe 'winning_diagonal?' do | |
it 'is false if all the spaces in both diagonals are not occupied by the same player' do | |
board = Board.new(3) | |
board.winning_diagonal?.should eq false | |
end | |
it 'is true if all the spaces in a diagonal are occupied by the same player' do | |
board = Board.new(3) | |
player = Player.new('X') | |
board.spaces[0].occupy(player) | |
board.spaces[4].occupy(player) | |
board.spaces[8].occupy(player) | |
board.winning_diagonal?.should eq true | |
end | |
end | |
describe 'has_winning_combination?' do | |
it 'is false when the board does not have a winning combination' do | |
board = Board.new(3) | |
board.has_winning_combination?.should eq false | |
end | |
it 'is true when there is a winning comibination' do | |
board = Board.new(3) | |
player = Player.new('X') | |
board.spaces[0].occupy(player) | |
board.spaces[1].occupy(player) | |
board.spaces[2].occupy(player) | |
board.has_winning_combination?.should eq true | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Game | |
def initialize(number_of_players=2, board_size=3) | |
@players = [] | |
create_players(number_of_players) | |
@current_player = @players[0] | |
@board = Board.new(board_size) | |
end | |
attr_reader :players, :current_player, :board | |
def create_players(number_of_players) | |
symbols = { 0 => 'X', 1 => 'O', 2 => '@', 3 => '$', 4 => '&' } | |
number_of_players.times do |i| | |
@players << Player.new(symbols[i]) | |
end | |
end | |
def switch_current_player | |
@current_player = @players.pop | |
@players.unshift(@current_player) | |
end | |
def has_winner? | |
@board.has_winning_combination? | |
end | |
def over? | |
@board.spaces.all? { |space| space.occupied? } || has_winner? | |
end | |
def tie? | |
@board.spaces.all? { |space| space.occupied? } && !has_winner? | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'game' | |
require 'player' | |
require 'board' | |
require 'space' | |
describe Game do | |
it 'is initialized with a number of players and board size' do | |
game = Game.new(2, 3) | |
game.should be_an_instance_of Game | |
end | |
it 'has players' do | |
game = Game.new(3, 3) | |
game.players.length.should eq 3 | |
end | |
it 'has a board' do | |
game = Game.new(3, 3) | |
game.board.should be_an_instance_of Board | |
end | |
it 'has a current player' do | |
game = Game.new(3, 3) | |
game.current_player.symbol.should eq 'X' | |
end | |
it 'can switch the current player' do | |
game = Game.new(2, 3) | |
game.switch_current_player | |
game.current_player.symbol.should eq 'O' | |
end | |
describe 'has_winner?' do | |
it 'is true if there is a winner' do | |
game = Game.new(2, 3) | |
game.board.spaces[0].occupy(game.current_player) | |
game.board.spaces[1].occupy(game.current_player) | |
game.board.spaces[2].occupy(game.current_player) | |
game.has_winner?.should eq true | |
end | |
it 'is false if there is no winner' do | |
game = Game.new(2, 3) | |
game.has_winner?.should eq false | |
end | |
end | |
describe 'over?' do | |
it 'is true when all the spaces are occupied' do | |
game = Game.new(2, 4) | |
game.board.spaces.each do |space| | |
space.occupy(game.current_player) | |
end | |
game.over?.should eq true | |
end | |
it 'is true if the board has a winning combination' do | |
game = Game.new(2, 3) | |
game.board.spaces[0].occupy(game.current_player) | |
game.board.spaces[1].occupy(game.current_player) | |
game.board.spaces[2].occupy(game.current_player) | |
game.over?.should eq true | |
end | |
end | |
describe 'tie?' do | |
it 'is true if the game is over and there is no winner' do | |
game = Game.new | |
game.board.spaces[0].occupy(game.current_player) | |
game.board.spaces[1].occupy(game.current_player) | |
game.board.spaces[5].occupy(game.current_player) | |
game.board.spaces[6].occupy(game.current_player) | |
game.switch_current_player | |
game.board.spaces[2].occupy(game.current_player) | |
game.board.spaces[3].occupy(game.current_player) | |
game.board.spaces[4].occupy(game.current_player) | |
game.board.spaces[7].occupy(game.current_player) | |
game.board.spaces[8].occupy(game.current_player) | |
game.tie?.should eq true | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Player | |
def initialize(symbol) | |
@symbol = symbol | |
end | |
attr_reader :symbol | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'game' | |
require 'player' | |
require 'board' | |
require 'space' | |
describe Player do | |
it 'is initialized with a symbol' do | |
player = Player.new('X') | |
player.should be_an_instance_of Player | |
end | |
it 'has a symbol' do | |
player = Player.new('X') | |
player.symbol.should eq 'X' | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Space | |
def initialize(number, column, row) | |
@number = number | |
@column = column | |
@row = row | |
@mark = number | |
end | |
attr_reader :number, :occupying_player, :mark, :column, :row | |
def occupy(player) | |
@occupying_player = player | |
@mark = player.symbol | |
end | |
def occupied? | |
occupying_player != nil | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'game' | |
require 'player' | |
require 'board' | |
require 'space' | |
describe Space do | |
it 'initializes with a number, column and row' do | |
space = Space.new(1, 0, 0) | |
space.should be_an_instance_of Space | |
end | |
it 'has a mark' do | |
space = Space.new(1, 0, 0) | |
space.mark.should eq 1 | |
end | |
it 'is occupied by no one when created' do | |
space = Space.new(1, 0, 0) | |
space.occupying_player.should eq nil | |
end | |
it 'can be occupied by a player' do | |
space = Space.new(1, 0, 0) | |
player = Player.new('X') | |
space.occupy(player) | |
space.occupying_player.should eq player | |
end | |
it 'has its mark changed when it is occupied' do | |
space = Space.new(1, 0, 0) | |
player = Player.new('X') | |
space.occupy(player) | |
space.mark.should eq 'X' | |
end | |
describe 'occupied?' do | |
it "is false if a player is not occupying the space" do | |
space = Space.new(1, 0, 0) | |
space.occupied?.should eq false | |
end | |
it 'is true if a player is occupying the space' do | |
space = Space.new(1, 0, 0) | |
player = Player.new('X') | |
space.occupy(player) | |
space.occupied?.should eq true | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ThreeDBoard | |
def initialize | |
@boards = [Board.new, Board.new, Board.new] | |
end | |
attr_reader :boards | |
def straight_down_win? | |
(0..8).any? do |board_space_index| | |
@boards[0].spaces[board_space_index].occupying_player == @boards[1].spaces[board_space_index].occupying_player && @boards[1].spaces[board_space_index].occupying_player == @boards[2].spaces[board_space_index].occupying_player | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'three_d_board' | |
require 'game' | |
require 'player' | |
require 'board' | |
require 'space' | |
describe ThreeDBoard do | |
it 'has 3 boards' do | |
three_d_board = ThreeDBoard.new | |
three_d_board.boards.length.should eq 3 | |
end | |
describe 'straight_down_win?' do | |
it 'is true if the same space in each board is occupied by the same player' do | |
three_d_board = ThreeDBoard.new | |
player = Player.new('X') | |
three_d_board.boards[0].spaces[0].occupy(player) | |
three_d_board.boards[1].spaces[0].occupy(player) | |
three_d_board.boards[2].spaces[0].occupy(player) | |
three_d_board.straight_down_win?.should eq true | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require './lib/game' | |
require './lib/player' | |
require './lib/board' | |
require './lib/space' | |
@game = Game.new | |
def draw_board(board) | |
puts "\n\n" | |
puts "-------" * board.grid_length | |
(0...board.grid_length).each do |row_number| | |
board.get_row(row_number).each do |space| | |
if space.number < 10 | |
print "| #{space.mark} |" | |
elsif space.mark.to_i == 0 | |
print "| #{space.mark} |" | |
else | |
print "| #{space.mark} |" | |
end | |
end | |
puts "\n" | |
puts "-------" * board.grid_length | |
end | |
puts "\n\n" | |
end | |
def new_game_menu | |
puts "===================================================================" | |
puts "******************** Welcome to Tic-Tac-Toe! ********************" | |
puts "===================================================================" | |
puts "\n" | |
puts "How many players?" | |
number_of_players = gets.to_i | |
puts "How big of a board would you like?" | |
grid_size = gets.to_i | |
@game = Game.new(number_of_players, grid_size) | |
draw_board(@game.board) | |
turn_menu | |
end | |
def turn_menu | |
puts "===================================================================" | |
puts "It's #{@game.current_player.symbol}'s turn! Enter the number of the space you'd like to mark." | |
puts "===================================================================" | |
player_selection | |
if @game.has_winner? | |
puts "#{@game.current_player.symbol} wins!" | |
play_again | |
elsif @game.tie? | |
puts "Cat's game!" | |
play_again | |
else | |
@game.switch_current_player | |
turn_menu | |
end | |
end | |
def player_selection | |
chosen_space_index = gets.to_i - 1 | |
if chosen_space_index < 0 || chosen_space_index > @game.board.spaces.length | |
puts "That is not a valid space number. Please choose again." | |
player_selection | |
elsif @game.board.spaces[chosen_space_index].occupied? | |
puts "That space is already occupied. Please choose a different space." | |
player_selection | |
else | |
@game.board.spaces[chosen_space_index].occupy(@game.current_player) | |
draw_board(@game.board) | |
end | |
end | |
def play_again | |
puts "Would you like to play again? (Y / N)" | |
choice = gets.chomp.downcase | |
if choice == 'y' | |
new_game_menu | |
elsif choice == 'n' | |
puts "Good-bye!" | |
else | |
puts "Sorry, I didn't understand that" | |
play_again | |
end | |
end | |
new_game_menu |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment