Quick Update

I just finished up the Git section of the Flatiron curriculum and I’m moving into HTML and CSS. Hoping to get through it fairly quickly since I’ve worked on this before in several tutorials and such. You never know, however, if there is something new or interesting in store. After this its back into some Ruby!

I’m also going to start preparing for my talk on Bmore on Rails here soon. More details forthcoming!

Completing Object Oriented Tic Tac Toe!

It is always satisfying when you get to the end of something. There is a sense of satisfaction and maybe even a bit of apprehension. That is what I can say as I came to the end of the Introduction to Ruby at Flatron School. I can say two things with certainty:

  1. I never thought I would be challenged this much with Tic Tac Toe.
  2. I still don’t feel 100% confident with Ruby. 🙁

I mean, I feel much better with it than I did coming in. I had done some study with it at Treehouse, and the Learn Ruby the Hard Way book from Zed Shaw. Flatiron challenged me. I nearly broke me at times, as anyone following this journey can attest to.

And that was the intro.

In any case, part one is over. As such, this post is going to delve into reviewing the last part of the intro to Ruby: Object-oriented Tic Tac Toe.

To begin, its probably imperative to explain the difference between procedural Ruby and Object-oriented Ruby. I understood it like this.

In the procedural approach, we wrote a series of methods and had the data laying there at the beginning by itself. We then, in a step by step approach, acted on the data. It was not organized into anything, and could be haphazard in how it is handled. We have to know what is happening to the data as we go down the list of procedures. In the procedural version of tic tac toe, we acted on the board array. If we have a procedure that affects it in a way we don’t account for, the next step could break or cause us any number of issues.

In the object oriented approach, the object we create acts on its on data. Inside the object, the data and methods are all bundled together. To see the end result of the procedural tic tac toe, check here. Now, let’s look at the object oriented approach!

First, I’ll lay out my code:

This is the bin file:

And here is the Ruby file:

So, to understand what is happening, we need to start with what a class is. Flatiron decribed it as a blueprint used to build an object. So, we are creating a blueprint here of what a Tic Tac Toe game is. This entire object is the Tic Tac Toe game. When, in the bin file this is called:

It is creating an instance of the Tic Tac Toe game that loads everything needed to play the game until a victor is crowned or it ends in a draw.

I won’t go over everything inside this as it will probably look familiar. There is a big difference, however, in that the board array is created here:

and then passed around inside the object. I will admit to being confused on the argument being passed in here. Flatiron presented this as:

But when I went and built it I just created the board as the Array with 9 empty strings. I did not, and still don’t, understand why the “or” statement is needed here. What is confusing is the need for the argument being (board = nil). I tried doing it with only board passed in and it broke the whole thing…

And this is the error I was given:

I mean, I passed in board still. Why does it need to be nil? In any case, being nil works for it, and who am I to argue…

Now, some things to note. @board is an instance variable. This allows it to be passed around from method to method inside this object. We are creating it inside a special method in Ruby called #initialize which allows us to create certain attributes inside our instance. Every game of Tic Tac Toe needs a board. the board is used throughout this object, so it is best to create it here. Notice though that once we create it here, we don’t need to use it as an argument throughout the rest of the object. Let’s compare the #display_board methods from procedural and object oriented approaches:

Procedural:

Object Oriented:

Notice in procedural that board needs passed in as an argument. You create the argument and then pass it in. In the object oriented approach, we create it in the #initialize method, and now it just needs called. Notice where it is called throughout. We do still have arguments in the other methods, but where board would have needed called, I used the instance variable.

There are two other methods that I should take a minute to look at as they were interesting. Again, the comparison helps here:

Procedural

Object Oriented:

These were tricky and it was because I forgot that in the procedural approach that when i used a helper method I have to pass in its arguments also. In the object oriented approach, the @board instance variable is again already there. The object is handling that data, so you just need to call the method and let Ruby handle the rest!

Otherwise, this lab was pretty straightforward. Wherever the local variable board was in the procedural approach, I replaced it with the @board instance variable, removed it from the arguments and then it worked. Honestly, I was expecting a few days of hell, so I’ll take it.

Finished with Intro to Ruby at Flatiron

