Tic Tac Toe v1 Flashcards

1
Q

class : BOARD

Board#initialize

A Board instance must have an instance variable to represent the game grid. For now, Board#initialize does not need to accept any arguments. Initialize the grid so that all positions are empty; this means that every position should contain an underscore (‘_’).

A

class Board

attr_accessor :grid
    def initialize
        @grid = Array.new(3) { Array.new(3) {"_"} }
    end

end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

class : BOARD

How do you create methods to check if a position (or coordinates) are 1) valid and 2) empty?

A
  1. FIRST create bracket only and brackets equal methods to make it easier.
  2. To check if the position is valid, iterate through the grid with nested iterations to get all the valid index pairs into an indices array. Then see if that indices array includes the position given.
  3. To check if empty, use the bracket only method (self[position]) to see if equals to the “_” indicating a mark has not already been placed.

def valid?(position) #returns true or false
valid_indices = []
(0…@grid.length).each do |i1|
(0…@grid[0].length).each do |i2|
valid_indices &laquo_space;[i1, i2]
end
end
valid_indices.include?(position)
end

    def [](position)
        row = position[0]
        column = position[1]
        @grid[row][column]
    end
    def []=(position, value)
        row = position[0]
        column = position[1]
        @grid[row][column] = value
    end
def empty?(position)
    self[position] == "_"
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

class : BOARD

Create method #place_mark that takes in a position and mark. This method should assign the given mark to the specified position of the grid. It should raise an error when the position is not #valid? or not #empty?.

A
  1. Using the bracket equal method here to reassign the value to the provided mark given that it’s both valid and empty.

def place_mark(position, mark)
if self.valid?(position) && self.empty?(position)
self[position] = mark
else
raise “Your input is not valid. Try again”
end
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

class : BOARD

Create a method that prints out each row on a separate line.

A
def print
        @grid.each do |row|
            puts row.join(" ")
        end
    end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

class : BOARD

create two methods - 1) check if any of the rows have the same marks and 2) check if any of the columns have the same marks.

A
  1. Nested enumerables and like count, my inner enumerable .all? doesnt need a full block code and can just take the one parameter in parenthesis
  def win_row?(mark)
        @grid.any? { |row| row.all?(mark) }
    end
    def win_col?(mark)
       @grid.transpose.any? { |row| row.all?(mark) }
    end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

class : BOARD

Create a method that checks if the provided mark wins diagonally in either direction.

A

CHECK WHICH ARRAY YOURE SHOVELING INTO

def win_diagonal?(mark)

    forward = []
    (0...@grid.length).each do |i|
        forward << self.grid[i][i]
    end
        backwards = []
        reverse = @grid.reverse
        (0...reverse.length).each do |i|
            backwards << reverse[i][i]
        end
    forward.all?(mark) || backwards.all?(mark)

end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

class : BOARD

Create a method that checks to see if there’s w in either via rows, columns, or diagonally

A

def win?(mark)
win_row?(mark) || win_col?(mark) || win_diagonal?(mark)
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

class : BOARD

Create a method to check if there are any empty positions USING THE .EMPTY method already created.

A
  1. Find all the valid positions and iterate through them.
  2. The valid positions index will be a 2d array and iterating through them will give you a specific position. Use each position as an argument for the #empty? method. and check with #any? if any are true.

def empty?(position)
self[position] == “_”
end

def empty_positions?
   valid_indices = []
    (0...@grid.length).each do |i1|
        (0...@grid[0].length).each do |i2|
            valid_indices << [i1, i2]
        end
    end
    valid_indices.any? { |pair| self.empty?(pair) }
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

class : HumanPlayer

Create a method to get a position from the Human Player instance.

A
  1. Print a statement to ask for coordinates
  2. Get the user response with gets.chomp
  3. Convert the user’s response from strings to integer and shovel into an array.
  4. Raise an error if the array is not a length of 2 exactly
  5. MAKE SURE YOU RETURN THE POSITION

def get_position
p “Enter coordinates with two numbers separated by a single space.”
response = gets.chomp
position = []
response.each_char do |e|
position &laquo_space;e.to_i if e != “ “
end

    if position.length != 2 
        raise "Not valid position. Try again"
    end

    position 
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

class : GAME

How do you initialize the board for just two players?

A
  1. Don’t forget to create attr_reader and attr_accessor for the attributes
  2. There are 5 attributes to create - 1) player 1, 2) player 2, 3) player 3, and 4) board
  3. Each of the two players, the attributes will be initialized as INSTANCES of the HumanPlayer class.
  4. the Current Player will by default be @player_1
  5. the board attribute will be initialized to an INSTANCE of board class.

class Game

attr_reader :player_1, :player_2
attr_accessor :current_player, :board

def initialize(player_1_mark, player_2_mark)
    @player_1 = HumanPlayer.new(player_1_mark)
    @player_2 = HumanPlayer.new(player_2_mark)
    @current_player = @player_1
    @board = Board.new
end

end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

class : GAME

How do you create a method to switch turns?

A
  1. if the current player is player_1 then switch to player_2 or vice versa
  2. USE @ SYMBOLS
def switch_turn
        if @current_player == @player_1
            @current_player = @player_2
        else
            @current_player = @player_1
        end
    end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

class : GAME

Create a method to play the game using the following criteria:

while there exists empty positions on the board
print the board
get a position from the current player
place their mark at that position of the board
check if that user has won
if they win, print out a ‘victory’ message saying who won and return to end the game
otherwise they did not win, so switch turns
if we finish the while loop without returning, that means there are no more empty positions on the board and noone has won, so print a ‘draw’ message

A
  1. DONT FORGET THE @ SYMBOL.
  2. Creating a while loop using the #empty_positions method creating under the Board class.
  3. print the board using the #print method under Board class
  4. get the position by invoking the #get_position method under the Human_Player class and then assigning it to a position variable to then use elsewhere
  5. Invoke on the #place_mark method under Board class which requires a position and mark passed through as argument. This will use the position that we just got from the user and THE CURRENT PLAYERS MARK cause the current player is the DYNAMIC variable that changes from player 1 or 2 with the #switch_turn method
  6. then need to check if there’s win by invoking on the #win? method under Board class which checks to see if there’s a win in either row, column or both diagonals. But the #win? method requires a mark to be passed through as an argument so will use CURRENT PLAYERS’s mark
  7. create an if/else statement that if there’s a win to print out a victory message and then RETURN to “break” it if there is no win than to switch turns using SELF since it’s a game method and we’re in the game class.
  8. If we break out of the #empty_positions? loop without a win then the game is over with a draw. print message accordingly but OUTSIDE of the while loop.

def play
while board.empty_positions?
@board.print
position = @current_player.get_position
board.place_mark(position, current_player.mark)
if board.win?(current_player.mark)
p “Game over. #{current_player.mark} won!”
return
else
self.switch_turn
end
end

    p "Game over. It's a draw. Play again."
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is a shortcut of finding all the index pairs in a 2d array that’s square sized?

A

indices = (0…length).to_a
indices.product(indices)

COMBINATION provides unique combinations but will return an enumerator and needs to converted to an array while PRODUCT provides all possible combinations and returns an array already. For example…

a = [1, 2, 3, 4]

input : a.combination(a).to_a
output : [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

input : a.product(a)
output : [[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4], [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4]]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What’s an important thing about bracket methods when using “self”

A

WHEN CALLING OUTSIDE OF THE INITIAL METHOD DEFINITION, NEED TO USE SELF

SELF [ POSITION ]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly