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); } }
/*----------------------------------------------------------------------------*/ 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; }
/* * 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); } }
/*----------------------------------------------------------------------------*/ 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; }
/*----------------------------------------------------------------------------*/ 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; }
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:; }}} }
/* * 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); }
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; } }
/*----------------------------------------------------------------------------*/ 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; }
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); } }
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; }
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; }
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); } } }
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; } } }
/*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); }