Пример #1
0
void LuminesRobot::thinkNextBlock(btype *map, int width, int height, const BlockSet coming[3])
{
    int i, j;
    ::std::vector< int > tops(width,0);
    ::std::vector< Sets > sets((width-1)*4*(width-1)*4*(width-1)*4);
    sets.clear();
    tops.clear();
    for (i=0;i<width;i++)
    {
        for (j=height-1;j>=0;j--)
        {
            if (map[i+j*width] == BT_NONE)
                break;
        }
        tops.push_back(j);
    }
    Sets base;
    base.level = -1;
    thinkNextBlockI(base, tops, sets, 0, map, width, height, coming);

    assert(sets.size());
    ::std::sort(sets.begin(), sets.end());

    m_res.clear();
    
    LuRobotResultPair res;
    for (i = 0; i <= sets[0].level; i++)
    {
        res.x = sets[0].x[i];
        res.r = sets[0].r[i];
        m_res.push_back(res);
    }

}
Пример #2
0
//=============================================================================
// METHOD    : SPELLcontroller::notifyCommandToCore
//=============================================================================
void SPELLcontroller::notifyCommandToCore( const std::string& id )
{
	// Notify the adapter and the driver to give the chance
	// to abort ongoing operations if needed
	if (id == CMD_ABORT ||
		id == CMD_PAUSE ||
		id == CMD_INTERRUPT ||
		id == CMD_SKIP  ||
		id == CMD_RUN)
	{
		bool controlled = SPELLexecutor::instance().getConfiguration().hasControlClient();
		if (controlled)
		{
			DEBUG("[C] Notify command " + id + " to core IN");
			SPELLdriverManager::instance().onCommand(id);
			DEBUG("[C] Notify command to core OUT");
		}
		else
		{
			DEBUG("[C] Notify command " + id + " to core IN (NOCLT)");
			SPELLsafeThreadOperations tops("SPELLcontroller::onCommand()");
			SPELLdriverManager::instance().onCommand(id);
			DEBUG("[C] Notify command to core OUT");
		}
	}
}
int main(){
	
	int i;
	printf("is stack empty? \n");
	printf(BOOL_PRINT(isEmpty()));
	
	push(10);
	printf("top is at %d\n",tops() );

	push(11);
	push(12);
	push(15);

	i = pop();
	printf("Popped data is %d\n",i );

	printf("top is at %d\n",tops());

	stack_print(); // Note: this is just for vizualizing and this actually results in loss of stack data

	return 0;
}
Пример #4
0
void LuminesRobot::think(btype *map, int width, int height, const BlockSet coming[3])
{
    thinkNextBlock(map, width, height, coming);
    return;
    int i, j;
    int r, t;
    int score;
    BlockSet bs;
    int top1, top2;
    LuRobotResultPair res;
    ::std::vector< int > tops(width,0);
    ::std::vector< Set > sets((width-1)*4);
    sets.clear();
    tops.clear();

#ifdef _DEBUG
    OutputDebugString("\n");
#endif
    for (i=0;i<width;i++)
    {
        for (j=height-1;j>=0;j--)
        {
            if (map[i+j*width] == BT_NONE)
                break;
#ifdef _DEBUG
            if (map[i+j*width] == BT_A)
                OutputDebugString("a");
            else 
                OutputDebugString("b");
        }
        char n[3];
        sprintf(n,"%d\n",j);
        OutputDebugString(n);
#else
        }
#endif

        tops.push_back(j);
    }
