21 Commits
v0.1 ... v0.5

Author SHA1 Message Date
036a8e4645 Moved string literals to the defines.h header. 2023-08-08 17:50:51 +03:00
5482fe1814 More moved some Print*() methods to a separate class. 2023-08-08 13:25:18 +03:00
f7572874b0 Removed headers.h file due to recursive inclusion.
Also, moved Print*() methods to separate class.
2023-08-07 19:37:59 +03:00
33d1f783ac Added the new PrintGameInitialQuery() method. 2023-08-06 14:34:29 +03:00
872e390ce9 Refactored the PrintSteps() method. 2023-08-06 14:28:10 +03:00
5a4fa61ed2 Version 0.4 2023-08-04 14:19:23 +03:00
8197a64803 Refactored GetNumber() method. 2023-08-04 13:55:27 +03:00
e75d82e896 Reworked the user input in the game class. 2023-08-03 01:00:32 +03:00
7669dff7a6 Moved header's includes into separete header file. 2023-08-02 23:01:19 +03:00
7edca0b5e6 Version 0.3 2023-08-02 15:52:23 +03:00
340924213a Some fixes. 2023-08-02 15:49:16 +03:00
3833461e90 Reverted indexing. 2023-08-02 15:22:21 +03:00
3e22bb1dc1 Added the ability to set the number of digits in the guessed number. 2023-08-02 15:11:25 +03:00
324510173a Fixed memory leak. 2023-07-03 15:58:51 +03:00
ba43d72188 Version 0.2 2023-06-30 20:35:46 +03:00
2d9c1c1d57 Added error messages. 2023-06-30 20:26:58 +03:00
a34da8d34f Refactored IsEqual() function. 2023-06-30 20:18:42 +03:00
2bc245354c Added check for the same digits in user input. 2023-06-30 18:59:51 +03:00
c0dfdf53bb Added the output of number of total steps at the end of game. 2023-06-30 15:58:57 +03:00
4b634caf52 Moved initialization of number of digits from constructor to method. 2023-06-30 15:38:28 +03:00
ae4230e721 The game are working! 2023-06-14 22:42:11 +03:00
12 changed files with 337 additions and 44 deletions

View File

@@ -1,21 +1,27 @@
// Bulls and Cows the game
// CGame.cpp
//
#include "defines.h"
#include "CGame.h"
#include <random>
#include "CUserInput.h"
#include "CPrint.h"
#include <iostream>
#include <random>
// Initialize the variables
void CGame::Init()
{
m_ucBulls = 0;
m_ucCows = 0;
m_uStepCounter = 0;
m_fGameIsEnd = false;
m_sLastError = L"";
std::random_device r;
std::default_random_engine e(r());
std::uniform_int_distribution<int> d(0, 9);
m_uGuessedNumber = new int[m_ucDigits] { 0 };
int n = 0;
for (int i = 0; i < m_ucDigits; ++i)
@@ -23,45 +29,101 @@ void CGame::Init()
n = d(e);
if (i > 0)
{
while (CGame::IsEqual(n, i))
while (IsEqual(m_uGuessedNumber, n, i))
{
n = d(e);
}
}
m_uGuessedNumber[i] = n;
}
}
void CGame::ShowGuessedNumber()
void CGame::Start()
{
for (int i = 0; i < m_ucDigits; ++i)
CStep step;
int ret = 0;
while (!m_fGameIsEnd)
{
std::cout << m_uGuessedNumber[i];
do
{
CPrint::GameHeader();
CPrint::GuessedNumber(this, IS_SHOW);
CPrint::Steps(this);
} while (!GetNumber(step));
m_uStepCounter++;
}
std::cout << std::endl;
CPrint::GameHeader();
CPrint::GuessedNumber(this, true);
CPrint::Steps(this);
CPrint::GameFooter(this);
}
void CGame::PrintGameHeader()
bool CGame::GetNumber(CStep step)
{
std::wcout << L"Áûêè è Êîðîâû. Âåðñèÿ " << VERSION << std::endl;
}
std::wcout << L"\t\t\t\t\t" << m_sLastError << L"\r";
std::wcout << "=>\t";
bool CGame::IsEqual(int n, int j)
{
j--;
bool result = false;
CUserInput userInput(m_ucDigits);
while (j >= 0)
if (userInput.Get())
{
if (n == m_uGuessedNumber[j]) result = true;
j--;
for (unsigned i = 0; i < userInput.m_vUserInput.size(); i++)
{
if (IsEqual(userInput.m_vUserInput, userInput.m_vUserInput.at(i), i))
{
m_sLastError = strERROR_1;
return false;
}
}
}
return result;
else
{
m_sLastError = strERROR_2_1 + std::to_wstring(m_ucDigits) + strERROR_2_2;
return false;
}
step.StoreStepNumber(userInput.m_vUserInput);
step.CheckForAnimals(m_uGuessedNumber, m_ucDigits);
m_Steps.push_back(step);
if (step.GetStepAnimals().first == m_ucDigits) m_fGameIsEnd = true;
m_sLastError = L"";
return true;
}
CGame::CGame(int digits)
CGame::CGame()
{
m_ucDigits = digits;
CUserInput userInput(1);
bool ok = false;
do
{
CPrint::GameHeader();
CPrint::GameInitialQuery();
std::wcout << "=> ";
if (userInput.Get())
{
if ((userInput.m_vUserInput.at(0) >= 3) && (userInput.m_vUserInput.at(0) <= 5))
{
m_ucDigits = userInput.m_vUserInput.at(0);
ok = true;
}
else
{
userInput.m_vUserInput.clear();
}
}
} while (!ok);
}
CGame::~CGame()
{
delete[] m_uGuessedNumber;
}

