class Rubykon::CLI
Constants
- CHAR_LABELS
- EXIT
- GTP_COORDINATE
- MOVE_CONSIDERATIONS_COUNT
- X_LABEL_PADDING
- Y_LABEL_WIDTH
Public Class Methods
new(output = $stdout, input = $stdin)
click to toggle source
# File lib/rubykon/cli.rb, line 11 def initialize(output = $stdout, input = $stdin) @output = output @input = input @state = :init @move_validator = MoveValidator.new @root = nil end
Public Instance Methods
start()
click to toggle source
# File lib/rubykon/cli.rb, line 19 def start @output.puts 'Please enter a board size (common sizes are 9, 13, and 19)' size = get_digit_input @output.puts <<-PLAYOUTS Please enter the number of playouts you'd like rubykon to make! More playouts means rubykon is stronger, but also takes longer. For 9x9 10000 is an acceptable value, for 19x19 1000 already take a long time (but still plays bad). PLAYOUTS playouts = get_digit_input init_game(size, playouts) game_loop end
Private Instance Methods
ask_for_input()
click to toggle source
# File lib/rubykon/cli.rb, line 120 def ask_for_input @output.puts "Make a move in the form XY, e.g. A19, D7 as the labels indicate!" @output.puts 'Or ask rubykon what it is thinking with "wdyt"' get_input end
bot_move()
click to toggle source
# File lib/rubykon/cli.rb, line 101 def bot_move @output.puts 'Rubykon is thinking...' @root = @mcts.start @game_state, @playouts move = @root.best_move make_move(move) end
bot_turn?()
click to toggle source
# File lib/rubykon/cli.rb, line 80 def bot_turn? @game.next_turn_color == Board::BLACK end
exit_if_desired(input)
click to toggle source
# File lib/rubykon/cli.rb, line 49 def exit_if_desired(input) quit if input.match EXIT end
game_loop()
click to toggle source
# File lib/rubykon/cli.rb, line 69 def game_loop print_board while true if bot_turn? bot_move else human_input end end end
get_digit_input()
click to toggle source
# File lib/rubykon/cli.rb, line 33 def get_digit_input input = get_input until input.match /^\d\d*$/ @output.puts "Input has to be a number. Please try again!" input = get_input end input end
get_input()
click to toggle source
# File lib/rubykon/cli.rb, line 42 def get_input @output.print '> ' input = @input.gets.chomp exit_if_desired(input) input end
human_input()
click to toggle source
# File lib/rubykon/cli.rb, line 108 def human_input input = ask_for_input.upcase case input when GTP_COORDINATE human_move(input) when 'WDYT'.freeze print_move_considerations else invalid_input end end
human_move(input)
click to toggle source
# File lib/rubykon/cli.rb, line 126 def human_move(input) move = move_from_input(input) if @move_validator.valid?(*move, @game_state.game) make_move(move) else retry_input end end
init_game(size, playouts)
click to toggle source
# File lib/rubykon/cli.rb, line 58 def init_game(size, playouts) board_size = size.to_i @output.puts "Great starting a #{board_size}x#{board_size} game with #{playouts} playouts" @game = Game.new board_size @game_state = GameState.new @game @mcts = MCTS::MCTS.new @board = @game.board @gtp_converter = GTPCoordinateConverter.new(@board) @playouts = playouts.to_i end
invalid_input()
click to toggle source
# File lib/rubykon/cli.rb, line 161 def invalid_input puts "Sorry, didn't catch that!" end
labeled_board()
click to toggle source
# File lib/rubykon/cli.rb, line 88 def labeled_board rows = [] x_labels = X_LABEL_PADDING + CHAR_LABELS.take(@board.size).join(' ') rows << x_labels board_rows = @board.to_s.split("\n").each_with_index.map do |row, i| y_label = "#{@board.size - i}".rjust(Y_LABEL_WIDTH) y_label + row + y_label end rows += board_rows rows << x_labels rows.join "\n" end
make_move(move)
click to toggle source
# File lib/rubykon/cli.rb, line 154 def make_move(move) @game_state.set_move move print_board @output.puts "#{move.last} played at #{@gtp_converter.to(move.first)}" @output.puts "#{@game.next_turn_color}'s turn to move!'" end
move_from_input(input)
click to toggle source
# File lib/rubykon/cli.rb, line 149 def move_from_input(input) identifier = @gtp_converter.from(input) [identifier, :white] end
print_board()
click to toggle source
# File lib/rubykon/cli.rb, line 84 def print_board @output.puts labeled_board end
print_move_considerations()
click to toggle source
# File lib/rubykon/cli.rb, line 140 def print_move_considerations best_children = @root.children.sort_by(&:win_percentage).reverse top_children = best_children.take(MOVE_CONSIDERATIONS_COUNT) moves_to_win_percentage = top_children.map do |child| "#{@gtp_converter.to(child.move.first)} => #{child.win_percentage * 100}%" end.join "\n" @output.puts moves_to_win_percentage end
quit()
click to toggle source
# File lib/rubykon/cli.rb, line 53 def quit @output.puts "too bad, bye bye!" exit end
retry_input()
click to toggle source
# File lib/rubykon/cli.rb, line 135 def retry_input @output.puts 'That was an invalid move, please try again!' human_input end