Пример #5
0
/* VARARGS */
char	*
tparm(char *instring, long fp1, long fp2, long p3, long p4,
	long p5, long p6, long p7, long p8, long p9)
{
	static	char	result[512];
	static	char	added[100];
	long		vars[26];
	STACK		stk;
	char		*cp = instring;
	char		*outp = result;
	char		c;
	long		op;
	long		op2;
	int		sign;
	int		onrow = 0;
	long		p1 = fp1, p2 = fp2;  /* copy in case < 2 actual parms */
	char		*xp;
	char		formatbuffer[100];
	char		*format;
	int		looping;
	short		*regs = cur_term->_regs;
	int		val;


	if ((val = setjmp(env)) != 0) {
#ifdef DEBUG
		switch (val) {
			case MEM_ALLOC_FAIL:
				fprintf(outf, "TPARM: Memory allocation"
				    " failure.");
				break;
			case STACK_UNDERFLOW:
				fprintf(outf, "TPARM: Stack underflow.");
				break;
		}
#endif  /* DEBUG */

		if (val == STACK_UNDERFLOW)
			free_stack(&stk);
		return (NULL);
	}

	init_stack(&stk);
	push(&stk, 0);

	if (instring == 0) {
#ifdef	DEBUG
		if (outf)
			fprintf(outf, "TPARM: null arg\n");
#endif	/* DEBUG */
		free_stack(&stk);
		return (NULL);
	}

	added[0] = 0;

	while ((c = *cp++) != 0) {
		if (c != '%') {
			*outp++ = c;
			continue;
		}
		op = tops(&stk);
		switch (c = *cp++) {
			/* PRINTING CASES */
			case ':':
			case ' ':
			case '#':
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
			case '.':
			case 'd':
			case 's':
			case 'o':
			case 'x':
			case 'X':
				format = formatbuffer;
				*format++ = '%';

			/* leading ':' to allow +/- in format */
			if (c == ':')
				c = *cp++;

			/* take care of flags, width and precision */
			looping = 1;
			while (c && looping)
				switch (c) {
					case '-':
					case '+':
					case ' ':
					case '#':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
					case '.':
						*format++ = c;
						c = *cp++;
						break;
					default:
						looping = 0;
				}

			/* add in the conversion type */
			switch (c) {
				case 'd':
				case 's':
				case 'o':
				case 'x':
				case 'X':
					*format++ = c;
					break;
				default:
#ifdef	DEBUG
				if (outf)
					fprintf(outf, "TPARM: invalid "
					    "conversion type\n");
#endif	/* DEBUG */
				free_stack(&stk);
				return (NULL);
			}
			*format = '\0';

			/*
			 * Pass off the dirty work to sprintf.
			 * It's debatable whether we should just pull in
			 * the appropriate code here. I decided not to for
			 * now.
			 */
			if (c == 's')
				(void) sprintf(outp, formatbuffer,
				    (char *) op);
			else
				(void) sprintf(outp, formatbuffer, op);
			/*
			 * Advance outp past what sprintf just did.
			 * sprintf returns an indication of its length on some
			 * systems, others the first char, and there's
			 * no easy way to tell which. The Sys V on
			 * BSD emulations are particularly confusing.
			 */
				while (*outp)
				    outp++;
				(void) pop(&stk);

				continue;

			case 'c':
			/*
			 * This code is worth scratching your head at for a
			 * while.  The idea is that various weird things can
			 * happen to nulls, EOT's, tabs, and newlines by the
			 * tty driver, arpanet, and so on, so we don't send
			 * them if we can help it.  So we instead alter the
			 * place being addessed and then move the cursor
			 * locally using UP or RIGHT.
			 *
			 * This is a kludge, clearly.  It loses if the
			 * parameterized string isn't addressing the cursor
			 * (but hopefully that is all that %c terminals do
			 * with parms).  Also, since tab and newline happen
			 * to be next to each other in ASCII, if tab were
			 * included a loop would be needed.  Finally, note
			 * that lots of other processing is done here, so
			 * this hack won't always work (e.g. the Ann Arbor
			 * 4080, which uses %B and then %c.)
			 */
				switch (op) {
				/*
				* Null.  Problem is that our
				* output is, by convention, null terminated.
				*/
					case 0:
						op = 0200; /* Parity should */
							/* be ignored. */
						break;
				/*
				* Control D.  Problem is that certain very
				* ancient hardware hangs up on this, so the
				* current(!) UNIX tty driver doesn't xmit
				* control D's.
				*/
					case _CHCTRL('d'):
				/*
				* Newline.  Problem is that UNIX will expand
				* this to CRLF.
				*/
					case '\n':
						xp = (onrow ? cursor_down :
						    cursor_right);
					if (onrow && xp && op < lines-1 &&
					    cursor_up) {
						op += 2;
						xp = cursor_up;
					}
					if (xp && instring ==
					    cursor_address) {
						(void) strcat(added, xp);
						op--;
					}
					break;
				/*
				 * Tab used to be in this group too,
				 * because UNIX might expand it to blanks.
				 * We now require that this tab mode be turned
				 * off by any program using this routine,
				 * or using termcap in general, since some
				 * terminals use tab for other stuff, like
				 * nondestructive space.  (Filters like ul
				 * or vcrt will lose, since they can't stty.)
				 * Tab was taken out to get the Ann Arbor
				 * 4080 to work.
				 */
				}

				/* LINTED */
				*outp++ = (char)op;
				(void) pop(&stk);
				break;

			case 'l':
				xp = pop_char_p(&stk);
				push(&stk, strlen(xp));
				break;

			case '%':
				*outp++ = c;
				break;

			/*
			* %i: shorthand for increment first two parms.
			* Useful for terminals that start numbering from
			* one instead of zero(like ANSI terminals).
			*/
			case 'i':
				p1++;
				p2++;
				break;

			/* %pi: push the ith parameter */
			case 'p':
				switch (c = *cp++) {
					case '1':
						push(&stk, p1);
						break;
					case '2':
						push(&stk, p2);
						break;
					case '3':
						push(&stk, p3);
						break;
					case '4':
						push(&stk, p4);
						break;
					case '5':
						push(&stk, p5);
						break;
					case '6':
						push(&stk, p6);
						break;
					case '7':
						push(&stk, p7);
						break;
					case '8':
						push(&stk, p8);
						break;
					case '9':
						push(&stk, p9);
						break;
					default:
#ifdef	DEBUG
						if (outf)
							fprintf(outf, "TPARM:"
							    " bad parm"
							    " number\n");
#endif	/* DEBUG */
						free_stack(&stk);
						return (NULL);
				}
			onrow = (c == '1');
			break;

			/* %Pi: pop from stack into variable i (a-z) */
			case 'P':
				if (*cp >= 'a' && *cp <= 'z') {
					vars[*cp++ - 'a'] = pop(&stk);
				} else {
					if (*cp >= 'A' && *cp <= 'Z') {
						regs[*cp++ - 'A'] =
							/* LINTED */
							(short) pop(&stk);
					}
#ifdef	DEBUG
					else if (outf) {
						fprintf(outf, "TPARM: bad"
						    " register name\n");
					}
#endif	/* DEBUG */
				}
				break;

			/* %gi: push variable i (a-z) */
			case 'g':
				if (*cp >= 'a' && *cp <= 'z') {
					push(&stk, vars[*cp++ - 'a']);
				} else {
					if (*cp >= 'A' && *cp <= 'Z') {
						push(&stk, regs[*cp++ - 'A']);
					}
#ifdef	DEBUG
					else if (outf) {
						fprintf(outf, "TPARM: bad"
						    " register name\n");

					}
#endif	/* DEBUG */
				}
				break;

			/* %'c' : character constant */
			case '\'':
				push(&stk, *cp++);
				if (*cp++ != '\'') {
#ifdef	DEBUG
					if (outf)
						fprintf(outf, "TPARM: missing"
						    " closing quote\n");
#endif	/* DEBUG */
					free_stack(&stk);
					return (NULL);
				}
				break;

			/* %{nn} : integer constant.  */
			case '{':
				op = 0;
				sign = 1;
				if (*cp == '-') {
					sign = -1;
					cp++;
				} else
					if (*cp == '+')
						cp++;
				while ((c = *cp++) >= '0' && c <= '9') {
					op = 10 * op + c - '0';
				}
				if (c != '}') {
#ifdef	DEBUG
					if (outf)
						fprintf(outf, "TPARM: missing "
						    "closing brace\n");
#endif	/* DEBUG */
					free_stack(&stk);
					return (NULL);
				}
				push(&stk, (sign * op));
				break;

			/* binary operators */
			case '+':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op + op2));
				break;
			case '-':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op - op2));
				break;
			case '*':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op * op2));
				break;
			case '/':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op / op2));
				break;
			case 'm':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op % op2));
				break; /* %m: mod */
			case '&':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op & op2));
				break;
			case '|':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op | op2));
				break;
			case '^':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op ^ op2));
				break;
			case '=':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op == op2));
				break;
			case '>':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op > op2));
				break;
			case '<':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op < op2));
				break;
			case 'A':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op && op2));
				break; /* AND */
			case 'O':
				op2 = pop(&stk);
				op = pop(&stk);
				push(&stk, (op || op2));
				break; /* OR */

			/* Unary operators. */
			case '!':
				push(&stk, !pop(&stk));
				break;
			case '~':
				push(&stk, ~pop(&stk));
				break;

			/* Sorry, no unary minus, because minus is binary. */

			/*
			* If-then-else.  Implemented by a low level hack of
			* skipping forward until the match is found, counting
			* nested if-then-elses.
			*/
			case '?':	/* IF - just a marker */
				break;

			case 't':	/* THEN - branch if false */
				if (!pop(&stk))
					cp = _branchto(cp, 'e');
					break;

			case 'e':	/* ELSE - branch to ENDIF */
				cp = _branchto(cp, ';');
				break;

			case ';':	/* ENDIF - just a marker */
				break;

			default:
