From a347e5a77652d2283b647582dd6aeb076c1731ea Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Mon, 29 May 2023 22:37:51 -0500 Subject: [PATCH] mastermind; basic logic, color highlighting, etc --- common/BoardBase.rb | 14 +++----------- common/GameBase.rb | 32 ++++++++++++++++++++++++++++---- common/String.rb | 26 ++++++++++++++++++++++++++ mastermind/Board.rb | 29 ++++++++++++++++++++++++++--- mastermind/CodeSet.rb | 35 +++++++++++++++++++++++++++++++++++ mastermind/Game.rb | 39 +++++++++++++++++++++++++++++++-------- mastermind/KeySet.rb | 12 ++++++++++++ mastermind/main.rb | 4 ++++ tic_tac_toe/Board.rb | 8 ++++---- tic_tac_toe/Game.rb | 32 ++++++++------------------------ 10 files changed, 177 insertions(+), 54 deletions(-) create mode 100644 common/String.rb diff --git a/common/BoardBase.rb b/common/BoardBase.rb index f9e59df..f2e3926 100644 --- a/common/BoardBase.rb +++ b/common/BoardBase.rb @@ -1,13 +1,5 @@ -class BoardBase - attr_accessor :turn - - def initialize(turn = 1) - @turn = turn - end - - def to_s - print " - Current turn: #{@turn}\n - " +module BoardBase + def check_for_winner + fail NotImplementedError, "Board must implement a 'check_for_winner' method" end end diff --git a/common/GameBase.rb b/common/GameBase.rb index 7a43393..4e5308b 100644 --- a/common/GameBase.rb +++ b/common/GameBase.rb @@ -1,6 +1,6 @@ -class GameBase - def initialize - puts "Welcome to Tic Tac Toe!" +module GameBase + def initialize(game_name = "(unspecified game)") + puts "Welcome to #{game_name}!" puts "Player 1, what is your name?" @player_one_name = gets.chomp @@ -10,7 +10,7 @@ class GameBase @playerOne = Player.new(@player_one_name) @playerTwo = Player.new(@player_two_name) @statusMessage = "" - @board = Board.new() + @board = Board.new @winner = nil @turn = 1 end @@ -24,4 +24,28 @@ class GameBase #{@board.to_s} " end + + def play + until @winner + self.turn + end + + @statusMessage = "#{@statusMessage + "\nPress 'x' to exit or 'a' to play again."}" + print self.to_s + + if gets.chomp == "a" + @board = Board.new + @winner = nil + @statusMessage = "" + @turn = 1 + self.play() + elsif gets.chomp != "x" + @statusMessage = "Please provide a valid input" + print self.to_s + end + end + + def turn + fail NotImplementedError, "Game must implement a 'turn' method" + end end diff --git a/common/String.rb b/common/String.rb new file mode 100644 index 0000000..caf4308 --- /dev/null +++ b/common/String.rb @@ -0,0 +1,26 @@ +# https://stackoverflow.com/questions/1489183/how-can-i-use-ruby-to-colorize-the-text-output-to-a-terminal +class String + def black; "\e[30m#{self}\e[0m" end + def red; "\e[31m#{self}\e[0m" end + def green; "\e[32m#{self}\e[0m" end + def brown; "\e[33m#{self}\e[0m" end + def blue; "\e[34m#{self}\e[0m" end + def magenta; "\e[35m#{self}\e[0m" end + def cyan; "\e[36m#{self}\e[0m" end + def gray; "\e[37m#{self}\e[0m" end + + def bg_black; "\e[40m#{self}\e[0m" end + def bg_red; "\e[41m#{self}\e[0m" end + def bg_green; "\e[42m#{self}\e[0m" end + def bg_brown; "\e[43m#{self}\e[0m" end + def bg_blue; "\e[44m#{self}\e[0m" end + def bg_magenta; "\e[45m#{self}\e[0m" end + def bg_cyan; "\e[46m#{self}\e[0m" end + def bg_gray; "\e[47m#{self}\e[0m" end + + def bold; "\e[1m#{self}\e[22m" end + def italic; "\e[3m#{self}\e[23m" end + def underline; "\e[4m#{self}\e[24m" end + def blink; "\e[5m#{self}\e[25m" end + def reverse_color; "\e[7m#{self}\e[27m" end +end diff --git a/mastermind/Board.rb b/mastermind/Board.rb index a1daa76..af0c974 100644 --- a/mastermind/Board.rb +++ b/mastermind/Board.rb @@ -1,11 +1,34 @@ require_relative "../common/BoardBase.rb" -class Board < BoardBase - def initialize(turn = 1) - super(turn) +class Board + attr_accessor :turn + attr_reader :guesses, :keys + + include BoardBase + + def initialize + @turn = 0 + @guesses = Array.new(12) + @keys = Array.new(12) + + # generate a random solution code from values between 1 and 6 + solution_code = Array.new(4).map { rand(1..6) } + @solution = CodeSet.new(solution_code) end def to_s print "wew" end + + def put_code(code) + @guesses[turn] = code + + status = nil + + if (code == @solution) + status = "win" + end + + status + end end diff --git a/mastermind/CodeSet.rb b/mastermind/CodeSet.rb index e69de29..1fc4fce 100644 --- a/mastermind/CodeSet.rb +++ b/mastermind/CodeSet.rb @@ -0,0 +1,35 @@ +require_relative "../common/String.rb" + +class CodeSet + attr_accessor :code + + def initialize(array_code = nil) + if (array_code) + if (array_code.any? { |code| code < 0 or code > 6 }) + raise ArgumentError, "Code must be between 1 and 6" + end + + @code = array_code + else + @code = Array.new(4) + end + end + + def to_s + output = "" + + for cell in @code + colorcode = cell + 31 + output += "\e[#{colorcode}m#{cell.to_s}\e[0m\n" + end + + output + end + + def put_codes(array_code) + @code << array_code + end +end + +thing = CodeSet.new([1,2,3,4]) +print thing.to_s diff --git a/mastermind/Game.rb b/mastermind/Game.rb index 88cc09f..14a21f1 100644 --- a/mastermind/Game.rb +++ b/mastermind/Game.rb @@ -1,16 +1,39 @@ require_relative "../common/GameBase.rb" +require_relative "../common/Player.rb" +require_relative "../common/Board.rb" +require_relative "KeySet.rb" +require_relative "CodeSet.rb" + +class Game + include GameBase -class Game < GameBase def initialize - puts "Welcome to Mastermind!" - puts "Player 1, what is your name?" - player_one_name = gets.chomp + super("Mastermind") + end - puts "Player 2, what is your name?" - player_two_name = gets.chomp + # inherits "play" + + def turn + # clear the terminal on each turn + puts "\e[H\e[2J" + print self.to_s + + puts "Player #{@turn % 2 == 0 ? @playerTwo.name : @playerOne.name}, please enter a guess." + player_input = gets.chomp + + unless player_input.is_a?(String) and player_input.length == 4 and player_input.split("").all? { |code| code.to_i.between?(1, 6) } + @statusMessage = "Invalid input. Expected a 4-digit code between 1 and 6." + self.turn + end - @playerOne = Player.new(player_one_name) - @playerTwo = Player.new(player_two_name) @statusMessage = "" + + # convert the player's input into a CodeSet object + player_code = CodeSet.new(player_input.split("").map { |code| code.to_i }) + + # pass object to the board, which will also check it against the solution + result = @board.put_code(player_code) + + @board.turn(@turn) end end diff --git a/mastermind/KeySet.rb b/mastermind/KeySet.rb index e69de29..099bd3e 100644 --- a/mastermind/KeySet.rb +++ b/mastermind/KeySet.rb @@ -0,0 +1,12 @@ +class KeySet + def initialize(array_keys = nil) + @key = Array.new(4) + if (array_keys) + @key << array_keys + end + end + + def put_keys(array_keys) + @key << array_keys + end +end diff --git a/mastermind/main.rb b/mastermind/main.rb index e69de29..c8956df 100644 --- a/mastermind/main.rb +++ b/mastermind/main.rb @@ -0,0 +1,4 @@ +require_relative "Game.rb" + +game = Game.new +game.play diff --git a/tic_tac_toe/Board.rb b/tic_tac_toe/Board.rb index 18853fe..bcc1e2e 100644 --- a/tic_tac_toe/Board.rb +++ b/tic_tac_toe/Board.rb @@ -1,10 +1,10 @@ require_relative "../common/BoardBase.rb" -class Board < BoardBase - attr_accessor :turn, :squares, :update_square +class Board + include BoardBase + attr_accessor :squares, :update_square - def initialize(turn = 1) - super(turn) + def initialize @squares = [ [" ", " ", " "], [" ", " ", " "], diff --git a/tic_tac_toe/Game.rb b/tic_tac_toe/Game.rb index 5c4c741..a7f3f95 100644 --- a/tic_tac_toe/Game.rb +++ b/tic_tac_toe/Game.rb @@ -2,34 +2,18 @@ require_relative "../common/GameBase.rb" require_relative "../common/Player.rb" require_relative "Board.rb" -class Game < GameBase +class Game + include GameBase + def initialize - super + super("Tic Tac Toe") @playerOne = Player.new(@player_one_name, "X") @playerTwo = Player.new(@player_two_name, "O") end - def play - until @winner - self.turn() - end + # inherits methods "play" and "to_s" from GameBase module - @statusMessage = "#{@statusMessage + "\nPress 'x' to exit or 'a' to play again."}" - print self.to_s - - if gets.chomp == "a" - @board = Board.new() - @winner = nil - @statusMessage = "" - @turn = 1 - self.play() - elsif gets.chomp != "x" - @statusMessage = "Please provide a valid input" - print self.to_s - end - end - - def turn() + def turn # clear the terminal on each turn puts "\e[H\e[2J" print self.to_s @@ -39,14 +23,14 @@ class Game < GameBase unless player_input.is_a?(Numeric) and player_input.between?(1, 9) @statusMessage = "Invalid input. Expected a number between 1 and 9." - self.turn() + self.turn end move_success = @board.update_square(player_input, @turn % 2 == 0 ? "O" : "X") if not move_success @statusMessage = "Invalid input. This square is already taken." - self.turn() + self.turn end if @statusMessage == "Invalid input. This square is already taken."