doing something a bit more marco-polo-ish (and more interesting, too)
This commit is contained in:
parent
5927b05f6c
commit
190bdbee9f
@ -1,25 +1,40 @@
|
|||||||
require 'socket'
|
require 'socket'
|
||||||
|
|
||||||
successes = 0
|
def main
|
||||||
backoff = 0.5
|
client_type = %w(read write).include?(ARGV.first) ? ARGV.first : 'read'
|
||||||
loop do
|
sleep_interval = (ARGV[1] || 0).to_f
|
||||||
begin
|
puts "Starting #{client_type} client"
|
||||||
TCPSocket.open('127.0.0.1', 22000) do |sock|
|
|
||||||
sock.send("sally #{rand(101)} #{rand(101)}\n", 0)
|
successes = 0
|
||||||
sock.recv(100)
|
backoff = 0.5
|
||||||
sock.close
|
nextloc = [rand(0..99), rand(0..99)]
|
||||||
STDOUT.write('.')
|
loop do
|
||||||
STDOUT.flush
|
begin
|
||||||
|
TCPSocket.open('127.0.0.1', 22000) do |sock|
|
||||||
|
case client_type
|
||||||
|
when 'read'
|
||||||
|
sock.send("marco sally\n", 0)
|
||||||
|
location = sock.recv(100).to_s.split[2,4].map(&:to_i)
|
||||||
|
puts "#{location.first} #{location.last}"
|
||||||
|
when 'write'
|
||||||
|
sock.send("polo sally #{nextloc.first} #{nextloc.last}\n", 0)
|
||||||
|
nextloc = sock.recv(100).to_s.split.map(&:to_i)
|
||||||
|
puts "sent location '#{nextloc.first} #{nextloc.last}'"
|
||||||
|
end
|
||||||
|
sock.close
|
||||||
|
end
|
||||||
|
successes += 1
|
||||||
|
backoff = 0.5
|
||||||
|
sleep sleep_interval
|
||||||
|
rescue
|
||||||
|
puts "made it #{successes} times. sleeping #{backoff} secs"
|
||||||
|
successes = 0
|
||||||
|
sleep backoff
|
||||||
|
backoff *= 2
|
||||||
end
|
end
|
||||||
successes += 1
|
|
||||||
backoff = 0.5
|
|
||||||
sleep 0.01 if ENV['SLEEP']
|
|
||||||
rescue
|
|
||||||
STDOUT.write('E')
|
|
||||||
STDOUT.flush
|
|
||||||
STDERR.write("\nmade it #{successes} times. sleeping #{backoff} secs\n")
|
|
||||||
successes = 0
|
|
||||||
sleep backoff
|
|
||||||
backoff *= 2
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if $0 == __FILE__
|
||||||
|
main
|
||||||
|
end
|
||||||
|
@ -1,33 +1,102 @@
|
|||||||
require 'logger'
|
|
||||||
|
|
||||||
require 'eventmachine'
|
require 'eventmachine'
|
||||||
require 'sequel'
|
require 'sequel'
|
||||||
|
|
||||||
DB = Sequel.connect("postgres://#{ENV['USER']}@localhost/marco_polo",
|
class MarcoPolo
|
||||||
:max_connections => 10)
|
attr_reader :locations, :db
|
||||||
DB.create_table! :locations do
|
|
||||||
primary_key :id
|
def initialize
|
||||||
String :client
|
@pool_range = 0..99
|
||||||
Integer :x
|
# I'm not using this (yet?) ... but don't want to forget how I did it
|
||||||
Integer :y
|
# @pool = [].tap do |board|
|
||||||
|
# @pool_range.each do |y|
|
||||||
|
# board << [].tap do |row|
|
||||||
|
# @pool_range.each do |x|
|
||||||
|
# row << "#{y}-#{x}"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
@db = Sequel.connect("postgres://#{ENV['USER']}@localhost/marco_polo",
|
||||||
|
:max_connections => 10)
|
||||||
|
unless @db.table_exists?(:locations)
|
||||||
|
@db.create_table :locations do
|
||||||
|
primary_key :id
|
||||||
|
String :client
|
||||||
|
DateTime :timestamp
|
||||||
|
Integer :x
|
||||||
|
Integer :y
|
||||||
|
constraint(:in_the_pool, 'x > -1 and x < 100 and y > -1 and y < 100')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@locations = @db[:locations]
|
||||||
|
puts "LET GAME BEGIN NOW"
|
||||||
|
end
|
||||||
|
|
||||||
|
def polo(client, x, y)
|
||||||
|
@locations.insert(:client => client, :x => x, :y => y,
|
||||||
|
:timestamp => Time.now)
|
||||||
|
nextloc(x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
def marco(client = nil)
|
||||||
|
if client
|
||||||
|
@locations.where(:client => client).order_by(:timestamp.desc).first
|
||||||
|
else
|
||||||
|
@locations.order_by(:timestamp.desc).first
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def nextloc(x, y)
|
||||||
|
# we allow exiting the pool as long as you get back in on the opposite side
|
||||||
|
# a la pac man
|
||||||
|
move_x, move_y = rand(-2..2), rand(-2..2)
|
||||||
|
new_x = x + move_x
|
||||||
|
new_x = 100 + new_x if new_x <= -1
|
||||||
|
new_y = y + move_y
|
||||||
|
new_y = 100 + new_y if new_y <= -1
|
||||||
|
[
|
||||||
|
new_x > 99 ? new_x % 100 : new_x,
|
||||||
|
new_y > 99 ? new_y % 100 : new_y
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module MarcoPoloServer
|
class MarcoPoloServer < EventMachine::Connection
|
||||||
def post_init
|
class << self
|
||||||
@locations = DB[:locations]
|
attr_accessor :game
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive_data(data)
|
def receive_data(data)
|
||||||
client, x, y = data.split
|
parts = data.to_s.split
|
||||||
@locations.insert(:client => client, :x => x.to_i, :y => y.to_i)
|
case parts.first
|
||||||
send_data("thanks\n")
|
when 'polo'
|
||||||
|
client, x, y = parts[1,4]
|
||||||
|
newloc = self.class.game.polo(client, x.to_i, y.to_i)
|
||||||
|
send_data("#{newloc.first} #{newloc.last}\n")
|
||||||
|
when 'marco'
|
||||||
|
if loc = self.class.game.marco(parts[1])
|
||||||
|
send_data("polo #{loc[:client]} #{loc[:x]} #{loc[:y]}\n")
|
||||||
|
else
|
||||||
|
send_data("polo NULL 0 0\n")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
send_data("#{parts.first}???\n")
|
||||||
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
STDERR.puts("#{e.class.name} #{e.message}: #{e.backtrace.join("\n")}")
|
STDERR.puts("#{e.class.name} #{e.message}: #{e.backtrace.join("\n")}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
EventMachine.run do
|
def main
|
||||||
host, port = '0.0.0.0', 22000
|
MarcoPoloServer.game = MarcoPolo.new
|
||||||
EventMachine.start_server(host, port, MarcoPoloServer)
|
EventMachine.run do
|
||||||
puts "Listening on #{host}:#{port}"
|
host, port = '0.0.0.0', 22000
|
||||||
|
EventMachine.start_server(host, port, MarcoPoloServer)
|
||||||
|
puts "Listening on #{host}:#{port}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if $0 == __FILE__
|
||||||
|
main
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user