#ifdef	DEBUG
				if (outf)
					fprintf(outf, "TPARM: bad % "
					    "sequence\n");
#endif	/* DEBUG */
				free_stack(&stk);
				return (NULL);
		}
	}
	(void) strcpy(outp, added);
	free_stack(&stk);
	return (result);
}
Пример #6
0
void CSite::writeSite(const int& iisitsf)
{
   //---------------------------------------------------------------------------------------------//
   bool isita  = bAtomInSite,            isiti  = bSaltInSite,             isitmd = bMDInSite,            isitpot = bPotentialInSite,
        isitx  = bAtomCoordInSite,       isitq  = bCrgInSite,              isitf  = bFieldInSite,         isitp   = bGridPotentialInSite,
        isitr  = bReactPotentialInSite,  isitc  = bCoulombPotentialInSite, isitap = bAtomPotentialInSite, isitdeb = bDebyeFractionInSite,
        isitsf = bSurfCrgInSite,         isittf = bTotalForceInSite,       isitrf = bReactForceInSite,    isitt   = bTotalPotentialInSite,
        isitcf = bCoulombForceInSite,    iself  = bPDB2FRCInSite;

   //----- ifrm is true if ANY of the flags for special output have been set
   bool ifrm = isita || isitq || isitp || isitf || isitr || isitt || isitc || isitx || isiti || isitrf || isitcf || isitap ||
               isittf || isitdeb;
   bool isitmp1 = ifrm; ifrm = ifrm || isitsf;
   bool ofrm = true;

   if (isitmd || isitpot) {iFrcFormatOut = -1; ofrm = false;}

   if (!ifrm && (0 == iFrcFormatOut || 3 == iFrcFormatOut))
   {
      isitx = true; isitq = true; isitf = true; isitp = true;
   }

   switch (iFrcFormatOut)
   {
      case 1: isitx = true; isitq = true; isitr = true; isitc = true; break;
      case 2: isitx = true; isitq = true; isitr = true; break;
      case 3: ofrm = false; break;
   }

   string vrow(80,' '),datum(65,' '); int j = 0, k = 0;

   if (isita)
   {
      vrow.replace(j,15,"ATOM DESCRIPTOR"); datum.replace(k,5,"ATOM ");
      j += 20; k += 5;
   }

   if (isitx)
   {
      vrow.replace(j+4,24,"ATOM COORDINATES (X,Y,Z)"); datum.replace(k,12,"COORDINATES ");
      j += 30; k += 12;
   }

   if (isitq)
   {
      vrow.replace(j+3,6,"CHARGE"); datum.replace(k,7,"CHARGE ");
      j += 10; k += 7;
   }

   if (isitp)
   {
      vrow.replace(j+2,8,"GRID PT."); datum.replace(k,11,"POTENTIALS ");
      j += 10; k += 11;
   }

   if (isiti)
   {
      vrow.replace(j+1,8,"SALT CON"); datum.replace(k,5,"SALT ");
      j += 10; k += 5;
   }

   if (80 <= j)
   {
      isitr  = false; isitc  = false; isitap = false; isitdeb = false; isitf = false;
      isitsf = false; isittf = false; isitrf = false; isitcf  = false; isitt = false;
   }

   if (isitr)
   {
      vrow.replace(j,10," REAC. PT."); datum.replace(k,9,"REACTION ");
      j += 10; k += 9;
   }

   if (80 <= j)
   {
                      isitc  = false; isitap = false; isitdeb = false; isitf = false;
      isitsf = false; isittf = false; isitrf = false; isitcf  = false; isitt = false;
   }

   if (isitc)
   {
      vrow.replace(j,10," COUL. POT"); datum.replace(k,10,"COULOMBIC ");
      j += 10; k += 10;
   }

   if (80 <= j)
   {
                                      isitap = false; isitdeb = false; isitf = false;
      isitsf = false; isittf = false; isitrf = false; isitcf  = false; isitt = false;
   }

   if (isitap)
   {
      vrow.replace(j+2,8,"ATOM PT."); datum.replace(k,11,"ATOMIC PT. ");
      j += 10; k += 11;
   }

   if (80 <= j)
   {
                                                      isitdeb = false; isitf = false;
      isitsf = false; isittf = false; isitrf = false; isitcf  = false; isitt = false;
   }

   if (isitdeb)
   {
      vrow.replace(j+3,11,"DEBFRACTION"); datum.replace(k,12,"DEBFRACTION ");
      j += 14; k += 12;
   }

   if (60 <= j)
   {
                                                                       isitf = false;
      isitsf = false; isittf = false; isitrf = false; isitcf  = false; isitt = false;
   }

   if (isitf)
   {
      vrow.replace(j+4,25,"GRID FIELDS: (Ex, Ey, Ez)"); datum.replace(k,7,"FIELDS ");
      j += 30;
   }

   if (60 <= j)
   {
      isitsf = false; isittf = false; isitrf = false; isitcf  = false; isitt  = false;
   }

   if (isitrf)
   {
      vrow.replace(j+4,25,"REAC. FORCE: (Rx, Ry, Rz)"); datum.replace(k,7,"RFORCE ");
      j += 30;
   }

   if (60 <= j)
   {
      isitsf = false; isittf = false; isitcf  = false; isitt  = false;
   }

   if (isitcf)
   {
      vrow.replace(j+4,25,"COUL. FORCE: (Cx, Cy, Cz)"); datum.replace(k,7,"CFORCE ");
      j += 30;
   }

   if (60 <= j)
   {
      isitsf = false; isittf = false; isitt  = false;
   }

   if (isittf)
   {
      vrow.replace(j+4,25,"TOTAL FORCE: (Tx, Ty, Tz)"); datum.replace(k,7,"TFORCE ");
      j += 30;
   }

   if (70 <= j)
   {
      isitt  = false;
   }

   if (isitt)
   {
      vrow.replace(j+4,6," TOTAL"); datum.replace(k,6,"TOTAL ");
      j += 10;
   }

   if (50 <= j) isitsf = false;

   if (isitsf)
   {
      vrow.replace(j+4,65,"sCharge,    x          y       z       urf.E°n,surf. E[kT/(qA)]");
      datum.replace(k,35,"SCh, x, y, z, surf En, surf. E");
      j += 50;
   }

   //---------------------------------------------------------------------------------------------//
   /*
    * if site potentials required and unformatted read/write, skip during formatted frc file read/write can write unformatted frc.pdb
    */
   bool ifrm2 = false, iqass = true;
   ifstream ifFileStream;
   vector<bool> residsf(iResidueNum,false);

   if (!(isitmd || isitpot)) cout << "\nwriting potentials at given sites...\n";

   if (iself)
   {
      cout << "using the current pdb file\n";
      ifrm2 = true; iqass = false;
   }
   else
   {
      if (!isitpot)
      {
         ifFileStream.open(strFrciFile.c_str()); // just inquire whether the file exists or not
         if (!ifFileStream.is_open())
         {
            CUnknownInFrcFile warning(strFrciFile);
            ifFileStream.close();
            return;
         }
         else
         {
            cout << "coordinates, etc for potential output read from file " << strFrciFile << endl;
            ifrm2 = checkFileFormat(strFrciFile);
         }

         ifFileStream.close();
      }
   }

   //----- if unformatted may not contain all the info needed for all options, i.e atom info
   if (!ifrm2 && isita)
   {
      CNoAtomInfo warning(strFrciFile);
      isita = false; iqass = false;
   }

   if (!ifrm2) iqass = false;

   if (!iself && !isitpot)
   {
      if (ifrm2) ifFileStream.open(strFrciFile.c_str());
      else       ifFileStream.open(strFrciFile.c_str(),ios::binary);

      if (!ifFileStream.is_open()) CUnknownInFrcFile warning(strFrciFile);
   }

   if (isitsf) //----- isitsf assumes ifrm2=.true.
   {
      ifstream ifFileStream15;
      string strLine,strHead;
      int iresnum;

      ifFileStream15.open(strFrciFile.c_str()); // just inquire whether the file exists or not
      if (!ifFileStream15.is_open())
      {
         CUnknownInFrcFile warning(strFrciFile);
      }
      else
      {
         cout << "coordinates, etc for potential output read from file " << strFrciFile << endl;
         while (!ifFileStream15.eof()) // loop D302
         {
            getline(ifFileStream15,strLine);
            strHead = strLine.substr(0,6);
            if (0 != strHead.compare("      ")) strHead = toUpperCase(strHead);
            if (0 != strHead.compare("ATOM  ") && 0 != strHead.compare("HETATM")) continue;
            iresnum = atoi(strLine.substr(23,4).c_str());
            residsf[iresnum-1] = true;
         }
      }

      ifFileStream15.close();
   }

   //---------------------------------------------------------------------------------------------//
   ofstream ofFileStream;

   if (ofrm) ofFileStream.open(strFrcFile.c_str());
   if(!(ofrm || isitmd || isitpot)) ofFileStream.open(strFrcFile.c_str(),ios::binary);

   if (!isitmd && !isitpot) cout << "potentials written to file " << strFrcFile << endl << endl;

   if (ofrm)
   {
      ofFileStream << "DELPHI SITE POTENTIAL FILE\n";
      ofFileStream << "grid size,percent fill:   " << iGrid << "    " << fPercentageFill << endl;
      ofFileStream << "outer diel. and first one assigned :   " << fExDielec << "    " << vctfMediaEps[1]*fEPKT << endl;
      ofFileStream << "ionic strength (M):   " << fIonStrength << endl;
      ofFileStream << "ion excl., probe radii:   " << fIonRadius << "    " << rgfProbeRadius[0] << "    " << rgfProbeRadius[1] << endl;
      ofFileStream << "linear, nolinear iterations:   " << iLinIterateNum << "    " << iNonIterateNum << endl;
      ofFileStream << "boundary condition:   " << iBndyType << endl;
      ofFileStream << "Data Output:   " << datum << endl;
      ofFileStream << "title: " << rgcFileMap << endl;
      ofFileStream << "\n\n";
      ofFileStream << vrow << endl;
   }

   if (!ofrm && (!(isitmd || isitpot)))
   {
      ofFileStream << fixed << setprecision(4);

      string strLine;
      strLine = "DELPHI FRC FILE"; ofFileStream << strLine << endl;
      strLine = "FORMAT NUMBER=1"; ofFileStream << strLine << endl;
      strLine = "DATA="; strLine.append(datum); ofFileStream << strLine << endl;
      ofFileStream << setw(5) << right << iGrid << setw(10) << right << fPercentageFill << setw(10) << right << fExDielec
                   << setw(10) << right << fIonStrength << endl;
      for (int i = 1; i <= iMediaNum; i++)
         ofFileStream << "dielectric in medium nr. " << i << ": " << vctfMediaEps[i]*fEPKT << endl;
      ofFileStream << setw(10) << right << fIonRadius << setw(10) << right << rgfProbeRadius[0] << setw(10) << right << rgfProbeRadius[1]
                   << setw(5) << right << iLinIterateNum << setw(5) << right << iNonIterateNum << setw(5) << right << iBndyType << endl;

      ofFileStream.unsetf(ios_base::floatfield);
   }

   if (!iself && (isitrf || isitmd || isittf))
   {
      CCalcReactForceError warning;
      isitrf = false; isittf = false; isitmd = false;
   }

   vector< SGrid<real> > rfield;

   if (isitrf || isitmd || isittf)
   {
      if (1 == iMediaNum && fZero > abs(vctfMediaEps[1]*fEPKT-1.0))
         rfield = rforceeps1();
      else
         rfield = rforce();
   }

   //---------------------------------------------------------------------------------------------//
   integer nnatom,inum,ncrgs;
   SGrid<real> cxyz = {0.0,0.0,0.0},xo,xn,fu,fl,xo2,fxyz,vtemp,xu2,xu,rxyz;
   real chrgv,radu,goff,vphi,aphi,etot,phiv,temp,phii,debyefraction,phirt,phict,phir,phias,tcrgs,dist,phirtt,crgs,phiat,phic,phiac,eps,phiact,phit;
   real sdist,ff,fn;
   string atm,res,rnum,chn,crdstr,atnum,atdes(16,' '),strLine,strHead;
   bool isitmp;
   int iFound,iresnum,idist,ncrg,jtmp;
   vector<bool> atmsf(iAtomNum*iisitsf,false);
   vector<real> sold,scomp;
   char otemp[10];
   string oline(80,' ');

   nnatom = 0; chrgv = 0.0; goff = ((real)iGrid+1.0)/2.0; etot = 0.0; phirt = 0.0; phict =0.0;

   if (isitpot)
   {
      CSitePhiError warning;
   }
   else
   {
      do // beginning of the big loop on natom
      {
         if(iself)
         {
            if (iAtomNum == nnatom) break;
            xo    = prgfgAtomCoordA[nnatom];
            chrgv = vctapAtomPdb[nnatom].getCharge();
            radu  = vctapAtomPdb[nnatom].getRadius()*fScale;
            atm   = vctapAtomPdb[nnatom].getAtInf().substr(0,4);
            res   = vctapAtomPdb[nnatom].getAtInf().substr(6,3);
            rnum  = vctapAtomPdb[nnatom].getAtInf().substr(11,4);
            chn   = vctapAtomPdb[nnatom].getAtInf().substr(10,1);
         }
         else
         {
            //if (!ifFileStream.is_open()) break;

            if(ifrm2) // formatted reading
            {
               getline(ifFileStream,strLine);

               if (ifFileStream.eof()) break;

               strHead = strLine.substr(0,6); strHead = toUpperCase(strHead);
               if (0 != strHead.compare("ATOM  ") && 0 != strHead.compare("HETATM")) continue;
               crdstr = strLine.substr(30,24);
               atnum = strLine.substr(6,5);
               xo.nX = atof(crdstr.substr(0,8).c_str()); xo.nY = atof(crdstr.substr(8,8).c_str()); xo.nZ = atof(crdstr.substr(16,8).c_str());
               inum = atoi(atnum.c_str());
            }
            else // unformatted (binary) reading
            {
               ifFileStream.read( reinterpret_cast<char*>(&xo.nX),sizeof(real) );
               ifFileStream.read( reinterpret_cast<char*>(&xo.nY),sizeof(real) );
               ifFileStream.read( reinterpret_cast<char*>(&xo.nZ),sizeof(real) );
               ifFileStream.read( reinterpret_cast<char*>(&radu), sizeof(real) );
               ifFileStream.read( reinterpret_cast<char*>(&chrgv),sizeof(real) );
            }
         } //----- end of atom reading

         nnatom++;

         isitmp = (isitq && iqass) || isitap || isitp;

         if((isita || isitmp) && !iself)
         {
            atm  = strLine.substr(11,5);
            res  = strLine.substr(17,3);
            rnum = strLine.substr(22,4);
            chn  = strLine.substr(21,1);

            if (0 !=  atm.compare("     ")) {atm  = removeSpace(atm);  atm  = toUpperCase(atm);}
            if (0 !=  res.compare("   "))   {res  = removeSpace(res);  res  = toUpperCase(res);}
            if (0 != rnum.compare("    "))  {rnum = removeSpace(rnum); rnum = toUpperCase(rnum);}
            if (0 != chn.compare(" "))      {chn  = removeSpace(chn);  chn  = toUpperCase(chn);}
         }

         xn = (xo-fgBoxCenter)*fScale+goff; // scale atoms to grid space

         if (isita)
         {
            atdes.assign(16,' ');
            atdes.replace( 0,atm.size(),atm);
            atdes.replace( 5,res.size(),res);
            atdes.replace( 9,chn.size(),chn);
            atdes.replace(11,rnum.size(),rnum);
         }

         /*
          * assign charge to atom, searching for decreasingly specific specification
          * note if no charge record found, is assumed to be 0.0
          */
         if(!iself && ifrm2 && isitmp)
         {
            chrgv = 0.0;
            iFound = FindRecord(atm,res,rnum,chn,CHARGEFILE,chrgv);
            if(isitap) iFound = FindRecord(atm,res,rnum,chn,SIZEFILE,radu);
            radu = radu*fScale;
         }

         if (isitsf)
         {
            iresnum = atoi(rnum.c_str());
            atmsf[nnatom-1] = false;
            if (residsf[iresnum-1]) atmsf[nnatom-1] = true;
         }

         if(isitap && fZero < abs(chrgv))
         {
            real rads = min(radu,fPotentialUpperBond*fScale);
            SGrid<real> xt;

            xt = xn; xt.nX += rads;
            vphi = interpl(iGrid,phimap,xt);
            aphi = vphi;

            xt = xn; xt.nX -= rads;
            vphi = interpl(iGrid,phimap,xt);
            aphi += vphi;

            xt = xn; xt.nY += rads;
            vphi = interpl(iGrid,phimap,xt);
            aphi += vphi;

            xt = xn; xt.nY -= rads;
            vphi = interpl(iGrid,phimap,xt);
            aphi += vphi;

            xt = xn; xt.nZ += rads;
            vphi = interpl(iGrid,phimap,xt);
            aphi += vphi;

            xt = xn; xt.nZ -= rads;
            vphi = interpl(iGrid,phimap,xt);
            aphi += vphi;

            aphi = aphi/6.0;
         }

         if (isitp || isiti || (isitap && fZero > abs(chrgv)))
         {
            vphi = interpl(iGrid,phimap,xn);
            if (isitap && fZero > abs(chrgv)) aphi = vphi;
            if (isitp) { etot += chrgv*vphi; phiv = vphi; }

            if (isiti)
            {
               CNoIDebMap warning;

               /*
                * we have changed the iconc action so that the phimap has NOT been converted to salt concentrations. therefore
                */
               if (0 != iNonIterateNum)
               {
                  temp = vphi*fTaylorCoeff5+fTaylorCoeff4; temp = vphi*temp+fTaylorCoeff3;
                  temp = vphi*temp+fTaylorCoeff2;          temp = vphi*temp+fTaylorCoeff1;
                  phii = vphi*temp;
               }
               else
                  phii = -fIonStrength*2.0*vphi;
            }
         } //----- end if isitp or isiti, salt and or potentials

         if (isitdeb) // it calculates the fraction of closest grid points that are in solution
         {
            cout << "Calculating Debye Fraction\n";
            debyefraction = boolinterpl(iGrid,prgbDielecMap,xn);
         }

         if (isitf)
         {
            xn.nX += 1.0;               fu.nX = interpl(iGrid,phimap,xn);
            xn.nX -= 2.0;               fl.nX = interpl(iGrid,phimap,xn);
            xn.nX += 1.0; xn.nY += 1.0; fu.nY = interpl(iGrid,phimap,xn);
            xn.nY -= 2.0;               fl.nY = interpl(iGrid,phimap,xn);
            xn.nY += 1.0; xn.nZ += 1.0; fu.nZ = interpl(iGrid,phimap,xn);
            xn.nZ -= 2.0;               fl.nZ = interpl(iGrid,phimap,xn);
            xn.nZ += 1.0;
            fxyz = (fl-fu)*0.5*fScale; // the electric field is opposite the potential gradient so I change the sign
         }

         /*
          * check if this point is within the box.
          */
         if (isitt)
         {
            SExtrema<real> bedge;
            bedge.nMin = fgBoxCenter-0.5*(iGrid-1)/fScale; bedge.nMax = fgBoxCenter+0.5*(iGrid-1)/fScale;

            int it = 0;
            if ( optORLT<real>(xo,bedge.nMin) || optORGT<real>(xo,bedge.nMax) ) it = 1;

            if (0 == it)
            {
               xo2 = (xo-fgBoxCenter)*fScale+goff;

               /*
                * first find reaction field from surface elements inside of the box..
                */
               phir=0.0; phias=0.0; ncrgs=0; tcrgs=0.0; sold.assign(30,0.0);

               for (integer i = 0; i < iDielecBndySum; i++)
               {
                  vtemp = xo - prgfgSurfCrgA[i]; dist = sqrt(optDot(vtemp,vtemp));
                  //----- first find reaction field from surface elements inside of the box
                  ncrgs++; tcrgs += prgfSurfCrgE[i]; phirtt = prgfSurfCrgE[i]/dist;
                  //----- medeps either epsin contain the 561.0 factor....
                  phirtt = phirtt*fEPKT; phir += phirtt;
                  xu2.nX = (real)prgigBndyGrid[i].nX; xu2.nY = (real)prgigBndyGrid[i].nY; xu2.nZ = (real)prgigBndyGrid[i].nZ;
                  crgs = prgfSurfCrgE[i];
                  //----- took place of repsin because eps is no more included in schrg , surface charge
                  phiat = tops(xu2,xo2,crgs,1.0,1); phiat = phiat*2.0; phias += phiat;
                  idist = (int)dist; sold[idist] += phiat - phirtt;
               }

               temp = 0.0;
               cout << "Writing sold(1:30) and temp \n";
               for (integer i = 0; i < 30; i++)
               {
                  temp += sold[i];
                  cout << sold[i] << " " << temp;
               }
               cout << endl;

               /*
                * next find the colombic potential for that site from charges within the box
                */
               phic = 0.0; phiac = 0.0; ncrg = 0;

               for (integer i = 0; i < iCrgGridNum; i++)
               {
                  it = 0;
                  if (optORLT<real>(prgfgCrgPoseA[i],bedge.nMin) || optORGT<real>(prgfgCrgPoseA[i],bedge.nMax)) it = 1;

                  if (0 == it)
                  {
                     ncrg++;
                     vtemp = xo - prgfgCrgPoseA[i]; dist = sqrt(optDot(vtemp,vtemp));

                     if (5.0 > dist)
                     {
                        if (fZero < dist) {temp = prggvAtomicCrg[i].nValue/dist; phic += temp/prgfAtomEps[i];}
                        //----- find analytic potential from this real charge..=phiac
                        xu  = prgfgCrgPoseA[i]; crgs = prggvAtomicCrg[i].nValue;
                        xu2 = (xu-fgBoxCenter)*fScale+goff;
                        eps = prgfAtomEps[i]*fEPKT;
                        phiact = tops(xu2,xo2,crgs,eps,1);
                        phiac += phiact;
                     }
                  }
               }

               /*
                * medeps, either epsin contain the 561.0 factor....
                */
               phiac = phiac*2.0;

               /*
                * find the grid potentials..
                */
               phiv = interpl(iGrid,phimap,xn);

               string strFileName7 = "extra.dat";
               ofstream ofFileSteam7;
               ofFileSteam7.open(strFileName7.c_str());
               ofFileSteam7 << phic << " " << phir << " " << phiv << " " << phias << " " << phiac << " "<< ncrg << " "
                            << ncrgs << " " << tcrgs << endl;
               ofFileSteam7.close();

               phit = phic + phir + phiv - phias - phiac;
            }
            else
               phit = 0.0;

            /*
             * phit contains the total corrected potential
             */
         }

         if (isitr)
         {
            scomp.assign(30,0.0); sold.assign(30,0.0); phir = 0.0;

            for (integer i = 0; i < iDielecBndySum; i++)
            {
               vtemp = xo - prgfgSurfCrgA[i]; dist = sqrt(optDot(vtemp,vtemp));
               idist = (int)dist;
               if (30 > idist) sold[idist] += fEPKT*prgfSurfCrgE[i]/dist;
               phir += prgfSurfCrgE[i]/dist;
            }

            /*
             * medeps either epsin contains the 561.0 factor....
             */
            phir = phir*fEPKT;

            for (integer i = 0; i < 30; i++)
            {
               if (0 == i) scomp[i] = sold[i];
               if (0 != i) scomp[i] = scomp[i-1]+sold[i];
            }

            phirt += phir*chrgv;
         }

         /*
          * medeps either epsin contains the 561.0 factor....
          */
         if (isitrf || isitmd || isittf) rxyz = rfield[nnatom-1]*fEPKT;

         if(isitcf || isitmd || isittf)
         {
            cxyz.nX = 0.0; cxyz.nY = 0.0; cxyz.nZ = 0.0;

            if (fZero < abs(chrgv))
            {
               for (integer i = 0; i < iCrgGridNum; i++)
               {
                  vtemp = xo - prgfgCrgPoseA[i]; dist = optDot(vtemp,vtemp);
                  if (fZero < dist)
                  {
                     sdist = sqrt(dist)*dist;
                     temp  = prggvAtomicCrg[i].nValue/(prgfAtomEps[i]*sdist);
                     cxyz  = cxyz + vtemp*temp;
                  }
               }

               /*
                * atmeps and medeps and epsin contain the 561.0 factor....
                */
               cxyz = cxyz*chrgv;
            }
         }

         if (isitc)
         {
            phic = 0.0;

            for (integer i = 0; i < iCrgGridNum; i++)
            {
               vtemp = xo - prgfgCrgPoseA[i]; dist = optDot(vtemp,vtemp);
               if (fZero < dist)
               {
                  sdist = sqrt(dist);
                  temp  = prggvAtomicCrg[i].nValue/sdist;
                  phic += temp/prgfAtomEps[i];
               }
            }

            /*
             * atmeps and medeps and epsin contain the 561.0 factor....
             */
            phict += phic*chrgv;
         }

         //---------------------------------------------------------------------------------------//
         /*
          * write out calculated/assigned charges
          *
          * need otemp cos can not write into a substring apparently
          * otemp needs to be at least 15 long to avoid an error!!
          */
         oline.assign(80,' '); // reset oline
         j = 0;

         if (isita)
         {
            oline.replace(j,16,atdes.substr(0,16));
            j += 20;
         }

         if (isitx)
         {
            sprintf(otemp,"%10.4f",xo.nX); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",xo.nY); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",xo.nZ); oline.replace(j,10,otemp); j += 10;
         }

         if (isitq)
         {
            sprintf(otemp,"%10.4f",chrgv); oline.replace(j,10,otemp); j += 10;
         }

         if (isitp)
         {
            sprintf(otemp,"%10.4f",phiv);  oline.replace(j,10,otemp); j += 10;

#ifdef MCCE
            mcce_phiv.push_back(phiv);
#endif
         }

         if (isiti)
         {
            sprintf(otemp,"%10.4f",phii);  oline.replace(j,10,otemp); j += 10;
         }

         if (isitr)
         {
            sprintf(otemp,"%10.4f",phir);  oline.replace(j,10,otemp); j += 10;
         }

         if (isitc)
         {
            sprintf(otemp,"%10.4f",phic);  oline.replace(j,10,otemp); j += 10;
         }

         if (isitap)
         {
            sprintf(otemp,"%10.4f",aphi);  oline.replace(j,10,otemp); j += 10;
         }

         if (isitdeb)
         {
            sprintf(otemp,"%10.4f",debyefraction); oline.replace(j,10,otemp); j += 10;
         }

         if (isitf)
         {
            sprintf(otemp,"%10.4f",fxyz.nX); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",fxyz.nY); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",fxyz.nZ); oline.replace(j,10,otemp); j += 10;
         }

         if (isitrf)
         {
            sprintf(otemp,"%10.4f",rxyz.nX); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",rxyz.nY); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",rxyz.nZ); oline.replace(j,10,otemp); j += 10;
         }

         if (isitcf)
         {
            sprintf(otemp,"%10.4f",cxyz.nX); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",cxyz.nY); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",cxyz.nZ); oline.replace(j,10,otemp); j += 10;
         }

         if (isittf)
         {
            vtemp = rxyz + cxyz;
            sprintf(otemp,"%10.4f",vtemp.nX); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",vtemp.nY); oline.replace(j,10,otemp); j += 10;
            sprintf(otemp,"%10.4f",vtemp.nZ); oline.replace(j,10,otemp); j += 10;
         }

         if (isitmd)
         {
            vtemp = rxyz + cxyz;
            cout << "atom: " << nnatom << " rx= " << rxyz.nX << " cx= " << cxyz.nX << " tx= " << vtemp.nX << endl;
            cout << "atom: " << nnatom << " ry= " << rxyz.nY << " cy= " << cxyz.nY << " ty= " << vtemp.nY << endl;
            cout << "atom: " << nnatom << " rz= " << rxyz.nZ << " cz= " << cxyz.nZ << " tz= " << vtemp.nZ << endl;
         }

         if (isitt)
         {
            sprintf(otemp,"%10.4f",phit); oline.replace(j,10,otemp); j += 10;
         }

         if (ofrm && isitmp1) ofFileStream << oline << endl;

         if (!ofrm && isitmp1)
         {
            if (isita)  ofFileStream << atdes << endl;
            if (isitx)  ofFileStream << xo    << endl;
            if (isitq)  ofFileStream << chrgv << endl;
            if (isitp)  ofFileStream << phiv  << endl;
            if (isiti)  ofFileStream << phii  << endl;
            if (isitr)  ofFileStream << phir  << endl;
            if (isitc)  ofFileStream << phic  << endl;
            if (isitap) ofFileStream << aphi  << endl;
            if (isitf)  ofFileStream << fxyz  << endl;
            if (isitrf) ofFileStream << rxyz  << endl;
            if (isitcf) ofFileStream << cxyz  << endl;
            if (isittf) { vtemp = rxyz + cxyz; ofFileStream << vtemp << endl;}
         }

      } while(true); // end of the big loop on natom
   }

   if (isitsf)
   {
      for (integer jj = 0; jj < iBndyGridNum; jj++)
      {
         integer i = prgiAtSurf[jj];

         if (atmsf[i-1] && (0 < prgiAtNdx[jj]))
         {
            /*
             * if the bgp belongs to the interesting site
             * attention: using always radprb(1), in some case might be inappropriate
             */
            xo = prgfgSurfCrgA[jj]+rgfProbeRadius[0]*prgfgSurfCrgE[jj];
            xn = (xo-fgBoxCenter)*fScale+goff;

            xn.nX += 1.0;               fu.nX = interpl(iGrid,phimap,xn);
            xn.nX -= 2.0;               fu.nX = interpl(iGrid,phimap,xn);
            xn.nX += 1.0; xn.nY += 1.0; fu.nY = interpl(iGrid,phimap,xn);
            xn.nY -= 2.0;               fu.nY = interpl(iGrid,phimap,xn);
            xn.nY += 1.0; xn.nZ += 1.0; fu.nZ = interpl(iGrid,phimap,xn);
            xn.nZ -= 2.0;               fu.nZ = interpl(iGrid,phimap,xn);
            xn.nZ += 1.0;

            fxyz = fl - fu;
            fn   = 0.5*fScale*(optDot(fxyz,prgfgSurfCrgE[jj]));
            ff   = 0.5*fScale*(optDot(fxyz,fxyz));

            if (ofrm)
            {
               jtmp = j;

               sprintf(otemp,"%10.4f",prgfSurfCrgE[jj]); oline.replace(jtmp,10,otemp); jtmp += 10;
               sprintf(otemp,"%10.4f",xo.nX);            oline.replace(jtmp,10,otemp); jtmp += 10;
               sprintf(otemp,"%10.4f",xo.nY);            oline.replace(jtmp,10,otemp); jtmp += 10;
               sprintf(otemp,"%10.4f",xo.nZ);            oline.replace(jtmp,10,otemp); jtmp += 10;
               sprintf(otemp,"%10.4f",fn);               oline.replace(jtmp,10,otemp); jtmp += 10;
               sprintf(otemp,"%10.4f",ff);               oline.replace(jtmp,10,otemp); jtmp += 10;

               ofFileStream << oline << endl;
            }

            if (!ofrm)  ofFileStream << prgfSurfCrgE[jj] << " " << fn << endl;
         }
      }
   }

   if(!iself) ifFileStream.close();

