odin-oop-with-ruby

Project 1: TicTacToe


first Version TicTactoe

the grid |X|.|.| is represented by an array of cell  (class Cell)
         |.|X|.|  
         |.|.|O|

class Cell cell.rb create a cell with three states :
- empty :e
- player :x :o

class Grid grid.rb create grid with cells

class Player

class Tictactoe tic_tac_toe.rb

   g = TicTacToe.start
   g.play

second version: TictacToe-rspec

the grid |X|.|.| is represented by an array of string ["X..",".X.","..O"]
         |.|X|.|  
         |.|.|O|
and to test if the current grid win compare each row column or diagonal with "XXX" or "OOO"     
[(3+3+2 )* 2 =  16 tests]
         |X|X|X|  |X|.|.|  |X|.|.|  |O|.|.|
         |.|.|.|  |X|.|.|  |.|X|.|  |.|O|.|
         |.|.|.|  |X|.|.|  |.|.|X|  |.|.|O|

 (i try TDD method in this version)    

📁tictactoe

      g = TicTacToe.start
      g.loop

spec

use double to simulate output start_game_spec.rb

     describe "start game" do
  let(:output) {double("output").as_null_object}**
  let(:game){Grid.new(output)}
  context "start game" do
  it "grid when start game" do
      output.should_receive(:puts).with("\n-------\n|.|.|.|\n-------\n|.|.|.|\n-------\n|.|.|.|\n-------\n")
      game.start
    end

use stub to simulate input loop_spec.rb

    describe "#loop" do
  let(:input){double("input")}
  let(:output){double("output").as_null_object}
  let(:game){TicTacToe.new(output,nil,nil,nil,input)}

  context "player select one cell " do
   it "player  X select cell 0,0" do
    input.stub(:gets).and_return("0 0")
    output.should_receive(:puts).with("\n-------\n|X|.|.|\n-------\n|.|.|.|\n-------\n|.|.|.|\n-------\n")
    game.loop  
  end

capture

   game = Game.create
    game.start
  • class Code code.rb compare a code with a guess and return feedback

  • class Playerplayer.rb

class Human < Player
class Computer < Player
interface
guess : void -> string
match : string -> void
  • helper.rb

    class Array
    substract [1,2].substract [1,2] = [0,0]
    index_zeros [0,2,0,4].index_zeros = [0,2]
    count_zeros [0,2,0,4].count_zeros = 2
    number_match [2,1,4].number_match [1,2,5,6] = [1,2]
    any_match? [1,2,3]any_match? [5,6,7] = true
    class Hash
    invert { 1: 2 , 2: 3 , 4: 3}.invert = { 2: [1], 3: [2,4]}
    class String
    to_array "12345".to_array = [1,2,3,4,5]

    comparaison guess and secret

    example :

    • secret = [1,2,3,4]
      guess = [5,2,4,3]

    • secret substract guess = [-4,0,-1,1]

    • index_zeros [1] : index of the digit at the right position
      [0,1,2,3] - [1] = [0,2,3]= valid index index of the digit not at the right position

    • hash_guess = { 0 => 5 , 2 => 4 , 3 => 3 }.invert = { 5=> 0 , 4 => 2 , 3=> 3}
      hash_secret = { 0 => 1 , 2 => 3 , 3 => 4 }.invert = { 1 => 0 , 3 => 2 , 4 => 3}

    • hash_guess.keys & hash_secret.keys = [3,4] digit present in guess and secret not at the right position

    • index_present = [2,3] index in guess of the digit not at the right position

    • feedback="...." feedback[1] = "+" feedback[2]="-" feedback[3]="-"

    feedback = ".+--"

    todo [] refactor