Клиент (листинг 18.2) оформлен в виде единственной программы. При первом запуске она становится TCP-сервером, а при втором — TCP-клиентом. Честно говоря, решение о том, что сервер будет играть белыми, совершенно произвольно. Вполне можно было бы реализовать приложение так, чтобы цвет не зависел от подобных деталей.
require 'socket'
require 'timeout'
ChessServer = '96.97.98.99' # Заменить этот IP-адрес.
ChessServerPort = 12000
PeerPort = 12001
WHITE, BLACK = 0, 1
Colors = %w[White Black]
def draw_board(board)
puts <<-EOF
+------------------------------+
| Заглушка! Шахматная доска... |
+------------------------------+
EOF
end
def analyze_move(who, move, num, board)
# Заглушка - черные всегда выигрывают на четвертом ходу.
if who == BLACK and num == 4
move << ' Мат!'
end
true # Еще одна заглушка - любой ход считается допустимым.
end
def my_move(who, lastmove, num, board, sock)
ok = false
until ok do
print '
Ваш ход: '
move = STDIN.gets.chomp
ok = analyze_move(who, move, num, board)
puts 'Недопустимый ход' if not ok
end
sock.puts move
move
end
def other_move(who, move, num, board, sock)
move = sock.gets.chomp
puts '
Противник: #{move}'
move
end
if ARGV[0]
myself = ARGV[0]
else
print 'Ваше имя? '
myself = STDIN.gets.chomp
end
if ARGV[1]
opponent_id = ARGV[1]
else
print 'Ваш противник? '
opponent_id = STDIN.gets.chomp
end
opponent = opponent_id.split(':')[0] # Удалить имя хоста.
# Обратиться к серверу
socket = TCPSocket.new(ChessServer, ChessServerPort)
response = nil
socket.puts 'login # {myself} #{opponent_id}'
socket.flush
response = socket.gets.chomp
name, ipname, color = response.split ':'
color = color.to_i
if color == BLACK # Цвет фигур другого игрока,
puts '
Устанавливается соединение...'
server = TCPServer.new(PeerPort)
session = server.accept
str = nil
begin
timeout(30) do
str = session.gets.chomp
if str != 'ready'
raise 'Ошибка протокола: получено сообщение о готовности #{str}.'
end
end
rescue TimeoutError
raise 'He получено сообщение о готовности от противника.'
end
puts 'Ваш противник #{opponent}... у вас белые.
'
who = WHITE
move = nil
board = nil # В этом примере не используется.
num = 0