This will be a quick update, but I want to come back tomorrow and do a good posts on Objects and how I went from the procedural code that ran the Tic Tac Toe game to an object oriented approach. It’s late, though, so tomorrow will be it. Still, very happy to be done with the first section. I’m on to Git and Version Control currently.

Completing the Hardest Section so Far at Flatiron School

I’m going to be honest. This last section was brutal. I had to reach out to help often, and I can’t say with certainty that I really understand everything as well I want to. It’s sort of like knowing what a hammer and screwdriver do, but I can’t build you a house with them…

I have discovered a few things about myself so far. Mainly, I tend to overly complicate my code. In the code I’m about to review, my last, most critical, piece of code was completely hampered by code that passed the initial tests in an earlier lesson but that was just overly complex or built on a flimsy foundation. The biggest culprit was the over method. I had to go out on Google and research it and found a much better solution that I admit I copied over. I took the time to marvel at its elegance which really made me question my own skills… I mean, look at the difference (I did need to fix the code up to work here, but I tend to take Ruby, a language that is heralded as simple and beautiful and make it byzantine…)

My first over? method:

and the new and improved method:

I mean, I don’t know how I never realized full was not needed originally… Oh well…

In any case, let’s take a look at what we have here…

First, we start with the bin file, which is what runs the game from the command line.

This is basically welcoming the player to the game, displaying the initial, empty board and then calling the play method to start the game. Next, we have the tic_tac_toe.rb file which has all of the methods handy. I’m going to show the whole thing first, the talk about each method briefly, explaining what I did in each, or why something works the way it does.

This is the nested array of winning combinations. I discussed this in an earlier post here.

This next bit I also discussed in a previous post here, but I have made some changes to the code, tweaking here and there to fix up stuff.

My biggest changes are using string interpolation to tighten up the display_board method, and in these two:

Completely tightening up the code. Let’s take a closer look.

In the position_taken? method, I went from this:

to what I have above. I actually came across the above code from a lesson where Flatiron School included it in a lab. I was blown away, but took the time to understand why they did what they did here.

My original code, and let’s be honest and say a lot of my code, relied on if else statements. I seem to use them everywhere. Once I had this pointed out, I started attempting to fix this. It has been long and arduous. I probably have more to fix. I am slowly learning, however, that everything in Ruby is truthy, except false and nil. This is a hard thing to keep in mind. In fact, I may have this wrong, but will continue looking into it.

Anyways, just look at how complex my original code is! If the board position is an empty space (defined two different ways) or nil, return false. If it has “X” or “O”, return true. But there is a lot there.

The better code

uses the exclamation point in front of two statements in parentheses which negates them. It basically says the position is taken if the two items inside the parentheses are not true, either the position is nil or an empty space. So simple!

For the valid_move? method, I simply removed the if statement as it was not needed.

In the move method above, I removed the default character as we will now be using X and O, I added the turn_count method as that will need to be incremented each time a move is taken, and I added the display_board method as whenever a move is made the user should see where the character was placed.

In the turn method, I changed the char argument to current_player(board) as this is where the X or O gets assigned from. I honestly feel like I could clean this up a little more… Maybe later on… Let’s look at the methods these are relying on.

So, as I said above, turn_count is basically starting a count at 0, and each time a move is made it increases count by 1.

The current_player method assumes the first move is X, thus if the turn_count is odd then it is O’s turn, otherwise if its even it is X’s turn.

I wrote about the above method extensively and recommend going and taking a look at it here.

These next methods look at the status of the game:

The first method is full? and what it does is use the enumerable of none? to ask whether there are empty or nil positions left on the board. Once there are none of these, the board is full.

Next, the draw? method sees whether the game is ended in a draw. If the won? method from above has returned nil, and the board is full, it returns true prompting the draw.

Next, is the over? method which gave me so much trouble. It essentially checks whether the game is either at a draw or a winner has been chosen and if so the game is over. So simple, yet it gave me MANY headaches. I overthought it…

Finally, the winner method decides who the winner is. I had this one also very complicated, and was able to simplify it once I got a handle on the != (not equal) and the idea of keeping it simple. Here was my original:

