Files
2026-02-02 04:50:13 +01:00

792 lines
27 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
#include "bagel/hodjnpodj/hnplibs/sprite.h"
#include "bagel/hodjnpodj/crypt/globals.h"
#include "bagel/hodjnpodj/crypt/crypt.h"
#include "bagel/hodjnpodj/hodjnpodj.h"
#include "bagel/metaengine.h"
namespace Bagel {
namespace HodjNPodj {
namespace Crypt {
/*****************************************************************
*
* CCryptogram
*
* FUNCTIONAL DESCRIPTION:
*
* Initializes members.
*
* FORMAL PARAMETERS:
*
* None
*
* IMPLICIT INPUT PARAMETERS:
*
* None
*
* IMPLICIT OUTPUT PARAMETERS:
*
* None
*
* RETURN VALUE:
*
* None
*
****************************************************************/
CCryptogram::CCryptogram(CDC *pDC) {
m_cRecordGram = new CCryptRecord();
m_cPaintGram = new CPaintGram(pDC);
m_cStats = new CStats();
/********************************************************
* Solved switch is used to prevent further user updates *
* after cryptogram is solved. *
********************************************************/
bIsGameOver = false; // Initialize solved switch
BagelMetaEngine::setKeybindingMode(KBMODE_MINIMAL);
}
/*****************************************************************
*
* ~Cryptogram
*
* FUNCTIONAL DESCRIPTION:
*
* Destructor
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
CCryptogram::~CCryptogram() {
if (m_cStats != nullptr)
delete m_cStats;
if (m_cPaintGram != nullptr)
delete m_cPaintGram;
if (m_cRecordGram != nullptr)
delete m_cRecordGram;
BagelMetaEngine::setKeybindingMode(KBMODE_NORMAL);
}
/*****************************************************************
*
* DrawGram
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
bool CCryptogram::DrawGram(CDC *pDC) {
bIsGameOver = false;
if (m_cRecordGram->GetRecord(m_cStats->ResetGame()) == false) // Attempt to get the record
return false;
m_cPaintGram->ClearGram(pDC);
m_cPaintGram->PaintAlphabet(pDC);
CreateCryptMap(m_cStats->m_nLettersSolved);
MarkSolvedLetters(pDC);
m_cPaintGram->InitGramPosition(m_cRecordGram);
m_cPaintGram->PaintGram(pDC, m_chEncryptGram);
return true;
}
void CCryptogram::DrawSource(CDC *pDC) {
m_cPaintGram->HiLiteOff(pDC);
m_cPaintGram->PaintGram(pDC, m_cRecordGram->GetSource());
}
void CCryptogram::MarkSolvedLetters(CDC *pDC) {
int i;
for (i = 0; i < ALPHABET; i++) { // flip thru Crypt Map
if (m_nCryptMap[DECRYPT_MAP][i] == i) // Does letter rep itself?
m_cPaintGram->RevealOn( // yes - Mark char as solved
pDC,
m_cPaintGram->IndexToChar(i)
);
} // end for
}
void CCryptogram::SolveCryptogram(CDC *pDC) {
int nReplaceCode;
int nAlphaCode;
int nGramCode;
int i;
for (i = 0; i < ALPHABET; i++) { // flip thru Crypt Map
if ((m_nCryptMap[DECRYPT_MAP][i] != i) && // Any chars rep another char?
(m_nCryptMap[DECRYPT_MAP][i] != NOT_USED)) {
nAlphaCode = m_cPaintGram->IndexToChar(i); // Replace this char
nGramCode = m_cPaintGram->IndexToChar(m_nCryptMap[DECRYPT_MAP][i]);
nReplaceCode = UpdateCryptMap(nGramCode, nAlphaCode); // Update internal rep
if (nReplaceCode != NOT_USED) { // New char used in gram?
m_cPaintGram->ReplaceLetter(pDC, m_cPaintGram->GetCharType(nAlphaCode), // Yes - swap w/temp char
m_cPaintGram->SetLimboTypeOn(nReplaceCode)); // ...Temporarily set it's code to limbo
m_cPaintGram->ReplaceLetter(pDC, nGramCode, m_cPaintGram->GetCharType(nAlphaCode)); // swap old char with new char
m_cPaintGram->ReplaceLetter(pDC, m_cPaintGram->SetLimboTypeOn(nReplaceCode), // Turn all limbo types off
m_cPaintGram->SetLimboTypeOff(nReplaceCode));
} else { // New char was not used in gram...
m_cPaintGram->ReplaceLetter(pDC, nGramCode, m_cPaintGram->GetCharType(nAlphaCode)); // ...simply replace old with new.
}
m_cPaintGram->UsedOff(pDC, nGramCode); // Turn used code off on old char since it's not being used anymore
m_cPaintGram->UsedOn(pDC, nAlphaCode); // Turn used code on new char now appearing in cryptogram
} // end if
} // end for
}
/*****************************************************************
*
* HandleUserUpdate
*
* FUNCTIONAL DESCRIPTION:
*
* Processes user interaction with the displayed cryptogram.
* Will modify both internal cryptogram representation by calling
* appropriate CCryptogram members, and visual crytogram rep by
* calling CPaintGram members.
*
* FORMAL PARAMETERS:
*
* pDC - used for visual updating
* cpointClicked - place where user clicked
*
* IMPLICIT INPUT PARAMETERS:
*
* m_cPaintGram member
*
* IMPLICIT OUTPUT PARAMETERS:
*
* modifies m_cPaintGram
*
* RETURN VALUE:
*
* void
*
****************************************************************/
bool CCryptogram::HandleUserUpdate(CDC *pDC, CPoint cpointClicked) {
CSprite *pSprite;
int nClickedCode;
int nHiLiteCode;
int nReplaceCode;
int nAlphaCode;
int nGramCode;
/*****************************
* Cryptogram already solved? *
*****************************/
if (bIsGameOver == true) {
//MessageBeep(-1); // No - exit
return false;
}
pSprite = m_cPaintGram->m_cDisplayLetters->Touched(cpointClicked);
/********************************
* Clicked on letter anywhere? *
********************************/
if (pSprite == nullptr) {
//MessageBeep(-1); // No - exit
return false;
}
/********************
* Symbol hilited? *
********************/
nClickedCode = (*pSprite).GetTypeCode();
if (m_cPaintGram->IsSymbolChar(nClickedCode) == true) {
return false; // Yes - do not hilite symbols
}
/********************
* Anything hilited? *
********************/
if (m_cPaintGram->IsHiLiteOn() == false) {
m_cPaintGram->HiLiteOn(pDC, nClickedCode); // No - hilite letter
return false;
}
/****************************************************************
* Was the letter clicked same as the letter currenly hilited? *
****************************************************************/
if (m_cPaintGram->IsHiLiteType(nClickedCode) == true) {
m_cPaintGram->HiLiteOff(pDC); // Yes - toggle hilite to off state
return false;
}
/************************************************************
* Was the area clicked same as the area currenly hilited? *
************************************************************/
nHiLiteCode = m_cPaintGram->GetHiLiteType(pDC);
ASSERT(nHiLiteCode);
if (
(m_cPaintGram->IsGramType(nClickedCode) &&
m_cPaintGram->IsGramType(nHiLiteCode)) ||
(m_cPaintGram->IsAlphabetType(nClickedCode) &&
m_cPaintGram->IsAlphabetType(nHiLiteCode))
) {
m_cPaintGram->HiLiteOff(pDC); // Yes - turn hilite off
m_cPaintGram->HiLiteOn(pDC, nClickedCode); // ...hilite new char
return false; // out of here.
}
/************************************************************
* User wants to switch letters. *
* Need to update internal cryptogram and visual reps. *
************************************************************/
if (m_cPaintGram->IsAlphabetType(nHiLiteCode) == true) { // Is the hilited char in the alphabet region?
nAlphaCode = nHiLiteCode; // Yes - assign it the alpha code
nGramCode = nClickedCode;
} else {
nAlphaCode = nClickedCode; // No - swap around clicked code
nGramCode = nHiLiteCode;
}
nReplaceCode = UpdateCryptMap(nGramCode, nAlphaCode); // Update internal rep
if (nReplaceCode != NOT_USED) { // New char used in gram?
/****************************************************************
* These next lines introduces the "LimboType." From the fact *
* that the new letter, "nAlphaCode," is already somewhere in *
* the displayed cryptogram, two additional letters need *
* replacing -- not just the old letter, "nGramCode," with the *
* new. The following algorithm was used to resolve this: *
* - The new char currently displayed needs to be replaced *
* with another temp char, "nReplaced," which is the *
* old char + LimboType. *
* - Next all old chars are replaced with the new char. Note *
* that the "old char + LimboType" will not be replaced with *
* the new char. *
* - Finally, set back temp char, "old + limbo," with old *
* char. *
* *
* That's what the next three lines do respectively. *
****************************************************************/
m_cPaintGram->ReplaceLetter(pDC, m_cPaintGram->GetCharType(nAlphaCode), // Yes - swap w/temp char
m_cPaintGram->SetLimboTypeOn(nReplaceCode)); // ...Temporarily set it's code to limbo
m_cPaintGram->ReplaceLetter(pDC, nGramCode, m_cPaintGram->GetCharType(nAlphaCode)); // swap old char with new char
m_cPaintGram->ReplaceLetter(pDC, m_cPaintGram->SetLimboTypeOn(nReplaceCode), // Turn all limbo types off
m_cPaintGram->SetLimboTypeOff(nReplaceCode));
} else { // New char was not used in gram...
m_cPaintGram->ReplaceLetter(pDC, nGramCode, m_cPaintGram->GetCharType(nAlphaCode)); // ...simply replace old with new.
}
m_cPaintGram->HiLiteOff(pDC); // Turn hilite off
m_cPaintGram->UsedOff(pDC, nGramCode); // Turn used code off on old char since it's not being used anymore
m_cPaintGram->UsedOn(pDC, nAlphaCode); // Turn used code on new char now appearing in cryptogram
return IsSolved();
}
/*****************************************************************
*
* HandleUserUpdate
*
* FUNCTIONAL DESCRIPTION:
*
* Processes user interaction with the displayed cryptogram.
* Will modify both internal cryptogram representation by calling
* appropriate CCryptogram members, and visual crytogram rep by
* calling CPaintGram members.
*
* FORMAL PARAMETERS:
*
* pDC - used for visual updating
* cpointClicked - place where user clicked
*
* IMPLICIT INPUT PARAMETERS:
*
* m_cPaintGram member
*
* IMPLICIT OUTPUT PARAMETERS:
*
* modifies m_cPaintGram
*
* RETURN VALUE:
*
* void
*
****************************************************************/
bool CCryptogram::HandleUserUpdate(CDC *pDC, unsigned int nChar) {
char nNewChar = toupper(nChar);
int nHiLiteCode;
int nReplaceCode;
int nAlphaCode;
int nGramCode;
/*****************************
* Cryptogram already solved? *
*****************************/
if (bIsGameOver == true) {
//MessageBeep(-1); // No - exit
return false;
}
/****************************************
* Is this a valid alphabetical letter? *
****************************************/
if (Common::isAlpha(nNewChar) == false) {
MessageBeep(-1); // No - exit
return false;
}
/********************
* Anything hilited? *
********************/
if (m_cPaintGram->IsHiLiteOn() == false) {
m_cPaintGram->HiLiteOn(pDC, nNewChar); // Turn hilite on that spec char
return false;
}
/*******************************
* Hilite in cryptogram region? *
*******************************/
nHiLiteCode = m_cPaintGram->GetHiLiteType(pDC);
ASSERT(nHiLiteCode);
if (m_cPaintGram->IsGramType(nHiLiteCode) == false) {
MessageBeep(-1); // No - exit
return false;
}
/*************************************
* Hilite same char as user typed in? *
*************************************/
if (nHiLiteCode == nNewChar) {
m_cPaintGram->HiLiteOff(pDC); // Turn hilite off
return false;
}
nAlphaCode = nNewChar;
nGramCode = nHiLiteCode;
/************************************************************
* User wants to switch letters. *
* Need to update internal cryptogram and visual reps. *
************************************************************/
nReplaceCode = UpdateCryptMap(nGramCode, nAlphaCode); // Update internal rep
if (nReplaceCode != NOT_USED) { // New char used in gram?
/****************************************************************
* These next lines introduces the "LimboType." From the fact *
* that the new letter, "nAlphaCode," is already somewhere in *
* the displayed cryptogram, two additional letters need *
* replacing -- not just the old letter, "nGramCode," with the *
* new. The following algorithm was used to resolve this: *
* - The new char currently displayed needs to be replaced *
* with another temp char, "nReplaced," which is the *
* old char + LimboType. *
* - Next all old chars are replaced with the new char. Note *
* that the "old char + LimboType" will not be replaced with *
* the new char. *
* - Finally, set back temp char, "old + limbo," with old *
* char. *
* *
* That's what the next three lines do respectively. *
****************************************************************/
m_cPaintGram->ReplaceLetter(pDC, m_cPaintGram->GetCharType(nAlphaCode), // Yes - swap w/temp char
m_cPaintGram->SetLimboTypeOn(nReplaceCode)); // ...Temporarily set it's code to limbo
m_cPaintGram->ReplaceLetter(pDC, nGramCode, m_cPaintGram->GetCharType(nAlphaCode)); // swap old char with new char
m_cPaintGram->ReplaceLetter(pDC, m_cPaintGram->SetLimboTypeOn(nReplaceCode), // Turn all limbo types off
m_cPaintGram->SetLimboTypeOff(nReplaceCode));
} else { // New char was not used in gram...
m_cPaintGram->ReplaceLetter(pDC, nGramCode, m_cPaintGram->GetCharType(nAlphaCode)); // ...simply replace old with new.
}
m_cPaintGram->HiLiteOff(pDC); // Turn hilite off
m_cPaintGram->UsedOff(pDC, nGramCode); // Turn used code off on old char since it's not being used anymore
m_cPaintGram->UsedOn(pDC, nAlphaCode); // Turn used code on new char now appearing in cryptogram
return IsSolved();
}
/*****************************************************************
*
* Encrypt
*
* FUNCTIONAL DESCRIPTION:
*
* Uses the Crypt Map to encode the phrase, as it originally
* appears.
*
* FORMAL PARAMETERS:
*
* None
*
* IMPLICIT INPUT PARAMETERS:
*
* m_cRecordGram - to obtain the original phrase.
* m_nCryptMap - to encrypt phrase
*
* IMPLICIT OUTPUT PARAMETERS:
*
* m_chEncrptGram - updated according to structure of
* m_nCryptMap.
*
* RETURN VALUE:
*
* void
*
****************************************************************/
void CCryptogram::Encrypt() {
int i;
/*******************
* Reset workbench. *
*******************/
Common::strcpy_s(m_chEncryptGram, m_cRecordGram->GetGram()); // Acquire copy of original
/*****************************************
* Encrypt entire string using crypt map. *
*****************************************/
for (i = 0; m_chEncryptGram[i] != 0; i++) {
if ((m_cPaintGram->IsAlphaChar(m_chEncryptGram[i]) == true) && // Is this a char?
(m_nCryptMap[DECRYPT_MAP][m_cPaintGram->CharToIndex(m_chEncryptGram[i])] != NOT_USED) // and should this char be encrypted?
) {
m_chEncryptGram[i] = m_cPaintGram->IndexToChar(
m_nCryptMap[DECRYPT_MAP][
m_cPaintGram->CharToIndex(m_chEncryptGram[i])
]
);
}
}
}
/*****************************************************************
*
* CreateEncryptMap
*
* FUNCTIONAL DESCRIPTION:
*
* Creates an En-Cryption Map Key by randomally selecting
* unique representations for each alphabetical letter.
*
* FORMAL PARAMETERS:
*
* nLettersSolved - number of characters not encrypted
*
* IMPLICIT INPUT PARAMETERS:
*
* m_nCryptMap - Resets En-Cryption Map Key
*
* IMPLICIT OUTPUT PARAMETERS:
*
* m_nCryptMap - Complete En-Cryption Map Key with exactly
* nLettersSolved chars mapped to themselves.
*
* RETURN VALUE:
*
* void
*
****************************************************************/
void CCryptogram::CreateCryptMap(int nLettersSolved) {
int nEncryptCode; // encrypted value
int nDecryptCode; // normal/decrypted value
bool bIsUsed; // tells if encrypt-decrypt map was used
int i, j; // index
/*******************
* Reset workbench. *
*******************/
Common::strcpy_s(m_chEncryptGram, m_cRecordGram->GetGram()); // Acquire copy of original
for (i = 0; i < ALPHABET; i++) { // Reset cryptmap
m_nCryptMap[DECRYPT_MAP][i] = NOT_USED;
m_nCryptMap[ENCRYPT_MAP][i] = NOT_USED;
}
/****************************************************
* Create encryption map based on letters in phrase. *
****************************************************/
for (i = 0; m_chEncryptGram[i] != 0; i++) {
if (m_cPaintGram->IsAlphaChar(m_chEncryptGram[i]) == true) { // Is this a char?
nDecryptCode = m_cPaintGram->CharToIndex(m_chEncryptGram[i]);
bIsUsed = (m_nCryptMap[DECRYPT_MAP][nDecryptCode] != NOT_USED);
if (bIsUsed == true) // Char already encrypted?
continue; // Yes - loop to next char in text
/******************************
* Find an unused encrypt map. *
******************************/
do {
nEncryptCode = brand() % ALPHABET;
bIsUsed = (m_nCryptMap[ENCRYPT_MAP][nEncryptCode] != NOT_USED);
} while (bIsUsed == true || nEncryptCode == nDecryptCode); // find unused map
/**************************************
* Record new encrypt/decrypt mapping. *
**************************************/
m_nCryptMap[DECRYPT_MAP][nDecryptCode] = nEncryptCode;
m_nCryptMap[ENCRYPT_MAP][nEncryptCode] = nDecryptCode;
}
}
/************************************************************************
* Decrypt letters solved given as function arg. *
* To keep letters solved random (as opposed to decrypting A, B, and C *
* in order) it seemed easier to change the map after it was fully *
* encrypted, provided from above. *
************************************************************************/
for (i = 0; i < nLettersSolved ; i++) {
for (j = 0; j < ALPHABET; j++) { // Are there any letters left to decrypt?
if (
m_nCryptMap[DECRYPT_MAP][j] != NOT_USED && // in the quote and
m_nCryptMap[DECRYPT_MAP][j] != j // not already solved
) {
bIsUsed = true; // Yes - so break
break;
} else
bIsUsed = false; // No - not this letter, keep looking
}
if (bIsUsed == false) // Any letters left to decrypt?
break; // No - by pass loop.
do {
nDecryptCode = brand() % ALPHABET; // find used char
bIsUsed = (
m_nCryptMap[DECRYPT_MAP][nDecryptCode] != NOT_USED && // in quote and
m_nCryptMap[DECRYPT_MAP][nDecryptCode] != nDecryptCode // not already solved
);
} while (bIsUsed == false);
nEncryptCode = m_nCryptMap[DECRYPT_MAP][nDecryptCode]; // gets corres decoder
/********************************************************************
* Need to know if the decrypted letter was used in the encryption *
* map before. If it was, then another encryption letter needs to *
* be used in it's place. *
********************************************************************/
bIsUsed = (m_nCryptMap[ENCRYPT_MAP][nDecryptCode] != NOT_USED);
if (bIsUsed == true) { // Decrypted letter used before?
m_nCryptMap[DECRYPT_MAP][m_nCryptMap[ENCRYPT_MAP][nDecryptCode]] = nEncryptCode; // Yes - Swap around encrypted chars
m_nCryptMap[ENCRYPT_MAP][nEncryptCode] = m_nCryptMap[ENCRYPT_MAP][nDecryptCode];
} else {
m_nCryptMap[ENCRYPT_MAP][nEncryptCode] = NOT_USED; // No - Mark encryption map as unused
}
/********************************************************************
* ENCRYPT_MAP is a reversed mirror of DECRYPT_MAP. I.e. if *
* "A points to X" in the DECRYPT_MAP, then "X points to A" in the *
* ENCRYPT_MAP. Specific reasons for assigning both sides of map *
* to "nDecryptCode" are tricky...8-]. Think about it. *
********************************************************************/
m_nCryptMap[DECRYPT_MAP][nDecryptCode] = nDecryptCode; // Match Decrypt map
m_nCryptMap[ENCRYPT_MAP][nDecryptCode] = nDecryptCode; // ...with Encrypt map
}
Encrypt(); // Create the real thing...update internal rep.
}
/*****************************************************************
*
* UpdateGramChar
*
* FUNCTIONAL DESCRIPTION:
*
* Replaces old char, "nOldType," with new char, "nNewType," in
* Crypt Map. Handles specific case when new char appears in
* Crypt Map prior to replacement.
*
* FORMAL PARAMETERS:
*
* nOldType - type code of old char
* nNewType - type code of new char
*
* IMPLICIT INPUT PARAMETERS:
*
* m_nCryptMap - En-Cryption Map Key
*
* IMPLICIT OUTPUT PARAMETERS:
*
* m_nCryptMap - nOldType is remapped to nNewType
*
* RETURN VALUE:
*
* nReplaceCode - value of any additional character that may
* need replacing.
*
****************************************************************/
int CCryptogram::UpdateCryptMap(int nOldType, int nNewType) {
int nOldIndex; // Crypt Map index equivalent of nOldType
int nNewIndex; // index equivalent of nNewType
int nEncryptCode; // old type
int nDecryptCode; // decryption map corresponding to old type
int nReplaceCode; // temporary old type
nOldIndex = m_cPaintGram->CharToIndex(m_cPaintGram->GetCharType(nOldType));
nNewIndex = m_cPaintGram->CharToIndex(m_cPaintGram->GetCharType(nNewType));
nEncryptCode = nOldIndex;
nDecryptCode = m_nCryptMap[ENCRYPT_MAP][nEncryptCode];
nReplaceCode = NOT_USED;
/************************************************************************
* Need to know if nNewType letter was used in the cryptogram *
* before. This can occur in two different instances: another letter *
* was encrypted into nNewType, or when nNewType just appears as a *
* straight representation of itself. If either was case, then another *
* letter needs to be used in it's place. *
************************************************************************/
if (m_nCryptMap[ENCRYPT_MAP][nNewIndex] != NOT_USED) { // New type used in encryption ma?
m_nCryptMap[DECRYPT_MAP][m_nCryptMap[ENCRYPT_MAP][nNewIndex]] = nEncryptCode; // Swap around encrypted chars
m_nCryptMap[ENCRYPT_MAP][nEncryptCode] = m_nCryptMap[ENCRYPT_MAP][nNewIndex];
nReplaceCode = m_cPaintGram->IndexToChar(nEncryptCode);
} else {
m_nCryptMap[ENCRYPT_MAP][nEncryptCode] = NOT_USED;
}
m_nCryptMap[DECRYPT_MAP][nDecryptCode] = nNewIndex; // Match Decrypt map
m_nCryptMap[ENCRYPT_MAP][nNewIndex] = nDecryptCode; // ...with Encrypt map
Encrypt(); // Update internal rep
return nReplaceCode; // return temporary value....
}
/*****************************************************************
*
* IsSolved
*
* FUNCTIONAL DESCRIPTION:
*
* Figures out if the cryptogram is solved, based on
* state of "m_nCryptMap" -- the En-Cryption Map Key.
*
* FORMAL PARAMETERS:
*
* void
*
* IMPLICIT INPUT PARAMETERS:
*
* m_nCryptMap - En-Cryption Map Key
*
* IMPLICIT OUTPUT PARAMETERS:
*
* None
*
* RETURN VALUE:
*
* nTotalSolved - number of correctly decrypted letters
*
****************************************************************/
bool CCryptogram::IsSolved() {
int i;
for (i = 0; i < ALPHABET; i++) { // flip thru Crypt Map
if ((m_nCryptMap[DECRYPT_MAP][i] != i) && // Any chars rep another char?
(m_nCryptMap[DECRYPT_MAP][i] != NOT_USED))
return false; // Yes - cryptogram not solved
}
bIsGameOver = true; // Mark cryptogram as solved
return true;
}
/*****************************************************************
*
* LettersSolved
*
* FUNCTIONAL DESCRIPTION:
*
* Figures out how many letters are properly decrypted, based on
* state of "m_nCryptMap" -- the En-Cryption Map Key.
*
* FORMAL PARAMETERS:
*
* void
*
* IMPLICIT INPUT PARAMETERS:
*
* m_nCryptMap - En-Cryption Map Key
*
* IMPLICIT OUTPUT PARAMETERS:
*
* None
*
* RETURN VALUE:
*
* nTotalSolved - number of correctly decrypted letters
*
****************************************************************/
int CCryptogram::LettersSolved() {
int i;
int nTotalSolved = 0;
for (i = 0; i < ALPHABET; i++) { // flip thru Crypt Map
if (m_nCryptMap[DECRYPT_MAP][i] == i) // Does letter rep itself?
nTotalSolved++; // Yes - it is a solved letter
}
return nTotalSolved;
}
} // namespace Crypt
} // namespace HodjNPodj
} // namespace Bagel