You are on page 1of 10

/* am folosit compilatorul GCC pentru Windows din pachetul MinGW

cu Visual Studio 2008 aveam probleme, erori de genul "Debug Asse


rtion Failed!" */
/* ruleaza doar pe Windows, din cauza functiei 'coutc' folosita pt. colorarea fo
nt-urilor;
cu portabilitatea ma obisnuiesc mai tarziu, candva in viitor :)
*/
/* ruleaza in mod optim intr-o consola cu fundal negru din cauza culorilor folos
ite */
/* jocul e pe baza de coordonate... daca il faceam cu campuri numerotate ca in e
xemplul dumneavoastra,
eram fortat sa caut acel numar introdus prin toata matricea dupa
fiecare mutare,
ceea ce nu mi s-a parut prea optim, chiar si cu un algoritm de c
autare rapid */
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <windows.h>
using namespace std;
enum Colors { blue=1, green, cyan, red, purple, yellow, grey, dgrey, hblue, hgre
en, hcyan, hred, hpurple, hyellow, hwhite };
void coutc (int, string);
void coutc (int, int);
string** setareTablaRegulaSemne (int &, int &, int &, string &, string &);
void dealocaTabla (string**, int, int);
void afisareTabla (string**, int, int, int);
void mutare (string**, string, string, string, int, int, int);
void afisareMutare (int, string);
int verificaMutareCorecta (string**, int, int, int, int);
void verificaCastig (string**, string, string, string, int, int, int);
void verificaContor (int, int, string, string, string);
void verificaSfarsitJoc (string**, int, int);
void optiuneaIncepereJoc();
void optiuneaReguli();
//practic meniul principal al jocului cu cele 3 optiuni
//apeleaza functiile asociate primelor 2 optiuni, a 3-a fiind iesirea din joc
int main() {
system ("cls");
int iAlegere;
do {
cout<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< "-=-=- M E N I U -=-=-" << endl
<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< "-=- -=-" << endl
<< "-=- [1] Incepere joc -=-" << endl
<< "-=- [2] Reguli -=-" << endl
<< "-=- [3] Iesire -=-" << endl
<< "-=- -=-" << endl
<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< endl;
cout << "Introduceti optiunea (1, 2 sau 3): ";
cin >> iAlegere;
if ( (iAlegere < 1) || (iAlegere > 3) ) {
system("cls");
main();
}
}
while ( (iAlegere < 1) || (iAlegere > 3) );
switch (iAlegere) {
case 1:
system ("cls");
optiuneaIncepereJoc();
break;
case 2:
system ("cls");
optiuneaReguli();
break;
case 3:
exit(0);
break;
}
getchar();
getchar();
return 0;
}
//functia principala a jocului care apeleaza mai multe sub-functii
void optiuneaIncepereJoc () {
int iLinii, iColoane, iRegula;
string** sTab;
string sJucator1, sJucator2;
cout<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< "-=-=- 1. Incepere joc -=-=-" << endl
<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< endl;
sTab = setareTablaRegulaSemne (iLinii, iColoane, iRegula, sJucator1, sJu
cator2);
int iAlegere;
do {
cout << "\nAlegeti jucatorul care muta primul (1 sau 2): ";
cin >> iAlegere;
}
while ( (iAlegere > 2) || (iAlegere < 1) );
afisareTabla (sTab, iLinii, iColoane, iRegula);
cout << "\nMutarea se face be baza de coordonate." << endl
<< "Se introduce 'x' si apoi 'y'." << endl
<< " 'x' = numarul liniei" << endl
<< " 'y' = numarul coloanei" << endl << endl;
if (iAlegere == 1) {
afisareMutare (1, sJucator1);
mutare (sTab, sJucator1, sJucator1, sJucator2, iLinii, iColoane,
iRegula);
}
else {
afisareMutare (2, sJucator2);
mutare (sTab, sJucator2, sJucator1, sJucator2, iLinii, iColoane,
iRegula);
}
dealocaTabla (sTab, iLinii, iColoane);
}
//se citesc marimile matricei de joc si regula de joc;
//se aloca dinamic matricea;
/* matricea jocului e mai bogata cu cate 2 linii si 2 coloane, care nu pot fi ma
rcate cu X sau 0,
nici nu sunt afisate, sunt folosite doar pentru verificare in ce
le 8 sensuri, pentru
a evita iesirea din limitele matricii */
//jucatorii isi aleg semnele de joc
string** setareTablaRegulaSemne (int &iLinii, int &iColoane, int &iRegula, strin
g &sJucator1, string &sJucator2) {
do {
cout << "Numarul de linii: ";
cin >> iLinii;
cout << "Numarul de coloane: ";
cin >> iColoane;
if ( (iLinii <3) || (iColoane <3) ) {
coutc (hred, "Numarul minim de linii si de coloane este:
3");
coutc (grey, "\n");
}
}
while ( (iLinii <3) || (iColoane <3) );
do {
cout << "\nNumarul semnelor pentru a castiga (regula): ";
cin >> iRegula;
if ( (iRegula > iLinii) || (iRegula > iColoane) ) {
coutc (hred, "Regula nu poate fi mai mare decat numarul
liniilor sau a coloanelor!");
coutc (grey, "\n");
}
if ( (iRegula <3) ) {
coutc (hred, "Imposibil de jucat cu mai putin de 3 semne
!");
coutc (grey, "\n");
}
}
while ( (iRegula > iLinii) || (iRegula > iColoane) || (iRegula <3) );
string** a = new string *[iLinii+2];
for (int i=0; i<iLinii+2; i++) {
a[i] = new string [iColoane+2];
for (int j=0; j<iColoane+2; j++) {
a[i][j] = "+";
}
}
char cAlegere;
do {
cout << endl << "Jucatorul 1 alege semnul de joc (X sau 0): ";
cin >> cAlegere;
cout << endl;
switch (cAlegere) {
case 'x':
case 'X':
sJucator1 = "X";
sJucator2 = "O";
cout << "Jucatorul 1 a ales: ";
coutc (hgreen, "X");
coutc (grey, "\n");
cout << "Jucatorul 2 va juca cu: ";
coutc (hred, "O");
coutc (grey, "\n");
break;
case 'o':
case 'O':
case '0':
sJucator1 = "O";
sJucator2 = "X";
cout << "Jucatorul 1 a ales: ";
coutc (hred, "O");
coutc (grey, "\n");
cout << "Jucatorul 2 va juca cu: ";
coutc (hgreen, "X");
coutc (grey, "\n");
break;
default:
coutc (hred, "Alegere gresita!");
coutc (grey, "\n");
}
}
while ( !( (cAlegere == 'x') || (cAlegere == 'X') || (cAlegere == 'o') |
| (cAlegere == 'O') || (cAlegere == '0') ) );
return a;
}
//dealocarea matricei dinamice
void dealocaTabla (string** a, int iLinii, int iColoane){
for (int i=0; i<iLinii+2; i++) {
delete a[i];
}
delete a;
}
//afiseaza tabla de joc cu coordinate si X-O-uri colorate;
//este apelata dupa fiecare mutare
void afisareTabla (string** a, int iLinii, int iColoane, int iRegula) {
system ("cls");
cout<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< " Regula este: " << iRegula << endl
<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< endl;
cout << endl << setw(4) << " ";
for (int coord=0; coord<iColoane; coord++) {
coutc (hyellow, coord+1);
}
cout << endl << endl;
int coord=1;
for (int i=1; i<iLinii+1; i++) {
coutc (hyellow, coord++);
coord--;
cout << "";
for (int j=1; j<iColoane+1; j++) {
if (a[i][j] == "X") {
coutc (hgreen, a[i][j]);
}
else {
if (a[i][j] == "O") {
coutc (hred, a[i][j]);
}
else {
coutc (dgrey, a[i][j]);
}
}
}
coutc (hyellow, coord++);
cout << endl << endl;
}
cout << setw(4) << " ";
for (int coord=0; coord<iColoane; coord++) {
coutc (hyellow, coord+1);
}
coutc (grey, "\n\n");
}
//este apelata la inceput, si apoi se apeleaza recursiv alternand jucatorii
//apeleaza functia de verificare a corectitudinii mutarilor
//apeleaza functia de verificare al unui posibil castigator;
//apeleaza functia de verificare al unui posibil sfarsit de joc;
void mutare (string** a, string sJucatorCurent, string sJucator1, string sJucato
r2, int iLinii, int iColoane, int iRegula) {
int x, y, bMutareCorecta, bSfarsitJoc;
do {
cout << " (orizontal/linia) : ";
cin >> x;
cout << " (vertical/coloana): ";
cin >> y;
bMutareCorecta = verificaMutareCorecta (a, x, y, iLinii, iColoan
e);
}
while (bMutareCorecta == 0);
a[x][y] = sJucatorCurent;
afisareTabla (a, iLinii, iColoane, iRegula);
verificaCastig (a, sJucatorCurent, sJucator1, sJucator2, x, y, iRegula);
verificaSfarsitJoc (a, iLinii, iColoane);
if (sJucatorCurent == sJucator1) {
afisareMutare (2, sJucator2);
mutare (a, sJucator2, sJucator1, sJucator2, iLinii, iColoane, iR
egula);
}
if (sJucatorCurent == sJucator2) {
afisareMutare (1, sJucator1);
mutare (a, sJucator1, sJucator1, sJucator2, iLinii, iColoane, iR
egula);
}
}
//"Jucatorul 1/2 (X/O) muta: " decide daca e vorba de 1 sau 2, respectiv X sau O
, si coloreaza in mod adecvat
void afisareMutare (int i, string sJucatorUrmator) {
cout << endl << "Jucatorul " << i << " (";
if (sJucatorUrmator == "X") {
coutc (hgreen, "X");
}
else {
coutc (hred, "O");
}
coutc (grey, "");
cout << ") muta: " << endl;
}
//verifica daca s-au intrecut limitele tabelei de joc
//verifica daca cumva campul ales este deja ocupat
int verificaMutareCorecta (string** a, int x, int y, int iLinii, int iColoane) {
if ( (x < 1) || (x > iLinii) || (y < 1) || (y > iColoane) ) {
coutc (hred, "Coordonate gresite!\nNumarul minim de linii si de
coloane este: 1");
coutc (hred, "\nNumarul maxim de linii: "); coutc (hred, iLinii)
;
coutc (hred, "\nNumarul maxim de coloane: "); coutc (hred, iColo
ane);
coutc (grey, "\n");
return 0;
}
if ( (a[x][y] == "X") || (a[x][y]) == "O" ) {
coutc (hred, "Campul este deja ocupat. Introduceti alte coordina
te!");
coutc (grey, "\n");
return 0;
}
else {
return 1;
}
}
//algoritmul cel mai interesant :)
//incepand cu ultimul camp marcat verifica daca exista un sir de semne de acelas
tip in 8 sensuri
//cele 8 sensuri fiind: sus, jos, stanga, dreapta, dreapta-sus, stanga-sus, drea
pta-jos, stanga-jos
//practic porneste pe rand in 4 sensuri si daca nu gaseste numarul necesar pt. a
castiga porneste in sensul opus!
//apeleaza functia de verificare a contorului
void verificaCastig (string** a, string sJucatorCurent, string sJucator1, string
sJucator2, int x, int y, int iRegula) {
int inX = x, inY = y, iContor = 0;
// stanga ==> dreapta
x = inX; y = inY; iContor = 0;
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
--y;
}
if (iContor == 0) {
y = inY;
}
else {
y = inY+1;
}
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
++y;
}
// sus ==> jos
x = inX; y = inY; iContor = 0;
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
--x;
}
if (iContor == 0) {
x = inX;
}
else {
x = inX+1;
}
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
++x;
}
// stanga-sus ==> dreapta-jos
x = inX; y = inY; iContor = 0;
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
--x;
--y;
}
if (iContor == 0) {
x = inX;
y = inY;
}
else {
x = inX+1;
y = inY+1;
}
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
++x;
++y;
}
// dreapta-sus ==> stanga-jos
x = inX; y = inY; iContor = 0;
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
--x;
++y;
}
if (iContor == 0) {
x = inX;
y = inY;
}
else {
x = inX+1;
y = inY-1;
}
while (a[x][y] == sJucatorCurent) {
iContor++;
verificaContor (iContor, iRegula, sJucatorCurent, sJucator1, sJu
cator2);
++x;
--y;
}
}
//verifica daca contorul a atins numarul regulii de joc, insemnand ca jucatorul
curent a castigat
void verificaContor (int iContor, int iRegula, string sJucatorCurent, string sJu
cator1, string sJucator2) {
if (iContor >= iRegula) {
if (sJucatorCurent == sJucator1) {
cout << "Jucatorul 1 (";
if (sJucator1 == "X") {
coutc (hgreen, "X");
}
else {
coutc (hred, "O");
}
coutc (grey, "");
cout << ") a castigat!" << endl;
}
else {
cout << "Jucatorul 2 (";
if (sJucator2 == "X") {
coutc (hgreen, "X");
}
else {
coutc (hred, "O");
}
coutc (grey, "");
cout << ") a castigat!" << endl;
}
cout << endl << "Apasati ENTER pentru a reveni la meniu.";
getchar();
getchar();
main();
}
}
//verifica matricea de joc, la primul camp "+" abandoneaza ciclurile repetitive
si decide ca jocul nu s-a terminat
//in caz contrar ajungand la sfarsitul ciclurilor decide ca jocul a luat sfarsit
(matricea de joc nu mai contine "+"-uri)
void verificaSfarsitJoc (string** a, int iLinii, int iColoane) {
int bSfarsitJoc = 1;
for (int i=1; i<iLinii+1; i++) {
for (int j=1; j<iColoane+1; j++) {
if (a[i][j] == "+") {
bSfarsitJoc = 0;
break;
}
}
if (bSfarsitJoc == 0) {
break;
}
}
if (bSfarsitJoc == 1) {
cout << endl << "Joc nedecis!\nApasati ENTER pentru a reveni la
meniu.";
getchar();
getchar();
main();
}
}
//o functie gasita pe net, folosita pt colorarea textelor/variabilelor afisate
//din cate inteleg cauta HANDLE-ul (HANDLE = un fel de variabila de control al p
roceselor din Windows???) componentei de iesire
//acesta fiind consola (deoarece folosim 'cout = console out') ==> ii schimba pe
rmanent culoarea textului
void coutc (int color, string output) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute (handle, color);
cout << setw(4) << output;
}
void coutc (int color, int output) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute (handle, color);
cout << setw(4) << output;
}
//functia care afiseaza regulile
//o gramada de text
void optiuneaReguli () {
cout<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< "-=-=- 2. Reguli -=-=-" << endl
<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< endl;
cout<< " Veti incepe jocul cu setarea" << endl
<< "marimii tabelei de joc, intai numarul" << endl
<< "de linii, apoi numarul de coloane," << endl
<< "urmat de regula de joc." << endl
<< endl
<< " 'Regula de joc' inseamna de cate" << endl
<< "semne consecutive de acelas tip" << endl
<< "(de exemplu de cate 'X'-uri) veti" << endl
<< "avea nevoie pentru a castiga jocul." << endl
<< endl
<< " Jucatorul cu nr. 1 isi va alege" << endl
<< "semnul, iar jucatorului cu nr. 2 ii" << endl
<< "va fi automat atribuit celalalt semn." << endl
<< endl
<< " Se va alege care jucator (1 sau 2)" << endl
<< "va incepe jocul." << endl
<< endl;
cout<< "Apasati ENTER pentru a continua!";
getchar();
getchar();
system("cls");
cout<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< "-=-=- 2. Reguli -=-=-" << endl
<< "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl
<< endl
<< " Marcarea casutelor se va face pe" << endl
<< "baza de coordinate. Intai va trebui" << endl
<< "sa introduceti numarul liniei, apoi" << endl
<< "numarul coloanei." << endl
<< endl
<< " De exemplu:" << endl
<< endl
<< "Jucatorul 1 ( X ) muta:" << endl
<< " (orizontal/linia) : 3 <ENTER>" << endl
<< " (vertical/coloana): 5 <ENTER>" << endl
<< endl
<< "va marca campul de pe a 3-a linie" << endl
<< "a coloanei a 5-a cu un 'X'." << endl
<< endl
<< " Jucatorii vor introduce" << endl
<< "coordinatele alternativ." << endl
<< endl;
cout<< "Apasati ENTER pt. a reveni la meniu.";
getchar();
main();
}

You might also like