예제 #1
0
파일: Board.cpp 프로젝트: alanjg/Chess
	void Board::MakePromotionMove(int move, int source, int destination, int oldPiece)
	{
		int promoType = GetPromoFromMove(move);
		if (promoType != PieceTypes::None)
		{
			RemovePiece(destination, oldPiece);
			int newPiece = Pieces::GetPiece(promoType, turn);
			AddPiece(destination, newPiece);

			ulong oldKey = TranspositionTable::GetPositionKey(destination, oldPiece);
			ulong newKey = TranspositionTable::GetPositionKey(destination, newPiece);
			
			zobristKey ^= oldKey;
			zobristKey ^= newKey;			
			pawnZobristKey ^= oldKey;
			
			positionalScore -= Evaluation::PieceSquareValue(oldPiece, destination);
			positionalScore += Evaluation::PieceSquareValue(newPiece, destination);
			
			endgamePositionalScore -= Evaluation::EndgamePieceSquareValue(oldPiece, destination);
			endgamePositionalScore += Evaluation::EndgamePieceSquareValue(newPiece, destination);
			
			materialScore -= Evaluation::PieceValue(oldPiece);
			materialScore += Evaluation::PieceValue(newPiece);
		}
	}
예제 #2
0
/*----------------------------------------------------------------------------*/
int MovePieceDown(struct GameData* pGameData)
{
	RemovePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);	// remove from old position

	if (!PlacePiece(pGameData, pGameData->m_FallingRow+1, pGameData->m_FallingCol))	// try to place in new position
	{		
		PlacePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);	// else restore old position
		pGameData->m_FallingRow = -1;
		return 0;
	}
	pGameData->m_FallingRow = (pGameData->m_FallingRow+1)%pGameData->m_Height;
	return 1;
}
예제 #3
0
파일: AsciiSrc.c 프로젝트: idunham/tinyxlib
/*
 * Function:
 *	FreeAllPieces
 *
 * Parameters:
 *	src - AsciiSrc Widget
 *
 * Description:
 *	Frees all the pieces.
 */
