Esempio n. 1
0
/* This is used when the player is moving one of her pieces that is
 * already on the board to a new space.
 *
 * Return true iff the current player can place the piece in board
 * position (x,y).
 *
 * We can move the old piece here if
 * 0) Target space is empty,
 * AND
 * 1a) Moving to an unoccupied neighboring space, OR
 * 1b) Moving to an unoccupied space that is one jump over a neighbor
 * AND
 * 2) The move does not result in disconnected board
 * AND
 * 3) Target space is still adjacent to an existing piece (could be our own
 *    piece or an enemy piece, doesn't matter)
 *
 * Hint: you may want to use checkNbrs, isNeighboringSpace,
 *       isJumpSpace, and isConnected as subroutines here.
 */
bool canPlaceOldPiece(int x, int y){
    //TODO
    int target = 20*y+x;
	if ((board[target]->type == 0) && (isNeighboringSpace(x,y) || isJumpSpace(x,y)))
		if(stillConnected(x,y))
			return true;
    return false;
}
Esempio n. 2
0
//*****************************************************************************
//
// Method: me_write
//
// Purpose:
//
//     This method writes a number of bytes to the communications channel.
//
// Returns:
//
//     > 0                              - write succeeded
//     -1                               - write failed
//
// Arguments:
//
// I   const char *buffer               - buffer to write
// I   int length                       - number of bytes to write
//
// History:
//
// Date      Author          Reason
// ====      ======          ======
//
// 27/11/97  Geoff Glasson   Original version
//
//*****************************************************************************
int TcpSocket::write ( const char  * pBuffer,                // Buffer to write
					  const int   pLength )                 // Number of bytes to write
{
	//
	// Write the buffer to the socket.
	//
	try
	{
		//
		// If the socket is not connected then we can't really write to
		// it.
		//
		if( false == stillConnected() )
		{

			//throw exception
			std::ostringstream streamErrInfo;
			std::string strErrorInfo;

			streamErrInfo <<  "Not connected";
			strErrorInfo = streamErrInfo.str();

			throw std::exception(strErrorInfo.c_str());
		}




		_LOG(SourceFLInfo, DebugDebug, "Attempting to write %d bytes to socket", pLength );


		//
		// Write the data to the stream.  Under UNIX we will retry if there is a
		// write already in progream.
		//
		const char * lvPacket;
		const int lvMaxPacketLength = 1024;
		int  lvPacketLength;
		int lvProgressing = 1;
		int lvTransferredBytes = 0;
		lvPacket = pBuffer;
		int lvNumberOfBytesWritten = 0;
		do
		{

			//
			// Determine the amount of data to be transferred.  The maximum packet
			// size is defined by lv_max_packet_length.
			//
			lvPacketLength = ( pBuffer + pLength) - lvPacket;
			if ( lvMaxPacketLength < lvPacketLength )
			{
				lvPacketLength = lvMaxPacketLength;
			}

#if !defined( WIN32 )
			LOG (SourceInfo, TA_Base_Core::DebugUtil::GenericLog,
				TA_Base_Core::DebugUtil::DebugDebug, 
				"About to write %d bytes to socket", lvPacketLength );

			lvNumberOfBytesWritten = ::write( socketId, lvPacket, lvPacketLength );
			int lvErrno = errno;
			if ( -1 == lvNumberOfBytesWritten )
			{

				LOG (SourceInfo, TA_Base_Core::DebugUtil::GenericLog,
					TA_Base_Core::DebugUtil::DebugWarn, 
					"Failed to write to socket: %s", strerror( lvErrno ) );

				//
				// If a write is in progress, sleep for 0.1 second2.
				//
				struct timespec lvSleepTime = { 0,
#if defined( SOLARIS )
					( unsigned long )( 0.1 * NANOSEC )
#else // !defined( SOLARIS )
					( unsigned long )( 0.1 * 1000000000 )
#endif // !defined( SOLARIS );
				};
				nanosleep( & lvSleepTime, NULL );
			}
#else // defined( WIN32 )
			//lvNumberOfBytesWritten = ::send( socketId, pBuffer, pLength, 0 );

			lvNumberOfBytesWritten = ::send( socketId, lvPacket, lvPacketLength, 0 );
			int lvErrno = 0;
			if ( SOCKET_ERROR == lvNumberOfBytesWritten )
			{
				lvErrno = WSAGetLastError();
				if ( WSAEALREADY == lvErrno )
				{

					_LOG(SourceFLInfo, DebugDebug, "Write in progress => waiting 1 millisecond before trying again");

					//
					// If a write is in progress, sleep for one millisecond then
					// try again.
					//
					Sleep( 1 );
				}
			}
#endif // WIN32
			else
			{
				if ( 0 != lvNumberOfBytesWritten )
				{
					lvTransferredBytes += lvNumberOfBytesWritten;
				}
				else
				{
						
					_LOG(SourceFLInfo, DebugDebug, "Wrote %d bytes to the socket", lvNumberOfBytesWritten);


				}

				if ( lvPacketLength == lvNumberOfBytesWritten )
				{
					lvPacket += lvMaxPacketLength;
				}
			}

			//
			// Determine if the transfer is progressing.
			//
			lvProgressing = 1;
			if ( ( EBADF == lvErrno ) || 
				( ENXIO == lvErrno ) || 
				( EPIPE == lvErrno ) ||
				( lvPacket > & pBuffer[ pLength - 1 ] ) )
			{
				lvProgressing = 0;
			}

#ifndef WIN32
			if ( ( ECONNRESET == lvErrno ) ||
				( ENOTCONN  == lvErrno ) ||
				( ECONNABORTED  == lvErrno ) )
#else // !WIN32
			if ( ( WSAECONNRESET == lvErrno ) ||
				( WSAENOTCONN  == lvErrno ) ||
				( WSAECONNABORTED  == lvErrno ) )
#endif // WIN32
			{
				m_isDisconnected = true;
				lvProgressing = 0;
			}

		} while ( 0 != lvProgressing );
		return lvTransferredBytes;
	}

	//
	// Deal with MS Visual C++ exceptions.
	//
	catch ( const unsigned int )
	{


		//throw exception
		std::ostringstream streamErrInfo;
		std::string strErrorInfo;

		streamErrInfo << "Unknown Microsoft exception caught";
		strErrorInfo = streamErrInfo.str();

		throw std::exception(strErrorInfo.c_str());
	}
}
Esempio n. 3
0
//*****************************************************************************
//
// Method: me_read
//
// Purpose:
//
//     This method reads a number of bytes from the channel.  It returns the
//     number of bytes read from the channel.  The method determines if the
//     client is still connected, and throws an exception if it is not.  The
//     checking works as follows:
//
//     If there is a socket ready for reading and there is no data to be read,
//     then the socket may not be connected.  After COMMS_CHECK_TIME seconds,
//     the client is "pinged" and if there is no response, the client is
//     assumed to have disconnected.  In this case, an exception is thrown.  If
//     a response is received, the method waits for another COMMS_CHECK_TIME
//     seconds before checking the connection status again.
//
// Returns:
//
//     0                                - read succeeded
//     non-0                            - read failed
//
// Arguments:
//
// O   char *buffer                     - buffer to read into
// O   unsigned int *length             - number of bytes read
// I   unsigned int max_length          - maximum length of the buffer
//
// History:
//
// Date      Author          Reason
// ====      ======          ======
//
// 19/08/98  Geoff Glasson   Channel now detects when the remote connection
//                           is closed unexpectedly and throws an
//                           CHANNEL_EX_COMMS_LOST exception.
//
// 12/01/97  Geoff Glasson   Added code to determine if the connection to the
//                           client is down.  It throws an exception so that
//                           higher level routines can figure out what to do.
//
// 27/11/97  Geoff Glasson   Original version
//
//*****************************************************************************
int TcpSocket::read ( char                  *pBuffer,           // Buffer to read into
					 unsigned int          *pLength,           // Number of bytes read
					 const unsigned int    pMaxLength)         // Maximum length of the buffer
{
	//
	// Do some validation.
	//
	//TA_DEBUG_ASSERT( 0 != pBuffer, "NULL pointer passed for read buffer" );
	//TA_DEBUG_ASSERT( 0 != pLength , "Zero length read requested" );
	//TA_DEBUG_ASSERT( 0 < pMaxLength , "Buffer length is zero or less" );

	try
	{
		//
		// If the socket is not connected then we can't really read from
		// it.
		//
		if( false == stillConnected() )
		{
			pBuffer[ 0 ] = '\0';
			*pLength = 0;


			std::ostringstream streamErrInfo;
			std::string strErrorInfo;

			streamErrInfo << "Not connected";
			strErrorInfo = streamErrInfo.str();

			throw std::exception(strErrorInfo.c_str());

		}

		//
		// Read max_length bytes from the socket.
		//
		*pLength = 0;

		fd_set lvIdset;
		FD_ZERO( & lvIdset);
		FD_SET( socketId, & lvIdset );
#if !defined( WIN32 )
		const int lvNumReady = select( FD_SETSIZE, & lvIdset, ( fd_set * )0,
			( fd_set * )0, & m_readingTimeout );
#else
		//xinsong ++
		//it seems that the timeout does not work properly when running in win32 
		const int lvNumReady = select( FD_SETSIZE, & lvIdset, ( fd_set * )0,
			( fd_set * )0, NULL );
#endif


		_LOG(SourceFLInfo, DebugInfo, "Number of ready sockets: %d", lvNumReady );
	

		// For Blocking sockets, select is in error if <=0
		// For NonBlocking sockets, select is in error if <0
		if ( (isBlocking  && lvNumReady <= 0) ||
			(!isBlocking && lvNumReady <  0) )
		{
#if !defined( WIN32 )
			const int lvErrno = errno;
#else // defined( WIN32 )
			const int lvErrno = WSAGetLastError();
#endif // defined( WIN32 )

			if ( EINTR == lvErrno )
			{
	
				_LOG(SourceFLInfo, DebugInfo, "Interrupted system call" );

				return 0;
			}

			std::string lvMessage = "Unable to read from socket - ";
#if !defined( WIN32 )
			lvMessage.append( strerror( errno ) );
#else // defined( WIN32 )
			LPVOID lpMsgBuf;
			FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
				FORMAT_MESSAGE_IGNORE_INSERTS, NULL, WSAGetLastError(),
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
				(LPTSTR) &lpMsgBuf,
				0,
				NULL );

			lvMessage.append( ( char * )lpMsgBuf );

			LocalFree( lpMsgBuf );
#endif // defined( WIN32 )

			m_isDisconnected = true;

			//throw exception
			std::ostringstream streamErrInfo;
			std::string strErrorInfo;

			streamErrInfo << lvMessage;
			strErrorInfo = streamErrInfo.str();

			throw std::exception(strErrorInfo.c_str());


		}

		if ( lvNumReady != 0 )
		{
			if ( false == FD_ISSET( socketId, & lvIdset ) )
			{
#if !defined( WIN32 )
				if ( ECONNRESET == errno ||
					ENOTCONN   == errno )
#else // defined( WIN32 )
				if ( WSAECONNRESET == WSAGetLastError() ||
					WSAENOTCONN   == WSAGetLastError() )
#endif // defined( WIN32 )
				{
					m_isDisconnected = true;

					//throw exception
					std::ostringstream streamErrInfo;
					std::string strErrorInfo;

					streamErrInfo << "Connection closed unexpectedly";
					strErrorInfo = streamErrInfo.str();

					throw std::exception(strErrorInfo.c_str());

				}
				else
				{
#if !defined( WIN32 )
					return errno;
#else // defined( WIN32 )
					return WSAGetLastError();
#endif // defined( WIN32 )
				}
			}

#if !defined( WIN32 )
			const int lvStatus = ::read( socketId, ( void * )pBuffer, pMaxLength );
#else // defined( WIN32 )
			const int lvStatus = recv( socketId, pBuffer, pMaxLength, 0 );
#endif // defined( WIN32 )

			if( 0 <= lvStatus )
			{
				* pLength = lvStatus;
				pBuffer[ * pLength ] = '\0';

	
				_LOG(SourceFLInfo, DebugDebug, "Read %d bytes from socket", lvStatus );

			}
			else
			{

				_LOG(SourceFLInfo, DebugDebug, "No data returned from socket" );
					

			}
		}
	}

	//
	// Handle Windows exceptions.
	//
	catch ( const unsigned int )
	{

		//throw exception
		std::ostringstream streamErrInfo;
		std::string strErrorInfo;

		streamErrInfo <<  "Unexpected Microsoft exception caught";
		strErrorInfo = streamErrInfo.str();

		throw std::exception(strErrorInfo.c_str());
	}

	//
	// Done.
	//
	return (0);
}