0 Replies - 2035 Views - Last Post: 16 June 2009 - 03:30 PM Rate Topic: -----

#1 TroyDowling  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 13-June 09

Working with sockets: Managing input from client

Posted 16 June 2009 - 03:30 PM

Hello, this is my first post here at DIC! Anyways, I've been working with Ruby for a while now but have just started to move into networking with it. As a project to learn about how it works, I wanted to build a simple Rock, Paper, Scissors online application. Basicially, two instances of the application run; one is the server, one is the client, both are players. How it should work is, the player who is also the server should enter their choice of rock paper or scissors and then the program will wait for input from the client via a socket. Then, the winner is decided and this process repeats. However, there is something wrong with my program, so as of now, the two players do not have to remain in sync with eachother. The client is able to enter their three choices all before the server player enters their first. Hopefully you understand what I am trying to accomplish and what the problem is. Below is the code for the entire program. Thanks in advance.

# Rock Paper Scissors
# 0.2.3
# GNU\GPL
# Troy Dowling
# A multiplayer, networked game of rock, papper, scissors

require "socket"													# This tells the ruby interpreter to include the libraries for creating and managing sockets.

class Game
	
	def initialize
		while true
			system "cls"
			system "clear"
			intro = <<INTRO												# This is a special way to create a string. Everything between the <<FOOBAR and FOOBAR is the string exactly how you format it in the IDE (that's why it does not follow normal indentation)
Hello and welcome to Rock Paper Scissors
	1) Host a server
	2) Join a server
	3) Help + Rules
	4) Quit
INTRO
			puts intro
			i = gets.chomp.strip.to_i								# Take the user's input, remove white space and turn the string into an integer.
			(i == 1) ? server() :									# This is a turnary conditional. Just a shorthand conditional... (CONDITIONAL) ? (IF TRUE) : (IF FALSE)
			(i == 2) ? join() :
			(i == 3) ? help() :
			(i == 4) ? exit : (puts "You must choose 1, 2 or 3.")
		end
	end
			  
	
	def server
		begin
			print "Address (default is localhost): "
			host = gets.chomp.strip
			(host == "") ? (host = "localhost") : (nil)				# If they did not enter their own address for the server, use 'localhost' as the default, otherwise do nothing.
			print "Port (default is 7994): "
			port = gets.chomp.strip
			(port == "") ? (port = 7994) : (nil)					# If they did not enter their own port for the server, use '7994' as the default, otherwise do nothing.
			
			puts "Starting server..."
			server = TCPserver.new(host,port)						# Create an instance of a TCP Server using the address and port defined above.
		rescue
			puts "The server could not start! Try using a different port."
			retry
		end
		server_address = server.addr								# Save the address and port date of this server and...
		puts "Server running on #{server_address.join('::')}"		# ...show this data. (It's actually an array of values, so we join all these values together in a string with "::" between each entry.)
		while true
			Thread.start(server.accept) do |@sock|					# Start a new thread that waits for a client to join the server
				puts "#{@sock} connected at #{Time.now}"
				bestOf = 3											# How many rounds to play total. I.e., the best of n rounds.
				roundCount = 0										# How many complete rounds have passed.
				while roundCount < bestOf
					print "Rock, Paper, Scissors: "
					call = gets.chomp.strip.downcase
					puts "Waiting on client..."
					clientCall = @sock.gets.chomp.strip.downcase	# THIS NEEDS TO ONLY ACCEPT ONE ENTRY AT A TIME. AS OF NOW, THE SERVER-SIDE WAITS FOR ALL THREE OF THE CLIENT'S ENTRIES BEFORE CONTINUING!!!
					winOrLose(call, clientCall)
					roundCount += 1
				end
				puts "#{@sock} disconnected."
				s.close
			end
		end
	end
	
	def join
		quitOrNot = 0
		begin
			print "Address: "
			host = gets.chomp.strip
			print "Port (default is 7994): "
			port = gets.chomp.strip
			(port == "") ? (port = 7994) : (nil)					# If they did not enter their own port for the server, use '7994' as the default, otherwise do nothing.
			
			print("Connecting...")

			clientsock = TCPsocket.open(host, port)					# Open up a socket (connection) to the server
		rescue
			puts " Could not open a connection to that server."
			quitOrNot += 1
			(quitOrNot < 3) ? (retry) : (puts "Exiting program..."; exit)
		end
		print(" done\n")
		puts("Connected from #{clientsock.addr[2]}::#{clientsock.addr[3]} to #{clientsock.peeraddr[2]}::#{clientsock.addr[3]}")
		bestOf = 3													# How many rounds to play total. I.e., the best of n rounds.
		roundCount = 0												# How many complete rounds have passed.
		while roundCount < bestOf
			print "Rock, Paper, Scissors: "
			call = gets.chomp.strip.downcase
			clientsock.write(call)
			roundCount += 1											# Add one to the roundCount
		end
		clientsock.close											# Close the connection to the server
	end
	
	def winOrLose(serv, client)
		puts serv
		puts client
	end
	
	def help()
		system "cls"
		system "clear"
		puts <<EOL
Welcome to Rock, Paper, Scissors Online!
----------------------------------------

HOW TO START A GAME SERVER

1) Run the game
2) Select "Host a Server"
3) In most cases you can leave the server address as the default 'localhost'
4) The same goes for the port number
5) The server is now running and waiting for a client to join before beginning the game!

HOW TO JOIN A SERVER

1) Run the game
2) Select "Join a server"
3) Enter the address of the server you wish to connect to.
4) Enter the port you wish to connect to; this is likely 7994.
5) You are now connected!

Press any key to return to menu...

EOL
		STDIN.gets
	end
	
end

prog = Game.new


This post has been edited by TroyDowling: 17 June 2009 - 02:51 PM


Is This A Good Question/Topic? 0
  • +

Page 1 of 1