static void
FreeAllPieces(AsciiSrcObject src)
{
    Piece *next, * first = src->ascii_src.first_piece;

#ifdef DEBUG
    if (first->prev != NULL)
	printf("Xaw AsciiSrc Object: possible memory leak in FreeAllPieces().\n");
#endif

    for (; first != NULL ; first = next) {
	next = first->next;
	RemovePiece(src, first);
    }
}
예제 #4
0
/*----------------------------------------------------------------------------*/
int GameRight(struct GameData* pGameData)
{
	if (pGameData->m_FallingRow >= 0)
	{
		RemovePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);	// remove from old position

		if (!PlacePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol+1))	// try to place in new position
		{		
			PlacePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);	// else restore old position
			return 0;
		}
		pGameData->m_MoveCount++;
		pGameData->m_FallingCol++;
		return 1;
	}
	return 0;
}
예제 #5
0
/*----------------------------------------------------------------------------*/
int AddRows(struct GameData* pGameData, int nRows)
{
	int i,r,c;
	for (i=0; i<nRows; i++)
	{
		// is the top row free?
		if (pGameData->m_FallingRow >= 0)
			RemovePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);
		for (c=0; c<pGameData->m_Base; c++)
		{
			if (pGameData->m_Grid[0][c]) 
			{
				return 0;
			}
		}
		// move the whole grid one up
		for (r=0; r<pGameData->m_Height-1; r++)
			for (c=0; c<pGameData->m_Base; c++)
				pGameData->m_Grid[r][c] = pGameData->m_Grid[r+1][c];
		// add random pieces to the bottom
		for (c=0; c<pGameData->m_Base; c++)
			pGameData->m_Grid[pGameData->m_Height-1][c] = rand()%pGameData->m_MaxPieces+1;
		// add about 30% spaces to the rows
		pGameData->m_Grid[pGameData->m_Height-1][rand()%pGameData->m_Base] = 0;
		for (c=0; c<pGameData->m_Base; c++)
			if (rand()%10 < 3)
				pGameData->m_Grid[pGameData->m_Height-1][rand()%pGameData->m_Base] = 0;
		// take care of the falling piece
		if (pGameData->m_FallingRow > 0)
		{
			pGameData->m_FallingRow--;
			GameStep(pGameData);
		}
		if (pGameData->m_FallingRow == 0)
		{
			if (!PlacePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol))	// try to place
			{
				pGameData->m_GameOver = 1;
				pGameData->m_FallingRow = -1;
				return 0;
			}
		}
	}
	return 1;
}
예제 #6
0
void Construct(Cube space,Piece p[8],int p_num){
  int x,y,z,rxy,rz;
  int next_p_num;
  int existing,i;
 
  for(z=1;z<=3;z++){for(y=1;y<=3;y++){for(x=1;x<=3;x++){
 
	for(rxy=0;rxy<6;rxy++){
	  for(rz=0;rz<4;rz++){
 
	    if(Judge(space,p,p_num,x,y,z)==1){
	      space=PutPiece(space,p,p_num,x,y,z);
	      printf("[[%d]] (%d,%d,%d)\n\n",p_num,x,y,z);
	      ShowSpace(space);
 
	      if(p_num<PIECENUM){
		if(ImpossibleBreak(space)==0){
		  next_p_num=p_num+1;
		  Construct(space,p,next_p_num);
		}
	      }else{ //completed
		existing=0;i=0;
		while(i<=ansnum&&existing==0){
		  if(CompareCube(space,ans[i])==1){existing=1;}
		  i++;
		}
		if(existing==0){ansnum++;ans[ansnum]=space;}
	      }
 
	      space=RemovePiece(space,p_num);
	      if(p_num==PIECENUM){goto noRotation;}
	    }
	    if(p_num==1){goto noRotation;}
 
	    p[p_num]=Rotate(p[p_num],2,0,1); //rotate z
	  }
	  if(rxy<=3){p[p_num]=Rotate(p[p_num],1,2,0);} //rotate x
	  else if(rxy==4){p[p_num]=Rotate(p[p_num],0,1,2);} //rotate y
	  else if(rxy==5){p[p_num]=Rotate(p[p_num],0,1,2);
	    p[p_num]=Rotate(p[p_num],0,1,2);}
	}
      noRotation:;
      }}}
}
예제 #7
0
파일: AsciiSrc.c 프로젝트: idunham/tinyxlib
/*
 * Function:
 *	WritePiecesToFile
 *
 * Parameters:
 *	src  - ascii source object
 *	name - name of the file
 *
 * Description:
 *	  Almost identical to WriteToFile, but only works for ascii src objects
 *	of type XawAsciiFile. This function avoids allocating temporary memory,
 *	what can be useful when editing very large files.
 *
 * Returns:
 *	returns True if sucessful, False otherwise
 */
static Bool
WritePiecesToFile(AsciiSrcObject src, String name)
{
    Piece *piece;
    int fd;

    if (src->ascii_src.data_compression) {
	Piece *tmp;

	piece = src->ascii_src.first_piece;
	while (piece) {
	    int bytes = src->ascii_src.piece_size - piece->used;

	    if (bytes > 0 && (tmp = piece->next) != NULL) {
		bytes = XawMin(bytes, tmp->used);
		memcpy(piece->text + piece->used, tmp->text, bytes);
		memmove(tmp->text, tmp->text + bytes, tmp->used - bytes);
		piece->used += bytes;
		if ((tmp->used -= bytes) == 0) {
		    RemovePiece(src, tmp);
		    continue;
		}
	    }
	    piece = piece->next;
	}
    }

    if ((fd = creat(name, 0666)) == -1)
	return (False);

    for (piece = src->ascii_src.first_piece; piece; piece = piece->next)
	if (write(fd, piece->text, piece->used) == -1)
	    return (False);

    if (close(fd) == -1)
	return (False);

    return (True);
}
예제 #8
0
파일: Board.cpp 프로젝트: alanjg/Chess
	void Board::MakeCaptureMove(int destination, int destPiece)
	{
		if(destPiece != Pieces::None)
		{
			RemovePiece(destination, destPiece);
			capturedPiece = Pieces::GetPieceTypeFromPiece(destPiece);
				
			ulong oldKey = TranspositionTable::GetPositionKey(destination, destPiece);
			zobristKey ^= oldKey;
			if (capturedPiece == PieceTypes::Pawn)
			{
				pawnZobristKey ^= oldKey;
			}
			materialScore -= Evaluation::PieceValue(destPiece);
			positionalScore -= Evaluation::PieceSquareValue(destPiece, destination);
			endgamePositionalScore -= Evaluation::EndgamePieceSquareValue(destPiece, destination);
			drawMoveCount = 0;
		}
		else
		{
			capturedPiece = PieceTypes::None;
		}
	}