#ifdef VERBOSE
   cout << "\n number of atom coordinates read : " << nnatom << endl << endl;
#endif

   etot = etot/2.0;

   if (ofrm)
   {
      if (0 == iFrcFormatOut)
      {
         ofFileStream << "total energy = " << etot << " kt\n";
         if (isitr)  ofFileStream << "corrected reaction field energy= " << phirt/2.0 << " kt\n";
         if (isitap) ofFileStream << "Atomic potential for charged atoms is averaged over a spherical surface of less than "
                                  << fPotentialUpperBond << " A\n";
      }

      if (1 == iFrcFormatOut)
      {
         ofFileStream << "corrected reaction field energy= " << phirt/2.0 << " kt\n";
         ofFileStream << "total coulombic energy     = " << phict/2.0 << " kt\n";
         if (isitap) ofFileStream << "Atomic potential for charged atoms is averaged over a spherical surface of less than "
                                  << fPotentialUpperBond << " A\n";
      }

      if (2 == iFrcFormatOut)
      {
         ofFileStream << "corrected reaction field energy= " << phirt/2.0 << " kt\n";
         if (isitap) ofFileStream << "Atomic potential for charged atoms is averaged over a spherical surface of less than "
                                  << fPotentialUpperBond << " A\n";
      }
   }

   /*
    * end of formatted frc read/write and unformatted frc write
    * end of unformatted frc.pdb read and frc write
    */
   if (ofFileStream.is_open()) ofFileStream.close();

