mastermind; basic logic, color highlighting, etc
This commit is contained in:
@@ -1,13 +1,5 @@
|
|||||||
class BoardBase
|
module BoardBase
|
||||||
attr_accessor :turn
|
def check_for_winner
|
||||||
|
fail NotImplementedError, "Board must implement a 'check_for_winner' method"
|
||||||
def initialize(turn = 1)
|
|
||||||
@turn = turn
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
print "
|
|
||||||
Current turn: #{@turn}\n
|
|
||||||
"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
class GameBase
|
module GameBase
|
||||||
def initialize
|
def initialize(game_name = "(unspecified game)")
|
||||||
puts "Welcome to Tic Tac Toe!"
|
puts "Welcome to #{game_name}!"
|
||||||
puts "Player 1, what is your name?"
|
puts "Player 1, what is your name?"
|
||||||
@player_one_name = gets.chomp
|
@player_one_name = gets.chomp
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ class GameBase
|
|||||||
@playerOne = Player.new(@player_one_name)
|
@playerOne = Player.new(@player_one_name)
|
||||||
@playerTwo = Player.new(@player_two_name)
|
@playerTwo = Player.new(@player_two_name)
|
||||||
@statusMessage = ""
|
@statusMessage = ""
|
||||||
@board = Board.new()
|
@board = Board.new
|
||||||
@winner = nil
|
@winner = nil
|
||||||
@turn = 1
|
@turn = 1
|
||||||
end
|
end
|
||||||
@@ -24,4 +24,28 @@ class GameBase
|
|||||||
#{@board.to_s}
|
#{@board.to_s}
|
||||||
"
|
"
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
26
common/String.rb
Normal file
26
common/String.rb
Normal file
@@ -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
|
||||||
@@ -1,11 +1,34 @@
|
|||||||
require_relative "../common/BoardBase.rb"
|
require_relative "../common/BoardBase.rb"
|
||||||
|
|
||||||
class Board < BoardBase
|
class Board
|
||||||
def initialize(turn = 1)
|
attr_accessor :turn
|
||||||
super(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
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
print "wew"
|
print "wew"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def put_code(code)
|
||||||
|
@guesses[turn] = code
|
||||||
|
|
||||||
|
status = nil
|
||||||
|
|
||||||
|
if (code == @solution)
|
||||||
|
status = "win"
|
||||||
|
end
|
||||||
|
|
||||||
|
status
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1,16 +1,39 @@
|
|||||||
require_relative "../common/GameBase.rb"
|
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
|
def initialize
|
||||||
puts "Welcome to Mastermind!"
|
super("Mastermind")
|
||||||
puts "Player 1, what is your name?"
|
end
|
||||||
player_one_name = gets.chomp
|
|
||||||
|
|
||||||
puts "Player 2, what is your name?"
|
# inherits "play"
|
||||||
player_two_name = gets.chomp
|
|
||||||
|
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 = ""
|
@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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
require_relative "Game.rb"
|
||||||
|
|
||||||
|
game = Game.new
|
||||||
|
game.play
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
require_relative "../common/BoardBase.rb"
|
require_relative "../common/BoardBase.rb"
|
||||||
|
|
||||||
class Board < BoardBase
|
class Board
|
||||||
attr_accessor :turn, :squares, :update_square
|
include BoardBase
|
||||||
|
attr_accessor :squares, :update_square
|
||||||
|
|
||||||
def initialize(turn = 1)
|
def initialize
|
||||||
super(turn)
|
|
||||||
@squares = [
|
@squares = [
|
||||||
[" ", " ", " "],
|
[" ", " ", " "],
|
||||||
[" ", " ", " "],
|
[" ", " ", " "],
|
||||||
|
|||||||
@@ -2,34 +2,18 @@ require_relative "../common/GameBase.rb"
|
|||||||
require_relative "../common/Player.rb"
|
require_relative "../common/Player.rb"
|
||||||
require_relative "Board.rb"
|
require_relative "Board.rb"
|
||||||
|
|
||||||
class Game < GameBase
|
class Game
|
||||||
|
include GameBase
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super("Tic Tac Toe")
|
||||||
@playerOne = Player.new(@player_one_name, "X")
|
@playerOne = Player.new(@player_one_name, "X")
|
||||||
@playerTwo = Player.new(@player_two_name, "O")
|
@playerTwo = Player.new(@player_two_name, "O")
|
||||||
end
|
end
|
||||||
|
|
||||||
def play
|
# inherits methods "play" and "to_s" from GameBase module
|
||||||
until @winner
|
|
||||||
self.turn()
|
|
||||||
end
|
|
||||||
|
|
||||||
@statusMessage = "#{@statusMessage + "\nPress 'x' to exit or 'a' to play again."}"
|
def turn
|
||||||
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()
|
|
||||||
# clear the terminal on each turn
|
# clear the terminal on each turn
|
||||||
puts "\e[H\e[2J"
|
puts "\e[H\e[2J"
|
||||||
print self.to_s
|
print self.to_s
|
||||||
@@ -39,14 +23,14 @@ class Game < GameBase
|
|||||||
|
|
||||||
unless player_input.is_a?(Numeric) and player_input.between?(1, 9)
|
unless player_input.is_a?(Numeric) and player_input.between?(1, 9)
|
||||||
@statusMessage = "Invalid input. Expected a number between 1 and 9."
|
@statusMessage = "Invalid input. Expected a number between 1 and 9."
|
||||||
self.turn()
|
self.turn
|
||||||
end
|
end
|
||||||
|
|
||||||
move_success = @board.update_square(player_input, @turn % 2 == 0 ? "O" : "X")
|
move_success = @board.update_square(player_input, @turn % 2 == 0 ? "O" : "X")
|
||||||
|
|
||||||
if not move_success
|
if not move_success
|
||||||
@statusMessage = "Invalid input. This square is already taken."
|
@statusMessage = "Invalid input. This square is already taken."
|
||||||
self.turn()
|
self.turn
|
||||||
end
|
end
|
||||||
|
|
||||||
if @statusMessage == "Invalid input. This square is already taken."
|
if @statusMessage == "Invalid input. This square is already taken."
|
||||||
|
|||||||
Reference in New Issue
Block a user