-
Notifications
You must be signed in to change notification settings - Fork 30
tic tac toe #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
tic tac toe #16
Changes from all commits
701bdc6
ed0184f
1455439
ce72cb4
9a9f2c8
9409342
a0a4fc1
c3d22a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| require_relative "model" | ||
| require_relative "view" | ||
|
|
||
| class Controller | ||
| def execute | ||
| loop do | ||
| run_menu | ||
| input = gets.chomp.upcase | ||
| print "\n" | ||
| sleep 1 | ||
| case input | ||
| when "S" | ||
| run_game | ||
| when "R" | ||
| display_move_list | ||
| when "Q" | ||
| quit_gracefully | ||
| else | ||
| puts "You aren't very good at this, are you?" | ||
| end | ||
| sleep 1 | ||
| end | ||
| end | ||
|
|
||
| private | ||
| def run_menu | ||
| Menu.new.list_options | ||
| end | ||
|
|
||
| def quit_gracefully | ||
| puts "Quitting gracefully..." | ||
| print "\n" | ||
| sleep 2 | ||
| %x( ^c ) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wat. Are you sending a Ctrl-C into the process to make it quit? I'm not sure if that's awesome or crazy or crazy-awesome. Perhaps a call to
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hahaha, I was proud of that line. Also, did not know about the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did this work for you? I can't make it work.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it did. It spit out a 4-5 line error message, and quite. Hence the 'quitting gracefully'. In any case, now that I know about exit, that's clearly the way to go. |
||
| end | ||
|
|
||
| def display_move_list | ||
| if @game | ||
| puts "\tX\t|\tO\t" | ||
| puts "----------------+-----------------" | ||
| @game.move_list.each_slice(2) do |pair| | ||
| x1 = pair[0].loc[:x] + 1 | ||
| y1 = pair[0].loc[:y] + 1 | ||
| print "\t#{x1}, #{y1}\t|" | ||
| if pair[1] | ||
| x2 = pair[1].loc[:x] + 1 | ||
| y2 = pair[1].loc[:y] + 1 | ||
| print "\t#{x2}, #{y2}" | ||
| end | ||
| print "\n" | ||
| end | ||
| else | ||
| puts "No last game to review." | ||
| end | ||
| end | ||
|
|
||
| def run_game | ||
| @game = Game.new | ||
| @board = Board.new | ||
| @board.draw | ||
| while [email protected]? do | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| new_move | ||
| end | ||
| sleep 1 | ||
| print "It's over. " | ||
| if @game.winner? == "X" || @game.winner? == "O" | ||
| puts "#{@game.winner?}'s win." | ||
| else | ||
| puts "It's a tie. How dull..." | ||
| end | ||
| end | ||
|
|
||
| def new_move | ||
| input = get_input | ||
| while !valid?(input) do | ||
| input = get_input | ||
| end | ||
| move = Move.new(input) | ||
| @game.register(move) | ||
| @board.add_to_pixel_array(move) | ||
| @board.draw | ||
| end | ||
|
|
||
| def get_input | ||
| print "row (1-3): " | ||
| x = gets.chomp.to_i - 1 | ||
| print "column (1-3): " | ||
| y = gets.chomp.to_i - 1 | ||
| {x: x, y: y} | ||
| end | ||
|
|
||
| def valid?(input) | ||
| x = input[:x] | ||
| y = input[:y] | ||
| if x < 0 || x > 2 || y < 0 || y > 2 | ||
| puts "That move is out of bounds" | ||
| false | ||
| elsif [email protected][x][y].nil? | ||
| puts "That square is already full" | ||
| false | ||
| else | ||
| true | ||
| end | ||
| end | ||
|
|
||
| end | ||
|
|
||
| Controller.new.execute | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| class Game | ||
| attr_reader :move_list, :grid | ||
|
|
||
| def initialize | ||
| @move_list = [] | ||
| @grid = [[nil, nil, nil],[nil, nil, nil],[nil, nil, nil]] | ||
| end | ||
|
|
||
| def register(move) | ||
| x = move.loc[:x] | ||
| y = move.loc[:y] | ||
| @grid[x][y] = move.symbol | ||
|
|
||
| @move_list << move | ||
| end | ||
|
|
||
| def winner? | ||
| result = false | ||
| # check rows, columns for winner | ||
| for i in 0..2 | ||
| result ||= (@grid[i][0] == @grid[i][1] && @grid[i][1] == @grid[i][2] && @grid[i][2]) | ||
| result ||= (@grid[0][i] == @grid[1][i] && @grid[1][i] == @grid[2][i] && @grid[2][i]) | ||
| end | ||
| # check diagonals for winner | ||
| result ||= (@grid[0][0] == @grid[1][1] && @grid[1][1] == @grid[2][2] && @grid[2][2]) | ||
| result ||= (@grid[0][2] == @grid[1][1] && @grid[1][1] == @grid[2][0] && @grid[2][0]) | ||
|
|
||
| # check for tie | ||
| # interesting project: better tie-detecting method | ||
| result ||= @move_list.count >= 9 | ||
| end | ||
|
|
||
| end | ||
|
|
||
| class Move | ||
| attr_reader :symbol, :loc | ||
| @@count = 0 | ||
|
|
||
| def initialize(location) | ||
| @@count += 1 | ||
| @id = @@count | ||
| @loc = location | ||
| @symbol = @id.even? ? "O" : "X" | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| class Menu | ||
| def list_options | ||
| puts "" | ||
| puts "(S)tart game" | ||
| puts "(R)eview last game" | ||
| puts "(Q)uit" | ||
| puts "" | ||
| print "Your choice: " | ||
| end | ||
| end | ||
|
|
||
| class Board | ||
|
|
||
| def initialize | ||
| # for good presentation, square width and height should both be even | ||
| @square_width = 6 | ||
| @square_height = 4 | ||
| @pixel_array = [] | ||
| set_pixel_array | ||
| end | ||
|
|
||
| def draw | ||
| @pixel_array.each{ |row| puts row.join } | ||
| end | ||
|
|
||
| def add_to_pixel_array(move) | ||
| x_dim = pixelize(move.loc[:x], @square_height) | ||
| y_dim = pixelize(move.loc[:y], @square_width) | ||
| @pixel_array[x_dim][y_dim] = move.symbol | ||
| end | ||
|
|
||
| private | ||
| def total_length(square_length) | ||
| 3 * square_length - 1 | ||
| end | ||
|
|
||
| def set_pixel_array | ||
| for row in 1..total_length(@square_height) | ||
| row_output = [] | ||
| for col in 1..total_length(@square_width) | ||
| if row % @square_height == 0 && col % @square_width == 0 | ||
| row_output << "+" | ||
| elsif row % @square_height == 0 | ||
| row_output << "-" | ||
| elsif col % @square_width == 0 | ||
| row_output << "|" | ||
| else | ||
| row_output << " " | ||
| end | ||
| end | ||
| @pixel_array << row_output | ||
| end | ||
| end | ||
|
|
||
| def pixelize(value, square_length) | ||
| (value + 0.5) * square_length - 1 | ||
| end | ||
|
|
||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this one second pause before reacting to the input?