예제 #9
0
/*----------------------------------------------------------------------------*/
int GameRotate(struct GameData* pGameData)
{
	unsigned long oldPosition;

	if (pGameData->m_FallingRow >= 0)
	{
		RemovePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);	// remove from old position
		oldPosition = pGameData->m_FallingPiece;
		pGameData->m_BlkRot = (pGameData->m_BlkRot+1)%4;					// rotate anti-clockwise
		pGameData->m_FallingPiece = pGameData->m_Shapes[pGameData->m_BlkNum][pGameData->m_BlkRot];

		if (!PlacePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol))// try to place in new position
		{	
			pGameData->m_BlkRot = (pGameData->m_BlkRot+3)%4;					// rotate anti-clockwise
			pGameData->m_FallingPiece = oldPosition;
			PlacePiece(pGameData, pGameData->m_FallingRow, pGameData->m_FallingCol);	// else restore old position
			return 0;
		}
		pGameData->m_MoveCount++;
		return 1;
	}
	return 0;
}
예제 #10
0
파일: Board.cpp 프로젝트: alanjg/Chess
	void Board::MakeEnPassantMove(bool isPawnMove, int source, int destination)
	{
		if (isPawnMove && enPassantRights.CaptureSquare() == destination)
		{
			int enPassantSquare = enPassantRights.PawnSquare();
			int otherPawn = Pieces::GetPiece(PieceTypes::Pawn, OtherColor(turn));
			RemovePiece(enPassantSquare, otherPawn);
			ulong oldKey = TranspositionTable::GetPositionKey(enPassantSquare, otherPawn);
			
			zobristKey ^= oldKey;
			pawnZobristKey ^= oldKey;
			
			materialScore -= Evaluation::PieceValue(otherPawn);
			positionalScore -= Evaluation::PieceSquareValue(otherPawn, enPassantSquare);
			endgamePositionalScore -= Evaluation::EndgamePieceSquareValue(otherPawn, enPassantSquare);
			
			capturedPiece = PieceTypes::Pawn;
		}		

		EnPassantRights newEnPassantRights = EnPassantRights::NoEnPassant;
		// Update en passant rights
		if (isPawnMove)
		{
			int delta = source - destination;
			if(delta == 16 || delta == -16)
			{
				newEnPassantRights = EnPassantRights((source + destination) / 2);
			}
		}

		if(enPassantRights.GetRights() != newEnPassantRights.GetRights())
		{
			zobristKey ^= TranspositionTable::GetEnPassantKey(enPassantRights);
			enPassantRights = newEnPassantRights;
			zobristKey ^= TranspositionTable::GetEnPassantKey(enPassantRights);
		}
	}
예제 #11
0
파일: Board.cpp 프로젝트: alanjg/Chess
	ulong Board::GetSafeKingMoves(int color)
	{
		ulong safeMoves = 0;	
		int kingSquare = GetKingSquare(color);
		ulong moves = MoveGenerator::kingAttacks[kingSquare];
		ulong newMoves = moves & (~colorBitBoards[color]);
		moves = newMoves;
		if(moves != 0)
		{
			RemovePiece(kingSquare, Pieces::GetPiece(PieceTypes::King, color));
		
			while(moves != 0)
			{
				int move = PopLowestSetBit(moves);
				if(!IsSquareAttacked(move, OtherColor(color)))
				{
					safeMoves |= BitBoard(move);
				}
			}
			AddPiece(kingSquare, Pieces::GetPiece(PieceTypes::King, color));
		}

		return safeMoves; 
	}
