AHE/Podstawy Programowania I/Projekt1/main.cpp

215 lines
7.4 KiB
C++

/*
Autor: Mateusz Słodkowicz
Grupa: D3
Numer Indeksu: 167675
Opis: Gra w Papier, Kamień, Nożyce.
Program zapyta do ilu wygranych chcesz zagrać.
Remis nie liczy się jako wygrana bądź przegrana.
Gra trwa do uzyskania przez kogoś wyniku podanego na początku, po zakończeniu gra wypisze kto wygrał "mecz"
oraz umożliwia rozpoczęcię kolejnego "meczu".
Aby zakończyć program należy przy wyborze "do ilu" podać zero.
Plik źródłowy powinien być zapisany z kodowaniem UTF-8.
*/
#include <chrono>
#include <iostream>
#include <random>
#include <string>
#ifdef _WIN32 // Dodatkowe nagłówki dla windows'a
#include <cstdlib>
#include <windows.h>
// Nieco jaśniejszy niż domyślny biały
#define DEFAULT_COLOR (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY)
#endif
void wypiszCzerwony(std::string tekst)
{
#ifdef _WIN32
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // "Uchwyt" wyjścia konsoli
std::cout << std::flush; // Flush aby przypadkiem program nie zmienił koloru poprzedniego tekstu
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY); // Ustawienie czerwonego koloru
std::cout << tekst << std::flush; // Flush aby program na pewno wypisał tekst przed ustawienie domyślnego koloru
SetConsoleTextAttribute(hConsole, DEFAULT_COLOR);
#else
std::cout << "\033[31m" << tekst << "\033[0m";
#endif
}
void wypiszZielony(std::string tekst)
{
#ifdef _WIN32
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
std::cout << std::flush;
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::cout << tekst << std::flush;
SetConsoleTextAttribute(hConsole, DEFAULT_COLOR);
#else
std::cout << "\033[32m" << tekst << "\033[0m";
#endif
}
void czyscEkran()
{
#ifdef _WIN32
system("cls"); // Wywołanie "cls" dla wyczyczenia ekranu konsoli na windowsie
#else
std::cout << "\033[2J\033[1;1H"; // Sekwencja czyszczenia dla terminala ANSI
#endif
}
int main()
{
#ifdef _WIN32
SetConsoleOutputCP(CP_UTF8); // Ustawienie kodowania UTF-8 dla wyjścia konsoli, pozwala wyświetlić polskie znaki.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, DEFAULT_COLOR);
#endif
// Generator liczb
auto seed = std::chrono::system_clock::now().time_since_epoch().count(); // większa dokładność czasu niż time(0)
std::mt19937 rng(seed); // Generator licz losowych
std::uniform_int_distribution<char> dist('1', '3'); // Zakres liczb (znaków) losowych
// Zmienne
unsigned int wybor = 0;
unsigned int wygraneGracza = 0;
unsigned int wygraneKomputera = 0;
unsigned char ostatniaRunda = 0;
unsigned char ostatniMecz = 0;
char gracz = 0, komputer = 0;
// Główna pętla gry
while (true)
{
czyscEkran();
// Wypisanie wyniku ostatniego meczu
if (ostatniMecz != 0)
std::cout << "Ostatni mecz: ";
if (ostatniMecz == 1)
wypiszZielony("Wygrana gracza\n");
else if (ostatniMecz == 2)
wypiszCzerwony("Wygrana komputera\n");
// Reset zmiennych
wygraneKomputera = 0;
wygraneGracza = 0;
ostatniaRunda = 0;
ostatniMecz = 0;
wybor = 0;
// Wybór do ilu wygranych
std::cout << "Do ilu wygranych chcesz zagrać?\n"
"Wprowadź 0 aby wyjść z programu\n"
"Ile: ";
while (!(std::cin >> wybor))
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
wypiszCzerwony("Błąd, wprowadź jeszcze raz.\n");
std::cout << "Ile: ";
}
if (!wybor)
break;
// Pętla do czasu wygranej gracza lub komputera
while (wygraneGracza != wybor && wygraneKomputera != wybor)
{
czyscEkran();
gracz = 0;
komputer = dist(rng);
// Wypisanie wyniku ostatniej rundy
if (ostatniaRunda != 0)
std::cout << "Ostatnia runda: ";
if (ostatniaRunda == 1)
wypiszZielony("Wygrana gracza\n");
else if (ostatniaRunda == 2)
wypiszCzerwony("Wygrana komputera\n");
else if (ostatniaRunda == 3)
std::cout << "Remis\n";
// Wypisanie danych aktualnego meczu
std::cout << "Gra do: " << wybor << "\n\n"
<< "GRACZ ";
wypiszZielony(std::to_string(wygraneGracza));
std::cout << " - ";
wypiszCzerwony(std::to_string(wygraneKomputera));
std::cout << " KOMPUTER\n\n";
// Menu wyboru
std::cout << "1. Papier\n"
"2. Kamień\n"
"3. Nożyce\n";
while (gracz < '1' || gracz > '3')
{
std::cout << "Wybór: ";
while (!(std::cin >> gracz))
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// Remis
if (gracz == komputer)
ostatniaRunda = 3;
// Switch z wyborem gracza, porównanie do komputera
else
switch (gracz)
{
case '1': // Gracz wybrał papier
if (komputer == '2') // Komputer wybrał kamień
{
++wygraneGracza;
ostatniaRunda = 1;
}
else if (komputer == '3') // Komputer wybrał nożyce
{
++wygraneKomputera;
ostatniaRunda = 2;
}
break;
case '2': // Gracz wybrał kamień
if (komputer == '3') // Komputer wybrał nożyce
{
++wygraneGracza;
ostatniaRunda = 1;
}
else if (komputer == '1') // Komputer wybrał papier
{
++wygraneKomputera;
ostatniaRunda = 2;
}
break;
case '3': // Gracz wybrał nożyce
if (komputer == '1') // Komputer wybrał papier
{
++wygraneGracza;
ostatniaRunda = 1;
}
else if (komputer == '2') // Komputer wybrał kamień
{
++wygraneKomputera;
ostatniaRunda = 2;
}
break;
}
}
// Ustawienie wyniku meczu
if (wygraneGracza == wybor)
ostatniMecz = 1;
else
ostatniMecz = 2;
};
czyscEkran();
std::cout << "Dziękujemy za grę!";
return 0;
}