Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

RefleX - Czy sprostasz zadaniu?


Rekomendowane odpowiedzi

Opublikowano

Hej!

Po prawie dwumiesięcznej rozłące z C++ postanowiłem na szybko napisać grę, aby sobie przypommnieć co i jak ;) Grę pisałem dwa dni (dokładnie to jeden jakby nie liczyć poprawek wizualnych, kosmetycznych). W grze macie za zadanie być takim MathMaste'em :D Wybieracie poziom trudności i działanie (na razie tylko Dodawanie i Odejmowanie).

 

Co w grze? :

- rankingi (zapisywanie wyników do plików)

- poziomy trudności

- całkiem ładne GUI

- zero grywalności (chyba, że ktoś idzie do podstawówki i chce poćwiczyć ._.)

 

Ocena nie obowiązkowa, lecz mile widziana. Propozycje zostaną wprowadzone jak mi się zechce, gdyż gry nie zamierzam rozwijać ;) To taki teścik.

Następna gra, którą chcę zrobić będzie w bibliotece SFML, więc będzie na o wiele wyższym poziomie ;)

 

Download: 

https://www.dropbox.com/s/pex2vxmh63btc97/RefleX%20v1.0.exe

Skan: 

https://www.virustotal.com/pl/file/8605bb530a620d3ddc268ed604302394396edeae122c9ad2902d0179c1402e4b/analysis/1405933939/

ScreenShot'y:

dcr5i8.jpg

g7wedd.jpg

ls5pqp.jpg

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

Sterowanie strzałkami ;) Góra - dół

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

Aj! Zapomniałem o tym że nie powinno się porównywać liczb zmiennoprzecinkowych ze względu na ich dokładność. Zaraz poprawie.

 

EDIT: Poprawione!, nowy download link w pierwszym poście

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

Dzięki za opinię :) problem nadal występuje?

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

  • 2 tygodnie później...
  • 1 miesiąc temu...
  • 1 miesiąc temu...
  • 3 miesiące temu...
Opublikowano

@ref, dodaję kod do shejtowania oceny:

 

 

#include <iostream>
#include <string>
#include <conio.h>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <fstream>
#include <sstream>
#include <vector>
#include <iomanip>

using namespace std;

int Cwidth;
int Cheight;

static const double EPS = 0.000001;

void color(int kolor) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), kolor);
}

void center(string str) {
	for (int i = 0; i < (int)((Cwidth - str.length()) / 2); i++) cout << " ";
	cout << str;
}

void banner() {
	color(6);
	center(" _____     ___ _     __ __ \n");
	center("| __  |___|  _| |___|  |  |\n");
	center("|    -| -_|  _| | -_|-   -|\n");
	center("|__|__|___|_| |_|___|__|__|\n");
	color(7);
}

void line() {
	for (int i = 0; i < Cwidth; i++) cout << "-";
}

void bufferinfo()
{
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
	HANDLE hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);
	Cwidth = csbiInfo.dwSize.X;
	Cheight = csbiInfo.dwSize.Y;
}

int menu(string opcje[], int opcje_ilosc) { // Menu odp. za wybor trybu, dzialania i poziomu
	int wybr_opcja = 0; // Wybrana opcja w menu
	
	while(true) { // Petla do wybrania opcji
		system("CLS"); // Czyszczenie ekranu

		banner();
		line();
		cout << endl;

		for (int i = 0; i < opcje_ilosc; i++) { // Wypisywanie opcji
			if (opcje[i] == "Powrót" || opcje[i] == "Wyjście") color(12);
			else color(7);

			if (i == wybr_opcja) cout << "[x] "; // Jesli wybrana to zaznacz
			else cout << "[-] "; // Jesli nie to nie
			cout << opcje[i] << endl; // Wypisz nazwe
		}

		cout << endl;
		color(7);
		line();
		color(6);
		center("@ RefleX");
		color(7);
		cout << endl;
		line();


		char znak = _getch(); // Pobierz znak
		if (znak == 72 && wybr_opcja > 0) wybr_opcja--; // Jesli strzalka w gore to zdekramentuj wybr_opcja
		if (znak == 80 && wybr_opcja < opcje_ilosc - 1) wybr_opcja++; // Jesli strzalka w dol to odwrotnie
		if (znak == 13) return wybr_opcja; // Jesli enter to zakoncz wybieranie
	}
}