I mean, in retrospect, it makes sense. You look at what happened with the won? method. If the game was nil, you return nil. Otherwise, if one of the winning combination returns “X” that means all are “X” and that is the winner. If one of them is “O”, then “O” wins.

This does the same thing, but once I realized it really doesn’t matter in this method that I extrapolate the “X” or “O” I was able to beat it int submission. I just needed to grab the “X” or “O”…

The problem I think I am experiencing is that I need to keep each helper method exactly to their function and nothing else. That is hard to keep in mind at times.

Finally, the last method:

This one was a doozy, but since over? was broke it caused me multiple headaches.

So, basically all it does is say until over? returns true, take turns. If a draw? occurs, tell the user its a “Cats game” and if someone wins congratulate them and call the character.

So, this overall was a huge learning experience. It was difficult and took a lot longer than I thought. There was many times I said to myself:

I think the increasing difficulty was at times a huge jump, but it also got me out of my comfort spot and seeking help which led to some interesting discussions concerning Ruby. That was the most helpful in getting me where I am right now.

Quick Update

So, I’m still on the Tic Tac Toe Game Status lab, but making progress. I will update more once I finish it up, but as its late I’m calling it a night.

I will say so far this lab has been the hardest one I’ve dealt with. Almost there, though!

The Answer at Last: Nested Arrays and Enumerables

First and foremost, I want to acknowledge the help of several people at the Flatiron School community program for walking me through this one. Thanks again to @thomasshines, @lord_of_yoghurt and @theredshirtman for the help and encouragement. It was a painful experience but extremely rewarding.

Overall, I learned much about enumeration, the find method, and nested arrays. So, let’s get to it. Also, spoiler alerts as you really should give it the old college try. I went two days and got extremely close before realizing it was time to reach out. During that time I learned more about how other enumerators worked. This method of learning is painful but rewarding.

My first mistake was in forgetting how to access the nested array.

Let’s look back at where I ended day 2.

Each will iterate over each of the arrays in the WIN_COMBINATIONS constant. Let’s look at that again.

So, what was first pointed out is that I need to think of what is being iterated through. Therefore my ending method from Day 2 should first be changed to this:

A small, but significant change as it tells me what I’m looking at. When win_combo is called it is the first of the nested arrays. And

that win_combo[0] will pull the first index spot of each of the nested arrays.

So, this is a part I really got stuck on. Looking back, the each method will iterate through the top level of the array, which is WIN_COMBINATIONS. When we add the [0] part that is accessing the next level down. To solve this we must be able to access the individual indexes INSIDE the nested arrays.

Next, I had settled on select as the method that would work. select however would not work as it will go through the entire array and return everything that returns true as an array. The method that will work best is find. find (or detect for those who want to use that. They are the same.) will go through and stop iterating once it has satisfied the conditions given. So, here is where we are so far:

Now, at this point we have enough knowledge to solve the first part. We know that this:

will iterate through each of the nested arrays and return back the first index of each. Therefore, win_combo[1] and win_combo[2] will grab the last few indexes.

What we need to satisfy in this method is that three indexes in the WIN_COMBINATIONS nested arrays return all three and that they match, giving us three in a row. Right now, it does not matter if X or O wins, only that they match. To do this we need to use some boolean logic.

So, if win_combo[0] is equal to win_combo[1] and if win_combo[0] is also equal to win_combo[2], that means all three match. So, let’s put this logic into our method, remembering that we are also passing in a board that the users are going to update as the play. That board is an array. Here’s an example:

board = [“X”, “X”, “X”, ” “, ” “, ” “, ” “, ” “, ” “]

and in this example, there are 3 X’s in the top row to win. And here is the updated board:

Let’s read through the code here.

The find method comes to the first array in the WIN_COMBINATIONS constant which is [0, 1, 2]. At this point we are inside the block. We get to the first part of the  logic within:

And if we look at the board array above we see it will return “X”.

And it then asks if it is equal to the next part,

This will also return “X”. So far, so good! At this point we come to the && statement. This tells us that for this to come back true we will need both sides of the equation to come back true. So far, the left hand side is true. Will the right hand side be? Next part:

OK, we already see this before and it was “X”. We use this as sort of an anchor. If the first side has returned true, we could use either index to compare the last index. So, last one:

And this one is also “X”. This means we have a true result and find will stop iterating. It will return the [0, 1, 2] array.

Let’s see if it works for the middle row, which would be [3, 4, 5]…

Here’s the board:

So, let’s read through it our code again, starting from the top.

Will return ” “. OK,

Will return ” “. OK, and…

Will return ” “. AND IT STOPS ITERATING AND RETURNS [0, 1, 2]. OK, not the time to panic. This actually makes logical sense as ” ” == ” ” and ” ” == ” “. We need a way to tell Ruby to not accept empty spaces as part of our logic. Thankfully, we built this method before!

Just a quick explanation. The method here says if the board[index] is nil or empty that it is not taken. We want our method to only consider taken spots. So, I originally wanted to slam this on the end of every one of the board[win_combo[*]] pieces. That was the wrong impulse. Instead, what we want to do is add it to our logic. We are asking Ruby to ask if it is true that the positions are taken. So, let’s add it and see what happens.

OK, let’s read through it quickly. We already now that the first array, [0, 1, 2] had all returned ” ” and ruby originally found that true. Now, it will fail the last condition as the ” ” is false for position_taken?. Awesome!

So, we now begin iterating through [3, 4, 5]. Remember we start back at the 0 column in the index:

This returns “X”

This returns “X”

And this returns “X”! And it stops! [3, 4, 5] is the returned array as it matches the won? conditions. And that is it.

If you have questions, please ask them in comments. I hope this helps everyone struggling to understand this. I can take very little credit for solving it on my own, though I tried like hell, but I hope my write up helps answer the questions I had and that you may have.

 

Blogging Through a Problem at Flatiron School

So, I’m stuck since last night on a problem in the Flatiron School Community Based Program. I figured that it would be a good idea to use this blog as my rubber duck and work though this step by step. So, here’s a rubber duck for me to explain it to. For those thinking I’ve lost my mind, go here.

That’s right, Bat Duck is here to help me solve the problem!

So, let me lay out what I’m trying to do by rephrasing the issue. No copying and pasting!

The first method I need to build is one called won? that will take in all the possible ways of winning tic tac toe.

So, you can win by getting three in a row on each row as well as each column, as well as 3 in the diagonals from upper left to bottom right and from upper right to bottom left. That is 8 different ways to win.

Now, we have been using an array for this so each space in the tic tac board is numbered 0 to 8, with 0 at the top left hand corner down to 8 in the lower right hand corner. The first task is for me to make a nested array of all the combinations to win, utilizing the indexes of each space, and place them inside a constant. A constant is a variable type in Ruby that begins with a capital letter and is used for data that is unlikely to change. Since the ways to win are set in stone, this will be a constant. This is simple enough. Take a look:

This next part is where I got confused. So, the method should accept a board as an argument. So, something like this but updated with moves (X or O wherever the user moved):

And return false/ nil if there is no win combination present in the board, and if there is a winning combination of indexes, return that as an array. It was clear, however, that this method should not decide WHO won, ie whether X or O had the winning combination. This is a helper method to be used in another method in a bit.

OK, so let’s look back over the ways this whole lesson discussed enumerating through these arrays.

First is the Boolean Enumerables. Let’s start with all?.

all? will take an array of data and then decide if all the data meets the requirements. The example given in the lesson was passing in an array like [1,3,5] and asking Ruby if they were odd. Since ALL of the numbers were evaluated as true then it returned true.

The next Boolean Enumerable is none?. It is the opposite of all? in that it asks the opposite of all. So, if asked if [1,3,5] are even, it will say none are and return true.

Next up is any?. Any will go through an array like [1,2,3,5,7,9] and ask are ANY of these even. Since 2 is even it will say true, one of this list is even.

Next is include? which asks does this array of numbers, [34,56,78,98,345,43, 65] include a specific number, 72. The method will go through and if it finds the number it returns true. If not, its false.

