From 1ce7a5a1defb1763830e4f3aa1ca5c1fd9ae53f9 Mon Sep 17 00:00:00 2001 From: matthew lee Date: Wed, 10 Oct 2018 23:48:26 -0400 Subject: [PATCH 01/29] initial commit --- Jays-Game/view.rb | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Jays-Game/view.rb b/Jays-Game/view.rb index e90ae7c..ddf553c 100644 --- a/Jays-Game/view.rb +++ b/Jays-Game/view.rb @@ -1,19 +1,19 @@ module GameView - module Print + module Print - class << self - def run_spinner - print "Loading (please wait) " - 5.times { print "."; sleep 1; } - print "\n" - end + class << self + def run_spinner + print "Loading (please wait) " + 5.times { print "."; sleep 1; } + print "\n" + end - def error_message + def error_message puts "That's not a command key. Try again!" - end - - def title_screen + end + + def title_screen title = < Date: Wed, 2 Jan 2019 04:27:58 -0500 Subject: [PATCH 02/29] initial commit --- Jays-Game/controller.rb | 3 -- Jays-Game/view.rb | 53 ++++++++++----------- ttt/README.md | 37 +++++++++++++++ ttt/game.rb | 102 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 30 deletions(-) create mode 100644 ttt/README.md create mode 100644 ttt/game.rb diff --git a/Jays-Game/controller.rb b/Jays-Game/controller.rb index c043b14..b7a9879 100644 --- a/Jays-Game/controller.rb +++ b/Jays-Game/controller.rb @@ -10,9 +10,6 @@ def run! Print::run_spinner Print::title_screen - #Make todoList methods like RESTful endpoints (new/edit/update/delete) - #Think Backbone Model & View - loop do Print::menu case Print::fetch_user_input diff --git a/Jays-Game/view.rb b/Jays-Game/view.rb index ddf553c..fac7682 100644 --- a/Jays-Game/view.rb +++ b/Jays-Game/view.rb @@ -1,11 +1,10 @@ module GameView - + # module inside module? no closing end? module Print - - class << self - def run_spinner - print "Loading (please wait) " - 5.times { print "."; sleep 1; } + class << self + def run_spinner + print "Loading (please wait) " + 5.times { print "."; sleep 1 } print "\n" end @@ -14,28 +13,28 @@ def error_message end def title_screen -title = <<TITLE + title = <<-EOS - ********** || ********** - * TODO MAGIC * - ********** || ********** + ********** || ********** + * TODO MAGIC * + ********** || ********** -TITLE - puts title - end + EOS + puts title + end def menu -menu = <<EOS + menu = <<-EOS - ***** Welcome ***** - - (V)iew your todos - - (A)dd a todo - - (C)omplete a todo - - (D)elete a todo - - (Q)uit program - ***** ***** + ***** Welcome ***** + - (V)iew your todos + - (A)dd a todo + - (C)omplete a todo + - (D)elete a todo + - (Q)uit program + ***** ***** -EOS + EOS puts menu end @@ -44,16 +43,16 @@ def menu def print_list(todos) todos.each do |todo| if todo.completed? - puts "[X] #{todo.id} || #{todo.title} - #{todo.description}" + puts "[X] #{todo.id} || #{todo.title} - #{todo.description}" else - puts "[_] #{todo.id} || #{todo.title} - #{todo.description}" + puts "[_] #{todo.id} || #{todo.title} - #{todo.description}" end end end def serialize_todo - {}.tap do |obj| - ["\nEnter the title:", "\nEnter the description:"].each do |t| + {}.tap do |obj| + ["\nEnter the title:", "\nEnter the description:"].each do |t| if obj.empty? obj[:title] = fetch_user_input(t) else @@ -73,7 +72,7 @@ def completed_id fetch_user_input(gimme_id) end - def fetch_user_input(question=nil) + def fetch_user_input(question = nil) puts question if question print "> " gets.chomp diff --git a/ttt/README.md b/ttt/README.md new file mode 100644 index 0000000..588e7e8 --- /dev/null +++ b/ttt/README.md @@ -0,0 +1,37 @@ +Hello, +I’m the project manager at a Command Line Games, Inc. I have a small dev team and we hired a +consulting company to help us build an app that will feature a number of games for children, one being +Tic Tac Toe. +They just demoed the basic version of the Tic Tac Toe game in the console and my boss wasn’t thrilled +with what he saw. The game play was rough. It didn’t function as he expected. We’ve decided to move +in a different direction and bring in someone else. While my boss doesn’t have a technical background, +I do, and we both understand the importance of writing code that can be maintained in the future. +We would like you to improve the existing Tic Tac Toe that the previous firm worked on. There are a +number of issues with the code. Below I’ve listed some of those issues, but I’m sure there are more. +● The game does not gracefully handle bad user input. +● In its current form, it’s supposed to be played at a difficulty level of “hard”, meaning the computer +player cannot be beaten. In reality, however, the computer player can be beaten in certain +situations. This is more like a “medium” difficulty level. +● The game play left a lot to be desired. The user messages are lacking. They’re unclear. It’s +confusing to see the spot that’s selected and the board all on the screen. It’s easy to get lost in +what’s happening. It’s weird the way the computer picks its spot without notifying the user. +As you can tell, there are a lot of problems and from what our devs say, the code itself is a mess. It’s +untested and therefore unmaintainable. It’s poorly­written and inflexible. This puts us in a difficult +position because we have a number of features we would like to add and we’re hoping you can help. +We hope that you’ll be able to help us get the code in a better state. Without that, our devs don’t even +think we’ll be able to implement the new features my boss has requested. For one thing, the existing +code is so coupled to the console that implementing any other UI is nearly impossible! Below you’ll see +a list of the features we’re hoping to add. +● Allow the user to choose the game type (human v. human, computer v. computer, human v. +computer). +● Allow the user to choose which player goes first. +● Allow the user to choose with what “symbol” the players will mark their selections on the board +(traditionally it’s “X” and “O”). +Could you implement these features? + +Your code will be judged on the following criteria: + +Adherence to SOLID principles +Appropriate separation of concerns +Clarity and readability +Expressive naming diff --git a/ttt/game.rb b/ttt/game.rb new file mode 100644 index 0000000..973f0f2 --- /dev/null +++ b/ttt/game.rb @@ -0,0 +1,102 @@ +class Game + def initialize + @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] + @com = "X" # the computer's marker + @hum = "O" # the user's marker + end + + def start_game + # start by printing the board + puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" + puts "Enter [0-8]:" + # loop through until the game was won or tied + until game_is_over(@board) || tie(@board) + get_human_spot + if !game_is_over(@board) && !tie(@board) + eval_board + end + puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" + end + puts "Game over" + end + + def get_human_spot + spot = nil + until spot + spot = gets.chomp.to_i + if @board[spot] != "X" && @board[spot] != "O" + @board[spot] = @hum + else + spot = nil + end + end + end + + def eval_board + spot = nil + until spot + if @board[4] == "4" + spot = 4 + @board[spot] = @com + else + spot = get_best_move(@board, @com) + if @board[spot] != "X" && @board[spot] != "O" + @board[spot] = @com + else + spot = nil + end + end + end + end + + def get_best_move(board, next_player, depth = 0, best_score = {}) + available_spaces = [] + best_move = nil + board.each do |s| + if s != "X" && s != "O" + available_spaces << s + end + end + available_spaces.each do |as| + board[as.to_i] = @com + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move + else + board[as.to_i] = @hum + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move + else + board[as.to_i] = as + end + end + end + if best_move + return best_move + else + n = rand(0..available_spaces.count) + return available_spaces[n].to_i + end + end + + def game_is_over(b) + [b[0], b[1], b[2]].uniq.length == 1 || + [b[3], b[4], b[5]].uniq.length == 1 || + [b[6], b[7], b[8]].uniq.length == 1 || + [b[0], b[3], b[6]].uniq.length == 1 || + [b[1], b[4], b[7]].uniq.length == 1 || + [b[2], b[5], b[8]].uniq.length == 1 || + [b[0], b[4], b[8]].uniq.length == 1 || + [b[2], b[4], b[6]].uniq.length == 1 + end + + def tie(b) + b.all? { |s| s == "X" || s == "O" } + end +end + +game = Game.new +game.start_game From fc2d186d34ed1559d77edb7edd942beb69b406e1 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Wed, 2 Jan 2019 05:51:50 -0500 Subject: [PATCH 03/29] js to ruby view --- Jays-Game/controller.rb | 6 +++--- Jays-Game/view.rb | 1 - ttt/controller.rb | 14 ++++++++++++++ ttt/model.rb | 0 ttt/view.rb | 29 +++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 ttt/controller.rb create mode 100644 ttt/model.rb create mode 100644 ttt/view.rb diff --git a/Jays-Game/controller.rb b/Jays-Game/controller.rb index b7a9879..d6d2281 100644 --- a/Jays-Game/controller.rb +++ b/Jays-Game/controller.rb @@ -1,5 +1,5 @@ -require_relative 'view' -require_relative 'model' +require_relative "view" +require_relative "model" class GameController include GameView @@ -22,7 +22,7 @@ def run! when "D" todoList.delete_todo(Print::deleted_id.to_i) when "Q" - puts "We're done" + puts "We're done" exit else Print::error_message diff --git a/Jays-Game/view.rb b/Jays-Game/view.rb index fac7682..2ad4e20 100644 --- a/Jays-Game/view.rb +++ b/Jays-Game/view.rb @@ -1,5 +1,4 @@ module GameView - # module inside module? no closing end? module Print class << self def run_spinner diff --git a/ttt/controller.rb b/ttt/controller.rb new file mode 100644 index 0000000..19e128f --- /dev/null +++ b/ttt/controller.rb @@ -0,0 +1,14 @@ +require_relative "view" +require_relative "model" + +class Controller + include View + + def run! + # game = Game.new + Print::welcome + Print::acceptable_moves + end +end + +Controller.new.run! diff --git a/ttt/model.rb b/ttt/model.rb new file mode 100644 index 0000000..e69de29 diff --git a/ttt/view.rb b/ttt/view.rb new file mode 100644 index 0000000..d665ddd --- /dev/null +++ b/ttt/view.rb @@ -0,0 +1,29 @@ +module View + module Print + class << self + def tell_user(message) + puts message + end + + def welcome + tell_user "Welcome to Tic Tac Toe!" + end + + def acceptable_moves + tell_user "Please enter a unique number between 0-8." + end + + def report_winner(currentTurn) + tell_user "Game over. #{currentTurn} won." + end + + def report_tie + tell_user "Game over. Tied game." + end + + def report_move(currentTurn, positionPlacement) + tell_user "#{currentTurn}'s move: #{positionPlacement}" + end + end + end +end From e93de65f1a187b5f2deaafcd87eaf51afd576aba Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Wed, 2 Jan 2019 16:01:12 -0500 Subject: [PATCH 04/29] static board --- ttt/controller.rb | 13 ++++++++++--- ttt/model.rb | 9 +++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 19e128f..e279634 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -4,11 +4,18 @@ class Controller include View - def run! - # game = Game.new + def start_game + game = Game.new Print::welcome + render_board(game) Print::acceptable_moves end + + def render_board(game) + Print::tell_user( + " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" + ) + end end -Controller.new.run! +Controller.new.start_game diff --git a/ttt/model.rb b/ttt/model.rb index e69de29..91b7c99 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -0,0 +1,9 @@ +class Game + attr_reader :board + + def initialize + @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] + @X = "X" + @O = "O" + end +end From 0c0698746dfd69d157fce8b80ccbef10553ff3b4 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Wed, 2 Jan 2019 23:29:04 -0500 Subject: [PATCH 05/29] . --- ttt/controller.rb | 12 +++++++ ttt/game.rb | 2 ++ ttt/model.rb | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/ttt/controller.rb b/ttt/controller.rb index e279634..6c39622 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -16,6 +16,18 @@ def render_board(game) " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" ) end + + def play + end + +=begin + until game_over + get_human_move + game.check_game_over + get_computer_move + game.check_game_over + end +=end end Controller.new.start_game diff --git a/ttt/game.rb b/ttt/game.rb index 973f0f2..6b89b81 100644 --- a/ttt/game.rb +++ b/ttt/game.rb @@ -24,9 +24,11 @@ def get_human_spot spot = nil until spot spot = gets.chomp.to_i + # puts spot >= 0 && spot <= 8 ? "valid input" : "invalid input" if @board[spot] != "X" && @board[spot] != "O" @board[spot] = @hum else + # puts "unacceptable input" spot = nil end end diff --git a/ttt/model.rb b/ttt/model.rb index 91b7c99..d11685f 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -6,4 +6,85 @@ def initialize @X = "X" @O = "O" end + + def get_human_move + move = nil + until move + move = gets.chomp.to_i + if @board[move] != "X" && @board[move] != "O" + @board[move] = @hum + else + move = nil + end + end + end + + def eval_board + spot = nil + until spot + if @board[4] == "4" + spot = 4 + @board[spot] = @com + else + spot = get_best_move(@board, @com) + if @board[spot] != "X" && @board[spot] != "O" + @board[spot] = @com + else + spot = nil + end + end + end + end + + def get_best_move(board, next_player, depth = 0, best_score = {}) + available_spaces = [] + best_move = nil + board.each do |s| + if s != "X" && s != "O" + available_spaces << s + end + end + available_spaces.each do |as| + board[as.to_i] = @com + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move + else + board[as.to_i] = @hum + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move + else + board[as.to_i] = as + end + end + end + if best_move + return best_move + else + n = rand(0..available_spaces.count) + return available_spaces[n].to_i + end + end + + def check_game_over + winner(@board) || tie(@board) ? true : false + end + + def winner(board) + [board[0], board[1], board[2]].uniq.length == 1 || + [board[3], board[4], board[5]].uniq.length == 1 || + [board[6], board[7], board[8]].uniq.length == 1 || + [board[0], board[3], board[6]].uniq.length == 1 || + [board[1], board[4], board[7]].uniq.length == 1 || + [board[2], board[5], board[8]].uniq.length == 1 || + [board[0], board[4], board[8]].uniq.length == 1 || + [board[2], board[4], board[6]].uniq.length == 1 + end + + def tie(board) + board.all? { |s| s == "X" || s == "O" } + end end From 8943a51c0366fcfc16a66ad4ec5586482d5966bd Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 7 Jan 2019 15:19:43 -0500 Subject: [PATCH 06/29] seperated into MVC, clean up and test --- ttt/controller.rb | 20 ++++++++++---------- ttt/game.rb | 14 +++++++++----- ttt/model.rb | 26 ++++++++++++++++---------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 6c39622..e39177f 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -9,6 +9,7 @@ def start_game Print::welcome render_board(game) Print::acceptable_moves + play(game) end def render_board(game) @@ -17,17 +18,16 @@ def render_board(game) ) end - def play + def play(game) + until game.check_game_over + game.get_human_move + if !game.check_game_over + game.eval_board + end + puts " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" + end + puts "Game over" end - -=begin - until game_over - get_human_move - game.check_game_over - get_computer_move - game.check_game_over - end -=end end Controller.new.start_game diff --git a/ttt/game.rb b/ttt/game.rb index 6b89b81..2a68675 100644 --- a/ttt/game.rb +++ b/ttt/game.rb @@ -23,12 +23,15 @@ def start_game def get_human_spot spot = nil until spot - spot = gets.chomp.to_i - # puts spot >= 0 && spot <= 8 ? "valid input" : "invalid input" - if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @hum + spot = gets.chomp + if spot.to_i.to_s == spot && spot.to_i >= 0 && spot.to_i <= 8 + spot = spot.to_i + if @board[spot] != "X" && @board[spot] != "O" + @board[spot] = @hum + puts "you went #{spot}" + end else - # puts "unacceptable input" + puts "invalid entry" spot = nil end end @@ -49,6 +52,7 @@ def eval_board end end end + puts "computer went #{spot}" end def get_best_move(board, next_player, depth = 0, best_score = {}) diff --git a/ttt/model.rb b/ttt/model.rb index d11685f..7124722 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -10,10 +10,15 @@ def initialize def get_human_move move = nil until move - move = gets.chomp.to_i - if @board[move] != "X" && @board[move] != "O" - @board[move] = @hum + move = gets.chomp + if move.to_i.to_s == move && move.to_i >= 0 && move.to_i <= 8 + move = move.to_i + if @board[move] != "X" && @board[move] != "O" + @board[move] = "O" + puts "you went #{move}" + end else + puts "invalid move" move = nil end end @@ -24,16 +29,17 @@ def eval_board until spot if @board[4] == "4" spot = 4 - @board[spot] = @com + @board[spot] = @X else - spot = get_best_move(@board, @com) + spot = get_best_move(@board, @X) if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @com + @board[spot] = @X else spot = nil end end end + puts "computer went #{spot}" end def get_best_move(board, next_player, depth = 0, best_score = {}) @@ -45,14 +51,14 @@ def get_best_move(board, next_player, depth = 0, best_score = {}) end end available_spaces.each do |as| - board[as.to_i] = @com - if game_is_over(board) + board[as.to_i] = @X + if check_game_over best_move = as.to_i board[as.to_i] = as return best_move else - board[as.to_i] = @hum - if game_is_over(board) + board[as.to_i] = "O" + if check_game_over best_move = as.to_i board[as.to_i] = as return best_move From 4e5cad9a053768447086a3964d8684bbcaefea44 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Wed, 9 Jan 2019 16:56:19 -0500 Subject: [PATCH 07/29] . --- ttt/controller.rb | 41 +++++++++++++----- ttt/game.rb | 108 ---------------------------------------------- ttt/model.rb | 35 +++++++-------- ttt/view.rb | 14 ++++-- 4 files changed, 56 insertions(+), 142 deletions(-) delete mode 100644 ttt/game.rb diff --git a/ttt/controller.rb b/ttt/controller.rb index e39177f..bd3b162 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -7,26 +7,45 @@ class Controller def start_game game = Game.new Print::welcome - render_board(game) + Print::render_board(game) Print::acceptable_moves play(game) end - def render_board(game) - Print::tell_user( - " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" - ) - end - def play(game) until game.check_game_over - game.get_human_move + get_human_spot(game) + # place_spot(current_turn, position_placement) + game.move(game.current_turn, game.position_placement) + game.switch_turns if !game.check_game_over - game.eval_board + # game.eval_board + end + Print::render_board(game) + end + end + + def get_human_spot(game) + spot = nil + until spot + spot = gets.chomp + if spot.to_i.to_s == spot && spot.to_i >= 0 && spot.to_i <= 8 + spot = spot.to_i + # change this block by referring to position & current turn in model, spot this block to another method to be called in play + if game.board[spot] != "X" && game.board[spot] != "O" + game.board[spot] = "O" + end + else + Print::acceptable_moves + spot = nil end - puts " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" end - puts "Game over" + end + + def place_move + end + + def get_computer_move(game) end end diff --git a/ttt/game.rb b/ttt/game.rb deleted file mode 100644 index 2a68675..0000000 --- a/ttt/game.rb +++ /dev/null @@ -1,108 +0,0 @@ -class Game - def initialize - @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] - @com = "X" # the computer's marker - @hum = "O" # the user's marker - end - - def start_game - # start by printing the board - puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" - puts "Enter [0-8]:" - # loop through until the game was won or tied - until game_is_over(@board) || tie(@board) - get_human_spot - if !game_is_over(@board) && !tie(@board) - eval_board - end - puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" - end - puts "Game over" - end - - def get_human_spot - spot = nil - until spot - spot = gets.chomp - if spot.to_i.to_s == spot && spot.to_i >= 0 && spot.to_i <= 8 - spot = spot.to_i - if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @hum - puts "you went #{spot}" - end - else - puts "invalid entry" - spot = nil - end - end - end - - def eval_board - spot = nil - until spot - if @board[4] == "4" - spot = 4 - @board[spot] = @com - else - spot = get_best_move(@board, @com) - if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @com - else - spot = nil - end - end - end - puts "computer went #{spot}" - end - - def get_best_move(board, next_player, depth = 0, best_score = {}) - available_spaces = [] - best_move = nil - board.each do |s| - if s != "X" && s != "O" - available_spaces << s - end - end - available_spaces.each do |as| - board[as.to_i] = @com - if game_is_over(board) - best_move = as.to_i - board[as.to_i] = as - return best_move - else - board[as.to_i] = @hum - if game_is_over(board) - best_move = as.to_i - board[as.to_i] = as - return best_move - else - board[as.to_i] = as - end - end - end - if best_move - return best_move - else - n = rand(0..available_spaces.count) - return available_spaces[n].to_i - end - end - - def game_is_over(b) - [b[0], b[1], b[2]].uniq.length == 1 || - [b[3], b[4], b[5]].uniq.length == 1 || - [b[6], b[7], b[8]].uniq.length == 1 || - [b[0], b[3], b[6]].uniq.length == 1 || - [b[1], b[4], b[7]].uniq.length == 1 || - [b[2], b[5], b[8]].uniq.length == 1 || - [b[0], b[4], b[8]].uniq.length == 1 || - [b[2], b[4], b[6]].uniq.length == 1 - end - - def tie(b) - b.all? { |s| s == "X" || s == "O" } - end -end - -game = Game.new -game.start_game diff --git a/ttt/model.rb b/ttt/model.rb index 7124722..f97a877 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -1,27 +1,25 @@ class Game - attr_reader :board + attr_reader :board, :X, :O + attr_accessor :current_turn, :position_placement def initialize @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] - @X = "X" - @O = "O" + @X = "X" #computer/second + @O = "O" #human/first + @current_turn = @O + @position_placement end - def get_human_move - move = nil - until move - move = gets.chomp - if move.to_i.to_s == move && move.to_i >= 0 && move.to_i <= 8 - move = move.to_i - if @board[move] != "X" && @board[move] != "O" - @board[move] = "O" - puts "you went #{move}" - end - else - puts "invalid move" - move = nil - end - end + def switch_turns + @current_turn = @current_turn == @X ? @O : @X + end + + def position_placement + @position_placement = 4 + end + + def move(current_turn, position_placement) + puts "#{current_turn} moves to #{position_placement}" end def eval_board @@ -39,7 +37,6 @@ def eval_board end end end - puts "computer went #{spot}" end def get_best_move(board, next_player, depth = 0, best_score = {}) diff --git a/ttt/view.rb b/ttt/view.rb index d665ddd..46b9ea8 100644 --- a/ttt/view.rb +++ b/ttt/view.rb @@ -13,16 +13,22 @@ def acceptable_moves tell_user "Please enter a unique number between 0-8." end - def report_winner(currentTurn) - tell_user "Game over. #{currentTurn} won." + def report_winner(current_turn) + tell_user "Game over. #{current_turn} won." end def report_tie tell_user "Game over. Tied game." end - def report_move(currentTurn, positionPlacement) - tell_user "#{currentTurn}'s move: #{positionPlacement}" + def report_move(current_turn, position_placement) + tell_user "#{current_turn}'s move: #{position_placement}" + end + + def render_board(game) + Print::tell_user( + " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" + ) end end end From 78f85ada63954f2f357fe7c1aa2c4fd19dda0588 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Thu, 10 Jan 2019 03:07:51 -0500 Subject: [PATCH 08/29] ask user questions. switch turns for game over... default is O. computer move after user questions --- ttt/controller.rb | 47 ++++++++++++++++++++--------------------- ttt/model.rb | 53 ++++++++++++++++++++--------------------------- ttt/view.rb | 21 ++++++++++++------- 3 files changed, 57 insertions(+), 64 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index bd3b162..8b20dc9 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -8,44 +8,41 @@ def start_game game = Game.new Print::welcome Print::render_board(game) - Print::acceptable_moves play(game) end def play(game) - until game.check_game_over - get_human_spot(game) - # place_spot(current_turn, position_placement) - game.move(game.current_turn, game.position_placement) + until game.game_is_over + handle_human_move(game) + Print::report_move(game.current_turn, game.spot) + game.switch_turns + handle_computer_move(game) if !game.game_is_over game.switch_turns - if !game.check_game_over - # game.eval_board - end Print::render_board(game) end + handle_game_over(game) end - def get_human_spot(game) - spot = nil - until spot - spot = gets.chomp - if spot.to_i.to_s == spot && spot.to_i >= 0 && spot.to_i <= 8 - spot = spot.to_i - # change this block by referring to position & current turn in model, spot this block to another method to be called in play - if game.board[spot] != "X" && game.board[spot] != "O" - game.board[spot] = "O" - end - else - Print::acceptable_moves - spot = nil - end - end + def handle_human_move(game) + Print::acceptable_moves + spot = gets.chomp + valid_move(spot, game) ? game.move(spot.to_i) : handle_human_move(game) + end + + def valid_move(spot, game) + spot.to_i.to_s == spot && + spot.to_i >= 0 && spot.to_i <= 8 && + game.board[spot.to_i] != game.X && + game.board[spot.to_i] != game.O ? + true : false end - def place_move + def handle_computer_move(game) + game.eval_board end - def get_computer_move(game) + def handle_game_over(game) + game.winner(game.board) ? Print::report_winner(game.current_turn) : Print::report_tie end end diff --git a/ttt/model.rb b/ttt/model.rb index f97a877..60ab151 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -1,61 +1,52 @@ class Game attr_reader :board, :X, :O - attr_accessor :current_turn, :position_placement + attr_accessor :symbol, :current_turn, :spot def initialize @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] - @X = "X" #computer/second - @O = "O" #human/first + @X = "X" + @O = "O" + @center = "4" + @symbol @current_turn = @O - @position_placement + @spot end def switch_turns @current_turn = @current_turn == @X ? @O : @X end - def position_placement - @position_placement = 4 - end - - def move(current_turn, position_placement) - puts "#{current_turn} moves to #{position_placement}" + def move(spot) + @spot = spot + @board[spot] = @current_turn end def eval_board - spot = nil - until spot - if @board[4] == "4" - spot = 4 - @board[spot] = @X - else - spot = get_best_move(@board, @X) - if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @X - else - spot = nil - end - end + if @board[4] == @center + @board[4] = @current_turn + else + spot = get_best_move(@board) + @board[spot] = @current_turn end end - def get_best_move(board, next_player, depth = 0, best_score = {}) + def get_best_move(board) available_spaces = [] best_move = nil board.each do |s| - if s != "X" && s != "O" + if s != @X && s != @O available_spaces << s end end available_spaces.each do |as| - board[as.to_i] = @X - if check_game_over + board[as.to_i] = @current_turn + if game_is_over best_move = as.to_i board[as.to_i] = as return best_move else - board[as.to_i] = "O" - if check_game_over + board[as.to_i] = @O + if game_is_over best_move = as.to_i board[as.to_i] = as return best_move @@ -72,7 +63,7 @@ def get_best_move(board, next_player, depth = 0, best_score = {}) end end - def check_game_over + def game_is_over winner(@board) || tie(@board) ? true : false end @@ -88,6 +79,6 @@ def winner(board) end def tie(board) - board.all? { |s| s == "X" || s == "O" } + board.all? { |s| s == @X || s == @O } end end diff --git a/ttt/view.rb b/ttt/view.rb index 46b9ea8..d0ab1c3 100644 --- a/ttt/view.rb +++ b/ttt/view.rb @@ -9,6 +9,17 @@ def welcome tell_user "Welcome to Tic Tac Toe!" end + def render_board(game) + Print::tell_user( + " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" + ) + end + + def ask_symbol(game) + tell_user("Do you want to be X or O?") + gets.chomp + end + def acceptable_moves tell_user "Please enter a unique number between 0-8." end @@ -21,14 +32,8 @@ def report_tie tell_user "Game over. Tied game." end - def report_move(current_turn, position_placement) - tell_user "#{current_turn}'s move: #{position_placement}" - end - - def render_board(game) - Print::tell_user( - " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" - ) + def report_move(current_turn, spot) + tell_user "#{current_turn}'s move: #{spot}" end end end From c4b54b351474396fe2a0d60727181f870ae365a3 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Thu, 10 Jan 2019 03:57:25 -0500 Subject: [PATCH 09/29] reporting correct winner --- ttt/controller.rb | 6 +++--- ttt/model.rb | 34 +++++++--------------------------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 8b20dc9..c45a1fe 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -15,9 +15,9 @@ def play(game) until game.game_is_over handle_human_move(game) Print::report_move(game.current_turn, game.spot) - game.switch_turns + game.switch_turns if !game.game_is_over handle_computer_move(game) if !game.game_is_over - game.switch_turns + game.switch_turns if !game.game_is_over Print::render_board(game) end handle_game_over(game) @@ -26,7 +26,7 @@ def play(game) def handle_human_move(game) Print::acceptable_moves spot = gets.chomp - valid_move(spot, game) ? game.move(spot.to_i) : handle_human_move(game) + valid_move(spot, game) ? game.move(spot) : handle_human_move(game) end def valid_move(spot, game) diff --git a/ttt/model.rb b/ttt/model.rb index 60ab151..c96abf1 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -18,49 +18,29 @@ def switch_turns def move(spot) @spot = spot - @board[spot] = @current_turn + @board[@spot.to_i] = @current_turn end def eval_board + # take center if empty if @board[4] == @center @board[4] = @current_turn + # if center isn't available, take random move else - spot = get_best_move(@board) + spot = get_random_move(@board) @board[spot] = @current_turn end end - def get_best_move(board) + def get_random_move(board) available_spaces = [] - best_move = nil + random_move = nil board.each do |s| if s != @X && s != @O available_spaces << s end end - available_spaces.each do |as| - board[as.to_i] = @current_turn - if game_is_over - best_move = as.to_i - board[as.to_i] = as - return best_move - else - board[as.to_i] = @O - if game_is_over - best_move = as.to_i - board[as.to_i] = as - return best_move - else - board[as.to_i] = as - end - end - end - if best_move - return best_move - else - n = rand(0..available_spaces.count) - return available_spaces[n].to_i - end + return available_spaces.sample.to_i end def game_is_over From 69b13f23180eb325dc25df77cab534168a176736 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Fri, 11 Jan 2019 10:46:39 -0500 Subject: [PATCH 10/29] . --- ttt/controller.rb | 10 ++++++---- ttt/model.rb | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index c45a1fe..8d38fa0 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -13,6 +13,7 @@ def start_game def play(game) until game.game_is_over + # game.get_best_move(game) handle_human_move(game) Print::report_move(game.current_turn, game.spot) game.switch_turns if !game.game_is_over @@ -30,10 +31,11 @@ def handle_human_move(game) end def valid_move(spot, game) - spot.to_i.to_s == spot && - spot.to_i >= 0 && spot.to_i <= 8 && - game.board[spot.to_i] != game.X && - game.board[spot.to_i] != game.O ? + int = spot.to_i + int.to_s == spot && + int >= 0 && int <= 8 && + game.board[int] != game.X && + game.board[int] != game.O ? true : false end diff --git a/ttt/model.rb b/ttt/model.rb index c96abf1..1cec855 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -22,10 +22,8 @@ def move(spot) end def eval_board - # take center if empty if @board[4] == @center @board[4] = @current_turn - # if center isn't available, take random move else spot = get_random_move(@board) @board[spot] = @current_turn From c5eef590b817a7260c030a63f1282161adba602c Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Fri, 11 Jan 2019 11:01:07 -0500 Subject: [PATCH 11/29] . --- ttt/computer_move.rb | 81 +++++++++++++++++++++++++++++++++ ttt/original.rb | 104 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 ttt/computer_move.rb create mode 100644 ttt/original.rb diff --git a/ttt/computer_move.rb b/ttt/computer_move.rb new file mode 100644 index 0000000..d553621 --- /dev/null +++ b/ttt/computer_move.rb @@ -0,0 +1,81 @@ +# original method: +def get_best_move(board, next_player, depth = 0, best_score = {}) + best_move = nil + available_spaces(board).each do |as| + space = as.to_i + board[space] = @com + if game_is_over(board) + best_move = space + board[space] = as + return best_move + else + board[space] = @hum + if game_is_over(board) + best_move = space + board[space] = as + return best_move + else + board[space] = as + end + end + end + if best_move + return best_move + else + n = rand(0..available_spaces.count) + return available_spaces[n].to_i + end +end + +def available_spaces(board) + available_spaces = [] + board.each do |space| + if space != "X" && space != "O" + available_spaces << space + end + end +end + +def move(spot) + @spot = spot + @board[@spot.to_i] = @current_turn +end + +def eval_board + if @board[4] == @center + @board[4] = @current_turn + else + spot = get_random_move(@board) + @board[spot] = @current_turn + end +end + +def get_random_move(board) + available_spaces = [] + random_move = nil + board.each do |s| + if s != @X && s != @O + available_spaces << s + end + end + return available_spaces.sample.to_i +end + +def game_is_over + winner(@board) || tie(@board) ? true : false +end + +def winner(board) + [board[0], board[1], board[2]].uniq.length == 1 || + [board[3], board[4], board[5]].uniq.length == 1 || + [board[6], board[7], board[8]].uniq.length == 1 || + [board[0], board[3], board[6]].uniq.length == 1 || + [board[1], board[4], board[7]].uniq.length == 1 || + [board[2], board[5], board[8]].uniq.length == 1 || + [board[0], board[4], board[8]].uniq.length == 1 || + [board[2], board[4], board[6]].uniq.length == 1 +end + +def tie(board) + board.all? { |spot| spot == @X || spot == @O } +end diff --git a/ttt/original.rb b/ttt/original.rb new file mode 100644 index 0000000..6b89b81 --- /dev/null +++ b/ttt/original.rb @@ -0,0 +1,104 @@ +class Game + def initialize + @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] + @com = "X" # the computer's marker + @hum = "O" # the user's marker + end + + def start_game + # start by printing the board + puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" + puts "Enter [0-8]:" + # loop through until the game was won or tied + until game_is_over(@board) || tie(@board) + get_human_spot + if !game_is_over(@board) && !tie(@board) + eval_board + end + puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" + end + puts "Game over" + end + + def get_human_spot + spot = nil + until spot + spot = gets.chomp.to_i + # puts spot >= 0 && spot <= 8 ? "valid input" : "invalid input" + if @board[spot] != "X" && @board[spot] != "O" + @board[spot] = @hum + else + # puts "unacceptable input" + spot = nil + end + end + end + + def eval_board + spot = nil + until spot + if @board[4] == "4" + spot = 4 + @board[spot] = @com + else + spot = get_best_move(@board, @com) + if @board[spot] != "X" && @board[spot] != "O" + @board[spot] = @com + else + spot = nil + end + end + end + end + + def get_best_move(board, next_player, depth = 0, best_score = {}) + available_spaces = [] + best_move = nil + board.each do |s| + if s != "X" && s != "O" + available_spaces << s + end + end + available_spaces.each do |as| + board[as.to_i] = @com + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move + else + board[as.to_i] = @hum + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move + else + board[as.to_i] = as + end + end + end + if best_move + return best_move + else + n = rand(0..available_spaces.count) + return available_spaces[n].to_i + end + end + + def game_is_over(b) + [b[0], b[1], b[2]].uniq.length == 1 || + [b[3], b[4], b[5]].uniq.length == 1 || + [b[6], b[7], b[8]].uniq.length == 1 || + [b[0], b[3], b[6]].uniq.length == 1 || + [b[1], b[4], b[7]].uniq.length == 1 || + [b[2], b[5], b[8]].uniq.length == 1 || + [b[0], b[4], b[8]].uniq.length == 1 || + [b[2], b[4], b[6]].uniq.length == 1 + end + + def tie(b) + b.all? { |s| s == "X" || s == "O" } + end +end + +game = Game.new +game.start_game From 7c29fd30c88b398ed0b66660520b815b2424827a Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Fri, 11 Jan 2019 14:11:58 -0500 Subject: [PATCH 12/29] . --- ttt/commented_out.rb | 37 +++++++++++++++++++++++++++++++++++++ ttt/original.rb | 37 +++++++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 ttt/commented_out.rb diff --git a/ttt/commented_out.rb b/ttt/commented_out.rb new file mode 100644 index 0000000..936c083 --- /dev/null +++ b/ttt/commented_out.rb @@ -0,0 +1,37 @@ +def get_best_move(board, next_player, depth = 0, best_score = {}) + available_spaces = get_available_spaces(board) + best_move = nil + available_spaces.each do |as| + board[as.to_i] = @com +=begin + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move +=end +=begin + else + board[as.to_i] = @hum + if game_is_over(board) + best_move = as.to_i + board[as.to_i] = as + return best_move +=end +=begin + else + board[as.to_i] = as + end + end +=end + end +=begin + if best_move + return best_move +=end +=begin + else + n = rand(0..available_spaces.count) + return available_spaces[n].to_i + end +=end +end diff --git a/ttt/original.rb b/ttt/original.rb index 6b89b81..541a25e 100644 --- a/ttt/original.rb +++ b/ttt/original.rb @@ -52,13 +52,8 @@ def eval_board end def get_best_move(board, next_player, depth = 0, best_score = {}) - available_spaces = [] + available_spaces = [] || get_available_spaces(board) best_move = nil - board.each do |s| - if s != "X" && s != "O" - available_spaces << s - end - end available_spaces.each do |as| board[as.to_i] = @com if game_is_over(board) @@ -76,12 +71,30 @@ def get_best_move(board, next_player, depth = 0, best_score = {}) end end end - if best_move - return best_move - else - n = rand(0..available_spaces.count) - return available_spaces[n].to_i + best_move ? best_move : get_random_move(board) + end + + #receives board array, returns array of available spaces + def get_available_spaces(board) + available_spaces = [] + board.each do |space| + if space != "X" && space != "O" + available_spaces << space + end end + return available_spaces + end + + #receives board array and best_move variable, returns boolean + def winning_move(board, best_move) + end + + #receives board array and best_move variable, returns boolean + def block_winning_move(board, best) + end + + def get_random_move(available_spaces) + return available_spaces.sample.to_i end def game_is_over(b) @@ -96,7 +109,7 @@ def game_is_over(b) end def tie(b) - b.all? { |s| s == "X" || s == "O" } + b.all? { |space| space == "X" || space == "O" } end end From 30bdd9435754bf99050c356b3ca9aeacaa93ecae Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Fri, 11 Jan 2019 15:24:08 -0500 Subject: [PATCH 13/29] try to initialize available_spaces --- ttt/original.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ttt/original.rb b/ttt/original.rb index 541a25e..c18ad16 100644 --- a/ttt/original.rb +++ b/ttt/original.rb @@ -52,7 +52,8 @@ def eval_board end def get_best_move(board, next_player, depth = 0, best_score = {}) - available_spaces = [] || get_available_spaces(board) + available_spaces = [] + get_available_spaces(available_spaces) best_move = nil available_spaces.each do |as| board[as.to_i] = @com @@ -75,13 +76,13 @@ def get_best_move(board, next_player, depth = 0, best_score = {}) end #receives board array, returns array of available spaces - def get_available_spaces(board) - available_spaces = [] - board.each do |space| + def get_available_spaces(available_spaces) + @board.each do |space| if space != "X" && space != "O" available_spaces << space end end + puts "available_spaces: #{available_spaces}" return available_spaces end From b6dcb7bff7b7ec3aa7589d744b4e9438164d1b84 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Fri, 11 Jan 2019 18:36:19 -0500 Subject: [PATCH 14/29] successfully added winner&tie, replaced board with @board, still need to initialize @available_spots, disect eval_board & get_best_move --- ttt/original.rb | 55 +++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/ttt/original.rb b/ttt/original.rb index c18ad16..48f685a 100644 --- a/ttt/original.rb +++ b/ttt/original.rb @@ -10,25 +10,23 @@ def start_game puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" puts "Enter [0-8]:" # loop through until the game was won or tied - until game_is_over(@board) || tie(@board) + until winner || tie get_human_spot - if !game_is_over(@board) && !tie(@board) + if !winner && !tie eval_board end puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" end - puts "Game over" + puts winner ? "game over: winner" : "game over: tie" end def get_human_spot spot = nil until spot spot = gets.chomp.to_i - # puts spot >= 0 && spot <= 8 ? "valid input" : "invalid input" if @board[spot] != "X" && @board[spot] != "O" @board[spot] = @hum else - # puts "unacceptable input" spot = nil end end @@ -41,7 +39,7 @@ def eval_board spot = 4 @board[spot] = @com else - spot = get_best_move(@board, @com) + spot = get_best_move if @board[spot] != "X" && @board[spot] != "O" @board[spot] = @com else @@ -51,28 +49,28 @@ def eval_board end end - def get_best_move(board, next_player, depth = 0, best_score = {}) + def get_best_move #(board, next_player, depth = 0, best_score = {}) available_spaces = [] get_available_spaces(available_spaces) best_move = nil available_spaces.each do |as| - board[as.to_i] = @com - if game_is_over(board) + @board[as.to_i] = @com + if winner best_move = as.to_i - board[as.to_i] = as + @board[as.to_i] = as return best_move else - board[as.to_i] = @hum - if game_is_over(board) + @board[as.to_i] = @hum + if winner best_move = as.to_i - board[as.to_i] = as + @board[as.to_i] = as return best_move else - board[as.to_i] = as + @board[as.to_i] = as end end end - best_move ? best_move : get_random_move(board) + best_move ? best_move : get_random_move(available_spaces) #(@board) end #receives board array, returns array of available spaces @@ -82,35 +80,34 @@ def get_available_spaces(available_spaces) available_spaces << space end end - puts "available_spaces: #{available_spaces}" return available_spaces end #receives board array and best_move variable, returns boolean - def winning_move(board, best_move) + def winning_move end #receives board array and best_move variable, returns boolean - def block_winning_move(board, best) + def block_winning_move end def get_random_move(available_spaces) return available_spaces.sample.to_i end - def game_is_over(b) - [b[0], b[1], b[2]].uniq.length == 1 || - [b[3], b[4], b[5]].uniq.length == 1 || - [b[6], b[7], b[8]].uniq.length == 1 || - [b[0], b[3], b[6]].uniq.length == 1 || - [b[1], b[4], b[7]].uniq.length == 1 || - [b[2], b[5], b[8]].uniq.length == 1 || - [b[0], b[4], b[8]].uniq.length == 1 || - [b[2], b[4], b[6]].uniq.length == 1 + def winner + [@board[0], @board[1], @board[2]].uniq.length == 1 || + [@board[3], @board[4], @board[5]].uniq.length == 1 || + [@board[6], @board[7], @board[8]].uniq.length == 1 || + [@board[0], @board[3], @board[6]].uniq.length == 1 || + [@board[1], @board[4], @board[7]].uniq.length == 1 || + [@board[2], @board[5], @board[8]].uniq.length == 1 || + [@board[0], @board[4], @board[8]].uniq.length == 1 || + [@board[2], @board[4], @board[6]].uniq.length == 1 end - def tie(b) - b.all? { |space| space == "X" || space == "O" } + def tie + @board.all? { |space| space == "X" || space == "O" } end end From ae900d54df8068aae4ffd50e25e596faf361f75c Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 00:45:51 -0500 Subject: [PATCH 15/29] . --- ttt/original.rb | 51 +++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/ttt/original.rb b/ttt/original.rb index 48f685a..6cd03a6 100644 --- a/ttt/original.rb +++ b/ttt/original.rb @@ -5,51 +5,36 @@ def initialize @hum = "O" # the user's marker end - def start_game - # start by printing the board + def play_game puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" puts "Enter [0-8]:" - # loop through until the game was won or tied until winner || tie - get_human_spot + get_human_move if !winner && !tie - eval_board + get_computer_move end puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" end puts winner ? "game over: winner" : "game over: tie" end - def get_human_spot - spot = nil - until spot - spot = gets.chomp.to_i - if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @hum - else - spot = nil - end + def get_human_move + space = nil + until space + space = gets.chomp.to_i + space_available?(space) ? @board[space] = @hum : space = nil end end - def eval_board - spot = nil - until spot - if @board[4] == "4" - spot = 4 - @board[spot] = @com - else - spot = get_best_move - if @board[spot] != "X" && @board[spot] != "O" - @board[spot] = @com - else - spot = nil - end - end - end + def get_computer_move + space_available?(4) ? @board[4] = @com : @board[get_best_move] = @com + end + + def space_available?(space) + @board[space.to_i] != "X" && @board[space.to_i] != "O" end - def get_best_move #(board, next_player, depth = 0, best_score = {}) + def get_best_move available_spaces = [] get_available_spaces(available_spaces) best_move = nil @@ -70,13 +55,13 @@ def get_best_move #(board, next_player, depth = 0, best_score = {}) end end end - best_move ? best_move : get_random_move(available_spaces) #(@board) + get_random_move(available_spaces) end #receives board array, returns array of available spaces def get_available_spaces(available_spaces) @board.each do |space| - if space != "X" && space != "O" + if space_available?(space) available_spaces << space end end @@ -112,4 +97,4 @@ def tie end game = Game.new -game.start_game +game.play_game From 25579470e81c737a945486dc8fd74ae67c70f97c Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 01:32:41 -0500 Subject: [PATCH 16/29] odd side effect from get_available_spacess, need to simplify get_best_move --- ttt/original.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ttt/original.rb b/ttt/original.rb index 6cd03a6..03e5b93 100644 --- a/ttt/original.rb +++ b/ttt/original.rb @@ -31,27 +31,27 @@ def get_computer_move end def space_available?(space) - @board[space.to_i] != "X" && @board[space.to_i] != "O" + @board[space] != "X" && @board[space] != "O" end def get_best_move available_spaces = [] get_available_spaces(available_spaces) best_move = nil - available_spaces.each do |as| - @board[as.to_i] = @com + available_spaces.each do |space| + @board[space.to_i] = @com if winner - best_move = as.to_i - @board[as.to_i] = as + best_move = space.to_i + @board[space.to_i] = space return best_move else - @board[as.to_i] = @hum + @board[space.to_i] = @hum if winner - best_move = as.to_i - @board[as.to_i] = as + best_move = space.to_i + @board[space.to_i] = space return best_move else - @board[as.to_i] = as + @board[space.to_i] = space end end end @@ -61,7 +61,8 @@ def get_best_move #receives board array, returns array of available spaces def get_available_spaces(available_spaces) @board.each do |space| - if space_available?(space) + if space != "X" && space != "O" + # if space_available?(space.to_i).....ignoring for now, but need to integrate available_spaces << space end end From 0e56cbdeca6cf88b2782927ccf51b9dad4f763a0 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 05:13:55 -0500 Subject: [PATCH 17/29] moved original into model successfully --- ttt/commented_out.rb | 37 ---------------- ttt/computer_move.rb | 81 ---------------------------------- ttt/controller.rb | 26 +++++------ ttt/model.rb | 103 +++++++++++++++++++++++++++++-------------- ttt/original.rb | 15 +++---- ttt/view.rb | 4 +- 6 files changed, 88 insertions(+), 178 deletions(-) delete mode 100644 ttt/commented_out.rb delete mode 100644 ttt/computer_move.rb diff --git a/ttt/commented_out.rb b/ttt/commented_out.rb deleted file mode 100644 index 936c083..0000000 --- a/ttt/commented_out.rb +++ /dev/null @@ -1,37 +0,0 @@ -def get_best_move(board, next_player, depth = 0, best_score = {}) - available_spaces = get_available_spaces(board) - best_move = nil - available_spaces.each do |as| - board[as.to_i] = @com -=begin - if game_is_over(board) - best_move = as.to_i - board[as.to_i] = as - return best_move -=end -=begin - else - board[as.to_i] = @hum - if game_is_over(board) - best_move = as.to_i - board[as.to_i] = as - return best_move -=end -=begin - else - board[as.to_i] = as - end - end -=end - end -=begin - if best_move - return best_move -=end -=begin - else - n = rand(0..available_spaces.count) - return available_spaces[n].to_i - end -=end -end diff --git a/ttt/computer_move.rb b/ttt/computer_move.rb deleted file mode 100644 index d553621..0000000 --- a/ttt/computer_move.rb +++ /dev/null @@ -1,81 +0,0 @@ -# original method: -def get_best_move(board, next_player, depth = 0, best_score = {}) - best_move = nil - available_spaces(board).each do |as| - space = as.to_i - board[space] = @com - if game_is_over(board) - best_move = space - board[space] = as - return best_move - else - board[space] = @hum - if game_is_over(board) - best_move = space - board[space] = as - return best_move - else - board[space] = as - end - end - end - if best_move - return best_move - else - n = rand(0..available_spaces.count) - return available_spaces[n].to_i - end -end - -def available_spaces(board) - available_spaces = [] - board.each do |space| - if space != "X" && space != "O" - available_spaces << space - end - end -end - -def move(spot) - @spot = spot - @board[@spot.to_i] = @current_turn -end - -def eval_board - if @board[4] == @center - @board[4] = @current_turn - else - spot = get_random_move(@board) - @board[spot] = @current_turn - end -end - -def get_random_move(board) - available_spaces = [] - random_move = nil - board.each do |s| - if s != @X && s != @O - available_spaces << s - end - end - return available_spaces.sample.to_i -end - -def game_is_over - winner(@board) || tie(@board) ? true : false -end - -def winner(board) - [board[0], board[1], board[2]].uniq.length == 1 || - [board[3], board[4], board[5]].uniq.length == 1 || - [board[6], board[7], board[8]].uniq.length == 1 || - [board[0], board[3], board[6]].uniq.length == 1 || - [board[1], board[4], board[7]].uniq.length == 1 || - [board[2], board[5], board[8]].uniq.length == 1 || - [board[0], board[4], board[8]].uniq.length == 1 || - [board[2], board[4], board[6]].uniq.length == 1 -end - -def tie(board) - board.all? { |spot| spot == @X || spot == @O } -end diff --git a/ttt/controller.rb b/ttt/controller.rb index 8d38fa0..54aa0ba 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -13,38 +13,32 @@ def start_game def play(game) until game.game_is_over - # game.get_best_move(game) handle_human_move(game) - Print::report_move(game.current_turn, game.spot) game.switch_turns if !game.game_is_over + puts "switching turns after human" handle_computer_move(game) if !game.game_is_over game.switch_turns if !game.game_is_over - Print::render_board(game) + puts "switching turns after computer" end handle_game_over(game) end def handle_human_move(game) Print::acceptable_moves - spot = gets.chomp - valid_move(spot, game) ? game.move(spot) : handle_human_move(game) - end - - def valid_move(spot, game) - int = spot.to_i - int.to_s == spot && - int >= 0 && int <= 8 && - game.board[int] != game.X && - game.board[int] != game.O ? - true : false + space = gets.chomp + game.valid_move(space) ? game.move(space.to_i) : handle_human_move(game) + Print::report_move(game.current_turn, game.space) + Print::render_board(game) end def handle_computer_move(game) - game.eval_board + game.get_computer_move + Print::report_move(game.current_turn, game.space) + Print::render_board(game) end def handle_game_over(game) - game.winner(game.board) ? Print::report_winner(game.current_turn) : Print::report_tie + game.winner ? Print::report_winner(game.current_turn) : Print::report_tie end end diff --git a/ttt/model.rb b/ttt/model.rb index 1cec855..e6483f7 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -1,62 +1,101 @@ class Game attr_reader :board, :X, :O - attr_accessor :symbol, :current_turn, :spot + attr_accessor :symbol, :current_turn, :space def initialize @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] - @X = "X" - @O = "O" - @center = "4" + @X = "X" #computer + @O = "O" #human + @space @symbol @current_turn = @O - @spot + end + + def valid_move(space) + int = space.to_i + int.to_s == space && + int >= 0 && + int <= 8 && + @board[int] != @X && + @board[int] != @O ? + true : false end def switch_turns @current_turn = @current_turn == @X ? @O : @X end - def move(spot) - @spot = spot - @board[@spot.to_i] = @current_turn + def move(space) + @space = space + @board[@space] = @current_turn end - def eval_board - if @board[4] == @center - @board[4] = @current_turn - else - spot = get_random_move(@board) - @board[spot] = @current_turn - end + def get_computer_move + space_available?(4) ? @board[4] = @X : @board[get_best_space] = @X + # space_available?(4) ? move(4) : move(get_best_space) end - def get_random_move(board) + def space_available?(space) + @board[space] != "X" && @board[space] != "O" + end + + def get_best_space available_spaces = [] - random_move = nil - board.each do |s| - if s != @X && s != @O - available_spaces << s + get_available_spaces(available_spaces) + best_move = nil + available_spaces.each do |space| + @board[space.to_i] = @X + # winning_move + if winner + best_move = space.to_i + @board[space.to_i] = space + return best_move + else + @board[space.to_i] = @hum + # block_winning_move + if winner + best_move = space.to_i + @board[space.to_i] = space + return best_move + else + # reset board + @board[space.to_i] = space + end end end + get_random_move(available_spaces) + end + + #receives board array, returns array of available spaces + def get_available_spaces(available_spaces) + @board.each do |space| + if space != "X" && space != "O" + available_spaces << space + end + end + return available_spaces + end + + def get_random_move(available_spaces) return available_spaces.sample.to_i end def game_is_over - winner(@board) || tie(@board) ? true : false + winner || tie ? true : false end - def winner(board) - [board[0], board[1], board[2]].uniq.length == 1 || - [board[3], board[4], board[5]].uniq.length == 1 || - [board[6], board[7], board[8]].uniq.length == 1 || - [board[0], board[3], board[6]].uniq.length == 1 || - [board[1], board[4], board[7]].uniq.length == 1 || - [board[2], board[5], board[8]].uniq.length == 1 || - [board[0], board[4], board[8]].uniq.length == 1 || - [board[2], board[4], board[6]].uniq.length == 1 + def winner + [@board[0], @board[1], @board[2]].uniq.length == 1 || + [@board[3], @board[4], @board[5]].uniq.length == 1 || + [@board[6], @board[7], @board[8]].uniq.length == 1 || + [@board[0], @board[3], @board[6]].uniq.length == 1 || + [@board[1], @board[4], @board[7]].uniq.length == 1 || + [@board[2], @board[5], @board[8]].uniq.length == 1 || + [@board[0], @board[4], @board[8]].uniq.length == 1 || + [@board[2], @board[4], @board[6]].uniq.length == 1 end - def tie(board) - board.all? { |s| s == @X || s == @O } + def tie + @board.all? { |space| space == "X" || space == "O" } end end diff --git a/ttt/original.rb b/ttt/original.rb index 03e5b93..f331e9b 100644 --- a/ttt/original.rb +++ b/ttt/original.rb @@ -27,30 +27,33 @@ def get_human_move end def get_computer_move - space_available?(4) ? @board[4] = @com : @board[get_best_move] = @com + space_available?(4) ? @board[4] = @com : @board[get_best_space] = @com end def space_available?(space) @board[space] != "X" && @board[space] != "O" end - def get_best_move + def get_best_space available_spaces = [] get_available_spaces(available_spaces) best_move = nil available_spaces.each do |space| @board[space.to_i] = @com + # winning_move if winner best_move = space.to_i @board[space.to_i] = space return best_move else @board[space.to_i] = @hum + # block_winning_move if winner best_move = space.to_i @board[space.to_i] = space return best_move else + # reset board @board[space.to_i] = space end end @@ -69,14 +72,6 @@ def get_available_spaces(available_spaces) return available_spaces end - #receives board array and best_move variable, returns boolean - def winning_move - end - - #receives board array and best_move variable, returns boolean - def block_winning_move - end - def get_random_move(available_spaces) return available_spaces.sample.to_i end diff --git a/ttt/view.rb b/ttt/view.rb index d0ab1c3..f43fc28 100644 --- a/ttt/view.rb +++ b/ttt/view.rb @@ -32,8 +32,8 @@ def report_tie tell_user "Game over. Tied game." end - def report_move(current_turn, spot) - tell_user "#{current_turn}'s move: #{spot}" + def report_move(current_turn, space) + tell_user "#{current_turn}'s move: #{space}" end end end From 446e930eec227c7adca8a03ef97bd94af62cc531 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 06:28:57 -0500 Subject: [PATCH 18/29] ready to ask user questions --- ttt/controller.rb | 14 +++++++++++--- ttt/model.rb | 17 ++++------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 54aa0ba..a9fd1a2 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -15,10 +15,8 @@ def play(game) until game.game_is_over handle_human_move(game) game.switch_turns if !game.game_is_over - puts "switching turns after human" handle_computer_move(game) if !game.game_is_over game.switch_turns if !game.game_is_over - puts "switching turns after computer" end handle_game_over(game) end @@ -26,11 +24,21 @@ def play(game) def handle_human_move(game) Print::acceptable_moves space = gets.chomp - game.valid_move(space) ? game.move(space.to_i) : handle_human_move(game) + valid_move(space, game) ? game.move(space.to_i) : handle_human_move(game) Print::report_move(game.current_turn, game.space) Print::render_board(game) end + def valid_move(space, game) + int = space.to_i + int.to_s == space && + int >= 0 && + int <= 8 && + game.board[int] != game.X && + game.board[int] != game.O ? + true : false + end + def handle_computer_move(game) game.get_computer_move Print::report_move(game.current_turn, game.space) diff --git a/ttt/model.rb b/ttt/model.rb index e6483f7..0b90641 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -11,16 +11,6 @@ def initialize @current_turn = @O end - def valid_move(space) - int = space.to_i - int.to_s == space && - int >= 0 && - int <= 8 && - @board[int] != @X && - @board[int] != @O ? - true : false - end - def switch_turns @current_turn = @current_turn == @X ? @O : @X end @@ -32,7 +22,6 @@ def move(space) def get_computer_move space_available?(4) ? @board[4] = @X : @board[get_best_space] = @X - # space_available?(4) ? move(4) : move(get_best_space) end def space_available?(space) @@ -42,6 +31,7 @@ def space_available?(space) def get_best_space available_spaces = [] get_available_spaces(available_spaces) + # if difficulty == impossible best_move = nil available_spaces.each do |space| @board[space.to_i] = @X @@ -63,7 +53,8 @@ def get_best_space end end end - get_random_move(available_spaces) + # + get_random_space(available_spaces) end #receives board array, returns array of available spaces @@ -76,7 +67,7 @@ def get_available_spaces(available_spaces) return available_spaces end - def get_random_move(available_spaces) + def get_random_space(available_spaces) return available_spaces.sample.to_i end From 88cfc3d77c5b9dd739b4df248be81a783a3cbb52 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 07:04:00 -0500 Subject: [PATCH 19/29] need to fix impossible --- ttt/controller.rb | 21 +++++++++++++++++++-- ttt/model.rb | 39 ++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index a9fd1a2..85b8b3f 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -8,12 +8,31 @@ def start_game game = Game.new Print::welcome Print::render_board(game) + difficulty_setting(game) play(game) end + def difficulty_setting(game) + Print::tell_user("Choose computer difficulty: [0] Random or [1] Impossible") + difficulty = gets.chomp + case difficulty + when "0" + Print::tell_user("Difficulty: Random") + game.set_difficulty(0) + when "1" + Print::tell_user("Difficulty: Impossible") + game.set_difficulty(1) + else + Print::tell_user("Invalid input, please enter 0 or 1") + difficulty(game) + end + end + def play(game) until game.game_is_over handle_human_move(game) + Print::report_move(game.current_turn, game.space) + Print::render_board(game) game.switch_turns if !game.game_is_over handle_computer_move(game) if !game.game_is_over game.switch_turns if !game.game_is_over @@ -25,8 +44,6 @@ def handle_human_move(game) Print::acceptable_moves space = gets.chomp valid_move(space, game) ? game.move(space.to_i) : handle_human_move(game) - Print::report_move(game.current_turn, game.space) - Print::render_board(game) end def valid_move(space, game) diff --git a/ttt/model.rb b/ttt/model.rb index 0b90641..65bbff0 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -1,14 +1,19 @@ class Game attr_reader :board, :X, :O - attr_accessor :symbol, :current_turn, :space + attr_accessor :symbol, :current_turn, :space, :difficulty def initialize @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] @X = "X" #computer @O = "O" #human - @space @symbol @current_turn = @O + @space + @difficulty + end + + def set_difficulty(setting) + @difficulty = setting end def switch_turns @@ -31,29 +36,29 @@ def space_available?(space) def get_best_space available_spaces = [] get_available_spaces(available_spaces) - # if difficulty == impossible - best_move = nil - available_spaces.each do |space| - @board[space.to_i] = @X - # winning_move - if winner - best_move = space.to_i - @board[space.to_i] = space - return best_move - else - @board[space.to_i] = @hum - # block_winning_move + if @difficulty == 1 + best_move = nil + available_spaces.each do |space| + @board[space.to_i] = @X + # winning_move if winner best_move = space.to_i @board[space.to_i] = space return best_move else - # reset board - @board[space.to_i] = space + @board[space.to_i] = @hum + # block_winning_move + if winner + best_move = space.to_i + @board[space.to_i] = space + return best_move + else + # reset board + @board[space.to_i] = space + end end end end - # get_random_space(available_spaces) end From ac69950085db01f1c649dbdc834228a07c2f3d05 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 17:48:55 -0500 Subject: [PATCH 20/29] get_best_space iteration needs tweeking --- ttt/controller.rb | 5 +++-- ttt/model.rb | 46 +++++++++++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 85b8b3f..9350d34 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -7,8 +7,9 @@ class Controller def start_game game = Game.new Print::welcome - Print::render_board(game) + difficulty_setting(game) + Print::render_board(game) play(game) end @@ -24,7 +25,7 @@ def difficulty_setting(game) game.set_difficulty(1) else Print::tell_user("Invalid input, please enter 0 or 1") - difficulty(game) + difficulty_setting(game) end end diff --git a/ttt/model.rb b/ttt/model.rb index 65bbff0..f6ac450 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -26,7 +26,7 @@ def move(space) end def get_computer_move - space_available?(4) ? @board[4] = @X : @board[get_best_space] = @X + space_available?(4) ? @board[4] = @current_turn : @board[get_best_space] = @current_turn end def space_available?(space) @@ -39,29 +39,45 @@ def get_best_space if @difficulty == 1 best_move = nil available_spaces.each do |space| - @board[space.to_i] = @X - # winning_move - if winner - best_move = space.to_i + best_move = space.to_i + @board[best_move] = @current_turn + if winning_move?(space) + puts "winnging move" + @board[space.to_i] = space + return best_move + elsif block_win?(space) + puts "block move" + @board[space.to_i] = space + return best_move + elsif block_fork?(space) + puts "block fork move" @board[space.to_i] = space return best_move else - @board[space.to_i] = @hum - # block_winning_move - if winner - best_move = space.to_i - @board[space.to_i] = space - return best_move - else - # reset board - @board[space.to_i] = space - end + @board[best_move] = space end end end + puts "random move" get_random_space(available_spaces) end + def winning_move?(space) + puts "checking winning move" + move(space.to_i) + winner + end + + def block_win?(space) + switch_turns + move(space.to_i) + switch_turns + winner + end + + def block_fork?(space) + end + #receives board array, returns array of available spaces def get_available_spaces(available_spaces) @board.each do |space| From 74754a73ff04b0a3fe5d233a3f4b06f447889aa8 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Sun, 13 Jan 2019 23:02:14 -0500 Subject: [PATCH 21/29] before reorganizing get_best_move --- ttt/model.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ttt/model.rb b/ttt/model.rb index f6ac450..50467e1 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -34,8 +34,7 @@ def space_available?(space) end def get_best_space - available_spaces = [] - get_available_spaces(available_spaces) + available_spaces = get_available_spaces if @difficulty == 1 best_move = nil available_spaces.each do |space| @@ -63,12 +62,13 @@ def get_best_space end def winning_move?(space) - puts "checking winning move" + puts "checking winning #{@current_turn} move" move(space.to_i) winner end def block_win?(space) + puts "checking blocking move" switch_turns move(space.to_i) switch_turns @@ -79,8 +79,10 @@ def block_fork?(space) end #receives board array, returns array of available spaces - def get_available_spaces(available_spaces) + def get_available_spaces + available_spaces = [] @board.each do |space| + # available_spaces << space if space_available?(space.to_i) if space != "X" && space != "O" available_spaces << space end From 58faa4efec2f2055e4f096538871d611a9327334 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 03:39:20 -0500 Subject: [PATCH 22/29] successfully ordered winner vs block win, but need to block fork still. continue on with settings --- ttt/model.rb | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/ttt/model.rb b/ttt/model.rb index 50467e1..646bbc5 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -26,7 +26,7 @@ def move(space) end def get_computer_move - space_available?(4) ? @board[4] = @current_turn : @board[get_best_space] = @current_turn + space_available?(4) ? move(4) : move(get_best_space) end def space_available?(space) @@ -41,34 +41,42 @@ def get_best_space best_move = space.to_i @board[best_move] = @current_turn if winning_move?(space) - puts "winnging move" @board[space.to_i] = space return best_move - elsif block_win?(space) - puts "block move" - @board[space.to_i] = space - return best_move - elsif block_fork?(space) - puts "block fork move" + else + @board[best_move] = space + end + end + available_spaces.each do |space| + best_move = space.to_i + @board[best_move] = @current_turn + if block_win?(space) @board[space.to_i] = space return best_move else @board[best_move] = space end end + # available_spaces.each do |space| + # best_move = space.to_i + # @board[best_move] = @current_turn + # if block_fork?(space) + # @board[space.to_i] = space + # return best_move + # else + # @board[best_move] = space + # end + # end end - puts "random move" get_random_space(available_spaces) end def winning_move?(space) - puts "checking winning #{@current_turn} move" move(space.to_i) winner end def block_win?(space) - puts "checking blocking move" switch_turns move(space.to_i) switch_turns From 4283b9e5fc88f179bbb5e885e4db12cb312d9bc0 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 14:21:39 -0500 Subject: [PATCH 23/29] . --- ttt/controller.rb | 15 +++++++++------ ttt/model.rb | 3 ++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 9350d34..2535229 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -14,17 +14,20 @@ def start_game end def difficulty_setting(game) - Print::tell_user("Choose computer difficulty: [0] Random or [1] Impossible") + Print::tell_user("Choose computer difficulty: [0] Easy or [1] Hard") difficulty = gets.chomp case difficulty when "0" - Print::tell_user("Difficulty: Random") - game.set_difficulty(0) + Print::tell_user("Difficulty: Easy") + game.set_difficulty("Easy") when "1" - Print::tell_user("Difficulty: Impossible") - game.set_difficulty(1) + Print::tell_user("Difficulty: Hard") + game.set_difficulty("Hard") + # when "2" + # Print::tell_user("Difficulty: Impossible") + # game.set_difficulty("Impossible") else - Print::tell_user("Invalid input, please enter 0 or 1") + Print::tell_user("Invalid input, please enter 0 or 1") #or 2 difficulty_setting(game) end end diff --git a/ttt/model.rb b/ttt/model.rb index 646bbc5..7b1d93c 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -35,7 +35,7 @@ def space_available?(space) def get_best_space available_spaces = get_available_spaces - if @difficulty == 1 + if @difficulty == "Hard" #|| @difficulty == "Impossible" best_move = nil available_spaces.each do |space| best_move = space.to_i @@ -57,6 +57,7 @@ def get_best_space @board[best_move] = space end end + # if @difficulty == "Impossible" # available_spaces.each do |space| # best_move = space.to_i # @board[best_move] = @current_turn From b0ffcd7bc03e6e864376e7acc748a38dedbdb95b Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 14:35:36 -0500 Subject: [PATCH 24/29] . --- ttt/controller.rb | 21 ++++++++++++++++++++- ttt/model.rb | 11 +++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 2535229..e46dd4c 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -7,12 +7,31 @@ class Controller def start_game game = Game.new Print::welcome - + mode_setting(game) difficulty_setting(game) Print::render_board(game) play(game) end + def mode_setting(game) + Print::tell_user("Choose game mode:\n[0] Human vs Computer [1] Human vs Human, or [2] Computer vs Computer") + mode = gets.chomp + case mode + when "0" + Print::tell_user("Mode: Human vs Computer") + # game.set_mode("HvC") + when "1" + Print::tell_user("Mode: Human vs Human") + # game.set_mode("HvH") + when "2" + Print::tell_user("Mode: Computer vs Computer") + # game.set_mode("CvC") + else + Print::tell_user("Invalid input, please enter 0, 1 or 2") + mode_setting(game) + end + end + def difficulty_setting(game) Print::tell_user("Choose computer difficulty: [0] Easy or [1] Hard") difficulty = gets.chomp diff --git a/ttt/model.rb b/ttt/model.rb index 7b1d93c..7eec189 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -10,6 +10,9 @@ def initialize @current_turn = @O @space @difficulty + @easy = "Easy" + @hard = "Hard" + @impossible = "Impossible" end def set_difficulty(setting) @@ -30,12 +33,12 @@ def get_computer_move end def space_available?(space) - @board[space] != "X" && @board[space] != "O" + @board[space] != @X && @board[space] != @O end def get_best_space available_spaces = get_available_spaces - if @difficulty == "Hard" #|| @difficulty == "Impossible" + if @difficulty == @hard #|| @difficulty == @impossible best_move = nil available_spaces.each do |space| best_move = space.to_i @@ -92,7 +95,7 @@ def get_available_spaces available_spaces = [] @board.each do |space| # available_spaces << space if space_available?(space.to_i) - if space != "X" && space != "O" + if space != @X && space != @O available_spaces << space end end @@ -119,6 +122,6 @@ def winner end def tie - @board.all? { |space| space == "X" || space == "O" } + @board.all? { |space| space == @X || space == @O } end end From 9e954f9799b440709a90a1e6529762dc36e8ea99 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 15:17:00 -0500 Subject: [PATCH 25/29] successfully added settings.mode and .difficulty. todo: add order and symbol --- ttt/controller.rb | 40 ++++++++++++++++++++-------------------- ttt/model.rb | 12 +++++++++++- ttt/view.rb | 10 ++++++---- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index e46dd4c..4754da6 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -8,24 +8,22 @@ def start_game game = Game.new Print::welcome mode_setting(game) - difficulty_setting(game) + difficulty_setting(game) if game.mode == game.HvC + Print::report_settings(game) Print::render_board(game) play(game) end def mode_setting(game) - Print::tell_user("Choose game mode:\n[0] Human vs Computer [1] Human vs Human, or [2] Computer vs Computer") + Print::tell_user("Choose game mode:\n[0] #{game.HvC} [1] #{game.HvH}, or [2] #{game.CvC}") mode = gets.chomp case mode when "0" - Print::tell_user("Mode: Human vs Computer") - # game.set_mode("HvC") + game.set_mode(game.HvC) when "1" - Print::tell_user("Mode: Human vs Human") - # game.set_mode("HvH") + game.set_mode(game.HvH) when "2" - Print::tell_user("Mode: Computer vs Computer") - # game.set_mode("CvC") + game.set_mode(game.CvC) else Print::tell_user("Invalid input, please enter 0, 1 or 2") mode_setting(game) @@ -33,18 +31,16 @@ def mode_setting(game) end def difficulty_setting(game) - Print::tell_user("Choose computer difficulty: [0] Easy or [1] Hard") + Print::tell_user("Choose computer difficulty:\n[0] #{game.easy} or [1] #{game.hard}") difficulty = gets.chomp case difficulty when "0" - Print::tell_user("Difficulty: Easy") - game.set_difficulty("Easy") + game.set_difficulty(game.easy) when "1" - Print::tell_user("Difficulty: Hard") - game.set_difficulty("Hard") + game.set_difficulty(game.hard) # when "2" # Print::tell_user("Difficulty: Impossible") - # game.set_difficulty("Impossible") + # game.set_difficulty(game.impossible) else Print::tell_user("Invalid input, please enter 0 or 1") #or 2 difficulty_setting(game) @@ -53,12 +49,16 @@ def difficulty_setting(game) def play(game) until game.game_is_over - handle_human_move(game) - Print::report_move(game.current_turn, game.space) - Print::render_board(game) - game.switch_turns if !game.game_is_over - handle_computer_move(game) if !game.game_is_over - game.switch_turns if !game.game_is_over + if game.mode != game.CvC + handle_human_move(game) + Print::report_move(game.current_turn, game.space) + Print::render_board(game) + game.switch_turns if !game.game_is_over + end + if game.mode != game.HvH + handle_computer_move(game) if !game.game_is_over + game.switch_turns if !game.game_is_over + end end handle_game_over(game) end diff --git a/ttt/model.rb b/ttt/model.rb index 7eec189..fc80a65 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -1,6 +1,8 @@ class Game attr_reader :board, :X, :O - attr_accessor :symbol, :current_turn, :space, :difficulty + attr_accessor :symbol, :current_turn, :space, + :mode, :HvC, :HvH, :CvC, + :difficulty, :easy, :hard, :impossible def initialize @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] @@ -9,12 +11,20 @@ def initialize @symbol @current_turn = @O @space + @mode + @HvC = "Human vs Computer" + @HvH = "Human vs Human" + @CvC = "Computer vs Computer" @difficulty @easy = "Easy" @hard = "Hard" @impossible = "Impossible" end + def set_mode(setting) + @mode = setting + end + def set_difficulty(setting) @difficulty = setting end diff --git a/ttt/view.rb b/ttt/view.rb index f43fc28..4e1ec8b 100644 --- a/ttt/view.rb +++ b/ttt/view.rb @@ -11,13 +11,15 @@ def welcome def render_board(game) Print::tell_user( - " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n" + " #{game.board[0]} | #{game.board[1]} | #{game.board[2]} \n===+===+===\n #{game.board[3]} | #{game.board[4]} | #{game.board[5]} \n===+===+===\n #{game.board[6]} | #{game.board[7]} | #{game.board[8]} \n\n" ) end - def ask_symbol(game) - tell_user("Do you want to be X or O?") - gets.chomp + def report_settings(game) + tell_user "*******************************" + tell_user "Game Settings:\nMode: #{game.mode}\n" + tell_user "Difficulty: #{game.difficulty}" if game.mode != game.HvH + tell_user "*******************************" end def acceptable_moves From 496ab6a076d96583e91b8e99d0f631074530fe8e Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 16:55:05 -0500 Subject: [PATCH 26/29] . --- ttt/controller.rb | 12 ++++++------ ttt/view.rb | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 4754da6..46399ff 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -7,14 +7,14 @@ class Controller def start_game game = Game.new Print::welcome - mode_setting(game) - difficulty_setting(game) if game.mode == game.HvC + handle_mode_setting(game) + handle_difficulty_setting(game) if game.mode == game.HvC Print::report_settings(game) Print::render_board(game) play(game) end - def mode_setting(game) + def handle_mode_setting(game) Print::tell_user("Choose game mode:\n[0] #{game.HvC} [1] #{game.HvH}, or [2] #{game.CvC}") mode = gets.chomp case mode @@ -26,11 +26,11 @@ def mode_setting(game) game.set_mode(game.CvC) else Print::tell_user("Invalid input, please enter 0, 1 or 2") - mode_setting(game) + handle_mode_setting(game) end end - def difficulty_setting(game) + def handle_difficulty_setting(game) Print::tell_user("Choose computer difficulty:\n[0] #{game.easy} or [1] #{game.hard}") difficulty = gets.chomp case difficulty @@ -43,7 +43,7 @@ def difficulty_setting(game) # game.set_difficulty(game.impossible) else Print::tell_user("Invalid input, please enter 0 or 1") #or 2 - difficulty_setting(game) + handle_difficulty_setting(game) end end diff --git a/ttt/view.rb b/ttt/view.rb index 4e1ec8b..b65cf7d 100644 --- a/ttt/view.rb +++ b/ttt/view.rb @@ -18,7 +18,7 @@ def render_board(game) def report_settings(game) tell_user "*******************************" tell_user "Game Settings:\nMode: #{game.mode}\n" - tell_user "Difficulty: #{game.difficulty}" if game.mode != game.HvH + tell_user "Difficulty: #{game.difficulty}" if game.mode == game.HvC tell_user "*******************************" end From 692f7d56f68a1ab7c96f852c5829d91b05c43d78 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 17:43:21 -0500 Subject: [PATCH 27/29] successfully added game.order, .symbol.. need difficulty=impossible --- ttt/controller.rb | 39 ++++++++++++++++++++++++++++++++++++++- ttt/model.rb | 43 ++++++++++++++++++++++++++++++++++++------- ttt/view.rb | 6 +++++- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/ttt/controller.rb b/ttt/controller.rb index 46399ff..bc9ed35 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -8,7 +8,11 @@ def start_game game = Game.new Print::welcome handle_mode_setting(game) - handle_difficulty_setting(game) if game.mode == game.HvC + if game.mode != game.CvC + handle_order_setting(game) + handle_symbol_setting(game) + handle_difficulty_setting(game) if game.mode == game.HvC + end Print::report_settings(game) Print::render_board(game) play(game) @@ -30,6 +34,34 @@ def handle_mode_setting(game) end end + def handle_order_setting(game) + Print::tell_user("Choose your order:\n[0] #{game.first} or [1] #{game.second}") + order = gets.chomp + case order + when "0" + game.set_order(game.first) + when "1" + game.set_order(game.second) + else + Print::tell_user("Invalid input, please enter 0 or 1") + handle_order_setting(game) + end + end + + def handle_symbol_setting(game) + Print::tell_user("Choose your symbol:\n[0] #{game.X} or [1] #{game.O}") + symbol = gets.chomp + case symbol + when "0" + game.set_symbol(game.X) + when "1" + game.set_symbol(game.O) + else + Print::tell_user("Invalid input, please enter 0 or 1") + handle_symbol_setting(game) + end + end + def handle_difficulty_setting(game) Print::tell_user("Choose computer difficulty:\n[0] #{game.easy} or [1] #{game.hard}") difficulty = gets.chomp @@ -48,6 +80,11 @@ def handle_difficulty_setting(game) end def play(game) + game.set_first_turn if game.mode != game.CvC + if game.mode == game.HvC && game.order = game.second + handle_computer_move(game) + game.switch_turns + end until game.game_is_over if game.mode != game.CvC handle_human_move(game) diff --git a/ttt/model.rb b/ttt/model.rb index fc80a65..3f00634 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -1,34 +1,63 @@ class Game attr_reader :board, :X, :O - attr_accessor :symbol, :current_turn, :space, - :mode, :HvC, :HvH, :CvC, - :difficulty, :easy, :hard, :impossible + attr_accessor :mode, :HvC, :HvH, :CvC, + :order, :first, :second, + :symbol, + :difficulty, :easy, :hard, :impossible, + :current_turn, :space def initialize @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] - @X = "X" #computer - @O = "O" #human - @symbol - @current_turn = @O @space + @mode @HvC = "Human vs Computer" @HvH = "Human vs Human" @CvC = "Computer vs Computer" + + @order + @first = "First" + @second = "Second" + + @symbol + @X = "X" + @O = "O" + @difficulty @easy = "Easy" @hard = "Hard" @impossible = "Impossible" + @current_turn = @O end def set_mode(setting) @mode = setting end + def set_order(setting) + @order = setting + end + + def set_symbol(setting) + @symbol = setting + end + def set_difficulty(setting) @difficulty = setting end + def set_first_turn + if (@symbol == @X && order == @first) + @current_turn = @X + elsif (@symbol == @X && order == @second) + @current_turn = @O + elsif (@symbol == @O && order == @first) + @current_turn = @O + elsif (@symbol == @O && order == @second) + @current_turn = @X + end + end + def switch_turns @current_turn = @current_turn == @X ? @O : @X end diff --git a/ttt/view.rb b/ttt/view.rb index b65cf7d..7f0010c 100644 --- a/ttt/view.rb +++ b/ttt/view.rb @@ -18,7 +18,11 @@ def render_board(game) def report_settings(game) tell_user "*******************************" tell_user "Game Settings:\nMode: #{game.mode}\n" - tell_user "Difficulty: #{game.difficulty}" if game.mode == game.HvC + if game.mode != game.CvC + tell_user "Order: #{game.order}\n" + tell_user "Symbol: #{game.symbol}\n" + tell_user "Difficulty: #{game.difficulty}\n" if game.mode == game.HvC + end tell_user "*******************************" end From 0977509c4b8d99e90c00c00e13bba917b7e47591 Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 18:48:36 -0500 Subject: [PATCH 28/29] no impossible difficulty, space_available? needs tweeking, next: tests --- ttt/controller.rb | 14 +------ ttt/model.rb | 23 +++++++----- ttt/original.rb | 96 ----------------------------------------------- ttt/tests.rb | 0 4 files changed, 16 insertions(+), 117 deletions(-) delete mode 100644 ttt/original.rb create mode 100644 ttt/tests.rb diff --git a/ttt/controller.rb b/ttt/controller.rb index bc9ed35..ad166df 100644 --- a/ttt/controller.rb +++ b/ttt/controller.rb @@ -81,7 +81,7 @@ def handle_difficulty_setting(game) def play(game) game.set_first_turn if game.mode != game.CvC - if game.mode == game.HvC && game.order = game.second + if game.mode == game.HvC && game.order == game.second handle_computer_move(game) game.switch_turns end @@ -103,17 +103,7 @@ def play(game) def handle_human_move(game) Print::acceptable_moves space = gets.chomp - valid_move(space, game) ? game.move(space.to_i) : handle_human_move(game) - end - - def valid_move(space, game) - int = space.to_i - int.to_s == space && - int >= 0 && - int <= 8 && - game.board[int] != game.X && - game.board[int] != game.O ? - true : false + game.valid_move(space) ? game.move(space.to_i) : handle_human_move(game) end def handle_computer_move(game) diff --git a/ttt/model.rb b/ttt/model.rb index 3f00634..914400a 100644 --- a/ttt/model.rb +++ b/ttt/model.rb @@ -47,14 +47,10 @@ def set_difficulty(setting) end def set_first_turn - if (@symbol == @X && order == @first) - @current_turn = @X - elsif (@symbol == @X && order == @second) - @current_turn = @O - elsif (@symbol == @O && order == @first) - @current_turn = @O - elsif (@symbol == @O && order == @second) - @current_turn = @X + if @symbol == @X + @current_turn = @order == @first ? @X : @O + else + @current_turn = @order == @first ? @O : @X end end @@ -67,6 +63,16 @@ def move(space) @board[@space] = @current_turn end + def valid_move(space) + int = space.to_i + int.to_s == space && + int >= 0 && + int <= 8 && + @board[int] != @X && + @board[int] != @O ? + true : false + end + def get_computer_move space_available?(4) ? move(4) : move(get_best_space) end @@ -129,7 +135,6 @@ def block_win?(space) def block_fork?(space) end - #receives board array, returns array of available spaces def get_available_spaces available_spaces = [] @board.each do |space| diff --git a/ttt/original.rb b/ttt/original.rb deleted file mode 100644 index f331e9b..0000000 --- a/ttt/original.rb +++ /dev/null @@ -1,96 +0,0 @@ -class Game - def initialize - @board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"] - @com = "X" # the computer's marker - @hum = "O" # the user's marker - end - - def play_game - puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" - puts "Enter [0-8]:" - until winner || tie - get_human_move - if !winner && !tie - get_computer_move - end - puts " #{@board[0]} | #{@board[1]} | #{@board[2]} \n===+===+===\n #{@board[3]} | #{@board[4]} | #{@board[5]} \n===+===+===\n #{@board[6]} | #{@board[7]} | #{@board[8]} \n" - end - puts winner ? "game over: winner" : "game over: tie" - end - - def get_human_move - space = nil - until space - space = gets.chomp.to_i - space_available?(space) ? @board[space] = @hum : space = nil - end - end - - def get_computer_move - space_available?(4) ? @board[4] = @com : @board[get_best_space] = @com - end - - def space_available?(space) - @board[space] != "X" && @board[space] != "O" - end - - def get_best_space - available_spaces = [] - get_available_spaces(available_spaces) - best_move = nil - available_spaces.each do |space| - @board[space.to_i] = @com - # winning_move - if winner - best_move = space.to_i - @board[space.to_i] = space - return best_move - else - @board[space.to_i] = @hum - # block_winning_move - if winner - best_move = space.to_i - @board[space.to_i] = space - return best_move - else - # reset board - @board[space.to_i] = space - end - end - end - get_random_move(available_spaces) - end - - #receives board array, returns array of available spaces - def get_available_spaces(available_spaces) - @board.each do |space| - if space != "X" && space != "O" - # if space_available?(space.to_i).....ignoring for now, but need to integrate - available_spaces << space - end - end - return available_spaces - end - - def get_random_move(available_spaces) - return available_spaces.sample.to_i - end - - def winner - [@board[0], @board[1], @board[2]].uniq.length == 1 || - [@board[3], @board[4], @board[5]].uniq.length == 1 || - [@board[6], @board[7], @board[8]].uniq.length == 1 || - [@board[0], @board[3], @board[6]].uniq.length == 1 || - [@board[1], @board[4], @board[7]].uniq.length == 1 || - [@board[2], @board[5], @board[8]].uniq.length == 1 || - [@board[0], @board[4], @board[8]].uniq.length == 1 || - [@board[2], @board[4], @board[6]].uniq.length == 1 - end - - def tie - @board.all? { |space| space == "X" || space == "O" } - end -end - -game = Game.new -game.play_game diff --git a/ttt/tests.rb b/ttt/tests.rb new file mode 100644 index 0000000..e69de29 From 63a7c9ab650da407b1e6e83e6f43078f2d3f0f9d Mon Sep 17 00:00:00 2001 From: matthew lee <matthewlee07@gmail.com> Date: Mon, 14 Jan 2019 20:55:34 -0500 Subject: [PATCH 29/29] final --- ttt/README.md | 37 ------------------------------------- ttt/tests.rb | 0 2 files changed, 37 deletions(-) delete mode 100644 ttt/README.md delete mode 100644 ttt/tests.rb diff --git a/ttt/README.md b/ttt/README.md deleted file mode 100644 index 588e7e8..0000000 --- a/ttt/README.md +++ /dev/null @@ -1,37 +0,0 @@ -Hello, -I’m the project manager at a Command Line Games, Inc. I have a small dev team and we hired a -consulting company to help us build an app that will feature a number of games for children, one being -Tic Tac Toe. -They just demoed the basic version of the Tic Tac Toe game in the console and my boss wasn’t thrilled -with what he saw. The game play was rough. It didn’t function as he expected. We’ve decided to move -in a different direction and bring in someone else. While my boss doesn’t have a technical background, -I do, and we both understand the importance of writing code that can be maintained in the future. -We would like you to improve the existing Tic Tac Toe that the previous firm worked on. There are a -number of issues with the code. Below I’ve listed some of those issues, but I’m sure there are more. -● The game does not gracefully handle bad user input. -● In its current form, it’s supposed to be played at a difficulty level of “hard”, meaning the computer -player cannot be beaten. In reality, however, the computer player can be beaten in certain -situations. This is more like a “medium” difficulty level. -● The game play left a lot to be desired. The user messages are lacking. They’re unclear. It’s -confusing to see the spot that’s selected and the board all on the screen. It’s easy to get lost in -what’s happening. It’s weird the way the computer picks its spot without notifying the user. -As you can tell, there are a lot of problems and from what our devs say, the code itself is a mess. It’s -untested and therefore unmaintainable. It’s poorly­written and inflexible. This puts us in a difficult -position because we have a number of features we would like to add and we’re hoping you can help. -We hope that you’ll be able to help us get the code in a better state. Without that, our devs don’t even -think we’ll be able to implement the new features my boss has requested. For one thing, the existing -code is so coupled to the console that implementing any other UI is nearly impossible! Below you’ll see -a list of the features we’re hoping to add. -● Allow the user to choose the game type (human v. human, computer v. computer, human v. -computer). -● Allow the user to choose which player goes first. -● Allow the user to choose with what “symbol” the players will mark their selections on the board -(traditionally it’s “X” and “O”). -Could you implement these features? - -Your code will be judged on the following criteria: - -Adherence to SOLID principles -Appropriate separation of concerns -Clarity and readability -Expressive naming diff --git a/ttt/tests.rb b/ttt/tests.rb deleted file mode 100644 index e69de29..0000000