diff --git a/README.md b/README.md index aaaae14..bf9947c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ ## project_game_center -[An Object-Oriented Ruby project from the Viking Code School](http://www.vikingcodeschool.com) \ No newline at end of file +[An Object-Oriented Ruby project from the Viking Code School](http://www.vikingcodeschool.com) + +Robert Wayne \ No newline at end of file diff --git a/connect_four/connect_four.rb b/connect_four/connect_four.rb deleted file mode 100644 index 34bc0e8..0000000 --- a/connect_four/connect_four.rb +++ /dev/null @@ -1 +0,0 @@ -# Your code here! \ No newline at end of file diff --git a/connect_four/lib/board.rb b/connect_four/lib/board.rb new file mode 100644 index 0000000..1ec0848 --- /dev/null +++ b/connect_four/lib/board.rb @@ -0,0 +1,320 @@ +class Board + def initialize(*board_state) + @board = board_state || Array.new(6) { Array.new(7) } + end + + def render + puts + + 5.downto(0) do |row| + @board[row].each do |column| + print "| " + column.nil? ? print("-") : print(column) + print " |" + end + puts + end + + 7.times { print "|---|" } + puts + 1.upto(7) { |i| print "| #{i} |" } + puts + puts + end + + def winning_combination?(piece) + winning_diagonal?(piece) || winning_vertical?(piece) || winning_horizontal?(piece) + end + + def full? + @board.each do |row| + row.each do |slot| + return false if slot.nil? + end + end + + true + end + + def add_piece(column_label, piece) + column_index = column_label - 1 + + if move_valid?(column_label) + @board.each_with_index do |row, i| + if row[column_index].nil? + @board[i][column_index] = piece + return true + end + end + else + false + end + end + + def winning_vertical_available?(piece) + verticals.each do |column| + consecutive_pieces = 0 + column.each do |slot| + if slot == piece + consecutive_pieces += 1 + elsif slot.nil? && consecutive_pieces == 3 + return true + else + consecutive_pieces = 0 + end + end + end + false + end + + def winning_vertical_move(piece) + verticals.each_with_index do |column, column_index| + consecutive_pieces = 0 + column.each do |slot| + if slot == piece + consecutive_pieces += 1 + elsif slot == nil && consecutive_pieces == 3 + return column_index + else + consecutive_pieces = 0 + end + end + end + + false + end + + def winning_horizontal_available?(piece) + horizontals.each_with_index do |row, row_index| + consecutive_pieces = 0 + + row.each_with_index do |slot, column_index| + if slot == piece + consecutive_pieces += 1 + elsif consecutive_pieces == 3 + if column_index >= 4 + column_before_sequence = column_index - 4 + slot_before_sequence = @board[row_index][column_before_sequence] + return true if slot_before_sequence.nil? + end + + return true if slot.nil? + end + end + end + + false + end + + def winning_horizontal_move(piece) + horizontals.each_with_index do |row, row_index| + consecutive_pieces = 0 + + row.each_with_index do |slot, column_index| + if slot == piece + consecutive_pieces += 1 + elsif consecutive_pieces == 3 + if column_index >= 4 + column_before_sequence = column_index - 4 + slot_before_sequence = @board[row_index][column_before_sequence] + return column_before_sequence if slot_before_sequence.nil? + end + + return column_index if slot.nil? + end + end + end + + false + end + + private + + def move_valid?(column_label) + if column_valid?(column_label) && column_available?(column_label) + true + else + puts "Invalid move." + false + end + end + + def column_valid?(column_label) + if column_label >= 1 && column_label <= 7 + true + else + puts "Invalid move." + end + end + + def column_available?(column_label) + column(column_label).include?(nil) ? true : false + end + + def column(column_label) + column_arr = [] + + @board.each do |row| + column_arr.push(row[column_label - 1]) + end + + column_arr + end + + def winning_diagonal?(piece) + diagonals.each do |diagonal| + consecutive_pieces = 0 + diagonal.each do |slot| + if slot == piece + consecutive_pieces += 1 + return true if consecutive_pieces == 4 + else + consecutive_pieces = 0 + end + end + end + + false + end + + def winning_vertical?(piece) + verticals.each do |column| + consecutive_pieces = 0 + column.each do |slot| + if slot == piece + consecutive_pieces += 1 + return true if consecutive_pieces == 4 + else + consecutive_pieces = 0 + end + end + end + + false + end + + def winning_horizontal?(piece) + horizontals.each do |row| + consecutive_pieces = 0 + row.each do |slot| + if slot == piece + consecutive_pieces += 1 + return true if consecutive_pieces == 4 + else + consecutive_pieces = 0 + end + end + end + + false + end + + def diagonals + diagonals_arr = [] + + 3.times do |i| + column_start = 0 + row_start = 0 + row_start += i + column = column_start + row = row_start + diagonal = [] + + while column <= 6 && row <= 5 + diagonal.push(@board[row][column]) + column += 1 + row += 1 + end + + diagonals_arr.push(diagonal) + end + + 3.times do |i| + column_start = 1 + row_start = 0 + column_start += i + column = column_start + row = row_start + diagonal = [] + + while column <= 6 && row <= 5 + diagonal.push(@board[row][column]) + column += 1 + row += 1 + end + + diagonals_arr.push(diagonal) + end + + 3.times do |i| + column_start = 6 + row_start = 0 + row_start += i + column = column_start + row = row_start + diagonal = [] + + while column >= 0 && row <= 5 + diagonal.push(@board[row][column]) + column -= 1 + row += 1 + end + + diagonals_arr.push(diagonal) + end + + 3.times do |i| + column_start = 5 + row_start = 0 + column_start -= i + column = column_start + row = row_start + diagonal = [] + + while column >= 0 && row <= 5 + diagonal.push(@board[row][column]) + column -= 1 + row += 1 + end + + diagonals_arr.push(diagonal) + end + + diagonals_arr + end + + def verticals + columns = [] + + 1.upto(7) do |column_label| + columns.push(column(column_label)) + end + + columns + end + + def horizontals + @board + end + + def slot_available? + if @board[row_index][column_index].nil? + true + else + false + end + end + + def possible_move?(column_index, row_index) + if slot_available? + if row_index == 0 + true + elsif @board[row_index - 1][column_index].nil? + false + else + true + end + end + end + +end \ No newline at end of file diff --git a/connect_four/lib/computer_player.rb b/connect_four/lib/computer_player.rb new file mode 100644 index 0000000..4578a6f --- /dev/null +++ b/connect_four/lib/computer_player.rb @@ -0,0 +1,22 @@ +require_relative 'player' + +class ComputerPlayer < Player + def initialize(name = "Computer Player", piece, board) + raise "Piece must be a symbol!" unless piece.is_a?(Symbol) + @name = name + @piece = piece + @board = board + end + + private + + def ask_for_column + if @board.winning_vertical_available?(piece) + @board.winning_vertical_move(piece) + 1 + elsif @board.winning_horizontal_available?(piece) + @board.winning_horizontal_move(piece) + 1 + else + rand(6) + 1 + end + end +end \ No newline at end of file diff --git a/connect_four/lib/connect_four.rb b/connect_four/lib/connect_four.rb new file mode 100644 index 0000000..4509b7b --- /dev/null +++ b/connect_four/lib/connect_four.rb @@ -0,0 +1,59 @@ +require_relative 'board.rb' +require_relative 'player.rb' +require_relative 'computer_player.rb' + +class ConnectFour + def initialize + @board = Board.new + @player_x = Player.new("Player 1", :X, @board) + @player_o = ComputerPlayer.new("Player 2", :O, @board) + @current_player = @player_x + end + + def play + loop do + @board.render + @current_player.get_column + break if check_game_over + switch_players + end + end + + private + + def check_game_over + check_victory || check_draw + end + + def check_victory + if @board.winning_combination?(@current_player.piece) + @board.render + if @current_player.is_a?(ComputerPlayer) + puts "The computer beat you!" + else + puts "Congratulations, #{@current_player.name}! You won!" + end + + true + else + false + end + end + + def check_draw + if @board.full? + puts "It's a draw!" + true + else + false + end + end + + def switch_players + if @current_player == @player_x + @current_player = @player_o + else + @current_player = @player_x + end + end +end \ No newline at end of file diff --git a/connect_four/lib/player.rb b/connect_four/lib/player.rb new file mode 100644 index 0000000..3521dd8 --- /dev/null +++ b/connect_four/lib/player.rb @@ -0,0 +1,35 @@ +class Player + attr_accessor :name, :piece + + def initialize(name = "Mystery Player", piece, board) + raise "Piece must be a symbol!" unless piece.is_a?(Symbol) + @name = name + @piece = piece + @board = board + end + + def get_column + loop do + column = ask_for_column + + if validate_column_format(column) + break if @board.add_piece(column, @piece) + end + end + end + + private + + def ask_for_column + puts "Please choose a column for your next move." + gets.strip.to_i + end + + def validate_column_format(column) + if column >= 1 && column <= 7 + true + else + puts "Your choice is not in the proper format." + end + end +end \ No newline at end of file diff --git a/connect_four/spec/board_spec.rb b/connect_four/spec/board_spec.rb new file mode 100644 index 0000000..466fd6a --- /dev/null +++ b/connect_four/spec/board_spec.rb @@ -0,0 +1,106 @@ +require 'board.rb' + +describe Board do + # initialize + + # winning_combination? + describe '#winning_combination?' do + it "returns a boolean value" do + + end + + it "returns true if a winning diagonal combination exists for the given piece" do + + end + + it "returns true if a winning vertical combination exists for the given piece" do + + end + + it "returns true if a winning horizontal combination exists for the given piece" do + + end + + it "returns false if no winning combination exists for the given piece" do + + end + end + + # full? + describe '#full?' do + it "returns false if there are any empty slots" do + + end + + it "returns true if there is a piece in every slot" do + + end + end + + # add_piece + describe '#add_piece' do + it "adds the given piece to the given column" do + + end + + it "adds the given piece to the correct row in the column" do + + end + + it "returns true if the piece has been added to the board" do + + end + + it "returns false if the piece has not been added to the board" do + + end + + it "adds the piece to the column according to the column label displayed to the user" do + + end + + it "does not add the piece to the column according to the zero-based column index" do + + end + end + + # winning_vertical_available? + describe '#winning_vertical_available?' do + it "returns true if there is a move available that will result in a vertical winning combination for the given piece" do + + end + + it "does not return true if there is a move available that will result in a vertical winning combination for a different piece" do + + end + end + + # winning_vertical_move + describe '#winning_vertical_move' do + it "returns the move that will result in a vertical winning combination for the given piece" do + + end + + it "does not return the move that will result in a vertical winning combination for a different piece" do + + end + end + + # winning_horizontal_available? + it "returns true if there is a move available that will result in a horizontal winning combination for the given piece" do + + end + + it "does not return true if there is a move available that will result in a horizontal winning combination for a different piece" do + + end + + # winning_horizontal_move + it "returns the move that will result in a horizontal winning combination for the given piece" do + + end + + it "does not return the move that will result in a horizontal winning combination for a different piece" do + + end +end \ No newline at end of file diff --git a/connect_four/spec/computer_player_spec.rb b/connect_four/spec/computer_player_spec.rb new file mode 100644 index 0000000..f85d07c --- /dev/null +++ b/connect_four/spec/computer_player_spec.rb @@ -0,0 +1,5 @@ +require 'computer_player.rb' + +describe ComputerPlayer do + +end \ No newline at end of file diff --git a/connect_four/spec/connect_four_spec.rb b/connect_four/spec/connect_four_spec.rb new file mode 100644 index 0000000..75b266d --- /dev/null +++ b/connect_four/spec/connect_four_spec.rb @@ -0,0 +1,6 @@ +require 'connect_four.rb' + +describe ConnectFour do + # initialize + # play +end \ No newline at end of file diff --git a/connect_four/spec/player_spec.rb b/connect_four/spec/player_spec.rb new file mode 100644 index 0000000..5fa838e --- /dev/null +++ b/connect_four/spec/player_spec.rb @@ -0,0 +1,6 @@ +require 'player.rb' + +describe Player do + # initialize + # get_column +end \ No newline at end of file