So, would any of these work. I’m not so sure yet. I’m taking an array and asking it the same player token is in the 3 spots for each of each array in the WIN_COMBINATIONS constant. I can see where a few of these may work, but none honestly scream at me as the winner. Let’s look at the other enumerables…

These are search enumerables. Honestly, that alone makes me feel a little more comfortable as searching through the board to see if any are winning combinations is sort of what I need to do.

The first is select. Now, this looks promising. First, it will return a new array with the results that passed true. OK, that sounds promising. So, for example, if I have an array like this: [1,2,3,4,5,6,7,8] and tell it to select the even numbers it will return this: [2,4,6,8]. So, if I tell it to select the matching arrays that have X’s at 3 indexes, will it return those? OK, I want to try this.

To the IDE!

OK, as of 11:30PM I am still stuck… I will keep up this tomorrow for those wondering.

To sum up what I have discovered, including help from someone on a Slack channel related to Flatiron’s Learn platform,

I have this:

and the i inside the pipes is the single array inside the larger WIN_COMBINATIONS constant. I need to compare the values of board to the positions inside of i. I’m still trying to make this work, but I probably need sleep at this point to approach it with fresh eyes…

A Look at Ruby Methods, Loops, and Logic

As my last post noted, I am currently enrolled at Flatiron School’s Online Community-Powered Bootcamp. It has been a great experience thus far. This blog has always been a place for me to note my studies and thoughts about what I’m learning. I have discovered over the time I’ve been here that others also have come by to enhance their learning, and for that I’m grateful and happy.

As such, I will be blogging here again regularly. My last post prior to this resurgence was in 2015. I was not inactive, per se, but I slowly became more active as 2016 went on. I was embroiled in the election, and once it began wrapping up I started studying again. I went through the Web Dev Bootcamp’s Javascript section and built a few of the #Javascript30 projects but I missed Ruby on Rails. I looked at a few options before settling on the Flatiron program. While the price is a big commitment, but I am committed to make this change.

I will be mostly using this as a way to look at the code I’m writing as I complete projects for this bootcamp and explaining what I’m doing. One of the things I like is that I’m not just being told “type this” and blindly mimicking code. I actually have to sit down and write the code. So, this is all code I’ve written.

So, this first section is an intro to Ruby. I’ve learned about variables, methods, logic and conditions, boolean, and loops. I also learned, for the first time, about command line applications. So, I’m going to post the code I have written up to a lesson that looks at taking a turn in the tic tac toe app we are building and break it down. First, I’ll post the bin file, turn,

and now, the Ruby turn.rb file.

So, first and foremost, a command line application, called a CLI for command line interface, is a file that the user launches to run the application from the command line. No graphics here. This is called the bin file, and is stored in the bin directory in our application. This is the executable file we run our program from. Let’s go through this file line by line. I’ll post it again:

Ok, the first line is known as the shebang line:

This tells the interpreter to use Ruby as the language for the file.

Next, we tell the bin file to require the turn.rb file with this line:

This gives us access to methods we define in that file. This will be important in just a minute.

Now, we are going to create an array called board and set it up with some strings with a space in them:

And then greet the user and call two methods from the turn.rb file. Both will pass in board as an argument:

OK, now that we are through the bin file, let’s look at the turn.rb file in more depth. This file is located in the lib directory. I’ll put the whole thing here for reference, but then pull out each method individually as we go through it:

Let’s break this down. First, we call a method titled display_board that accepts one argument, the array we defined in the bin file. This method will build the frame of our tic tac toe board.

When we run the app, it will display like this:

Very high res, HD graphics!

Inside each puts call, you will notice these:

This is a string interpolation. Basically, this allows us to put the variable inside of the string. This in particular is pulling the data from the array. As the game is played the users will place their X and O markers in the 9 quadrants of the tic tac toe board. They will be asked to select a space numbered 1 to 9, with 1 being the top left corner and 9 being the bottom right corner. The X’s and O’s will be put inside the array in the necessary spots, and then the display_board method will interpolate the marker as it is updated.

Next, let’s look at the turn method, and as we go through it we will discuss the methods that are called from inside it. First, the method:

So, this again takes the argument of board. It asks the user, as we discussed above, to choose a space from 1 to 9 and then takes the input using the gets method. gets will take the users input, and then, using the strip method will remove any new lines or trailing whitespace. Next, this input is sent to another method defined called input_to_index:

This method will first take the argument input and turn it into an integer with the to_i method then it subtracts 1 from it. This is because the array starts counting at 0, while we are asking the user to start counting the quadrants at 1. so, while the top left square in the array is 0, the user is entering 1. Subtracting 1 fixes this. Let’s return now back to the turn method.

We are now going to define a new variable, m, and have this variable decide whether the move made by the user is a valid move. This is calling another method, valid_move?, which is below, along with it’s helper method, position_taken?:

It will probably be best to start looking at position_taken? first. This takes two arguments, the board array and the index we just created with the input_to_index method. It uses an if statement to decide whether the position the user has chosen is taken already. So, the first part of the method asks “if the spot on the board is empty then return false (the position is NOT taken), then the next part says “else, if there is an X or O already there, return true (the position IS taken). Notice here that we are using the || for the boolean for “or”.

Now, looking at this, we return to the valid_move? method. This method is deciding whether the move the user made is valid. If the user tries to take a position already taken it is not valid, hence we utilize the position_taken? method we just discussed. It also looks at a range to ensure the user is playing on the board and not in a position elsewhere. This utilizes the between? method which passes in to arguments, the start and end of the numeric range which here is 0-8. Notice also that the if statement is using && for an “and” comparison, as well as the ! in front of position_taken? to make it negative, reading instead “position is not taken.” So, this method is literally saying “if the move is between 0-8 and the position is NOT taken, its a valid move, otherwise it is not a valid move.”

So, moving forward in the turn method, the move we asked the user to make is validated through the valid_move? method. If the move is valid, which returns true, then we allow the move to proceed via the move method. Here it is:

This brings in three arguments, the board array, the index and the char argument which is the X or O for each user. Currently, the char is set to X as a default argument. Soon, it will allow the O character. This method takes the index we created from the users input and places the X on the position they chose, updating the board array.

If the move is not valid, a loop is called. Let me place this part below so we can walk through it.

So, first, m enters here as false. The loop states “until m is true, this loop will keep coming around.” The user is told the move was invalid and prompted to enter another move. The input is taken through all of the above methods we discussed again and if the move is valid, the loop ends. If not, we go through until it is valid.

Here is what we are hoping happens:

And here it is with me choosing an invalid position:

This time I showed where I called the bin using ruby bin/turn. I made the move, picking a position WAY off the board, and then the app told me the move was invalid and prompted me again. This time I got it right and the lower left hand corner had an X added to it.

I hope this helps anyone visiting to understand Ruby methods, loops, and logic a bit better. If you have questions, feel free to ask!

 

Joining Flatiron and Next Steps

I just joined the Flatiron Community-Powered program and I’m extremely excited to be here. I started my coding journey back in 2015. Due to numerous hurdles, both professional and personal, I have been off and on the path numerous times. This time I am on the path for the duration. In fact, I’m putting my money on it.

I was extremely excited to find an affordable but well known program to join. Up until now I have used only either free or low cost programs. These include Free Code Camp, Odin School, Udemy courses and even excellent resources like Michael Hartl’s Ruby on Rails tutorial. I have learned a lot about languages, from Ruby to Javascript, but I feel that none were “just right.” I still feel I lack the ability to engage in the art of programming.

I include in this the ability to take a problem and break it down into small chunks and abstractly put together a program. This covers from idea to refactoring and deploying the app.

I have already started putting in place ways to ensure I am working daily. This includes adding the next portions of the course to an excellent habit app, Habitica! Here’s a look:

I’m off to keep working. I am hoping to use this space to discuss what I am learning and to work out the ideas in another way.

Quick Update: No, I am not Dead. Yes, I am still working on the Career Change

Sorry that I haven’t updated this in a long time but unfortunately life has been busy and stressful. So for a quick update, I am currently working on Ruby on rails going through the Odin project. I will go into more detail about this later, but at this time I’m really just kind of refreshing myself on all the stuff I worked on in the past. Also, I purchased a used mid-2010 MacBook Pro that is devoted to my web development endeavor.