예제 #12
0
파일: Board.cpp 프로젝트: alanjg/Chess
	void Board::UndoMove(int move, bool updateDrawState, const BoardState& undoState)
	{
		updateDrawState = true;
		isInCheck = undoState.isInCheck;
		castleRights = undoState.castleRights;
		enPassantRights = undoState.enPassantRights;
		drawMoveCount = undoState.drawMoveCount;
		materialScore = undoState.materialScore;
		positionalScore = undoState.positionalScore;
		endgamePositionalScore = undoState.endgamePositionalScore;

		if (move != NullMove)
		{
			turnsPlayed--;
			UndoMoveDrawState(updateDrawState);

			int source = GetSourceFromMove(move);
			int dest = GetDestFromMove(move);
			int piece = GetPiece(dest);

			MovePiece(dest, source, piece);
			
			if (GetPromoFromMove(move) != PieceTypes::None)
			{
				RemovePiece(source, piece);
				int oldPiece = Pieces::GetPiece(PieceTypes::Pawn, OtherColor(turn));
				AddPiece(source, oldPiece);
			}

			if (capturedPiece != PieceTypes::None)
			{
				int capture = Pieces::GetPiece(capturedPiece, turn);
				// was this an en passant capture? 
				if (enPassantRights.HasEnPassant() && dest == enPassantRights.CaptureSquare() && Pieces::GetPieceTypeFromPiece(piece) == PieceTypes::Pawn)
				{
					AddPiece(enPassantRights.PawnSquare(), capture);
				}
				else
				{
					AddPiece(dest, capture);
				}
			}

			// if this was a castle move, restore the rook
			if (Pieces::GetPieceTypeFromPiece(piece) == PieceTypes::King)
			{
				int delta = dest - source;
				if(delta == 2 || delta == -2)
				{
					int rookOrigin = dest + delta / 2;
					if(delta < 0)
					{
						rookOrigin--;
					}
					int rookDestination = dest - delta / 2;
					int rook = Pieces::GetPiece(PieceTypes::Rook, OtherColor(turn));
					MovePiece(rookDestination, rookOrigin, rook);
				}
			}

			capturedPiece = undoState.capturedPiece;
		}

		turn = OtherColor(turn);
		zobristKey = undoState.zobristKey;
		pawnZobristKey = undoState.pawnZobristKey;
	}