int zap() { // Pobieranie ilosci testow
	int testy; // Ilosc testow
	system("CLS"); // Wyczysc ekran
	do { // Petla do obslugi bledow, dzialanie tak dlugo az wprowadzone zostana poprawne dane
		cin.clear(); // Czysc flagi
		cin.sync(); // Czysc bufor
		cout << "Liczba zapytan: "; // Zapytanie o ilosc zapytan
		cin >> testy; // Wczytaj
		system("CLS"); // Wyczysc ekran
	} while (cin.fail());
	return testy; // Zwroc wartosc
}

void wartosci(int dzial, int poz, int & przedzial_pocz, int & przedzial_kon, int & po_przec) { // Wczytywanie wartosci zakresow dla poszczegolnych dzialan i poziomow
	switch (dzial) {
	case 0: // Dodawanie
		switch (poz) {
		case 0:
			przedzial_pocz = 0;
			przedzial_kon = 100;
			po_przec = 1;
			break;
		case 1:
			przedzial_pocz = -100;
			przedzial_kon = 100;
			po_przec = 10;
			break;
		case 2:
			przedzial_pocz = -1000;
			przedzial_kon = 1000;
			po_przec = 100;
			break;
		}
		break;
	case 1: // Odejmowanie
		switch (poz) {
		case 0:
			przedzial_pocz = 0;
			przedzial_kon = 100;
			po_przec = 1;
			break;
		case 1:
			przedzial_pocz = -100;
			przedzial_kon = 100;
			po_przec = 10;
			break;
		case 2:
			przedzial_pocz = -1000;
			przedzial_kon = 1000;
			po_przec = 100;
			break;
		}
		break;
	}
}

void wyniki() {
	system("CLS");
	fstream plik;
	plik.open("score.dat", ios::in);
	int ilosc_wpisow = 0;
	int ilosc_poz_na_str = 10;
	int obecna_str = 0;
	vector < string > wpisy;
	
	if (plik.good()) {
		string temp;
		while (!plik.eof()) {
			ilosc_wpisow++;
			getline(plik, temp);
			wpisy.push_back(temp);
		}
		plik.close();

		--ilosc_wpisow;
	}

	int ilosc_stron = (int)ceil((float)ilosc_wpisow / ilosc_poz_na_str);

	while (true) {
		system("CLS");

		color(10);
		line();
		ostringstream napis;
		napis << "RANKING" << endl;
		center(napis.str());
		line();

		color(7);

		for (int i = obecna_str * ilosc_poz_na_str; i < obecna_str * ilosc_poz_na_str + ilosc_poz_na_str; i++) {
			if (i >= ilosc_wpisow) cout << endl;
			else cout << i + 1 << " | " << wpisy[i] << endl;
		}

		color(10);
		line();
		ostringstream linia1, linia2, linia3;
		if (!ilosc_wpisow) linia1 << "Strona: 1/1";
		else linia1 << "Strona: " << obecna_str + 1 << "/" << ilosc_stron;
		linia1 << " | Pozycje od " << obecna_str * ilosc_poz_na_str + 1 << " do " << obecna_str * ilosc_poz_na_str + ilosc_poz_na_str  << " (wszystkich: " << ilosc_wpisow << ")" << endl;
		linia2 << "<- Następna / Poprzednia Strona ->" << endl;
		linia3 << "[ESC] Powrót do Menu" << endl;
		center(linia1.str());
		center(linia2.str());
		center(linia3.str());
		
		color(7);
		char znak = _getch();
		if (znak == 75 && obecna_str > 0) obecna_str--;
		else if (znak == 77 && obecna_str < ilosc_stron - 1) obecna_str++;
		else if (znak == 27) return;
	}
}

void zapisz(int poprawne, int ilosc_zapytan, int procent, int czas, int wybor_dzial, int wybor_poz) {
	system("CLS");
	string user;
	cout << "Nazwa Gracza (max. 16 znaków): ";
	cin >> setw(16) >> user; // Pobranie nazwy gracza

	ofstream plik;
	plik.open("score.dat", ios::app); // Otworzenie pliku

	if (plik.good()) {
		string dzial;
		if (wybor_dzial == 0) dzial = "DODAWANIE";
		else if (wybor_dzial == 1) dzial = "ODEJMOWANIE";

		string poz;
		if (wybor_poz == 0)  poz = "EASY";
		else if (wybor_poz == 1) poz = "NORMAL";
		else if (wybor_poz == 2) poz = "HARD";

		ostringstream wynik;
		wynik << user << " | " << poprawne << "/" << ilosc_zapytan << " | " << procent << "% | " << czas << "s | " << dzial << " | " << poz << endl;

		plik << wynik.str();
		plik.close();

		system("CLS");
		cout << "Zapisano!";
		Sleep(2000);
	}
	else {
		cout << "ERROR PRZY OTWARCIU PLIKU!";
		Sleep(2000);
	}
}

