portatlas/tictactoe-ruby

★ 0Forks 0RubyGitHub ↗Compare

README

Tic Tac Toe

##Specifications

  • allow for a human player
  • play against a computer player
  • have some user interface: console and web (sinatra)
  • never lose and win whenever possible

##How to run

  1. clone the repo to your local machine
  2. navigate to the directory and run bundle install
  3. run ruby bin/play_ttt on the command line to start playing

##Process Iteration 1)

  1. I started researching about algorithms that would allow me to use play tic tac toe with a computer, this is when I came across the minimax algorithms
  2. I played around with the minimax algorithm to get some understanding of how it works
  3. I started building a simple tic tac toe application with two people, this allowed me to break down the application into methods with single responsibility
  4. Now that I have some understanding of the components of the application, I used TDD to build this application based on the functionality that was required
    • a) Tic Tac Toe Board & Displaying it to the Screen
    • b) Functionality to move pieces on the board
    • c) Functionality to determine the status of if there is a win or a draw?
    • d) Created the minimax methods. There were many different ways of implementation but I used this repo as a reference.
    • e) Tying it all together and playing a game

Iteration 2)

  1. I began to refactor the code to remove the dependency the Game has on TicTacToe, instead of creating an instance of TicTacToe inside the Game Class. I created the TicTacToe instance outside and injected the dependency to the Game class as a parameter.
  2. I started to add more test to the Game Class so that any additional refactoring to the Game Class can be easily tested that behaviors do not change. The Game class was not developed with TDD, and I could see how the code became more procedural and problematic. If I had more time, I would have developed it with TDD. The lesson learned is that by not using TDD, I ended up going in circles creating code that works but not elegantly, writing test, refactoring, and end up having to rewrite test again. It turns out I would have been in a better position using TDD.
  3. I removed the logic where the code is decoupled with standard input (stdin) and standard output (stdout). I created a class to to encapsulate the User Inteface and a seperate class specifically for the stdin and stdout called Console. The Ui takes a paramter of IO in this specific case it takes the Console to handle input and output. After making this refactor, I realized my Game class is more concise and describe what it should do.

Iteration 3)

  1. I refactored the TicTacToe Class into the TictactoeBoard and TictactoeRules as they could be viewed as seperate components. One of the benefits of this change, is that the state of the board is constantly changing where as the rules should never change. For the web app, I was storing the board in my sessions, if I did not refactor and stored the entire TicTacToe Class then I would be storing more data than what's needed.
  2. I refactored the Game Class into a WebGameEngine and ConsoleGameEngine (inheriting from the GameEngine super class) in order to handle different interfaces. As my original Game class was not compatible with the HTTP request, refactoring was necessary.
  3. For the web based game I decided to use Sinatra as my web framework because it is light weight and fairly easy to implement. One of my issues was getting the session to store data even when new requests are made. After troubleshooting, I came across a stackoverflow article mentioning "set :session_secret, "My session secret"" is required if I am using shotgun. I am not entirely sure why this fixed it the issue but I would like to research this further.

##Things I Learned from this assignment

  1. I learned about the concept of minimax algorithm and how to apply it to a game like tic tac toe
  2. I learned about the send method and how to use it to dynamically pass in different parameters based on a given situation
  3. TDD saves time and heartache
  4. When refactoring consider how the code will interact with other components of the code. Does the current Class have more than one reason for change? Will state change? Does it serve a single purpose?

##What I can do to improve the application

  1. Create a more user interactive interface
  2. Implement a database to store user games and results

Contributors

portatlas

Issues