Module: Chess::Mouse

Included in:
Game
Defined in:
lib/chess/mouse/mouse_input.rb,
lib/chess/mouse/mouse_position.rb

Overview

Mouse

Instance Method Summary collapse

Instance Method Details

#button_type(x, _y) ⇒ String

returns which button was clicked

Examples:

x and y are decomposed from array

button_type([x,y])

Returns:

  • (String)


66
67
68
69
70
71
72
# File 'lib/chess/mouse/mouse_position.rb', line 66

def button_type((x, _y))
  if x.between?(5, 15)
    'save&exit'
  else
    'game_exit'
  end
end

#buttons_touched?(coord_x, coord_y) ⇒ Boolean

checks if a button was touched

Examples:

x and y are decomposed from array

buttons_touched?([x,y])

Returns:

  • (Boolean)


49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/chess/mouse/mouse_position.rb', line 49

def buttons_touched?((coord_x, coord_y))
  y = 11
  return false if coord_y != y

  start_x = 5
  end_x = 15
  save_and_exit = Array(start_x..end_x)
  start_x = 19
  end_x = 22
  exit = Array(start_x..end_x)
  (save_and_exit + exit).include?(coord_x)
end

#clicked_element(x, y, file_coords, rank_coords) ⇒ Array(file,rank)

returns the position of board where mouse clicked on console display

Examples:

x and y are decomposed from array

clicked_element([3,2],file_coords,rank_coords)

Parameters:

  • file_coords (Hash)
  • rank_coords (Hash)

Returns:

  • (Array(file,rank))


14
15
16
# File 'lib/chess/mouse/mouse_position.rb', line 14

def clicked_element((x, y), file_coords, rank_coords)
  [file_coords[x], rank_coords[y]]
end

#disable_mouse_trackingObject

disable the mouse tracking using xterm control sequences - invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking



36
37
38
39
# File 'lib/chess/mouse/mouse_input.rb', line 36

def disable_mouse_tracking
  print "\e[?1006l" # Disable SGR mouse tracking
  print "\e[?1000l" # Disable normal mouse tracking
end

#enable_mouse_trackingObject

enable the mouse tracking using xterm control sequences - invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking



29
30
31
32
# File 'lib/chess/mouse/mouse_input.rb', line 29

def enable_mouse_tracking
  print "\e[?1000h" # Enable normal mouse tracking
  print "\e[?1006h" # Enable SGR mouse tracking
end

#game_exit?(value) ⇒ Boolean

checks if exit code 0 is returned

Parameters:

  • value (Integer, nil)

Returns:

  • (Boolean)


90
91
92
# File 'lib/chess/mouse/mouse_input.rb', line 90

def game_exit?(value)
  value == 0 # rubocop:disable Style/NumericPredicate
end

#generate_file_coordsHash

generate file coords for the display

Returns:

  • (Hash)

    file_coords



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/chess/mouse/mouse_position.rb', line 20

def generate_file_coords
  file_coords = {}
  file_ord = 97 # ord for "a"
  board_start_x = 2
  board_end_x = 25
  (board_start_x..board_end_x).each_slice(3) do |arr| # a board square's string length on display is 3.
    arr.each { |elem| file_coords[elem] = file_ord.chr }
    file_ord += 1
  end
  file_coords
end

#generate_rank_coordsHash

generate rank coord for the display

Returns:

  • (Hash)

    rank_coords



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/chess/mouse/mouse_position.rb', line 34

def generate_rank_coords
  rank_coords = {}
  rank = 7 # black is on upper side of board so ranks go from 8 to 1 (7 to 0 cuz index start = 0) from top to bottom
  board_start_y = 2
  board_end_y = 9
  (board_start_y..board_end_y).each do |elem|
    rank_coords[elem] = rank
    rank -= 1
  end
  rank_coords
end

#input_loop(board) ⇒ Object

runs loop for mouse input

Parameters:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/chess/mouse/mouse_input.rb', line 43

def input_loop(board) # rubocop:disable Metrics/MethodLength
  file_coords = generate_file_coords
  rank_coords = generate_rank_coords
  loop do
    char = $stdin.getc
    next unless char == "\e"

    coord = read_input(char)
    board_pos = clicked_element(coord, file_coords, rank_coords)
    clicked = read_clicked(board_pos, coord)
    return_value = select_click_action(board, clicked, board_pos, coord)
    break if game_exit?(return_value)
  end
end

#read_clicked(file, rank, coord) ⇒ String

read what was clicked

Examples:

file and rank are decomposed from array

read_clicked([file,rank],coord)

Parameters:

  • coord (Array)

Returns:

  • (String)


78
79
80
81
82
83
84
85
86
# File 'lib/chess/mouse/mouse_input.rb', line 78

def read_clicked((file, rank), coord)
  if !(file.nil? || rank.nil?)
    'board'
  elsif buttons_touched?(coord)
    'button'
  else
    'outside'
  end
end

#read_input(char) ⇒ Array(x,y)

reads whole input sequence and returns the coords X and Y

Parameters:

  • char (Char)

Returns:

  • (Array(x,y))


61
62
63
64
65
66
67
68
69
70
# File 'lib/chess/mouse/mouse_input.rb', line 61

def read_input(char)
  sequence = char + $stdin.read(17)
  # storing anything left out here
  sequence += $stdin.getc while $stdin.ready? 
  input = sequence.split(';')
  x = input[1].to_i
  # for y the to_i will only take the first number from e.g "34M[0;12;0" ignoring everything after the first non Integer
  y = input[2].to_i
  [x, y]
end

#start_mouse_input(board) ⇒ Object

starts listening mouse input in console

Parameters:



9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/chess/mouse/mouse_input.rb', line 9

def start_mouse_input(board)
  warn_tmux_users if ENV['TMUX']
  system('stty -icanon -echo') # Disable canonical mode and echo in terminal
  enable_mouse_tracking
  begin
    puts 'Waiting for mouse click... Press Ctrl+C to quit.'
    input_loop(board)
  ensure # run these even if Ctrl+C was pressed
    disable_mouse_tracking
    system('stty icanon echo') # Restore terminal to sane mode
  end
end

#warn_tmux_usersObject

warns tmux users that mouse may not work



23
24
25
# File 'lib/chess/mouse/mouse_input.rb', line 23

def warn_tmux_users
  warn 'Mouse input may not work as expected in tmux'
end