Homework for 4B

Review

Topics Covered: Tic-tac-toe


Exercises

E1: Tic-Tac-Toe

This exercise is actually more of a mini-project: we're going to work through building a simple tic-tac-toe application from scratch. Pick a partner who you haven't worked with before, create tictactoe.rb in d4 and let's get started.

Step 1: TIC! (Planning)

As usual, we're going to plan out our approach before we start coding away. Read the following carefully—your program must do the following:

The player input will be an integer from 0-8 and the squares will be numbered top-left to bottom-right (0 is the top-left square, 2 is the top-right square, 4 is the middle square, and 8 is the bottom-right square).

In tictactoe.rb, answer the following questions:

# tictactoe.rb

# How will you keep track of whose turn it is?
# What data structure will you use to keep track of the board? You only
#   know two (Array, Hash), but remember they can be nested (meaning an
#   array can contain another array—it can even contain a hash that contains
#   another hash, though unclear if that will be useful :P)
# When a player makes a move, what should happen? 
# How do you keep track of which squares have Xs and which have Os?
# How do you detect a winner?
# When does the program stop? Is there a loop? If so, what kind?

Step 2: TAC! (Pseudo-code)

Pseudo-code is an informal, high-level description of your program's operation. Pseudo-code is written in english and outlines your program's behavior using step by step instructions. An example for tic-tac-toe:

# Every turn:
#   Update whose turn it is
#   Get user input
#   Update board
#   Check for winner

Of course, that's pretty easy to write. However, it may be less obvious how you would translate pseudo-code into good ol' Ruby. What exactly is a turn? How does one update the board? These are questions you've started thinking about in Step 1. For Step 2, expand your thinking, and the above pseudo-code, to make a more detailed outline. That is, your writing may contain words like "Array" and "Hash", but probably doesn't contain any "[" or "{" glyphs. As you write, consider these questions, and be ready to answer them:

It may be starting to become clear that coding is much more about thinking than anything else. While there isn't necessarily a best solution, there are solutions that are much more intuitive and easier to understand than others. Remember that code is meant to be read by humans, and when two pieces of code do the same thing with the same efficiency, the one that's simpler is always better.

Check in with a TA before continuing!

Step 3: TOE! (Code)

Now that you have your pseudo-code, it should be a simple matter to turn it into real code. Take a crack at it, and see if it works!

$ ruby tictactoe.rb 
Player 1:
0
Player 2:
1
Player 1:
kittens
Error: Invalid input
Player 1:
10
Error: Invalid input
Player 1:
3
Player 2:
2
Player 1:
2
Error: Square already taken
Player 1:
6
Congrats, player 1 won!

If you've gotten this far, you actually know quite a bit about coding, and the coding process. This was actually a Google coding interview problem (though keep that fact hush hush!). When you interview at companies—or try to code anything, really—this workflow is a good one to keep in mind: first talk through your solution and think about what data structures you'll use. Then write pseudo-code and try to foresee as many problems as you can. Only when you're confident in your thinking should you start coding.

Step 4: TIC-TAC-TOE! (User Experience)

To be honest, while your program is pretty awesome, it's not very user friendly. Since humans aren't very good at remembering what the board looks like, add a method to print out the board after each step. We've picked a design below, but feel free to make it look like however you want.

$ ruby tictactoe.rb
Player 1:
4
     |   |   
  ———+———+———
     | X |   
  ———+———+———
     |   |   
Player 2:
0
   O |   |   
  ———+———+———
     | X |   
  ———+———+———
     |   |   
Player 1:
2
   O |   | X 
  ———+———+———
     | X |   
  ———+———+———
     |   |   
Player 2:
6
   O |   | X 
  ———+———+———
     | X |   
  ———+———+———
   O |   |   
Player 1:
3
   O |   | X 
  ———+———+———
   X | X |   
  ———+———+———
   O |   |   
Player 2:
5
   O |   | X 
  ———+———+———
   X | X | O 
  ———+———+———
   O |   |   
Player 1:
1
   O | X | X 
  ———+———+———
   X | X | O 
  ———+———+———
   O |   |   
Player 2:
7
   O | X | X 
  ———+———+———
   X | X | O 
  ———+———+———
   O | O |   
Player 1:
8
   O | X | X 
  ———+———+———
   X | X | O 
  ———+———+———
   O | O | X 
Cats game!

E2: Bigger. Better. Quadrupled.

Now that you've mastered the basics of tic-tac-toe, it's time to move on to bigger and better things. Choose one of the following extension projects:

E6 (Bonus!): Computer Tic-Tac-Toe

While playing against a person is fun, us loners need something to do. Write a program that plays tic tac toe against you. Your implementation should give your opponenent artificial intelligence (AI)! While this may seem too difficult, it's not too hard if you split it into steps! Try giving the computer these abilities in order:

  1. Simply choose a random square to play in
  2. Play in a winning square if there is one
  3. Block the human from winning if they have a winning move
  4. Make the computer impossible to defeat!
  5. Allow the computer to take advantage of poor human play to win!

The first three items are quite manageable, and are a great start to making your opponent smart! The last two items will require some time studying Tic-Tac-Toe strategy, but are a fun way to practice the translation of human strategy to computer code!

$ ruby computer_tictactoe.rb
Would you like to be Player 1 or Player 2?
1
Player 1:
4
Computer: 0
   O |   |   
  ———+———+———
     | X |   
  ———+———+———
     |   |   
Player 1:
2
Computer: 6
6
   O |   | X 
  ———+———+———
     | X |   
  ———+———+———
   O |   |   
Player 1
5
Computer: 8
3
   O |   | X 
  ———+———+———
   O | X | X 
  ———+———+———
   O |   |   
The computer wins!

As you can see, it's pretty tough to get a computer to even be smart about something as simple as tic-tac-toe—the human brain is really amazing. Now consider how much code and intelligence is required to make a program that plays chess, or gives directions to some place depending on traffic and road closings... it's actually quite humbling.


Projects

Ruby: Fueling Consumerism

Onward the plot to bring consumerism to Cape Town. We have the Goods and the Vehicle, all we need is the Villan.

Create a Shopper class. It should:

More power, Less responsibility

Now create a SuperShopper class. It should:

As with before, download the test script from here. Save it into your shopping_cart directory, run it, and make all the tests pass!