void ZobristHashing::ExecuteMove(const Move& move) { if (move.HasUsedCell()) { // This move potentially shifts the TopLeft in our relative field // Trying to figure the new hash based on that move is complex // Rebasing the hash is faster _hash = RecaclulateHash(); return; } int positionTo = GetCellPosition(move.GetToCell()); int positionFrom = GetCellPosition(move.GetFromCell()); switch (move.GetMoveType()) { case INSERT: // Remove empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionTo]; // Insert tile with player _hash ^= _hashValues[HasTile | GetDataForPlayer(move.GetToCell())][positionTo]; break; case STEP: { int toCellData = GetCellData(move.GetToCell()); // FROM // Remove tile with player _hash ^= _hashValues[toCellData][positionFrom]; // Insert empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionFrom]; // TO // Remove empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionTo]; // Insert tile with player _hash ^= _hashValues[toCellData][positionTo]; break; } case JUMP: { int toCellData = GetCellData(move.GetToCell()); // FROM // Remove tile with player (xor flipped as the board state has already been updated!) _hash ^= _hashValues[toCellData ^ IsFlipped][positionFrom]; // Insert empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionFrom]; // TO // Remove empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionTo]; // Insert tile with player _hash ^= _hashValues[toCellData][positionTo]; break; } } }
void ZobristHashing::UndoMove(const Move& move, Players player) { if (move.HasUsedCell()) { // This move potentially shifts the TopLeft in our relative field // Trying to figure the new hash based on that move is complex // Rebasing the hash is faster _hash = RecaclulateHash(); return; } int playerValue = (player == Max) ? IsMax : 0; int positionTo = GetCellPosition(move.GetToCell()); int positionFrom = GetCellPosition(move.GetFromCell()); switch (move.GetMoveType()) { case INSERT: // Remove the player with tile _hash ^= _hashValues[HasTile | playerValue][positionTo]; // Insert empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionTo]; break; case STEP: { int cellData = GetCellData(move.GetFromCell()); // FROM // Remove empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionFrom]; // Insert player _hash ^= _hashValues[cellData][positionFrom]; // TO // Remove player _hash ^= _hashValues[cellData][positionTo]; // Insert empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionTo]; break; } case JUMP: { int cellData = GetCellData(move.GetFromCell()); // FROM // Remove empty tile _hash ^= _hashValues[HasTile | IsEmpty][positionFrom]; // Insert player _hash ^= _hashValues[cellData ^ IsFlipped][positionFrom]; // TO // Remove player _hash ^= _hashValues[cellData][positionTo]; // Insert player _hash ^= _hashValues[HasTile | IsEmpty][positionTo]; break; } } }
void CGame::Prepare (void) { mScore = 0; mGameBoard->Fill(); mArtifacts.Resize (sGridColCount, sGridRowCount); for (int x = 0; x < sGridColCount; x++) { for (int y = 0; y < sGridRowCount; y++) { int type = mGameBoard->Get (x,y); SDL_Point thePos = GetCellPosition ({ x, y }); CArtifactPtr artifact = std::make_shared<CArtifact> (mStage, mArtifactTextures[type]); artifact->SetPosition (thePos); artifact->SetClip (&mClipRect); mArtifacts.Set (x, y, artifact); mStage->AddDrawable (artifact); } } if (mGameBoard->RemoveCombinations (mRemovedEntries)) StartExplode(); StartDropping(); ShowAlert ("Press N to start"); }
BOOL cScrollIconGridDialog::GetPositionForXYRef(LONG mouseX, LONG mouseY, WORD& pos) { WORD x,y; BOOL rt = GetCellPosition(mouseX, mouseY, x, y); pos = y*m_nCol+x; //tmp) pos = GetPositionForCell(x,y); return rt; }
void CGame::StartSwap (SDL_Point inPt1, SDL_Point inPt2, bool inCanceling) { mDisableInputCount++; mIsSwapping = true; mIsCanceling = inCanceling; const Uint32 ticks = SDL_GetTicks(); mSwapEndTicks = ticks + sSwapDuration; mArtifact1 = mArtifacts.Get (mSelectedCell1); mArtifact2 = mArtifacts.Get (mSelectedCell2); if (mArtifact1) mArtifact1->StartMoveTo (GetCellPosition(mSelectedCell2), ticks, mSwapEndTicks); if (mArtifact2) mArtifact2->StartMoveTo (GetCellPosition(mSelectedCell1), ticks, mSwapEndTicks); }
void CGame::StartDropping (void) { std::vector<int> dropInfo; if (mGameBoard->GetDropInfo (dropInfo)) // gets for each column the lowest empty y-coordinate, or -1 if column is full { mDisableInputCount++; mIsDropping = true; const Uint32 ticks = SDL_GetTicks(); mDropEndTicks = ticks + sDropDuration; for (int x = 0; x < (int)dropInfo.size(); x++) { if (dropInfo[x] >= 0) // do we have an empty cell? { for (int y = dropInfo[x] - 1; y >= 0; y--) // start with the lower one { mGameBoard->Swap ({ x, y }, { x, y + 1 }); CArtifactPtr artifact = mArtifacts.Get (x, y); if (artifact) artifact->StartMoveTo (GetCellPosition ({ x, y + 1 }), ticks, mDropEndTicks); mArtifacts.Set (x, y + 1, artifact); mArtifacts.Set (x, y, nullptr); } SDL_Point topCell = { x, 0 }; int type = mGameBoard->SetRandom (topCell); SDL_Point thePos = GetCellPosition ({ x, -1 }); // get the position above the top cell CArtifactPtr artifact = std::make_shared<CArtifact> (mStage, mArtifactTextures[type]); artifact->SetPosition (thePos); artifact->SetClip (&mClipRect); mArtifacts.Set (topCell, artifact); mStage->AddDrawable (artifact); artifact->StartMoveTo (GetCellPosition (topCell), ticks, mDropEndTicks); } } } }
long long ZobristHashing::RecaclulateHash() { long long hash = 0; for (int x = 0; x < 20; ++x) { for (int y = 0; y < 20; ++y) { const Vector2D position = Vector2D(x, y); int cellData = GetCellData(position); if (cellData == 0) { // This cell is completely empty continue; } hash ^= _hashValues[cellData][GetCellPosition(Vector2D(x, y))]; } } return hash; }