void gra(int wybor_dzial, int wybor_poz, int ilosc_zapytan, int przedzial_pocz, int przedzial_kon, int po_przec) { // Funkcja z wlasciwa gra
	srand((unsigned)time(NULL)); // Liczby losowe

	int czasA, czasB;
	czasA = clock(); // Czas w trakcie zaczecia

	int poprawne = 0; // Ilosc poprawnych odpowiedzi
	double odp; // Odpowiedz

	for (int i = 0; i < ilosc_zapytan; i++) { // Petla do osiagniecia ilosci zapytan
		double a = (rand() % (przedzial_kon - przedzial_pocz + 1) + przedzial_pocz) + ((rand() % po_przec) * 1.0 / po_przec); // Losowanie liczby A
		double b = (rand() % (przedzial_kon - przedzial_pocz + 1) + przedzial_pocz) + ((rand() % po_przec) * 1.0 / po_przec); // Losowanie liczby B

		if (wybor_dzial == 0) { // Jesli wybrane zostalo dodawanie
			do {
				cin.clear();
				cin.sync();
				cout << a << " + " << b << " = ";
				cin >> odp;
			} while (cin.fail());

			if (fabs(fabs(odp) - fabs(a + ) <= EPS) {
				poprawne++;
				color(10);
				cout << "DOBRZE!" << endl << endl;
				color(7);
			}
			else  {
				color(12);
				cout << "ŻLE!";
				color(7);
				cout << " Poprawny wynik to: " << a + b << endl << endl;
			}
		}

		if (wybor_dzial == 1) { // Jesli wybrane zostalo odejmowanie
			do {
				cin.clear();
				cin.sync();
				cout << a << " - " << b << " = ";
				cin >> odp;
			} while (cin.fail());

			if (fabs(fabs(odp) - fabs(a - ) <= EPS) {
				poprawne++;
				color(10);
				cout << "DOBRZE!" << endl << endl;
				color(7);
			}
			else  {
				color(12);
				cout << "ŻLE!";
				color(7);
				cout << " Poprawny wynik to: " << a - b << endl << endl;
			}
		}
	}

	czasB = clock(); // Czas w trakcie zakonczenia

	int procent = (int)round(poprawne * 1.f / ilosc_zapytan * 100);
	int czas = (czasB - czasA) / 1000;
	color(12);
	line();
	center("GAME OVER");
	cout << endl;
	line();
	color(7);
	cout << endl;
	cout << "Twój wynik: " << poprawne << " / " << ilosc_zapytan << "!" << endl;
	cout << "Procent poprawnych: " << procent << "%" << endl;
	cout << "Czas rozwiązywania: " << czas << "s" << endl;
	cout << "Zapisać wynik? [T/N]: ";
	color(7);

	char znak;
	do { // Wcytaj wybór
		znak = _getch();
		if (znak == 't') zapisz(poprawne, ilosc_zapytan, procent, czas, wybor_dzial, wybor_poz); // Zapisanie wyniku
	} while (!(znak == 't' || znak == 'n'));
}

void inicjacja_gry() { // Funkcja odpowiadajaca za zainicjonowanie gry
	string opcje_dzial[] = { "Dodawanie", "Odejmowanie", "Powrót" }; // Dzialania
	string opcje_poz[] = { "Łatwy", "Normalny", "Trudny", "Powrót" }; // Poziomy
	int wybor_dzial, wybor_poz;
	do {
		wybor_dzial = menu(opcje_dzial, 3); // Wczytanie dzialania
		if (wybor_dzial == 2) return;
		wybor_poz = menu(opcje_poz, 4); // Wczytanie poziomu
	} while (wybor_poz == 3);

	int ilosc_zapytan = zap(); // Ile zapytan
	int przedzial_pocz, przedzial_kon, po_przec; // Zakres w zaleznosci od dzialania i poziomu
	wartosci(wybor_dzial, wybor_poz, przedzial_pocz, przedzial_kon, po_przec); // Wczytanie zakresow
	gra(wybor_dzial, wybor_poz, ilosc_zapytan, przedzial_pocz, przedzial_kon, po_przec); // Wlasciwa gra
}

int main() { // Glowna funkcja
	bufferinfo();
	setlocale(LC_ALL, "Polish"); // Polskie kodowanie

	string opcje_menu[] = { "Graj!", "Wyniki", "Wyjście" }; // Opcje menu

	while (true) {
		int wybor_menu = menu(opcje_menu, 3); // Wczytanie opcji menu

		if (wybor_menu == 0) inicjacja_gry();
		else if (wybor_menu == 1) wyniki();
		else if (wybor_menu == 2) return 0;
	}
} 

 

 

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

@MalakianPL, Chyba kolego nie w tym temacie piszesz :D

Co do podwójnego buforowania - impossible w konsoli (oswieccie mnie jeśli sie mylę)

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

No jak imposible :)...

 

BOOL WINAPI WriteConsoleOutput(
  _In_     HANDLE hConsoleOutput,
  _In_     const CHAR_INFO *lpBuffer,
  _In_     COORD dwBufferSize,
  _In_     COORD dwBufferCoord,
  _Inout_  PSMALL_RECT lpWriteRegion
);

Tworzysz cos podobnego do swapchain. Czyli 2 tabele dwuwymiarowe o rozmiarze konsoli, jedną tabele wyświetlasz(front buffer), na drugiej renderujesz(back buffer). Gdy skończysz renderować klatkę to wystarczy zamienić buffery i to pozwala na płynne renderowanie, bez takich "mignięć".

Opublikowano

Genialne! Czyli tak by to wyglądało?:

- wyświetlam zawartość bufora

- wpisuje nowy tekst do nowego bufora

- resztę bufora wypełniam bialymi znakami

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

class SwapChain
{
   const char* Buffer1;
   const char* Buffer2;

   bool Swaped = false;

   SwapChain(unsigned int Width, unsigned int Height)
   {
       //Jak wroce ze szkoly to ci dokoncze,
       //Tu dynamicznie alokujesz dwa buffory o rozmiarze Width x Height;
   }
  
   ~SwapChain()
   {
       if (Buffer1)
       {
           delete [] Buffer1;
           Buffer1 = nullptr;
       }

       if (Buffer1)
       {
           delete [] Buffer1;
           Buffer1 = nullptr;
       }
   }

   const char* GetBackBuffer()
   {
       return Swaped ? Buffer1 : Buffer2;
   }

   const char* GetFrontBuffer()
   {
       return Swaped ? Buffer2 : Buffer1;
   }

   void Present()
   {
       //Wyswietlenie back buffera
       //WriteConsoleOutput ... podając GetBackBuffer();

       Swaped != Swaped; //Zamiana bufforów
   } 
};

Uzycie bedzie proste.

 

void Render()

{

     //modyfikujez to co jest w BackBuffer //SwapChain->GetBackBuffer();

     //czyli renderujesz...

 

     //Gdy juz zrednerujesz.

    SwapChain->Present();

}

Opublikowano

^dzieki :). Odświeżam i proszę o dalsze opinie na temat kodu

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