View File

@@ -1,27 +1,43 @@
// Bulls and Cows the game
// CGame.h
//
#pragma once
#include "CStep.h"
#include <vector>
#define VERSION 0.1
#include <string>
class CGame
{
private:
unsigned char m_ucDigits;
int m_uStepCounter;
int* m_uGuessedNumber;
std::vector<CStep> m_Step;
int m_ucBulls;
int m_ucCows;
bool m_fGameIsEnd;
std::wstring m_sLastError;
bool IsEqual(int, int);
bool GetNumber(CStep);
template<typename T, typename N>
bool IsEqual(const T, const N, int);
public:
unsigned char m_ucBulls;
unsigned char m_ucCows;
int m_ucDigits; // Number of digits into the guessed number
int m_uStepCounter;
int* m_uGuessedNumber;
std::vector<CStep> m_Steps;
void Init();
void ShowGuessedNumber();
void PrintGameHeader();
CGame(int);
void Start();
CGame();
~CGame();
};
template<typename T, typename N>
bool CGame::IsEqual(const T number, const N digit, int i)
{
bool result = false;
while ((--i) >= 0)
{
if (digit == number[i]) result = true;
}
return result;
}

View File

@@ -0,0 +1,54 @@
// Bulls and Cows the game
// CPrint.cpp
//
#include "CPrint.h"
#include "defines.h"
#include <iostream>
void CPrint::GameInitialQuery()
{
std::wcout << strINITIAL_QUERY_1;
std::wcout << strINITIAL_QUERY_2 << std::endl;
}
void CPrint::GameHeader()
{
std::system("cls");
std::wcout << strGAME_NAME << ' ' << strGAME_VERSION << ' ' << VERSION << std::endl;
std::wcout << strGAME_COPYRIGHT << "\n\n" << std::endl;
}
void CPrint::GameFooter(CGame* const game)
{
std::wcout << "\n\n\t" << strVICTORY << std::endl;
std::wcout << strNUM_STEPS << game->m_uStepCounter << "\n\n" << std::endl;
}
void CPrint::Steps(CGame* const game)
{
if (game->m_Steps.size() < 1) return;
for (CStep& s : game->m_Steps)
{
std::wcout << '\t';
for (int& d : s.GetStepNumber()) std::wcout << d;
std::wcout << '\t' << s.GetStepAnimals().first << strBULLS << s.GetStepAnimals().second << strCOWS;
std::wcout << std::endl;
}
}
void CPrint::GuessedNumber(CGame* const game, const bool show)
{
std::wcout << '\t';
for (int i = 0; i < game->m_ucDigits; ++i)
{
show ? std::wcout << game->m_uGuessedNumber[i] : std::wcout << '#';
}
std::wcout << '\n' << '\t';
for (int i = 0; i < game->m_ucDigits; ++i)
{
std::wcout << '-';
}
std::wcout << std::endl;
}

View File

@@ -0,0 +1,15 @@
// Bulls and Cows the game
// CPrint.h
//
#pragma once
#include "CGame.h"
class CPrint
{
public:
static void GameInitialQuery();
static void GameHeader();
static void GameFooter(CGame* const);
static void Steps(CGame* const);
static void GuessedNumber(CGame* const, const bool);
};

View File

@@ -1,4 +1,42 @@
// Bulls and Cows the game
// CStep.cpp
//
#include "CStep.h"
void CStep::StoreStepNumber(std::vector<int>& digits)
{
m_uStepNumber = digits;
}
void CStep::CheckForAnimals(const int* digits, int size)
{
int b = 0, c = 0;
for (size_t i = 0; i < size; i++) // m_uGuessedNumber
{
for (size_t j = 0; j < size; j++) // m_uStepNumber
{
if ((m_uStepNumber[i] == digits[j]) && (i == j))
{
b++;
}
else if (m_uStepNumber[i] == digits[j])
{
c++;
}
}
}
m_uStepAnimals.first = b;
m_uStepAnimals.second = c;
}
std::vector<int> CStep::GetStepNumber()
{
return m_uStepNumber;
}
std::pair<int, int> CStep::GetStepAnimals()
{
return m_uStepAnimals;
}