예제 #13
0
void UpdateStates(const tMove *OpponentMove)
{
	// --- Get moved piece, update position ---
	tPiece	*moved_piece = GetPieceByPos(OpponentMove->x, OpponentMove->y);
	// - Sanity
	ASSERT( moved_piece );
	ASSERT( moved_piece->Team == !gMyColour );
	// - Only scouts can move multiple squares
	if( moved_piece->Rank == RANK_UNKNOWN && OpponentMove->dist > 1 )
		UpdateRank(moved_piece, '9');
	// - Update position
	 int newx = moved_piece->X, newy = moved_piece->Y;
	switch(OpponentMove->dir)
	{
	case DIR_INVAL:	break;
	case DIR_LEFT:	newx -= OpponentMove->dist;	break;
	case DIR_RIGHT:	newx += OpponentMove->dist;	break;
	case DIR_UP:	newy -= OpponentMove->dist;	break;
	case DIR_DOWN:	newy += OpponentMove->dist;	break;
	}
	tPiece	*my_piece = GetPieceByPos(newx, newy);
	
	// Check if one of my pieces has been taken
	switch( OpponentMove->result )
	{
	case RESULT_ILLEGAL:	break;
	case RESULT_INVAL:	break;
	case RESULT_OK:
		MovePieceTo(moved_piece, newx, newy);
		break;
	case RESULT_KILL:
	case RESULT_VICTORY:
		UpdateRank(moved_piece, OpponentMove->attacker);
		PieceExposed(my_piece);
		RemovePiece(my_piece);
		MovePieceTo(moved_piece, newx, newy);
		break;
	case RESULT_DIES:
		UpdateRank(moved_piece, OpponentMove->attacker);
		PieceExposed(my_piece);
		RemovePiece(moved_piece);
		break;
	case RESULT_BOTHDIE:
		UpdateRank(moved_piece, OpponentMove->attacker);
		RemovePiece(moved_piece);
		PieceExposed(my_piece);
		RemovePiece(my_piece);
		break;
	}

	// Update rank if revealed
	if( moved_piece->Rank == RANK_UNKNOWN )
		UpdateRank(moved_piece, gaBoardState[moved_piece->Y*giBoardWidth+moved_piece->X]);

	// - Update piece states
	DEBUG("Updating piece states");
	for( int y = 0; y < giBoardHeight; y ++ )
	{
		for( int x = 0; x < giBoardWidth; x ++ )
		{
			char	c = gaBoardState[y*giBoardWidth+x];
			if( c == '.' )	continue;
			if( c == '+' )	continue;
			tPiece *p = GetPieceByPos(x, y);
			if(!p) DEBUG("c = %c", c);
			ASSERT(p);
			if( p->Team == gMyColour )	continue ;
			if( p->Rank == RANK_UNKNOWN && c != '#' )
				UpdateRank(p, c);
		}
	}
}
예제 #14
0
void AI_HandleMove(int bMyMove, const tMove *Move)
{
	if( gbFirstTurn )
	{
		gbFirstTurn = false;
		
		AI_int_InitialiseBoardState();

		// Reverse the first move
		if( Move->dir != DIR_INVAL )
		{
			tPiece	*p;
			switch(Move->dir)
			{
			case DIR_INVAL:	ASSERT(Move->dir != DIR_INVAL);	break;
			case DIR_LEFT:	p = GetPieceByPos( Move->x-1, Move->y );	break ;
			case DIR_RIGHT:	p = GetPieceByPos( Move->x+1, Move->y );	break ;
			case DIR_UP:	p = GetPieceByPos( Move->x, Move->y-1 );	break ;
			case DIR_DOWN:	p = GetPieceByPos( Move->x, Move->y+1 );	break ;
			}
			MovePieceTo( p, Move->x, Move->y );
			p->StartX = Move->x;
			p->StartY = Move->y;
		}
	}

	if(Move->result == RESULT_VICTORY)
	{
		// TODO: Distiguish between victory conditions?
		// - Note flag location?

		// TODO: Save back initial board state
		DB_WriteBackInitialState(gsOpponentDbFilename, !gMyColour, gpCurrentGameState->Opponent.Pieces);
	}

	if( !bMyMove )
	{
		if( Move->dir != DIR_INVAL )
			UpdateStates(Move);
	}
	else
	{
		tPiece	*p = GetPieceByPos(Move->x, Move->y);
		ASSERT(p);

	 	int newx = p->X, newy = p->Y;
		switch(Move->dir)
		{
		case DIR_INVAL:	break;
		case DIR_LEFT:	newx -= Move->dist;	break;
		case DIR_RIGHT:	newx += Move->dist;	break;
		case DIR_UP:	newy -= Move->dist;	break;
		case DIR_DOWN:	newy += Move->dist;	break;
		}
		tPiece	*target = GetPieceByPos(newx, newy);

		switch(Move->result)
		{
		case RESULT_ILLEGAL:	break;
		case RESULT_INVAL:	break;
		case RESULT_OK:
			MovePieceTo(p, newx, newy);
			break;
		case RESULT_KILL:
			UpdateRank(target, Move->defender);
			RemovePiece(target);
			MovePieceTo(p, newx, newy);
			PieceExposed(p);	// TODO: Update oponent's view
			giTurnsSinceLastTake = 0;
			break;
		case RESULT_DIES:
		case RESULT_VICTORY:
			UpdateRank(target, Move->defender);
			PieceExposed(p);
			RemovePiece(p);
			giTurnsSinceLastTake = 0;
			break;
		case RESULT_BOTHDIE:
			UpdateRank(target, Move->defender);
			PieceExposed(p);
			RemovePiece(p);
			RemovePiece(target);
			giTurnsSinceLastTake = 0;
			break;
		}
	}
}
예제 #15
0
파일: AsciiSrc.c 프로젝트: idunham/tinyxlib
/*ARGSUSED*/
static int
ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos,
	    XawTextBlock *text)
{
    AsciiSrcObject src = (AsciiSrcObject)w;
    Piece *start_piece, *end_piece, *temp_piece;
    XawTextPosition start_first, end_first;
    int length, firstPos;

    /*
     * Editing a read only source is not allowed
     */
    if (src->text_src.edit_mode == XawtextRead) 
	return (XawEditError);

    start_piece = FindPiece(src, startPos, &start_first);
    end_piece = FindPiece(src, endPos, &end_first);

#ifndef OLDXAW
    /*
     * This is a big hack, but I can't think about a clever way to know
     * if the character being moved forward has a negative lbearing.
     *
     */
    if (start_piece->used) {
	int i;

	for (i = 0; i < src->text_src.num_text; i++) {
	    int line;
	    TextWidget ctx = (TextWidget)src->text_src.text[i];

	    for (line = 0; line < ctx->text.lt.lines; line++)
		if (startPos < ctx->text.lt.info[line + 1].position)
		    break;
	    if (i < ctx->text.lt.lines &&
		startPos > ctx->text.lt.info[i].position) {
		AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
		XawTextAnchor *anchor;
		XawTextEntity *entity;
		XawTextProperty *property;
		XFontStruct *font;

		if (XawTextSourceAnchorAndEntity(w, startPos, &anchor, &entity) &&
		    (property = XawTextSinkGetProperty(ctx->text.sink,
						       entity->property)) != NULL &&
		    (property->mask & XAW_TPROP_FONT))
		    font = property->font;
		else
		    font = sink->ascii_sink.font;

		if (font->min_bounds.lbearing < 0) {
		    int lbearing = font->min_bounds.lbearing;
		    unsigned char c = *(unsigned char*)
			(start_piece->text + (startPos - start_first));

		    if (c == '\t' || c == '\n')
			c = ' ';
		    else if ((c & 0177) < XawSP || c == 0177) {
			if (sink->ascii_sink.display_nonprinting)
			    c = c > 0177 ? '\\' : c + '^';
			else
			    c = ' ';
		    }
		    if (font->per_char &&
			(c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
			lbearing = font->per_char[c - font->min_char_or_byte2].lbearing;
		    if (lbearing < 0)
			_XawTextNeedsUpdating(ctx, startPos - 1, startPos);
		}
	    }
	}
    }


#endif

    /*
     * Remove Old Stuff
     */
    if (start_piece != end_piece) {
	temp_piece = start_piece->next;

	/*
	 * If empty and not the only piece then remove it.
	 */
	if (((start_piece->used = startPos - start_first) == 0)
	    && !(start_piece->next == NULL && start_piece->prev == NULL))
	    RemovePiece(src, start_piece);

	while (temp_piece != end_piece) {
	    temp_piece = temp_piece->next;
	    RemovePiece(src, temp_piece->prev);
	}

	end_piece->used -= endPos - end_first;
	if (end_piece->used != 0)
	    memmove(end_piece->text, end_piece->text + endPos - end_first,
		    (unsigned)end_piece->used);
    }
    else {		    /* We are fully in one piece */
	if ((start_piece->used -= endPos - startPos) == 0) {
	    if (!(start_piece->next == NULL && start_piece->prev == NULL))
		RemovePiece(src, start_piece);
	}
	else {
	    memmove(start_piece->text + (startPos - start_first),
		    start_piece->text + (endPos - start_first),
		    (unsigned)(start_piece->used - (startPos - start_first)));
	    if (src->ascii_src.use_string_in_place
		&& src->ascii_src.length - (endPos - startPos)
		< src->ascii_src.piece_size - 1)
		start_piece->text[src->ascii_src.length - (endPos - startPos)] =
		    '\0';
	}
    }

    src->ascii_src.length += -(endPos - startPos) + text->length;

    if ( text->length != 0) {
	/* 
	 * Put in the New Stuff
	 */
	start_piece = FindPiece(src, startPos, &start_first);

	length = text->length;
	firstPos = text->firstPos;

	while (length > 0) {
	    char *ptr;
	    int fill;

	    if (src->ascii_src.use_string_in_place) {
		if (start_piece->used == src->ascii_src.piece_size - 1) {
		    /*
		     * If we are in ascii string emulation mode. Then the
		     *	string is not allowed to grow
		     */
		    start_piece->used = src->ascii_src.length =
			src->ascii_src.piece_size - 1;
		    start_piece->text[src->ascii_src.length] = '\0';
		    return (XawEditError);
		}
	    }

	    if (start_piece->used == src->ascii_src.piece_size) {
		BreakPiece(src, start_piece);
		start_piece = FindPiece(src, startPos, &start_first);
	    }

	    fill = Min((int)(src->ascii_src.piece_size - start_piece->used),
		       length);

	    ptr = start_piece->text + (startPos - start_first);
	    memmove(ptr + fill, ptr,
		    (unsigned)(start_piece->used - (startPos - start_first)));
	    memcpy(ptr, text->ptr + firstPos, (unsigned)fill);

	    startPos += fill;
	    firstPos += fill;
	    start_piece->used += fill;
	    length -= fill;
	}
    }

    if (src->ascii_src.use_string_in_place)
	start_piece->text[start_piece->used] = '\0';

#ifdef OLDXAW
    src->ascii_src.changes = True;
    XtCallCallbacks(w, XtNcallback, NULL);
#endif

    return (XawEditDone);
}