Tak ogólnie patrząc to
1. Zmiennen globalne są złe
2. Nie wiem czemu EPS jest statyczna
3. Funkcje niektóre są za dlugie( powinny byc porozdzielone na mniejsze)
4. Używaj c++11 ( <random>)

5. Używaj ++i a nie i++

Opublikowano

1. Myślałem ze jak znany umiar, wiemy ze nie będziemy mieli zmiennych o tej samej nazwie i bedą używane w całym programie to nie są takie złe.

2. Tez teraz sie zastanawiam, powinno byc samo const

3. Myśle ze przy takiej ilości kodu to nie jest problemem, zwłaszcza ze go nie powtarzam.

4. W tamtych czasach jeszcze nie posiadałem takiej wiedzy i poznawałem podstawy :)

5. W pętlach jest różnica miedzy post a pre inkramentacja? Na to chyba należy zwrócić uwagę gdy inkrenentujemy jakaś zmienna przypisując ja do jeszcze innej

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Opublikowano

Dzięki za link, nie objaśnił jakoś szczególnie różnicy, ale o tym jeszcze poczytam. Co do 1 i 3 to teraz pisze inaczej, bardziej obiektowo.

3587513.png


Potrzebujesz pomocy? Pisz śmiało na PW/Skype/Gadu-Gadu!


(albo napisz na forum... ^.^)

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...