#ifdef VERBOSE
   cout << "frc stuff now done at "; pTimer->showTime(); cout << endl;
#endif
}
Пример #7
0
int main(void) {
  char in[BUFF_SIZE], out[BUFF_SIZE];
  register ssize_t wsz = 0, rsz, trsz; /* written bytes, read bytes and total processed bytes */
  for (;;) {
    trsz = 0;
    while ((INPUT - trsz) && (rsz = read(0, in + trsz, INPUT - trsz)) > 0) trsz += rsz;
    /*printf("%ld chars read\n", rsz);*/
    register char* f = in;
    register pile* prev = 0;
    register pile* p;
    register pile* last;
    p = deck;
    for (p = deck;; ++p) {
      /*
      c = fgetc(stdin);
      v = fgetc(stdin);
      */
      c = *f++;
      if (c == '#') goto end;
      v = *f++;
      /*
      fgetc(stdin);
      */
      f++;
      reset(&p->cards);
      push(&p->cards, c, v);
      p->prev = prev;
      if (prev) prev->next = p;
      prev = p;
      if (p == &deck[51]) break;
    }
    p->next = 0;
    p = deck;
    last = 0;
    while (p) {
      pile* m = 0;
      pile* p3 = p;
      if ((p3 = p->prev) && (p3 = p3->prev) && (p3 = p3->prev)) {
        if (topv(&p3->cards) == topv(&p->cards) || tops(&p3->cards) == tops(&p->cards)) {
          m = p3;
        }
      }
      pile* p1 = 0;
      if (!m && (p1 = p->prev)) {
        if (topv(&p1->cards) == topv(&p->cards) || tops(&p1->cards) == tops(&p->cards)) {
          m = p1;
        }
      }
      if (m) {
        push(&m->cards, topv(&p->cards), tops(&p->cards));
        pop(&p->cards);
        if (!size(&p->cards)) {
          p->prev->next = p->next;
          if (p->next) p->next->prev = p->prev;
        }
        p = m;
      } else {
        last = p;
        p = p->next;
      }
    }
    int sz = 1;
    p = last;
    while (p->prev) {
      ++sz;
      p = p->prev;
    }

    if (sz > 9)
      out[wsz++] = sz / 10 + '0';
    out[wsz++] = sz % 10 + '0';
    out[wsz++] = ' ';
    register const char* of;
    if (sz == 1)
      of = str_p1;
    else
      of = str_p2;
    while (*of) out[wsz++] = *of++;
    out[wsz++] = ' ';
    of = str_r;
    while (*of) out[wsz++] = *of++;

    /*
     * above is equal to this
    printf("%d %s %s", sz, (sz == 1) ? str_p1 : str_p2, str_r);
    */

    while (p) {
      sz = size(&p->cards);
      out[wsz++] = ' ';
      if (sz > 9)
        out[wsz++] = sz / 10 + '0';
      out[wsz++] = sz % 10 + '0';
      p = p->next;
    }
    out[wsz++] = '\n';
    /*
     * above is equal to this
    while (p) {
      printf(" %d", size(&p->cards));
      p = p->next;
    }
    printf("\n");
    */
  }
end:
  trsz = 0;
  while ((trsz = write(1, out, wsz - trsz)) > 0);
  return 0;
}