View File

@@ -1,11 +1,18 @@
// Bulls and Cows the game
// CStep.h
//
#pragma once
#include <tuple>
#include <vector>
class CStep
{
private:
std::vector<int> m_uStepNumber;
std::pair<int, int> m_uStepAnimals;
public:
std::tuple<int, int, int, int> m_uStepNumber;
std::tuple<unsigned char, unsigned char> m_ucStepAnimals;
void StoreStepNumber(std::vector<int>&);
void CheckForAnimals(const int*, int);
std::vector<int> GetStepNumber();
std::pair<int, int> GetStepAnimals();
};

View File

@@ -0,0 +1,39 @@
// Bulls and Cows the game
// CUserInput.cpp
//
#include "CUserInput.h"
#include <iostream>
#include <string>
#include <cwctype>
CUserInput::CUserInput(int nNumOfDigits)
{
m_nNumOfExpectedDigits = nNumOfDigits;
}
bool CUserInput::Get()
{
std::wstring sDigits;
wchar_t cDigit;
int nDigit;
std::getline(std::wcin, sDigits);
if (sDigits.length() != m_nNumOfExpectedDigits)
{
return false;
}
for (unsigned i = 0; i < m_nNumOfExpectedDigits; i++)
{
cDigit = sDigits.at(i);
if (!(bool)std::iswdigit(cDigit))
{
m_vUserInput.clear();
return false;
}
nDigit = ((int)cDigit) - 48;
m_vUserInput.push_back(nDigit);
}
return true;
}

View File

@@ -0,0 +1,15 @@
// Bulls and Cows the game
// CUserInput.h
//
#pragma once
#include <vector>
class CUserInput
{
public:
int m_nNumOfExpectedDigits;
std::vector<int> m_vUserInput;
CUserInput(int nNumOfExpectedDigits);
bool Get();
};

View File

@@ -77,10 +77,12 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4018;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -132,12 +134,17 @@
<ClCompile Include="..\..\..\MyFunctions\SetUserLocale.cpp" />
<ClCompile Include="bulls-and-cows.cpp" />
<ClCompile Include="CGame.cpp" />
<ClCompile Include="CPrint.cpp" />
<ClCompile Include="CStep.cpp" />
<ClCompile Include="CUserInput.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\MyFunctions\SetUserLocale.h" />
<ClInclude Include="CGame.h" />
<ClInclude Include="CPrint.h" />
<ClInclude Include="CStep.h" />
<ClInclude Include="CUserInput.h" />
<ClInclude Include="defines.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -27,6 +27,12 @@
<ClCompile Include="CStep.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CUserInput.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CPrint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CGame.h">
@@ -38,5 +44,14 @@
<ClInclude Include="CStep.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CUserInput.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CPrint.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -1,6 +1,6 @@
// Bulls and Cows the game
// bulls-and-cows.cpp
//
#include <Windows.h>
#include "..\..\..\MyFunctions\SetUserLocale.h"
#include "CGame.h"
@@ -8,12 +8,9 @@ int wmain(int argc, wchar_t* argv[])
{
if (!SetUserLocale()) return 1;
CGame game(4);
CGame game;
game.Init();
game.PrintGameHeader();
game.Start();
return 0;
}

View File

@@ -0,0 +1,28 @@
// Bulls and Cows the game
// defines.h
//
#pragma once
#define VERSION 0.4
#ifdef _DEBUG
#define IS_SHOW true
#else
#define IS_SHOW false
#endif
#define strERROR_1 L"Цифры в числе не должны повторяться!"
#define strERROR_2_1 L"Вы должны ввести "
#define strERROR_2_2 L"-значное число!"
#define strBULLS L" Б., "
#define strCOWS L" К."
#define strINITIAL_QUERY_1 L"Введите количество цифр в числе (от 3 до 5).\n"
#define strINITIAL_QUERY_2 L"Чем больше цифр - тем сложнее. Обычно 4.\n"
#define strGAME_NAME L"Быки и Коровы."
#define strGAME_VERSION L"Версия"
#define strGAME_COPYRIGHT L"Copyright (c) 2023 by W0LF aka 'dreamforce'"
#define strVICTORY L"!!! П О Б Е Д А !!!"
#define strNUM_STEPS L"\tКоличество ходов: "