Sunteți pe pagina 1din 96

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Facultatea Calculatoare, Informatic i Microelectronic
Catedra Calculataore

Teza de curs
Disciplina: Structuri de date i Algoritmi
Tema: Simularea unui Joc Sah.

A ndeplinit: st.gr.
A verificat: conf.univ. Marin Stefan

Chisinu
Aprob

ef catedr IA
________________conf. V. Moraru

Sarcina
tezei de an la disciplina Structuri de Date i Algoritmi

Studentul grupei C-142 (Nume, prenume)_____________________________________________________________

Tema:___________________________________________________________________

_____________________________________________________________________________________

DOMENIUL DE APLICARE ___________________________________________________________

_____________________________________________________________________________________

METODA, TEHNICA I ALGORITMII _________________________________________________

_____________________________________________________________________________________

MODELE DE STRUCTURI DE DATE __________________________________________________

_____________________________________________________________________________________

STILUL ELABORRII PROGRAMULI: STRUCTURAT, MODULAR, MENIURI .A.________________

_____________________________________________________________________________________

MATERIALE GRAFICE (SCHEMA-BLOC, GRAFICE, DESENE ETC.) _____________________

_____________________________________________________________________________________

STUDIUL COMPARTIMENTELOR SPECIALE _________________________________________

_____________________________________________________________________________________

Semntura studentului_______________

Data limit de susinere 21-05-2015

Conductorul tefan Marin

2
Sarcina lucrrii

17. Aplicatia Algoritmii si programul care va simula un joc sah

3
Cuprins

1. Capitalul 1
Analiza principiilor elaborarii aplicatie .................................................5

2. Capitolul 2
Analiza avantajelor elaborarii aplicatie in C++ ................................................. 6

3. Capitolul 3
Analiza scenariului a jocului de sah ........................14

4. Capitalul 4
Analiza implimintarii tehnici de programare....................................................15

5. Capitolul 5
Analiza regulilor de joc......................................................................................22

6. Capitolul 6
Instructiunile Globale ........................................................................................27

7. Capitolul 7
Incapsularea clase piese.....................................................................................36

8. Capitolul 8
Functia Principala Main( ) .................................................................................41

9. Exemple de programe atestate care au legatura direscta cu tema..........................44

Anexa 1. Listingul Programului dotat cu comentarii 48

4
Anexa 2. Rezultatele rulrii programului ..85

Concluzia....................................................................................................................87

Biografia.....................................................................................................................89

5
Capitolul I

Analiza principiilor elaborarii aplicatie.

Jocul de sah s-a nascut cel mai probabil in extremul Orient cu multe milenii in urma, intruchipand
fidela replica a unui razboi intre doua armate. Fascinat inca de mic de legenda nobilului intelept care se
spune ca a creat jocul de sah pentru a alunga plictiseala imparatului Indiei si care, pentru magistrala
creatie nu a solicitat decat o rasplata umila, si anume: un bob de grau pentru primul patrat al tablei de sah,
doua pentru al doilea si de cate doua ori mai multe pentru fiecare din cele saizeci si patru din campurile
esicherului. Mult mai tarziu am realizat ca 18 446 774 073 709 551 615 boabe de grau reprezentau,
probabil recolta mondiala pe cateva zeci sau sute de ani si ca aceasta era numai una din multele legende
care invaluie in mister inceputurile sahului.

Am fost de mic familiarizat cu disputa sahista, frecventand cluburi si cercuri sahiste si acordand
pana si in present o fractie considerabila de timp jocului. Sahul este un exercitiu al spiritului, presupune o
lupta cu un adversar in conditiile unei dispute cat se poate de echitabile. Sahul pune la incercare
inteligenta, perspicacitatea si prezenta de spirit. Jocul de sah reprezinta prin excelenta unul dintre
domeniile a caror cunoastere totala pare imposibila. Numarul practic infinit de mutari si variante posibile
poate sa starneasca un veritabil sentiment de curiozitate (celor care se aventureaza in acest imens labirint,
aparent fara iesire). Caracterul atractiv, distractiv al jocului de sah ofera oricui posibilitatea de a-si pune
in valoare si de a evidentia propriile capacitati, favorizand interactiunea tuturor factorilor psihici ce
contribuie si influenteaza activitatea de cunoastere, dezvoltarea curiozitatii si dorintei de a dezlega tainele
acestuia.

Necesitatea realizarii unui program pe calculator pentru a inlocui clasica tabla de sah este una
normala, asadar si urmareste alinierea gandirii sahiste la exigentele calculului artificial generat de un
algoritm. Computerul creaza conditiile si mecanismul jocului de sah, asumandu-si importantul rol de
mediator si arbitru in cadrul disputei dintre doi adversari umani.

6
Capitolul II

Analiza avantajelor elaborarii aplicatie in C/C++

In anul 1970, doi programatori, Brian Kerninghan si Dennis Ritchie, au creat limbajul C. Principalul
scop pentru care a fost realizat acest limbaj este rescrierea sistemului de operare UNIX, pentru a-l face
portabil pe toate platformele existente. Marele avantaj al limbajului C este acela de a fi extrem de flexibil
si de a permite atat programarea la nivel inalt cat si la nivel scazut. C-ul este un limbaj procedural, asadar
un program scris in C incepe de obicei cu definirea structurilor de date, apoi definirea functiilor pentru
lucrul cu aceste structuri.

Cresterea complexitatii programelor a dus la necesitatea elaborarii unor alte tipuri de limbaje.
Astfel, destinate inteligentei artificiale, au aparut limbajele care au la baza notiunea de 'cadru' si cele care
pleaca de la ideea de 'actor'. Primele implementeaza operatii asupra unor modele de entitati; celelalte
presupun faptul ca obiectele nu sunt simple elemente pasive asupra carora se fac anumite prelucrari, ci,
dimpotriva, ca menirea acestor obiecte consta in a realiza prelucrarile asupra lor insile.

De aici a pornit ideea de a grupa structurile de date cu operatiile care prelucreaza respectivele date.
Astfel s-a nascut notiunea de obiect sau clasa. Proiectarea de programe utilizand clase se numeste
programare orientata pe obiecte (OOP).

Primele limbaje orientate pe obiecte au fost SIMULA (1965) si SIMULA-2 (1967). In anii '70 a
aparut si celebrul limbaj SMALLTALK. Cel mai mare dezavantaj al lor a fost faptul ca au aparut ca
limbaje de sine statatoare, avand o raspandire relativ redusa. Din acest motiv, putin programatori erau
dispusi in acea vreme sa renunte la limbajele consacrate doar pentru a lucra obiectual.

In anul 1980, Bjarne Stroustrup a conceput limbajul 'C with Classes'. Acest limbaj a dus la
imbunatatirea C-ului prin adaugarea unor noi facilitati, printre care si lucrul cu clase. In vara 1983, C-
with-classes a patruns si in lumea academica si a institutiilor de cercetare. Astfel, acest limbaj a putut sa
evolueze datorita experientei acumulate de catre utilizatorii sai. Denumirea finala a acestui limbaj a fost
C++.

Succesul extraordinar pe care il are limbajul C++ a fost asigurat de faptul ca a extins cel mai
popular limbaj al momentului, C. Programele scrise in C functioneaza si in C++, si ele pot fi transformate
in C++ cu eforturi minime.

Instructiuni conditionale

In limbajul C intalnim doua instructiuni conditionale (if si switch), precum si o varianta imediata
a instructiunii if. Le vom descrie pe rand insistand asupra modalitatii de folosire si a greselilor frecvent
intalnite. Insa, inainte de aceasta vom detalia notiunea de conditie in acceptiunea limbajului C si vom
prezenta operatorii logici acceptati.

In limbajul C nu exista un tip logic de sine statator cum exista in Pascal tipul boolean. Pentru un
plus de flexibilitate si o mai mare putere de exprimare s-a convenit ca orice tip de variabila/expresie ce

7
poate fi evaluata la un tip diferit de tipul void sa poata fi considerata o expresie logica. Conventia
este ca orice expresie/variabila/constanta care este evaluata la o valoare nenula (diferita de 0) sa fie
considerata ca avand valoarea de adevar adevarat si orice expresie /variabila /constanta care este nula sa
fie considerate ca avand valoare de adevar fals. Pentru a clarifica acest concept vom prezenta cateva
exemple de conditii. La inceput vom declara cateva variabile:

int x = 3;
char ch = A;
char chn = 0x0;
float r = 0.0;
unsigned long ul = 0;

Acum sa vedem cateva expresii logice formate cu variabilele de mai sus si valoarea lor de adevar:

x - este o expresie care fiind diferita de 0 (3 != 0), se va evalua la adevarat

chn - este o expresie care fiind 0 (caracterul avand codul ASCII 0) este considerata falsa

x + ul - este o expresie a carei valoare este 3 + 0 = 3, adica adevarata

ch * 0 - este o expresie a carei valoare este 0 (A are codul ASCII 65, iar 65 * 0= 0), deci falsa

x / ch - este o expresie a carei valoare este 0 (3 / 65 in numere intregi are valoarea 0), deci falsa

sqrt(x) - este o expresie a carei valoare este nenula, radical din 3 este aprox. 1.732

De obicei nu vom testa pur si simplu o variabila, sau o expresie simpla, ci vom folosi operatori
pentru a defini o conditie. Deoarece in acceptiunea C nu exista un tip logic ci orice expresie poate fi o
conditie, se pot folosi absolut toti operatorii in cadrul expresiei (aritmetici, relationali, logici, pe biti, de
egalitate, etc). Operatorii logici (a nu se confunda cu operatorii aritmetici, relationali, de egalitate sau pe
biti care pot fi folositi in expresiile care se evalueaza pentru conditie) suportati de Csunt:

&& -si logic. Returneaza adevarat daca ambele expresii se evalueaza la valori nenule, altfel
returneaza fals. Daca prima expresie este evaluata la 0 (fals), a doua expresie nu se mai evalueaza. Acest
lucru poate cauza erori de programare greu de detectat in cazul in care cea de a doua expresie contine un
apel de functie. Apelul va avea loc numai daca prima conditie se evalueaza la adevarat (valoare nenula).

Atentie: un singur simbol & inseamna si pe biti si este diferit de &&.

|| -sau logic. Returneaza adevarat daca cel putin una din expresii se evalueaza la o valoare nenula.
In cazul in care prima expresie este adevarata, cea de a doua nu se mai evalueaza. Remarca este absolut
similara cu cea de la si logic.

Atentie: un singur simbol | insemna SAU pe biti si este diferit de ||.

! -negatie logica; Returneaza adevarat daca expresia este nula, fals in caz contrar. (!E) este
echivalent cu (E == 0).

Alti operatori mult folositi in conditii sunt operatorii de egalitatate:

8
== -egal. Returneaza adevarat (valoare nenula) daca cele doua expresii sunt egale, fals (0) daca cele
doua expresii sunt diferite. Din punct de vedere logic (E1 == E2) este echivalent cu (!(E1 - E2))

!= -diferit. Semnificatia este opusa operatorului ==. In consecinta, din punct de vedere logic (E1!=
E2) si (E1 - E2) sunt echivalente.

Ultimii operatori amintiti sunt cei relationali:

< -mai mic. Returneaza adevarat daca valoarea expresiei din stanga este mai mica decat a celei din
dreapta. Normal ca ambele expresii trebuie sa fie de tip scalar/numeric (integer/real/caracter/etc) pentru
ca sa se poate face comparatia.

<= -mai mic sau egal. Returneaza adevarat daca valoarea expresiei din stanga este mai mica sau
egala cu cea din dreapta.

> -mai mare. Returneaza adevarat daca valoarea expresiei din stanga este mai mare ca si cea din
dreapta.

>= -mai mare sau egal. Returneaza adevarat daca valoarea expresiei din stanga este mai mare sau
egala cu cea din dreapta.

Acum, dupa ce am prezentat cele mai importante lucruri despre ceea ce inseamna o conditie si care
sunt operatorii care pot fi folositi in definirea conditiilor, vom trece in revista instructiunile conditionale.

Conditia (- if):

Sintaxa instructiunii este:

if ( <conditie> ) <instructiune1>;

Sau in varianta cu executie alternativa (executie pentru cazul in care conditia este falsa)

if ( <conditie> ) <instructiune1>;

else <instructiune2>;

In ambele cazuri prin instructiune se intelege fie o instructiune simpla, fie una compusa (grup de
instructiuni incadrat de ). Conditia poate sa contina dupa cum am mentionat mai sus orice expresie. Este
bine insa sa nu se exagereze la folosirea expresiilor complexe deoarece aceasta afecteaza claritatea
codului.

Un exemplu in care se poate vedea aceasta este urmatorul:

o int x = 3;
o int y = 4;
o if(x = y)
o else
o printf(Conditie falsa);

In mod oarecum surprinzator pentru un neinitiat in C bucata de program la executie va tipari


Conditie adevarata. Aceasta deoarece conditia este x = y, adica o atribuire si nu o comparatie
(comparatia ar fi fost x == y), iar atribuirea primeste ca valoare, valoarea atribuita (4 in cazul nostru).

9
Recomandam o folosire mai putin tipica C, dar mult mai usor de inteles:

o int x = 3;
o int y = 4;
o x = y;
o if(x != 0) //mai normal pentru C++ ar fi fost sintaxa echivalenta if(x)

Mai facem doua remarci pentru instructiunea if. Este obligatoriu simbolul de terminare instructiune
; inainte de else. In cazul in care avem mai multe instructiuni if/else imbricate se recomanda folosirea
parantezelor acoladice pentru a ne asigura ca ramura de else se va interpreta pentru ramura de if la care ne
asteptam. De exemplu:

if(conditie_a)

else

Operatorul conditional (if imediat) ? :

In multe cazuri avem de atribuit o anumita valoare unei variabile in functie de o anumita conditie.
Sa presupunem urmatorul scenariu. Daca conditia_a este adevarata atunci vrem sa atribuim variabilei x
valoarea 1, daca nu valoarea 3. Evident acest lucru se poate scrie folosind instructiunea if:

o if(conditia_a)
o x = 1;
o else
o x = 3;

O alta posibilitate mult mai compacta si mai usor de scris este folosind operatorul if imediat:

x = (conditia_a) ? 1 : 3;

Instructiunea switch:

Formatul instructiunii este: switch ( <variabila> )

Este o instructiune folosita cand se doreste ca in functie de valoarea unei anumite expresii
(<variabila>) numerice sa se execute un grup de instructiuni. De obicei se foloseste in cazul in care avem
mai mult de trei variante (pentru 2 variante este mai comoda varianta cu if). Ca si interpretare in cazul in
care break este prezent pe toate ramurile de case, este echivalenta cu:

if(<variabila> == <constanta1>) <instructiune1>;

else if(<variabila> == <constanta2>) <instructiune2>;

else <instructiune_def>;

In cazul in care break nu este prezent pe una din ramuri se va executa in continuare instructiunea de
pe ramura urmatoare. O greseala comuna este uitarea instructiunii break in totalitate, in acest caz se vor
executa toate instructiunile situate mai jos de ramura de case pe care este selectata executia.

10
ex.

unsigned int uTest = 3; //evident in acest caz se va intra doar pe ramura pentru // valoarea 3,

//daca aceasta exista, altfel pe ramura default daca exista

unsigned uVal = 0;

switch(uTest)

Daca nu ar fi existat instructiunile break s-ar fi executat uVal = 78 si apoi uVal = 0, deoarece
neexistand instructiunea break de iesire din switch executia se continua liniar ignorand selectiile din
case. Desi aceasta pare un deficit, in fond este un avantaj, permitand un cod mai compact in cazul in care

conditiile din case sunt cumulative (adica pentru prima ramura se executa si codul de pe cea de a
doua ramura, etc.).

Instructiuni de ciclare:

In C instructiunile care pot fi folosite pentru a cicla (executa un grup de mai multe

instructiuni -numit si bucla de ciclare- in mod repetat) sunt:

- for

- while

- do while

Toate aceste instructiuni folosesc conditii pentru a iesi din bucla de ciclare. Reamintim ca in C o
conditie este formata din orice expresie, nu exista un tip specific 'logic' pentru conditii ca si in alte limbaje
de programare. Expresia care formeaza conditia este analizata si daca este diferita de zero se considera
valoare 'adevarat', iar daca este egala cu zero se considera 'fals'.

Vom analiza pe rand instructiunile de ciclare si vom specifica pentru fiecare cateva modalitati tipice
de folosire. Inainte insa vom reaminti cateva notiuni despre sirurile de caractere, deoarece o utilizare
tipica a tuturor instructiunilor de ciclare este parcurgerea sirurilor de caractere si executarea unor anumite
operatiuni pe acestea. Cele mai multe din exemple vor lucra cu siruri de caractere sau de intregi. Sirurile
de caractere in C/C++ sunt stocate ca si secvente de caractere in memorie terminate prin caracterul 0. Nu
este stocata lungimea in mod explicit. De exemplu cuvantul ABC este stocat in memorie ca un sir de
caractere A B C 0x0. Numeric in memorie se vor gasi codurile ASCII: 65 66 67 0, sau in hexazecimal
0x41 0x42 0x43 0x0. Sirurile sunt referite in general de pointeri la caracter. Deoarece in C++ un nume de
matrice/vector este un pointer constant la sirul -primul element din sir de fapt, dar acesta este urmat in
memorie de restul elementelor din sir- de caractere/elemente din matrice/vector, acesta se poate folosi
pentru a cicla peste vectorul respectiv. De exemplu urmatorul cod declara o variabila de tip sir de
caractere, apoi copiaza in sirul respectiv un alt sir, iar in final tipareste sirul..

unsigned char strBuffer[256];

strcpy(strBuffer, Un alt sir);

11
printf(strBuffer);

Instrctiunea for:

Sintaxa instructiunii este prezentata mai jos.

for ( [<instructiuni_initializare>] ; [<conditie_ciclare>] ; [<instructiuni_incrementare>] )

<instructiune_bucla>;

Este probabil cea mai folosita instructiune de ciclare, prin ea se pot emula toate celelalte
instructiuni.

In pozitia instructiuni_initializare se pot include mai multe instructiuni separate prin virgula ,.
Acestea pot fi declaratii de variabile, initializari, etc. Se vor executa la inceputul buclei, inainte de orice
instructiune din bucla. In cadrul instructiuni_incrementare se respecta aceleasi reguli, doar ca aceste
instructiuni se vor executa la fiecare ciclare. In mod normal aici se vor afla instructiuni care modifica
contoarele folosite in ciclu si in baza carora se va testa iesirea din bucla. Testul se va face in
conditie_ciclare. Conditia se testeaza pentru fiecare executie a buclei, inclusiv prima executie. sa
vedem de exemplu cum putem parcurge un sir de caractere, modificand caracterele la majuscule (in
engleza UpCase):

unsigned char strSir[256];

sscanf(Introduceti un sir de caractere (cuvant/propozitie): %s, strSir); //citim

for(int iIndex = 0; (strSir[iIndex]) && (iIndex < 256); iIndex++)

strSir[iIndex] = UpCase(strSir[iIndex]);

printf(nSirul convertit la majuscule: %sn, strSir);

Ne vom concentra asupra instructiunii for. La initializare pornim un contor care va creste de la 0
pana la valoarea pe care se afla pozitia ultima in sir (caracterul 0). Variabila declarata in cadrul
instructiunilor de initializare este local buclei for si nu poate fi folosita in afara ei. In conditie testam doua
lucruri: caracterul din sir de pe pozitia indicata de iIndex sa fie diferit de 0 si sa nu depasim
dimensiunea sirului. De obicei al doilea test nu se mai face, in cazul in care sirul este folosit corect, nu se
va ajunge niciodata sa se depaseasca dimensiunea maxima. Daca in schimb se incerca a se copia in spatiul
destinat unui sir un sir care este mai mare decat spatiul respectiv se poate ajunge in situatia in care nu mai
exista caracterul 0 de terminare si atunci se va depasi zona de date alocata sirului, algoritmul mergand in
continuare pana intalneste primul 0 in memoria de dupa sir (aceasta generand un memory overwrite si o
comportare aleatoare a programului).

Sa vedem de exemplu un mic program care determina lungimea unui sir de caractere (echivalent cu
strlen):

#include <stdio.h>

void main(void)

Ca si in cazul instructiunii switch este posibil sa folosim break pentru a intrerupe in mod fortat
bucla. O alta instructiune de control al executiei in cadrul buclei este continue care trece controlul la

12
inceputul buclei. De exemplu daca vrem sa parcurgem un sir de 20 de elemente si in loc de fiecare
element sa setam inversul acestuia (1/x, evident doar daca acesta este nenul).

float array[20];

void main ()

Instructiunea while:

Sintaxa instructiunii este urmatoarea:

while ( <conditie> ) <instructiune>;

Este folosita pentru ciclurile in care conditia nu depinde de un contor. De exemplu unul din cazurile
cele mai folosite sunt la citirea dintr-un fisier. Exemplul de mai jos prezinta un ciclu in care se citesc
dintr-un fisier (c:test.txt) blocuri de 1MB si se afiseaza de fiecare data nr. de bytes (octeti) cititi (cu unele
modificari s-ar putea folosi ca si un program de cautare in fisiere a unui text, sau de copiere).

const int BufferSize = 1024L * 1024L;

int *Buffer = (int *)malloc(BufferSize); //1Mb = 1024 * 1024 bytes

int fin = open(c:test.txt, O_RDONLY | O_BINARY);

int iBytesRead;

while((fin != -1) && (!eof(fin)))

close(fin);

Se remarca folosirea unor altor instructiuni de lucrul cu fisiere fata de articolul trecut. In mod
normal acestea sunt preferate -mai noi si mai eficiente-, desi in cele mai multe cazuri pentru convenienta
data de fprintf si fscanf se folosesc instructiunile mai vechi fopen,fclose.

Echivalentul in Pascal al instructiunii este while do. Mentionam aceasta pentru a se evita confuzia
dintre while si do while -ambele instructiuni C++. Prima testeaza conditia la inceput de bucla, a doua
executa bucla si abia apoi testeaza conditia (la sfarsit de bucla). In cazul while se poate intampla ca sa nu
se execute bucla nici macar o data daca la evaluarea conditiei de ciclare aceasta este mereu falsa. Ca si in
cazul instructiunii for se pot folosi break si continue pentru a intrerupe executia sau a relua executia de
la inceputul buclei (cu reevaluarea conditiei).

Instructiunea do while:

In cazurile in care este necesara cel putin o parcurgere a buclei inainte de testare se foloseste
instrucsiunea dowhile. Sintaxa ei este redata mai jos:

do <instructiune> while ( <conditie> );

Echivalentul ei in Pascal este repeat until. Ca si la while se folosesc


instructiunile break si continue pentru a controla executia in interiorul buclei. Diferenta vine din faptul
ca se executa in mod sigur cel putin o data bucla, pe cand la while bucla poate sa nu se execute deloc daca

13
se evalueaza la fals conditta in momentul atingerii instructiunii while. Mai jos dam un exemplu de
program care foloseste bucla do while pentru a testa introducerea unei parole:

#include <stdio.h>

#include <string.h>

int main ()

while (strcmp(pass, control));

return 0;

In cazul in care parola se va potrivi cu cea stocata in variabila checkword, functia strcmp (compara
doua stringuri) va intoarce 0 si conditia de iesire din bucla se va evalua la fals, parasindu-se bucla.

In cazul instructiunii do while la intanirea instructiunii continue nu se testeaza conditia (normal


daca ne gandim ca executia se reia de la inceputul buclei si conditia se testeaza la sfarsitul buclei).

14
Capitolul III

Analiza scenariilor de joc in Sah.

Jocul de sah este o disputa intre doi adversari pe o tabla de joc cu 64 de campuri ( 8 x 8 ) si 32
de piese (16 albe si 16 negre). Jucatorii muta alternative cate o piesa. Fiecare jucator dispune de un
rege, oregina, doua turnuri, doi nebuni, doi cai si opt nebuni , pozitia initiala fiind cea din
diagrama:

Liniile esicherului se numeroteaza cu cifre de la 1 la 8 iar


coloanele de la a la h, ca in diagrama.

Regele muta un camp in orice directie, regina efectueaza mutari


oricat de lungi pe linia, coloana sau una din diagonalele pe care se
gaseste; turnurile muta numai pe aceeasi linie sau coloana, nebunii pe
diagonala; caii efectueaza o mutare conjugata an forma de L.
Piesele nu pot sari peste alte piese in miscarea lor )afara de cai, care
nu au nici o restrictie in acest sens) si cand intampina o piesa adversa
o captureaza, eliminand+o de pe tabla. Mutarea pionului se realizeaza
astfel: din pizitia initiala maxim doua campuri pe verticala, apoi
numai cate unul singur. Pionul captureaza numai pe diagonala, mai
exact poate captura o piesa adversa care se gaseste pe unul din
campurile din fata sa , pe diagonala si la distanta de un singur camp.
Spre deosebire de fuguri, pionul nu poate muta niciodata inapoi. Cand
un pion ajunge pe ultima linie (a 8-a pentru alb si prima pentru negru ) se transforma intr-o figura, la alegere. Un
pion deplasat cu doua campuri din pozitia initiala poate fi capturat de un pion advers situat in stanga sau in dreapta
pozitiei sale finale prin pozitionarea acestuia din urma pe campul sarit de pion in miscarea sa initiala; procedura
se numeste luarea en passant si poate fi efectuata numai la mutarea imediat urmatoare celei a pionului de
capturat.

Regale aflat in pozitia initiala poate efectua o mutare speciala numita rocada, impreuna cu unul din turnurile
sale.conditiile care trebuie indeplinite pentru ca aceasta mutare sa poata fi efectuata sunt urmatoarele: regale sa nu
fie atacat nici in pozitia initiala si nici in pozitia finala, campul dintre acestea (unde va ajunge turnul ) de asemenea
sa nu fie atacat de o piesa adversa, atat regale cat si turnul sa nu fi efectuat pana in momentuls respectiv nici o
mutare si sa nu existe nici o piesa intre rege si turn.

Regele se va plasa la doua campuri distanta de pozitia sa initiala, pe orizontala, iar turnul din de pe flancul
respective va ocupa campul dintre rege si pozitia sa initiala.

Scopul jocului este matul.

Cand regale uneia din parti este atacat de o piesa adversa se considera pozitie de sah. Jucatorul cu piesele
respective are obligatia de a apara sahul fie mutand regale, fie capturand piesa atacatoare, fie interpunand o piesa
intre rege si aceasta (aceasta din urma posibilitate nu este valabila in cazul in care regale este atacat de un cal,
evident).

Este mat atunci cand regale uneia din parti este in sah si nu exista nici o mutare valida care sa apere regele.

Partida este declarata remiza cand cei doi regi raman singuri pe tabla sau cand se ajunge la o pozitie de pat.
Este pat cand jucatorul care trebuie sa mute nu are nici o mutare legala disponibila, nefiindu-i atacat regele.

15
Capitolul IV

Analiza implemintarii tehnicii de programare.


Este o tehnic de programare aplicabil algoritmilor care ofer mai multe soluii i are ca rezultat
obinerea tuturor soluiilor problemei. Fiecare soluie se memoreaz ntr-o structura de date de tip stiv
implementat cu ajutorul unui vector.
Deci fiecare soluie poate fi pus sub forma unui vector. ntr-un algoritm backtracking ne
intereseaz toate soluiile posibile. Pentru a obine fiecare soluie final se completeaz stiva nivel cu
nivel trecnd astfel prin soluii pariale. Astfel soluiile finale ct i cele pariale pentru a fi luate n
considerare trebuie s ndeplineasc anumite condiii numite condiii de validare. O soluie care
ndeplinete o astfel de condiie se numete soluie valid.
Toate configuraiile stivei ce reprezint soluii finale sunt alctuite din elementele aceleiai
mulimi bine definite pe care o numim mulimea soluiilor. Fiecare nou soluie parial se obine prin
completarea soluiei pariale precedente cu nc o nivel pe stiv. La fiecare nivel se pun valori din
mulimea soluiilor care nu au fost ncercate pn cnd se obine o soluie valid. n acest moment se trece
la nivelul urmtor n stiv pentru a completa mai departe soluia relund ncercrile pe noul nivel.
La un moment dat pe un anumit nivel nu mai exist nici o valoare nencercat din mulimea
valorilor problemei. n acest caz se face un pas napoi n stiv la nivelul anterior i se reia cutarea cu
valorile rmase nencercate pe acest nivel anterior.
Respectivul nivel a mai fost vizitat dar l-am abandonat dup ce am pus o valoare care a generat o
soluie valid. Deci este posibil s fi rmas aici valori nencercate. Dac nici pe acest nivel nu mai avem
valori nencercate mai facem un pas napoi n stiv. Mecanismul revenirilor a determinat denumirea de
metoda backtracking.
Plecnd de la nivelul 1 i repetnd algoritmul pn cnd pe toate nivelele au fost ncercate toate
valorile din mulimea valorilor se obin soluii finale care se tipresc.
Vom implementa metoda backtracking iterativ folosind o rutin unic aplicabil oricrei
probleme. Rutina va apela funcii care au ntotdeauna acelai nume i care din punct de vedere al metodei
realizeaz acelai lucru.
Sarcina rezolvatorului este s scrie explicit - pentru fiecare problem funciile aplicate de rutin:

1. Fiecare nivel al stivei trebuie iniializat cu o valoare aflat naintea tuturor valorilor posibile din
mulimea soluiilor. Aceast afiare se face cu funcia init().
2. Gsirea urmtorului element netestat de pe un nivel k al stivei St se face cu funcia succesor ()
0, altfel 1, dac exist valoare netestat pentru nivelul k . Dac exist valoare netestat (succesor),
atunci se va alege o nou valoare (netestat) pentru nivelul k.
3. Odat ales un element testarea condiiilor de validare se face cu funcia valid() 0, altfel
1, dac valoarea de p enivelul k ndeplinet e condiondide validare
4. Testul dac s-a ajuns sau nu la o soluie final se face cu funcia soluie () 0, altfel 1,
dac s- a completat ultimul nivel din stiv
5. Soluia se tiprete cu funcia tipar().

R u t i n a B a c k t r a c k i n g I T E R AT I V
k=1; //se completeaz stiva ncepnd cu primul nive
init (); //se iniializeaz primul nivel al stivei
while (k>0)

16
{ do{AS= succesor(); }while (AS && valid()==0);
//se caut succesor pe nivelul k atta timp ct exist successor
care nu este valid

if (AS) //exist successor


if solutie() //dac s-a completat stiva
tipar() //se tiprete soluia
else //stiva nu s-a completat
{
k++; // se trece pe nivelul urmtor
init(); // se iniializeaz noul nivel
}
else k--; // nu exist succesor pentru nivelul k, deci se coboar un nivel in stiva

Prezentarea Tehnicii Backtracking


Aceast tehnic poate fi utilizat pentru rezolvarea problemelor de cutare.
Cutarea
efectuat este exhaustiv, putnd fi folosit pentru generarea tuturor soluiilor
posibile.
Se folosete n rezolvarea problemelor care ndeplinesc simultan urmtoarele
condiii:
Soluia lor poate fi pus sub forma unui vector V = x1x2x3 . xn, cu
x1A1 . Xn An

Mulimile A1, A2, An sunt mulimi finite, iar elementele lor se afl ntr-o
ordine bine stabilit

Nu se dispune de o metod de rezolvare mai rapid


La ntlnirea unei astfel de probleme suntem tentai s generm toate elementele
produsului cartezian A1 A2 . An. Aceasta nu este totui o rezolvare foarte
rezonabil. Timpul de execuie este att de mare, nct poate fi considerat infinit.

Dac de exemplu dorim s generm toate permutrile unei mulimi, genernd


produsul cartezian, am putea obine 1,1,1,.1, pentru ca apoi s constatm c nu
am
obinut o permutare (cifrele nu sunt distincte), dei chiar de la a 2-a cifr se poate
observa
c cifrele nu sunt distincte.

Tehnica Backtracking are la baz un principiu extrem de simplu: se


construiete
soluia pas cu pas. Dac se constat c pentru o anumit valoare nu se poate
ajunge la
soluie, se renun la acea valoare i se reia cutarea din punctul unde am rmas.

Prezentarea algoritmului
Pentru uurarea nelegerii metodei vom prezenta o rutin unic, aplicabil oricrei

17
probleme, rutin care utilizeaz noiunea de stiv.

se alege primul element x1, ce aparine lui A1;

presupunnd generate elementele x1xk, vom avea 2 posibiliti:

1. nu s-a gsit un astfel de element, caz n care se reia cutarea, considernd


generate elementele x1 xk-1, iar aceasta se reia de la urmtorul element Ak,
rmas netestat.

2.a fost gsit, caz n care se testeaz dac acesta ndeplinete anumite
condiii
(rspunsul poate fi verificat de o funcie Validare care returneaz true sau
false).
3.dac le ndeplinete, se testeaz dac s-a ajuns la soluie (se utilizeaz
funcia Soluie, care returneaz true dac s-a ajuns la soluie)

dac s-a ajuns la soluie, se tiprete i se continu algoritmul


pentru gsirea unei alte soluii, considerndu-se generate x1xk, iar
elementul xk+1 se caut printre elementele mulimii Ak+1 rmase
netestate
dac nu s-a ajuns la soluie se reia algoritmul considerndu-se
generate elementele x1, xk, xk+1

4.dac nu le ndeplinete se reia algoritmul considernd generate x1xk, iar


elementul xk+1 se caut printre elementele mulimii Ak+1 rmase netestate

Problema Reginelor.
O s exemplificm tehnica cutrii cu reveniri cu ajutorul unei probleme clasice:
cum putem amplasa N regine pe o tabl de ah cu dimensiuni N x N astfel nct
acestea s
nu se atace dou cte dou.
Este evident c nu putem amplasa dect o singur regin pe linie sau pe coloan i
n final fiecare linie va avea amplasat cte o regin. De aceea vom ncerca
amplasarea
linie cu linie, ncepnd cu prima linie. Atunci cnd ncercm s amplasm o regin
pe o
linie ncepem cu prima coloan i continum cu urmtoarele, pn cnd gsim o
poziie
valid. n momentul n care nu mai gsim nici o poziie valid pe o linie vom reveni
la linia
anterioar, unde vom cuta urmtoarea poziie. S rezolvm, de exemplu, problema
pentru
N = 4.
ncepem cu prima linie i prima coloan:

18
Pe cea de-a doua linie nu putem amplasa nici o dam pn pe cea de-a treia
coloan:

Pe linia a treia nu putem amplasa nici o dam, de aceea vom reveni la linia
anterioar
pentru urmtoarea opiune:

Pe linia a treia prima opiune valid este pe coloana a doua:

Dar acum nu mai avem nici o opiune valid pentru linia a patra. Revenim la linia a
treia.
Dar nici aici nu mai avem nici o opiune valid. De aceea trebuie s revenim la linia
a doua.
Este evident c aici nu mai avem ce face aa c se revine pn la linia a I-a:

Acum putem trece la linia a II-a:

19
Pe linia a treia putem amplasa o regin chiar pe prima coloan:

n fine, pe ultima linie avem urmtoarea opiune valid:

Backtracking-ul se poate implementa mai uor recursiv. Programul


complet pentru varianta
recursiv este urmtorul:
#include "stdio.h"
#include "conio.h"
#include "math.h"
int ataca(int linie, int memorie[]) //aceasta funcie testeaz daca regina de pe
linie este atacata de
reginele poziionate anterior. Este de fapt funcia
de Validare
{
int i;
//luam pe rnd toate damele poziionate anterior
for(i=0;i<linie;i++)
//verificam daca cele 2 dame sunt pe aceeai
coloana sau pe diagonal
if((memorie[linie]==memorie[i]) ||
(abs(memorie[i]-memorie[linie])==linie-i))
// se ataca, deci nu sunt corect poziionate.
return 1;
return 0; //daca am ajuns aici, nseamn c nu se atac
}
//cile de afiare sunt infinite
void afiseaza(int dim,int memorie[])
{
int l,c;
for(l=0;l<=dim;l++)
printf("_");
for(l=0;l<dim;l++)
{
printf("\n|");

20
for(c=0;c<dim;c++)
if(memorie[l]==c)
printf("%c",6);
else
if((l+c)&1)
printf(" ");
else
printf("%c",219);
printf("|");
}
printf("\n");
for(l=0;l<=dim;l++)
printf("-");
printf("\n");
printf("o tasta, va rog!\n");
getch();
}
void dame(int dim,int linie, int memorie[])
// aici este funcia care face efectiv
backtracking-ul (suntem la

linia(nivelul) linie.
// dim ne spune ct de mare-i tabla
// memorie tine minte damele deja
poziionate. Ea este stiva
{
if(linie==dim) // daca am terminat
afiseaza(dim,memorie); //afim
else //altfel avem de lucru
for(memorie[linie]=0;memorie[linie]<dim;memorie[linie]++)
//ncercam toate coloanele de la stnga la
dreapta
if(!ataca(linie,memorie))
//daca e o poziie valida trecem la nivelul
urmtor
dame(dim,linie+1,memorie);
//cnd ne ntoarcem din apelul recursiv
nseamn c am revenit
// la acest nivel i ncercm urmtoarea
coloana
}
void main()
{
int n,memorie[100];
printf("dimensiunea tablei de joc=");
scanf("%d",&n);
dame(n,0,memorie);// prima linie are numrul zero
}

1. n continuare prezentm i o implementare


iterativ:

#include "stdio.h"
#include "conio.h"
#include "math.h"
int ataca(int linie, int memorie[])
//aceleai explicaii ca mai sus, dar nu de alta dar e aceeai
funcie
{

21
int i;
for(i=0;i<linie;i++)
if((memorie[linie]==memorie[i]) ||
(abs(memorie[i]-memorie[linie])==linie-i))
return 1;
return 0;
}
void afiseaza(int dim,int memorie[])
//la fel ca mai sus
{
int l,c;
for(l=0;l<=dim;l++)
printf("_");
for(l=0;l<dim;l++)
{

printf("\n|");
for(c=0;c<dim;c++)
if(memorie[l]==c)
printf("%c",6);
else
if((l+c)&1)
printf(" ");
else
printf("%c",219);
printf("|");
}
printf("\n");
for(l=0;l<=dim;l++)
printf("-");
printf("\n");
printf("o tasta, va rog!\n");
getch();
}
void main()
{
int n,memorie[100],nivel;
printf("dimensiunea tablei de joc=");
scanf("%d",&n);
nivel=0;
//datorit C-ului primul nivel are numrul zero
//punem prima dam s se nclzeasc pe
marginea tablei
memorie[nivel]=-1;
//ct timp nu ncercm s poziionm dama de
linia -1
while(nivel>=0)
{
if(nivel==n) //avem o soluie
{
afiseaza(nivel,memorie);
//ne ntoarcem la ultima linie
nivel--;
}
//ncercm urmtoarea poziie de pe linia curent
memorie[nivel]++;
// dac dama a epuizat coloanele
if(memorie[nivel]==n)
//revenim la linia anterioar
nivel--;
else // altfel

22
//dac este o poziie valid
if(!ataca(nivel,memorie))
memorie[++nivel]=-1;
//trecem la urmtorul nivel i scoatem nc o dam
la nclzire
}
}
Rezultat:

Concluzie:
Aceast tehnic este relativ uor de folosit, dar fiind foarte lent i consumatoare de
memorie este recomandabil pentru cazurile n care resursele nu sunt o problem.

Capitolul V
Avantajele regulilor de sah.

Regulile oficiale ale jocului sunt ntreinute de Federaia Internaional de ah sau FIDE[1]. Jocul se
desfoar pe tabla de ah. Aceasta are o form ptrat i este mprit n 8 linii i 8 coloane ce formeaz
64 de ptrate cu suprafee egale, numite cmpuricolorate alternativ n alb i negru. La nceput fiecare juctor
are 16 piese: 8 pioni, 2 turnuri (ture), 2 cai, 2 nebuni, un rege i o regin. Unul dintre juctori controleaz

23
piesele albe iar cellalt piesele negre. Juctorii mut pe rnd, respectnd anumite reguli; prima mutare
(nceputul partidei) revine juctorului cu piese albe. Scopul jocului este obinerea matului. Acesta survine
atunci cnd un rege este atacat i nu poate evita capturarea.

Reg Regin Tur Nebu Pio


Piesa Cal
e n n n

Numr 1 1 2 2 2 8

Valoar
9 5 3 3 1
e

Simbol

n ah, figur (sau pies major) reprezint orice pies cu excepia pionului. Piesele majore se mpart n dou
grupe: piese grele (turnul i regina) i piese uoare (nebunul i calul). Pentru analiza cantitativ a unei pozi ii,
exist o convenie care atribuie fiecrei piese cte un punctaj. Astfel regina prime te 7-12 puncte, fiecare turn
cte 4-6, fiecare nebun cte 3-4, fiecare cal cte 3-4 i fiecare pion cte 1.

Regulile miscarii figurilor

Fiecare pies de ah are propriul mod de a fi mutat. Csuele marcate n diagramele de mai jos cu X
reprezint micrile posibile ale piesei prezentate, doar dac ntre poziia ini ial i cea final nu exist alte
piese (inclusiv piese proprii); calul nu este restricionat de aceast cerin - de altfel, pentru acesta pozi iile
iniial i final nu sunt de-a lungul unei direcii specifice. Dac o pies a adversarului se gse te pe pozi ia
final a mutrii, atunci acea piesa este capturat. Singura excepie o face pionul care poate captura numai
deplasndu-se pe diagonal, n fa.

Micrile regelui

24
Regele poate muta doar n csu ele imediat adiacente, n cele 8 direc ii.

Micrile turnului

25
Turnul poate muta doar orizontal sau vertical.

Micrile nebunului

26
Nebunul poate muta doar diagonal, astfel c nu poate schimba culoarea csu elor accesibile.

Micrile reginei

Regina poate muta pe orice distan , n toate cele 8 direc ii.

Micrile calului

27
Calul poate muta doar n "form de L".

Micrile pionului*

28
* Pionul poate captura numai pe cercurile albe

Rocada mic

29
Pentru rocada mic regele trebuie s mute pe ptr elul marcat cu x, iar turnul pe cmpul alb.

Rocada mare

Pentru rocada mare regele trebuie s mute pe ptr elul marcat cu x, iar turnul pe cmpul alb.

O singur dat n decursul unei partide, fiecrui rege i se permite o mutare special numit rocad. Rocada
const n mutarea regelui dou cmpuri spre tur, apoi mutarea turei de partea opus regelui. Rocada poate
fi mic, cnd mutarea se face cu tura mai apropiat regelui, sau mare cnd mutarea este fcut cu tura mai
ndeprtat. Aceast mutare special este permis doar cnd se ndeplinesc anumite condi ii: [2]

30
Niciuna din piesele implicate nu au fost mutate n prealabil;

Nu trebuie s existe nici o alt pies ntre cele dou;

Regele nu trebuie s fie n ah i nici s treac peste cmpuri atacate de adversar. Ca i orice alt
mutare, regele nu are voie s intre n ah dup rocad.

En passant

31
Aceast mutare se poate efectua doar imediat dup ce un pion advers a ncercat s evite captura avansnd dou
ptrele.

En passant este micarea special n care un pion este capturat de un alt pion oponent, imediat dup ce
acesta s-a deplasat dou ptrate din poziia de start (pn n dreptul pionului oponent) i care ar fi fost oricum
capturat dac s-ar fi deplasat doar un ptrat. Poziia rezultat dup aceast mutare e similar cu pozi ia
mutrii i capturii normale a pionului. Mutarea en passant trebuie fcut imediat dup mutarea pionului, n caz
contrar se pierde dreptul de a o mai face.

Promovarea

Promovarea se realizeaz n momentul n care un pion avanseaz pn la ultima linie accesibil (a opta
pentru alb, prima pentru negru). n acea poziie, juctorul are obligaia de a schimba imediat pionul cu o pies
la alegere dintre regin, tur, cal sau nebun de aceeai culoare. n majoritatea cazurilor pionul este schimbat
cu regina si cu tura.

Capitolul VI

Functiile globale
Functiile globale au rolul de a veghea la modul in care sunt mutate piesele, implementand regulile
jocului de sah.

Pentru a putea manipula cele 32 de piese intr-o maniera cat mai rapida, am convenit la crearea unei
matrici de obiecte. Declararea ei se face in functia principala, care va fi explicata mai tirziu.

piese piesa[]=; //crearea celor 32 de piese

32
Se observa cum la crearea matricii de obiecte am invocat parametrii necesari activarii functiei
constructor a fiecaruia din cele 32 de obiecte. Acum vom putea apela foarte usor toate obiectele, neavand
nevoie decat de matrice si de o variabila de ciclare, care va lua valori corespunzatoare pozitiilor in
matrice a pieselor dorite.

Functiile globale insarcinate cu verificarea pozitiilor rezultate pe tabla de sah trebuie sa cunoasca
toate piesele pentru a putea extrage niste rezultate din relatiile existente intre acestea, de aceea ele vor
primi ca parametru matricea de obicte.

intro()

Functia intro() are rol introductiv, creand designul paginilor programului. Pentru desenarea
literelor din cuvantul SAH de pe prima pagina se utilizeaza functia fillpoly(int varfuri, int
coordonate[]), care are rolul de a umple un poligon inchis cu n varfuri ale caror coordonate x si z sunt
depuse in perechi consecutive in vectorul de intregi care ii este plasat ca parametru.

Comanda setcolor(9) reglementeaza utilizarea culorii albastre pentru scris cat si pentru desenul
figurilor geometrice. setfillstyle(SOLID_FILL, 12); stabileste maniera de umplere cu culoare solida a
figurilor geometrice create pe ecran, iar culoarea de umplere este orange.

In continuare se deseneaza cele trei litere ale cuvantului SAH, creand pentru fiecare in parte un
vector care sa resina coordonatele varfurilor lor. Vectorii au dimensiunea numeric egala cu dublul
numarului de varfuri. Incluzand si virgula de sub S se creaza 4 astfel de vecori care sunt pasati pe rand
functiei fillpoly().

In stanga jos se creaza apoi 4 patrate de culori alternative pe care se afiseaza cate o piesa de sah.

In dreapta jos se va afisa pe orizontala mesajul Designed by si pornind din colt, dar pe verticala
numele autorului: George-Stefan Farcas. Acest mesaj este omniprezent in program.

La apasarea oricarei taste programul acopera prima pagina trecand la cea de-a doua, unde este afisat
un mesaj:

Din nou, programul asteapta apasarea unei taste si purcede la afisarea celei de a 3-a pagini, cea care
va constitui suportul tablei de sah si al tuturor mesajelor de avertizare.

Se tiparesc pe ecran niste instructiuni legate de inceperea unui joc nou si de parasirea programului.

inline void intro()

nou()

Functia pentru joc nou are rolul de a reinitaliza toate cele 32 de piese, pe rand, dupa care va afisa
tabla de sah goala peste cea veche. Utilizand o variabila de ciclare, functia va afisa apoi piesele pe tabla.

void nou(register piese piesa[32])

contur()

33
Aceasta functie are rolul de a crea un contur incadrat in patratele tablei de sah afisata pe ecran,
pentru a evidentia astfel campul activ facilitand procesul de I/O (in/out). Tabla de sah este de dimensiuni
256x256 pixeli, asadar fiecare camp are dimensiunile 32x32 pixeli. Pentru o manipulare mai usoara,
funcsia accepta ca parametri valorile coordonatelor de tabla de sah, convertindu-le in pixeli.

Functia este definita ca inline. O functie inline, cand este apelata este inlocuita spontan cu codul
continut, evitandu-se

inline void contur(register int i,register int j,register int c)

Desenarea pieselor si a tablei de sah

Desenarea tablei de sah se efectueaza cu ajutorul functiei bar() punand pe ecran dreptunghiuri
umplute de culoare gri inchis cand suma liniei cu coloana este impara si gri deschis cand suma liniei cu
coloana este para. Urmatorul pas este incadrearea intr-un patrat a tablei de sah cu functia rectangle(). In
fine se afiseaza in jurul tablei literele si cifrele corespunzatoare liniilor si coloanelor tablei de sah.

void afiseaza_tabla()

else

setcolor(8);

rectangle(149,149,407,407);

outtextxy(131,i=163,'8');

outtextxy(131,i+=32,'7');

outtextxy(131,i+=32,'6');

outtextxy(131,i+=32,'5');

outtextxy(131,i+=32,'4');

outtextxy(131,i+=32,'3');

outtextxy(131,i+=32,'2');

outtextxy(131,i+=32,'1');

j=131;

i+=32;

outtextxy(j+=32,i-4,'a');

outtextxy(j+=32,i-4,'b');

outtextxy(j+=32,i-4,'c');

outtextxy(j+=32,i-4,'d');

outtextxy(j+=32,i-4,'e');

outtextxy(j+=32,i-4,'f');

34
outtextxy(j+=32,i-4,'g');

outtextxy(j+=32,i-4,'h');

Piesele sunt concepute ca niste suprafete poligonale inchise si sunt realizate cu ajutorul functiei
fillpoly() care retine doi parametri: numarul de varfuri al poligonului si coordonatele acestor varfuri
depuse intr-un vector. Functiile care deseneaza piesele primesc ca parametri pozitia de pe tabla si
culoarea. Iata spre exemplu functia corespunzatoare pionului:

void pion(register int i,register int j,int culoare)

ocupat()

Functia are rolul de a investiga existenta vreunei piese pe un camp dat al tablei de sah si de a
returna pozitia acesteia in matricea piesa[].

Pentru aceasta se cicleaza matricea pana cand se gaseste o piesa ale carei coordonate coincid cu ale
campului pe tabla de sah. Daca se gaseste o o piesa care sa verifice conditia i se returneaza pozitia din
cadrul matricii, altfel se returneaza conventional -1.

int ocupat(register int i,register int j,register piese piesa[32])

; //returneaza -1 dak e liber sau pozitia din matrice a piesei care ocupa capmul

mutare_valida()

Functia este creata pentru a verifica validitatea mutarii care trebuie efectuata.

In cazul in care campul dorit este ocupat de o piesa de aceeasi culoare, mutarea este ilegala si
functia va returna 0.

Se realizeaza mutarea logica temporara a piesei dorite cat si redicarea de pe tabla a piesei care a dat
sah regelui propriu (daca este cazul) dupa care se cauta vreun atac asupra regelui propriu. Daca regele
propriu nu ramane in sah dupa efectuarea mutarii logice, se poate purcede la mutarea efectiva a piesei.
Aceasta manevra este necesara pentru ca la finalul mutarii regele sa nu ramana in sah.

In cazul tuturor piesei se verifica specificitatea mutarii in functie de numele piesei. Regele va muta
un camp, calul in forma de L, nebunii pe diagonale, turnurile in linie dreapta, dama va muta precum
turnul sau precum nebunul, iar pionul cate un camp in fata,sau pe diagonala, cand captureaza.

Daca piesa este un pion, programul faciliteaza luarea en passant, verificandu-se respectarea
regulamentului. Din cauza faptului ca pionul se deplaseaza intr-o singura directie, este necesara detalierea
unui cod pentru fiecare din cele doua culori. Cand se intalneste o incalcare a regulilor jocului, functia
returneaza 0, altfel se continua pana la sfarsitul functiei. Daca se ajunge la sfarsitul functiei, mutarea va fi
considerata valida iar functia va returna 1. asadar functia are un caracter restrictiv, deoarece daca functia
ar returna intotdeauna 1 ar fi posibila efectuarea oricarei mutari.

Cand se muta regina, nebunul sau turnul se verifica in plus existenta vreunei piese intre campul de
plecare si cel de sosire, astfel incat piesa sa nu sara peste vreo piesa in miscarea sa.

35
Regele este restrictionat de atacurile adverse si de piesele proprii. Cand se doreste efectuarea
rocadei se face verificarea tuturor conditiilor impuse de regulament, dupa care se efectueaza mutarea
turnului inca din interiorul acestei functii. Este necesara aceasta procedura deoarece in functia principala
se va muta numai piesa selectata, si anume regele.

int mutare_valida(register int i, register int j,register int &cp,register piese piesa[32])

if( sah( piesa[cp].da_cul(), piesa ) && i == ultim->da_l() && j == ultim->da_c() )

piesa[cp].schimba(i,j,a,b);

r=sah(piesa[cp].da_cul(),piesa);

if ( !d ) ultim->schimba(x,y,d,d);

piesa[cp].schimba(a,b,c,c);

if(r)

switch(piesa[cp].da_p())

if ( ( j-piesa[cp].da_c() ) < 0 ) // nu muta inapoi

if ( ocupat( piesa[cp].da_l() , piesa[cp].da_c()+1 ,piesa ) != -1 )

if ( i!=piesa[cp].da_l() ) // nu muta pe alta coloana

if ( ( j-piesa[cp].da_c() ) > t ) //nu muta mai mult de doua campuri

break;

case 0 :

if ( ( j-piesa[cp].da_c() ) > 0 )

if ( ocupat( piesa[cp].da_l() , piesa[cp].da_c()-1 ,piesa ) != -1 )

if ( i!=piesa[cp].da_l() )

if ( ( piesa[cp].da_c() -j ) > t )

break; }

break;

case 't': if ( i == piesa[cp].da_l() || j == piesa[cp].da_c() )

if(l<0) for( k = piesa[cp].da_l()-1; k>i ; k-- ) }

if(c>0) for( k = piesa[cp].da_c()+1; k<j ; k++ ) }

36
if(c<0) for( k = piesa[cp].da_c()-1; k>j ; k-- ) }

else

break;

case 'n': if ( abs( i - piesa[cp].da_l() ) == abs( j - piesa[cp].da_c() ) )

if(l<0) for( k=1 ; k<c ; k++ ) }

else

if(l<0) for( k=-1 ; k>c ; k-- ) }

else

break;

case 'c': if ( ( abs( i - piesa[cp].da_l() ) + abs( j - piesa[cp].da_c() ) ) == 3 && abs( j - piesa[cp].da_c() ) <3

&& abs( i - piesa[cp].da_l() ) <3)

else

case 'r': if(atac(i,j,piesa[cp].da_cul(),piesa))

if ( piesa[cp].da_mutare()==0 && piesa[cp].da_c()==j && ( abs(piesa[cp].da_l()-i) == 2 ))

else

if( ocupat( k, piesa[cp].da_c(), piesa) != -1 )

if( atac( k, piesa[cp].da_c(),piesa[cp].da_cul(), piesa) )

tr= ocupat( q, piesa[cp].da_c(), piesa);

if( piesa[tr].da_mutare() != 0 )

piesa[tr].muta( k, piesa[cp].da_c() );

37
// rocada

else

if ( abs( i - piesa[cp].da_l() ) >1 || abs( j - piesa[cp].da_c() ) > 1 )

break;

case 'd': char ch;//retine 't' daca regina muta pe orizontala sau pe verticala si 'n' daca regina adopta o mutare de nebun

if ( i == piesa[cp].da_l() || j == piesa[cp].da_c() ) ch='t';

else

if ( abs( i - piesa[cp].da_l() ) == abs( j - piesa[cp].da_c() ) ) ch='n';

else

switch(ch)

case 't' : }

if(l<0) for( k = piesa[cp].da_l()-1; k>i ; k-- ) }

if(c>0) for( k = piesa[cp].da_c()+1; k<j ; k++ ) }

if(c<0) for( k = piesa[cp].da_c()-1; k>j ; k-- ) }

case 'n' :

register int l,c,k;

l= i - piesa[cp].da_l();

c= j - piesa[cp].da_c();

if(c>0)

{ if(l>0) for( k=1 ; k<c ; k++ ) }

if(l<0) for( k=1 ; k<c ; k++ ) }

else

if(l<0) for( k=-1 ; k>c ; k-- ) }

38
}

break;

default: break; }

return 1;

atac()

Functia are rolul de a verifica existenta vreunui atac din partea unei piese de o culoare data asupra
unui camp care este specificat de catre parametrii primiti. Culoarea pieselor asupra carora ne orientam
atentia este diferita de cea primita ca parametru.

Se cauta o relatie pozitionala intre campul dat si fiecare piesa din matrice care nu are culoarea
respectiva, luand in vedere maniera de mutare a acesteia. Mecanismul este similar cu cel al functiei
mutare_valida(), insa nu ia in discutie mutarea piesei pe campul dat. Acest mecanism este util la
verificarea pozitiei de sah, deoarece regele atacat este in sah indiferent daca piesa atacatoare este sau nu
legata de propriul rege.

int atac(register int i, register int j,register int cl,register piese piesa[32])

else

if(!ac) return 1;

else continue;

if( piesa[t].da_l() == i ^ piesa[t].da_c() == j )

else

switch( piesa[t].da_l() < i )

if(!ac) return 1;

else continue;

continue;

case 't':

if( piesa[t].da_l() == i ^ piesa[t].da_c() == j )

39
else

switch( piesa[t].da_l() < i )

if(!ac) return 1;

else continue;

continue;

case 'n': if( ( abs ( piesa[t].da_l()-i ) == abs (piesa[t].da_c()-j) ) && piesa[t].da_c() != j )

else

if(!ac) return 1;

else continue;

continue;

case 'c': if ( ( abs( i - piesa[t].da_l() ) + abs( j - piesa[t].da_c() ) ) == 3 &&

abs( j - piesa[t].da_c() ) <3 && abs( i - piesa[t].da_l() ) <3 )

return 1;

else continue;

case 'p': switch(cl)

continue;

return 0;

sah()

40
Functia cauta in matrice regele de culoarea plasata ca parametru, dupa care verifica daca acesta este
sau nu atacat, returnand aceeasi valoare ca apelarea functiei atac() pentru campul pe care se gaseste
regele.

int sah(register int cl,register piese piesa[32])

remiza()

Partida se declara remiza atunci cand pe tabla mai raman numai cei doi regi, adica cand toate
celelalte piese au fost capturate.

Cand una din piese este capturata, destructorul ei ii inlocuieste valoarea variabilei char piesa cu
litera a. Functia nu face altceva decat sa numere piesele capturate din matrice, adia cele care au litera a
depusa in variabila char piesa. Daca numarul de piese capturate este 30 este asadar remiza.

int remiza(register piese piesa[32])

pat()
int pat(register int cl,register piese piesa[32])

k++;}

if( k==32 )

return 1;

return 0;

mat()

Se considera pozitie de mat pozitia in care regele este atacat si jucatorul respectiv nu poate efectua
nici o mutare valida. Functia cauta regele in matrice, dupa care daca acesta este atacat continua
cuverificarea celei de-a doua conditii verificand pentru fiecare piesa in parte posibilitatea efectuarii cel
putin a unei mutari valide, caz in care nu mai este mat. Cazul in care piesa atacatoare poate fi luata
anuleaza pozitia de mat.

int mat(register int cl,register piese piesa[32])

k++;}

if( k==32 )

return 1;

return 0;

41
Capitolul VII

Incapsularea - Clasa piese


Incapsularea este un mecanism care leaga impreuna cod si date si le pastreaza pe ambele in
siguranta fata de intervantiile din afara si fata de eventualele utilizari eronate. Mai mult incapsularea este
cea care permite crearea obiectelor. Spus simplu, un obiect este o unitate logica ce incapsuleaza atat date
cat si cod care sa manevreze aceste date. Intr-un obiect o parte din cod si/sau date pot fi particulare acelui
obiect si inaccesibile pentru orice funcsie din afara sa. In acest fel, un obiect dispune de un nivel
semnificativ de protectie care impiedica modificarea accidentala sau utilizarea incorecta a partilor proprii
obiectului de catre sectiuni ale programului care nu au legatura.

In cele din urma un obiect este in fapt o variabila de un tip definit de utilizator, adica definirea unui
obiect creaza un nou tip de date.

In proiectul meu am definit clasa piese si am creat o matrice care sa retina toate cele 32 de piese
de pe tabla de sah, pentru a putea fi manipulate mai usor prin ciclarea unei variabile si nu prin apelare
separata a fiecarui obiect in parte.

Iata declararea clasei piese :

class piese

~piese() ;

void muta(register int i,register int j);

int da_l() ;

int da_c() ;

char da_p() ;

int da_cul() ;

int da_mutare()

void transformare();

int en() ;

void pune_en()

void schimba(int a,int b,int &c1,int &d) ;

friend void afiseaza_piesa(register int i,register int j,int culoare,register char piesa);

};

Caracteristicile fiecarei piese sunt : culoarea, forma, denumirea specifica, pozitionarea pe tabla,
maniera de deplasare, pozitia initiala, numarul de mutari effectuate cu piesa respectiva si chiar
oportunitatea de a captura pionul prin luarea en passant.

42
Membrii privati ai clasei piese

Culoarea fiecarei piese este retinuta de o variabila de tip intreg. Culoarea alba este asociata lui 15
iar cea neagra lui 0 (conform modului graphic din DOS). Valoarea initializata la inceput nu se modifica in
timpul rularii programului.

Denumirea specifica a fiecarei piese este acceptata de o variabila tip character care retine prima
litera din denumirea uzuala a piesei ( r d t n c si p ). La o captura, se va inlocui acest
character cu a.

Pozitia de pe tabla este retinuta de doua variabile intregi associate pozitiei pe orizontala si pe
verticala a piesei. Se utilizeaza valorile de la 1 la 8, intrucat esicherul are 8 randuri si 8 coloane. La o
captura, piesa eliminata va primi aici niste valori aleatorii extreme de mari.

Forma si maniera de deplasare specifica fiecarei piese este reglementata, insa de functii globale si
depend de variabila character corespunzatoare denumirii piesei. Am optat pentru definirea unor funtii
globale pentru desenarea pieselor pe tabla pentru a pastra cat mai compact codul clasei, considerand
asadar dimensiunile mai mari ale acestor functii grafice. De asemenea consider ca maiera de deplasare
este mai mult legata de aplicarea regulilor jocului, decat de obiectul in sine, ea fiind elaborata intr-o
maniera relationala cu celelalte piese de pe tabla.

Asadar clasa piese creaza obiecte generale care pot fi utilizate si la alte jocuri, ca de exemplu
Dame sau chiar Go.

In plus mai este definita o variabila intreaga en_pass, care ia valoarea 1 in momentul in care un
pion poate fi luat printr-o luare en_passant.

Membrii publici ai clasei piese

Membrii publici ai clasei piese sunt functii care au rolul de a manipula datele private ale obiectelor,
realizand astfel legatura cu programul. Ei sunt declarati dupa atributul public :.

Asadar, cand dorim modificarea unei variabile sau numai aflarea datei continute de aceasta este
necesar sa apelam o functie speciala care va modifica valoarea respectiva sau care o va returna, pentru a o
putea utilize in procesul relational al programului.

Majoritatea functiilor publice au coduri simple, urmatoarele functii, avand numai rolul de a returna
valoarea uneia din datele private ale obiectului:

int da_l() ;

int da_c() ;

char da_p() ;

int da_cul() ;

int da_mutare()

int en() ;

43
Tipul de declarare al functiilor este cel pe care functia il returneaza.

Urmatoarea functie are rolul de a modifica valoarea variabilei en_pass si este apelata evident
atunci cand se deschide oportunitatea de a captura pionul care descrie prima sa mutare peste doua
campuri la mutarea imediat urmatoare.

void pune_en()

Functia schimba(int a,int b, int &c1, int &d) are rolul de a altera coordonatele piesei. Procedura
este necesara in unele parti ale programului, deoarece realizeaza o operatiune pe cat de simpla, pe atat de
utila, deoarece este similara unei ridicari temporare de pe tabla a piesei. Este utila o asemenea actiune
cand se doreste verificarea legalitatii unor mutari pe tabla de sah (se efectueaza o pseudomutare dupa
care se poate evalua pozitia rezultata; daca aceasta din urma este valida, mutarea este corecta). In program
aceasta functie va fi apelata de un numar par de ori deoarece, dupa ce am ridicat piesa este imperativa
repozitionarea ei logica. Primii doi parametri contin coordonatele noi pe care le va primi piesa iar
celelalte doua au rolul de a retine coordonatele initiale ale ei. Acestea din urma sunt retinute in partea de
program care efectueaza cele doua apelari ale functiei, deoarece dotorita operatorului & functia va
primi de fapt niste referinte la variabilele care ii sunt pasate, putand astfel sa le modifice. Procedeul este
unul special si reuseste sa depaseasca doua probleme: o functie nu poate returna decat o singura valoare
si, in plus ea lucreaza cu variabile temporare a caror valori sunt distruse cand functia se incheie.

void schimba(int a,int b,int &c1,int &d) ;

Constructor si destructor

O functie constructor este o functie speciala, membra a unei clase care are acelasi nume cu clasa
din care face parte. Este un lucru obisnuit pentru unele parti ale unui obiect sa necesite initializare inainte
de a fi utilizate ( numele, pozitia initiala, culoarea, numarul de mutari realizate de piesa ). Cu ajutorul
functiei constructor, C++ permite obiectelor sa se initializeze singure, atunci cand sunt create.
Constructorul va fi apelat implicit si nu va necesita, apelarea efectiva nicaieri in program.

Constructorul utilizat an program accepta 4 parametri cu care va initializa piesa: pozitia pe


orizontala, pozitia pe verticala, culoarea si denumirea piesei.

piese(register int i, register int j, register char cul,register char ps)

Destructorul este complementul constructorului. La fel ca si acesta, el este activate implicit la


distrugerea obiectului ( la incheierea programului obiectele si variabilele create in program sunt distruse ).
Are acelasi nume ca si constructorul, insa precedat de un character ~. Totusi , functia destructor poate fi
apelata in program. Aici vom apela destructorul la eliminarea piesei de pe tabla, cu scopul de a altera
proprietatile acesteia (numele, pozitia), intrucat, deoarece utilizam o matrice de obiecte, desi este distrus
obiectul, el isi pastreaza pozitia in matrice, continuand sa fie prezent in program.

Destructorul da niste valori foarte mari coordonatelor piesei, ii altereaza numele, nu inainte de a
ssterge piesa de pe tabla prin afisarea ei de culoarea campului pe care a fost cand a fost capturata.

~piese() ;

Functii friend

44
O functie friend nu este membra a unei clase insa ea are acces direct la membrii privati ai clasei. Ea
este definita in afara clasei careia ii este prietena si redeclarata in ineriorul acesteia cu titlul de friend.

friend void afiseaza_piesa(register int i,register int j,int culoare,register char piesa);

Proiectul Sah.cpp utilizeaza o singura astfel de functie, si anume functia care are rolul de a hotari
forma fiecarei piese in functie de numele ei.

Functia afiseaza_piesa() utilizeaza o instructiune decizionala cazuala: switch. Expresia are rolul
de a prelua caracterul care defineste numele piesei si, in functie de valoarea acestuia apeleaza una din
functiile care deseneaza piese.

void afiseaza_piesa(register int i,register int j,int culoare,register char piesa)

Mutarea pieselor

Functia muta(register int i, register int j) este o functie membu a clasei piese, codul ei fiind insa
explicitat in afara clasei, utilizand operatorul de specificare a domeniului de apartenenta ::.

Functia accepta doi parametri, asociati pizitiei finale ocupata de piesa, si anume linia si respective
coloana.

Primul pas este stergerea piesei de pe pozitia initiala, prin desenarea pe campul initial ocupat a unei
piese de culoarea campului. In cazul in care se muta regele se afiseaza pe pozitia initiala o cruce. (regele
are desenata o cruce pe el iar cand este mutat functia care il deseneaza lasa in urma aceasta reminiscenta).
Urmatorul pas consta in modificarea coordonatelor de pe tabla ale piesei, marirea numarului de mutari cu
o unitate. Este atribuita pointerului global ultimo adresa din memorie a obiectului mutat. In fine,
urmeaza o serie de instructiuni care au rolul de a facilita luarea en passant: daca este efectuata prima
mutare a pionului, variabila en_pass retine valoarea 1, altfel 0. cand este efectuata luarea en passant
se distruge ultima piesa mutata (pion) a carui adresa din memorie este retinuta de pointerul ultim .

void piese::muta(register int i,register int j)

l=i;

c=j;

afiseaza_piesa(l,c,culoare,piesa);

mutare++;

if(piesa=='p' && (c==8 || c==1 ))

else en_pas=0;

if(ultim->da_p()=='p' && ultim->en() ) ultim->pune_en();

45
ultim=this;

} //codul de mai sus e necesar verificarii mutarii 'en passant' !

};

Transformarea pionului

Cand pionul ajunge pe campul de transformare, se apeleaza functia transformare(). Ea va afisa in


coltul din stanga sus cele patru figuri in care poate fi transformat pionul, realizand totodata un mecanism
pentru selectarea piesei dorite. Sunt prezente, de asemenea o serie de comenzi care au ca rol comunicarea
cu jucatorul de la tastatura. Dupa ce se stabileste piesa in care se face substitutia, pionul se transforma in
figura prin modificarea denumirii sale.

void piese::transformare()

break;

case 75 : if(i>0)

break;

} // muta conturul asupra piesei dorite si se opreste cand este apasat ENTER

switch(i)

// transforma pionul in figura

setfillstyle(SOLID_FILL,12);

bar(51,51,500,140);// acopera spatiul pentru mesaje

};

46
Capitolul VIII

Functia principala main()

Functia main() este functia principala a programului, functia care are rolul de a decide ordinea in care sunt apelate toate
celelalte parti ale programului. Aici este inclus algoritmul propriu-zis.

La incpeut se initializeaza modul grafic DOS utilizand initgraph() dupa ce am detectat adresa directa a memoriei RAM
video.

Se efectueaza functia intro(), dupa care se afiseaza tabla de sah. Se creaza matricea de piese.

Conditiile fiind create pentru joc, mai este necesara comunicarea cu jucatorii. Se stabileste ca primul jucator care muta
este albul si se afiseaza si se afiseaza conturul primului camp activ (care se va gasi in mijlocul tablei de sah) si se initializeaza
variabila cp, care retine pozitia in matrice a piesei selectate de jucator, cu -1. Utilizam o instructiune repetitiva while care se
incheie cand este indeplinita conditia pusa la ciclare aici se termina programul cand variabila gata ia o valoare diferita de 0.
Fiecare iterare a instructiunii consta in citirea unui caracter de la tastatura, cu ajutorul functiei getche(), care nu are efect pe
ecran, dupa care se efectueaza codul aferent fiecarei taste la fiecare iterare se elibereaza spatiul de lucru situat deaspupra
tablei de sah, pentru a nu suprapune iesirile textuale.

La introdcerea tastei BACKSPACE programul va interoga utilizatorul asupra dorintei de a incepe un joc nou, dupa care
mai citeste un caracter. Daca acesta este y(yes) se incepe un joc nou.

Urmatoarea etapa este reprezentata de verificarea eventualelor pozitii de sah, mat sau remiza. Aceste pozitii au efect
imediat pe ercan ( ex: ' ATENTIE! este sah!' ). Daca este mat sau remiza variabila gata este modificata, luand valoarea 1, iar
jocul se incheie, programul citind, insa in continuare taste pana la introducerea uneia din tastele ESC SAU BACKSPACE.

Urmeaza acum o instructiune cazuala switch:

Cand se apasa o sageata sau o cifra (afara de 5) se muta conturul in directia corespunzatoare.

Cand se apasa ENTER SAU 5 se activeaza o expresie conditionala care are rolul de a selecta piesa situata pe
campul activ sau de a o depune acolo. Cand se muta o piesa se verifica legalitatea mutarii cu ajutorul functiei mutare_valida(),
dupa care se efectueaza mutarea in cazul in care aceasta este valida. Cand campul este ocupat de o piesa adversa se
activeaza destructorul acesteia, ea fiind considerata captivata.

In finalul iterarii trebuie verificata legalitatea selectarii piesei (daca a fost selectata o piesa alba cand negrul este la
mutare, se abandoneaza selectia).

void main()

intro();

afiseaza_tabla();

piese piesa[]=; //crearea celor 32 de piese

register int i=4,j=4,ps,k,l,cp=-1,gata=0;

register char ch;

contur(i,j,4);

47
register int cl; //retine culoarea care muta

cl=15;

while(ch != 27)

if(!gata)

if(mat(cl, piesa) )

if(remiza(piesa))

switch(ch)

else continue; break;

case '6':

case 77: if(i<8)

else continue; break;

case '4' :

case 75: if(i>1)

else continue; break;

case '2' :

case 80: if(j>1)

else continue; break;

case '1': if(j>1 && i>1)

else continue; break;

case '3': if(j>1 && i<8)

else continue; break;

case '7': if(j<8 && i>1)

else continue; break;

case '9': if(j<8 && i<8)

else continue; break;

case '5':

case 13:

else

48
if(cp==ps) continue;

else

else

if(mutare_valida(i,j,cp,piesa))

if(piesa[cp].da_cul() != cl) cp=-1; //verifica daca este la mutare

break; }

default: break; }

getch();

49
Exemplu reprezentat prin fisier cu metode Backtracking:

Listingul programului:

#include <stdlib.h>//
#include <stdio.h>//
#include <conio.h>//biblioteci de date
#include <dos.h>//
#include <math.h>//

int i,j,j1=0,i1=0,k=0,Contor=0,tmp=0;//variabile de tip intregi

int a[8][8]={0};//declaram o matrice

void Citire()//functiea de citire din baza de date si inscriere


{FILE *F;//variabila de tip file care ne permite lucrarea cu fisiere

F=fopen("MarimeaBazei.txt","r");//inscrierea fisierul .txt


for(i=0;i<1;i++)//ciclu de parcurgere
{ fscanf(F,"%d",&tmp); }//inscrierea in fsiere
fclose(F);//inchidem fisierul
Contor=Contor+tmp;//contor atribuim contor+tmp

int b[1000][8];//tabel bidimensional

F=fopen("Baza.txt","r");//inscrierea fisierului .txt


for(i=0;i<Contor*8;i++)//ciclu de parcurgere in fisier
for(j=0;j<8;j++)//ciclu de parcurgere in fisier
{ fscanf(F,"%d",&b[i][j]);}//inscriem in fisere tabelul b
fclose(F);//inchidem fiserul

F-fopen("Baza.txt","a");//citirea din fisier


for(i=0;i<Contor*8;i++)//parcurgem fisieruk
{for(j=0;j<8;j++)//parcurgem fisierul
fprintf(F,"%d ",b[i][j]);//afisam informatia din fiser
printf("\n");} delay(5000);//pauza de 5000de milisecunde

void Salvare()//functia de salvare in fiser


{ FILE *F;

F=fopen("Baza.txt","a");//descidem fiserul .txt


// fprintf(F,"\n");
for(i=0;i<8;i++)//ciclu de parcurgere in fiser
{ for(j=0;j<8;j++)//cicul de parcurgere in fiser
{fprintf(F,"%d ",a[i][j]);}fprintf(F,"\n");}//afisarea din fiser a informatie

fclose(F);//inchidem fisierul

50
int ctrl(int i,int j)//functiea int ce retureaza

{//Conditiea pentru j<0


if(i==i&&j==0){if(a[i+1][j+1]==0) return 0;// verificam daca pe pozitea pestei mai sus se afla 0 ca sa depistam daca se poate misca
else return 1;}//casuta este ocupata nu se poate de miscat
//Conditiea sa nu depaseasca matricea j>8
else {if(i==i&&j==7){if(a[i+1][j-1]==0) return 0;//verifica numai in limitele tablei de dame 8x8
else return 1;}//este depasita limita
else if((a[i+1][j+1]==0)||(a[i+1][j-1]==0)) return 0;//verifica daca pe casuti se afla valoare 0 ce ne permite miscarea in casuta data
else return 1;}
}

int bate(int i,int j)//functiea de verificare si batere a altei peste


{ //j<0
if(i==0&&j==j){if(a[i][j-1]==2||a[i][j+1]==2) return 2;//vereifica daca in preajma daca in preajma damei se afla o dama a atversarului
else return 1;}
else
{ if(i==i&&j==0){if(a[i+1][j+1]==2||a[i-1][j+1]==2) return 2;//verifica daca are drepturi de batere a damei adversarului
else return 1;}
//j>8
else {if(i==i&&j==7){if(a[i+1][j-1]==2||a[i-1][j-1]==2) return 2;//aceieasi verificare numai alta pozitie verifica
else return 1;}
else if((a[i+1][j+1]==2||a[i+1][j-1]==2||a[i-1][j+1]==2||a[i-1][j-1]==2)) return 2;//aceieasi verificare numai alta pozitiea
else return 1;}}
}

void M1(){//finctiea de miscrare

if(a[i1][j1]==k){misca in pozitea ce mai rezonabila


for(i=0;i<8;i++)//misca in pozitea ce mai rezonabila
for(j=0;j<8;j++) if((i+j)%2!=1){if(a[i][j]==1){if(ctrl(i,j)==0){a[4][4]=1;}}}//misca in pozitea ce mai rezonabila
}
}

void mcr()//miscarea in pozitea


{ int po;
for(int i=0;i<8;i++)
for(int j=0;j<8;j++) if((i+j)%2!=0){ if(a[i][j]==1){if(ctrl(i,j)==0){a[i+1][j+1]=1;}} } getch();//misca in dependeta de jucator
}

void bat()
{ for(int i=0;i<8;i++)
for(int j=0;j<8;j++) if((i+j)%2!=0){ if(a[i][j]==1) {if(bate(i,j)==2) {printf("%d%d ",i,j);} }}//bate

}
void Afis()//afisarea la ecran
{
char ch;//variabile de tip char
textcolor(WHITE);//coloram contextul de cularea alba

for(i=0;i<8;i++)//cilcu de parcurgere pe verticala


{ printf("\n\t\t");//afisarea la distanta necesara unda de cealalat
for(j=0;j<8;j++)//cilcu de parcurgere pe orizontala
{ cprintf("%3d",a[i][j]);}//afisarea
printf("\n");}

g: bat(); M1(); Salvare(); Contor++;//batem salvam miscam


clrscr();//curatam ecranul
for(i=0;i<8;i++)//ciclu de parcurgere pe verticala
{ printf("\n");//rind nou
for(j=0;j<8;j++)//ciclu de parcurgere pe orizontala
{if((i+j)%2!=1) {textbackground(8);} else textbackground(2);//casutele pare le coloram de cularea verde casutele pare de culare neagaa
if((i==i1)&&(j==j1)) textbackground(1); cprintf("%3d",a[i][j]); }//la fel coloram casutele
printf("\n"); }

ch=getch();
switch(ch){
case '6': {j1++; if(j1==8){j1=0;} goto g;}//micarea prin patrice cu tasata 6 dereapta
case '4': {j1--; if(j1==-1){j1=7;} goto g;}//micarea prin matrice cu tasata 4 stinga
case '8': {i1--; if(i1==-1){i1=7;} goto g;}//miscarea prin matrice cu tasta 8sus
case '5': {i1++; if(i1==8){i1=0;} goto g;}//jos
case 27: { goto ex;}//ESC esim din program
case 13: { for(i=i1;i<=i1;i++)//functea ce permite preluarea damei si mutatea in directiea doritga
for(j=j1;j<=j1;j++) k=a[i][j];//depistam unde se afla casuta necesarea care o salvam in variabila k
for(i=i1;i<=i1;i++)//casuta selectata o inlocuim cu 0
for(j=j1;j<=j1;j++) a[i][j]=0; goto g;}//inlocuirea cu 0

51
case 32: { for(i=i1;i<=i1;i++)//space functea ce permite la utilizator sa plaseze dama selectata in locul dorit prin apasara tasta SPACE
for(j=j1;j<=j1;j++) if((i+j)%2!=1) {printf("\n\t\t\t\tErorr!!!");delay(250);goto g; }//in caza ca utilizatorul doreste sa introduca in
casuta incorecta se afiseaza mesajul dat cu o intrerupere de citeva secunde
else {a[i1][j1]=k; goto g;}}//schimbarea casutei cu casuta data
}

ex:

/*
void afi()//functia ce vareaza si afiseaza tabla de sah
{
int i,j,n=8,a[8][8],i1;//variabile de tip intregi

printf("\n");//caractere
for(i=0;i<n;i++)//marimea matridcei
for(i1=1;i1<6;i1++)//marieea matricei
{printf(""); for(j=0;j<n;j++)//afisarea cu elemente

if((i+j)%2!=1) {textbackground(BROWN);cprintf(" ");}//coloram spatiul tablei


else {textcolor(BLACK);//la fel
cprintf("");//la fel coloram cimpurile

}printf("");
printf("\n"); }
printf("");
}

void parc()//functiea de
{ int i,j,n=8,i1,i2;
clrscr();

printf("\n");
for(i=0;i<n-7;i++)
for(i1=0;i1<6;i1++)
{printf(""); for(j=0;j<n-7;j++)

if((i+j)%2!=1) {textbackground(BROWN);cprintf(" ");}


else {textcolor(BLACK);
cprintf("");

}
// printf("");
for(i2=0;i2<n-7;i2++) printf("\n"); }
// printf("");
}

*/
void main()//functiea priuncipala
{ clrscr();//curatam ecranul
FILE *F;//deschindem fiserul
Citire();
printf("%d",tmp);delay(500);//afisare cu intervala de 50 de milisecunde

for(i=0;i<8;i++)
for(j=0;j<8;j++)
if(((i+j)%2)!=0) {if(i<3) a[i][j]=1;
if(i>4) a[i][j]=2;}//verificam daca casutele selectate sun necesare
Afis();

F=fopen("MarimeaBazei.txt","w");//citim din fisier


fprintf(F,"%d ",Contor);
fclose(F);

getch();
}

52
53
Anexa 1. Listingul Programului dotat cu comentarii
#include <iostream> //bibliotecile folosite in program
#include<stdio..h>
#include<conio.h>
#include <string.h>
using namespace std; // variabila de tip unsigned
char a[100][100],aux[100][100],sirc[10]; // variabilede tip char in forma de tablouri si vectori, siruri de caractere
int col[10]={1,7,15,23,31,39,47,55,63,69},lin[10]={1,4,9,14,19,24,29,34,39,43},t[10][10],aux2[10][10],coox,cooy,xra,yra,xrn,yrn;
// var tip interger
//--------------------------------------------------------------------------------------------
void afisare2() // secventa de program care se ocupa cu afisarea
{
int i,j;
for(i=1;i<=8;i++)
{
for(j=1;j<=8;j++)
cout<<t[i][j]<<" ";
cout<<endl;
}
}

void flipt() // incapsularea adica granitle matricii fiind bidiminsionala 8x8


{
int i,j,x,y;
x=8;
y=8;
for(i=1;i<=8;i++)
{
for(j=1;j<=8;j++)
{
aux2[i][j]=0;
}
}
for(i=1;i<=8;i++)
{
y=8;
for(j=1;j<=8;j++)
{
aux2[i][j]=t[x][y];
y--;
}
x--;
}
for(i=1;i<=8;i++)
{
for(j=1;j<=8;j++)
{
t[i][j]=aux2[i][j];
}
}
}

void select(int x,int y) // secventa e progrogram care se ocupa cu selectarea


{

54
char c;
c=254;
x--;
y--;
y--;
y--;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y=y-6;
x++;
a[x][y]=c;
y=y+6;
a[x][y]=c;
x++;
y=y-6;
a[x][y]=c;
y=y+6;
a[x][y]=c;
y=y-6;
x++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
}

void afisare() // secventa de program care se ocupa cu afisarea formata din cicluri
{
int i,j;
for (i=0;i<=45;i++)
{
for (j=0;j<=71;j++)
cout<<a[i][j];
cout<<endl;
}
}

void neg(int x,int y) // secventa de program care are grija de piesele negre si inmatricularea lor in program
{
x++;
y--;
a[x][y]='N';
y++;
a[x][y]='e';
y++;
a[x][y]='g';
}

void alb(int x,int y) // secventa de program care se ocupa cu aplicarea a culorii albe
{
x++;
y--;
a[x][y]='A';
y++;
a[x][y]='l';
y++;
a[x][y]='b';
}

55
void casutaalbao(int x,int y) /inregistrarea casutelor
{
char c;
c=177;
x--;y--;y--;y--;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y=y-6;x++;a[x]
[y]=c;y=y+6;a[x][y]=c;x++;y=y-6;a[x][y]=c;y=y+6;a[x][y]=c;y=y-6;x++;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y++;a[x][y]=c;y++;a[x]
[y]=c;y++;a[x][y]=c;y++;a[x][y]=c;
}

void casutaalban(int xx,int yy) // inregistrearae casutelor


{
casutaalbao(xx,yy);
yy=yy-2;
char c;
c=177;
a[xx][yy]=c;yy++;a[xx][yy]=c;yy++;a[xx][yy]=c;yy++;a[xx][yy]=c;yy++;a[xx][yy]=c;xx++;yy=yy-4;a[xx][yy]=c;yy++;a[xx][yy]=c;yy+
+;a[xx][yy]=c;yy++;a[xx][yy]=c;yy++;a[xx][yy]=c;
}

void casutaalbaoo(int x,int y) / /inegistrearea casutelro


{
char c;
c=177;
x--;y--;y--;y--;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y=y-6;x+
+;aux[x][y]=c;y=y+6;aux[x][y]=c;x++;y=y-6;aux[x][y]=c;y=y+6;aux[x][y]=c;y=y-6;x++;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y+
+;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;y++;aux[x][y]=c;
}

void casutaalbann(int xx,int yy) //inregistrearea casutelor


{
casutaalbaoo(xx,yy);
yy=yy-2;
char c;
c=177;
aux[xx][yy]=c;yy++;aux[xx][yy]=c;yy++;aux[xx][yy]=c;yy++;aux[xx][yy]=c;yy++;aux[xx][yy]=c;xx++;yy=yy-4;aux[xx][yy]=c;yy+
+;aux[xx][yy]=c;yy++;aux[xx][yy]=c;yy++;aux[xx][yy]=c;yy++;aux[xx][yy]=c;
}

void resetaux() // secventa de program care in careva masura se ocupa cu disainu asa zis, aplica forma de chenar unde as fie incapsulate fig
{
int ok,x1,i,j;
char charm;
for (i=2;i<=42;i++)
{
if(i==2 || i==42)
{
x1=i;
strcpy(aux[i]," --------------------------------------------------------------- ");
}
else
{
if(i-5==x1)
{
strcpy(aux[i]," |-------|-------|-------|-------|-------|-------|-------|-------|");
x1=i;
}
else
strcpy(aux[i]," | | | | | | | | |");
}
}
ok=1;
for(i=1;i<=8;i++)
{
if (ok==1)
ok=0;
else
ok=1;
for(j=1;j<=8;j++)
{
if (ok==1)
ok=0;
else
ok=1;
if (ok==1)
{
if (t[i][j]==0)
casutaalbann(lin[i],col[j]);

56
else
casutaalbaoo(lin[i],col[j]);
}
}
}
i=lin[0];
charm='A';
for (j=1;j<=8;j++)
{
aux[i][col[j]]=charm;
charm++;
}
i=lin[9];
charm='A';
for (j=1;j<=8;j++)
{
aux[i][col[j]]=charm;
charm++;
}
j=col[0];
charm='1';
for (i=1;i<=8;i++)
{
aux[lin[i]][j]=charm;
charm++;
}
j=col[9];
charm='1';
for (i=1;i<=8;i++)
{
aux[lin[i]][j]=charm;
charm++;
}
}

void deselect(int x,int y) //deselectarea in caz de necesitate


{
char c;
resetaux();
x--;
y--;
y--;
if (aux[x][y]==' ')
{
c=' ';
}
else
{
c=177;
}
y--;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y=y-6;
x++;
a[x][y]=c;
y=y+6;
a[x][y]=c;
x++;
y=y-6;
a[x][y]=c;
y=y+6;
a[x][y]=c;
y=y-6;
x++;
a[x][y]=c;
y++;

57
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
y++;
a[x][y]=c;
}

void flip()
{
flipt();
int i,j,x,y;
resetaux();
//--------------------------------------------------------------------------------------------
for (i=1;i<=45;i++)
{
for (j=1;j<=71;j++)
{
if ((a[i][j]=='N' && a[i][j+1]=='e') || a[i][j]=='A')
{
a[i][j]=' ';
j++;
a[i][j]=' ';
j++;
a[i][j]=' ';
}
}
}
//--------------------------------------------------------------------------------------------
x=8;
for(i=1;i<=8;i++)
{
y=8;
for(j=1;j<=8;j++)
{
aux[lin[i]][col[j]]=a[lin[x]][col[y]]; // auz se pune pe linia si coloana dorita
y--;
}
x--;
}
for(i=1;i<=45;i++)
{
for(j=1;j<=71;j++)
{
a[i][j]=aux[i][j];
}
}
for(i=1;i<=8;i++)
{
for(j=1;j<=8;j++)
{
if(t[i][j]>0)
{
alb(lin[i],col[j]);
}
if(t[i][j]<0)
{
neg(lin[i],col[j]);
}
}
}
}

void convertire() // aici are loc convertirea, a table de sah de a A pina la H, adica 8 litere care este si marimea lungimei
{
coox=sirc[0]-48;
if (sirc[1]=='A') // conditii necesarea pentru convertire
cooy=1;
if (sirc[1]=='B')
cooy=2;
if (sirc[1]=='C')
cooy=3;
if (sirc[1]=='D')

58
cooy=4;
if (sirc[1]=='E')
cooy=5;
if (sirc[1]=='F')
cooy=6;
if (sirc[1]=='G')
cooy=7;
if (sirc[1]=='H')
cooy=8;
}

void aranjare() // aranjatea a literelor in jurul table de sah


{
char s2[3];
s2[0]=0;
s2[1]=0;
if(sirc[0]>'0' && sirc[0]<'9')
{
if(sirc[1]>96 && sirc[1]<'i')
{
if (sirc[1]=='a')
sirc[1]='A';
if (sirc[1]=='b')
sirc[1]='B';
if (sirc[1]=='c')
sirc[1]='C';
if (sirc[1]=='d')
sirc[1]='D';
if (sirc[1]=='e')
sirc[1]='E';
if (sirc[1]=='f')
sirc[1]='F';
if (sirc[1]=='g')
sirc[1]='G';
if (sirc[1]=='h')
sirc[1]='H';
}
}
if(sirc[0]>96 && sirc[0]<'i') // conditii necesare de pastrarea a limetelor
{
if (sirc[0]=='a')
sirc[0]='A';
if (sirc[0]=='b')
sirc[0]='B';
if (sirc[0]=='c')
sirc[0]='C';
if (sirc[0]=='d')
sirc[0]='D';
if (sirc[0]=='e')
sirc[0]='E';
if (sirc[0]=='f')
sirc[0]='F';
if (sirc[0]=='g')
sirc[0]='G';
if (sirc[0]=='h')
sirc[0]='H';
s2[1]=sirc[0];
s2[0]=sirc[1];
sirc[0]=s2[0];
sirc[1]=s2[1];
}
if (sirc[0]>=64 && sirc[0]<'I')
{
s2[1]=sirc[0];
s2[0]=sirc[1];
sirc[0]=s2[0];
sirc[1]=s2[1];
}
convertire();
}

int verificarecoo() // secventa de program care se ocupa cu verificarea, daca corespunde totul la locul unde a fost plasat si daca nu iesa
{
cin>>sirc;
if (strlen(sirc)==2)
{
if ((sirc[0]>'0' && sirc[0]<'9') || (sirc[0]>96 && sirc[0]<'i') || (sirc[0]>64 && sirc[0]<'I'))
{

59
if ((sirc[1]>'0' && sirc[1]<'9') || (sirc[1]>96 && sirc[1]<'i') || (sirc[1]>64 && sirc[1]<'I'))
{
if ((sirc[0]>'0' && sirc[0]<'9') && ((sirc[1]>96 && sirc[1]<'i') || (sirc[1]>=64 && sirc[1]<'I')))
return 1;
if ((sirc[1]>'0' && sirc[1]<'9') && ((sirc[0]>96 && sirc[0]<'i') || (sirc[0]>=64 && sirc[0]<'I')))
return 1;
return 0;
}
return 0;
}
return 0;
}
return 0;
}

void stergere(int x,int y) // stergerea unei figurin caz ca a fost batuta


{
int t=0,i,j;
y=y-2;
x--;
resetaux();
if (aux[x][y]!=' ')
t=1;
y--;
if (t==1)
{
for (i=x;i<=x+3;i++)
{
for (j=y;j<=y+6;j++)
{
a[i][j]=177;
}
}
}
else
{
for (i=x;i<=x+3;i++)
{
for (j=y;j<=y+6;j++)
{
a[i][j]=' ';
}
}
}
}

void scriere(int x,int y) // secventa de program care inscrie figurile si literele corespunzatatoare lor la fel si plasarea lor in tabla
{
int xx,yy;
xx=lin[x];
yy=col[y];
yy--;
yy--;
if (t[x][y]==1)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='P'; // P-> pion
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
alb(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==2)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';

60
yy++;
a[xx][yy]='T'; //T-> turn
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
alb(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==3)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='C'; //C-> cal
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
alb(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==4)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='N'; //N->nebun
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
alb(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==5)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='Q'; //Q->quen
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
alb(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==6)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='R'; // R-> nebun

61
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
alb(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==-1)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='P';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
neg(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==-2)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='T';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
neg(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==-3)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='C';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
neg(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==-4)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='N';
yy++;
a[xx][yy]=' ';

62
yy++;
a[xx][yy]=' ';
yy=yy-2;
neg(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==-5)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='Q';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
neg(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
if (t[x][y]==-6)
{
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]='R';
yy++;
a[xx][yy]=' ';
yy++;
a[xx][yy]=' ';
yy=yy-2;
neg(xx,yy);
xx++;
yy=yy-2;
a[xx][yy]=' ';
yy=yy+4;
a[xx][yy]=' ';
}
}
//--------------------------------------------------------------------------------------------
int opuse(int xx1,int yy1,int xx2,int yy2)
{
if (t[xx1][yy1]>0 && t[xx2][yy2]<0)
return 1;
if (t[xx1][yy1]<0 && t[xx2][yy2]>0)
return 1;
return 0;
}

int mutarepioninvers(int x1,int y1,int x2,int y2) //secventa care se ocupa cu mutarea pionului inver cind bati
{
int x;
x=x1;
if (t[x2][y2]==0 && y1==y2)
{
if (x1==7)
{
x1++;
if (x1==x2)
return 1;
x1++;
if (x1==x2)
return 1;
}
x1=x;
x1++;
if(x1==x2)
return 1;

63
}
if (t[x2][y2]!=0)
{
if (opuse(x1,y1,x2,y2)==1)
{
x1++;
y1++;
if (x1==x2 && y1==y2)
{
return 1;
}
y1--;
y1--;
if (x1==x2 && y1==y2)
{
return 1;
}
}
}
return 0;
}

int mutarepion(int x1,int y1,int x2,int y2) // se ocupa de mutarea pionui pe tabla se sah
{
int x;
x=x1;
if (t[x2][y2]==0 && y1==y2)
{
if (x1==7)
{
x1--;
if (x1==x2)
return 1;
x1--;
if (x1==x2)
return 1;
}
x1=x;
x1--;
if(x1==x2)
return 1;
}
if (t[x2][y2]!=0)
{
if (opuse(x1,y1,x2,y2)==1)
{
x1--;
y1--;
if (x1==x2 && y1==y2)
{
return 1;
}
y1++;
y1++;
if (x1==x2 && y1==y2)
{
return 1;
}
}
}
return 0;
}

int mutaretura(int x1,int y1,int x2,int y2) // mutarea turei pe table


{
int i,ok=1;
if (t[x2][y2]==0)
{
if (y1==y2)
{
if (x1<x2)
for (i=x1+1;i<=x2;i++)
{
if (t[i][y1]!=0) // conditii de mutare a pionului
ok=0;
}
else
for (i=x1-1;i>=x2;i--)

64
{
if (t[i][y1]!=0)
ok=0;
}
if (ok==1)
return 1;
}
if (x1==x2)
{
if (y1<y2)
for (i=y1+1;i<=y2;i++)
{
if (t[x1][i]!=0)
ok=0;
}
else
for (i=y1-1;i>=y2;i--)
{
if (t[x1][i]!=0)
ok=0;
}
if (ok==1)
return 1;
}
}
else
{
if (opuse(x1,y1,x2,y2)==1)
{
if (y1==y2)
{
if (x1<x2)
for (i=x1+1;i<x2;i++)
{
if (t[i][y1]!=0)
ok=0;
}
else
for (i=x1-1;i>x2;i--)
{
if (t[i][y1]!=0)
ok=0;
}
if (ok==1)
return 1;
}
if (x1==x2)
{
if (y1<y2)
for (i=y1+1;i<y2;i++)
{
if (t[x1][i]!=0)
ok=0;
}
else
for (i=y1-1;i>y2;i--)
{
if (t[x1][i]!=0)
ok=0;
}
if (ok==1)
return 1;
}
}
}
return 0;
}

int mutarecal(int x1,int y1,int x2,int y2) / /mutarea calului


{
if (t[x2][y2]==0)
{
if (x1-2==x2 && y1+1==y2) // conditiile de muate a calului
return 1;
if (x1-2==x2 && y1-1==y2)
return 1;
if (x1+1==x2 && y1-2==y2)
return 1;

65
if (x1-1==x2 && y1-2==y2)
return 1;
if (x1+2==x2 && y1+1==y2)
return 1;
if (x1+2==x2 && y1-1==y2)
return 1;
if (x1-1==x2 && y1+2==y2)
return 1;
if (x1+1==x2 && y1+2==y2)
return 1;
}
else
{
if (opuse(x1,y1,x2,y2)==1)
{
if (x1-2==x2 && y1+1==y2)
return 1;
if (x1-2==x2 && y1-1==y2)
return 1;
if (x1+1==x2 && y1-2==y2)
return 1;
if (x1-1==x2 && y1-2==y2)
return 1;
if (x1+2==x2 && y1+1==y2)
return 1;
if (x1+2==x2 && y1-1==y2)
return 1;
if (x1-1==x2 && y1+2==y2)
return 1;
if (x1+1==x2 && y1+2==y2)
return 1;
}
}
}

int mutarenebun(int x1,int y1,int x2,int y2) // muatrea nebunului


{
int i,j,ok;
if (t[x2][y2]==0)
{
ok=1;
i=x1;
j=y1;
if (x1>x2 && y1<y2) // conditii de muatare a nebunului
while (i>x2 && j<y2)
{
i--;
j++;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1<y2)
while (i<x2 && j<y2)
{
i++;
j++;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}

66
}
i=x1;
j=y1;
if (x1<x2 && y1>y2)
while (i<x2 && j>y2)
{
i++;
j--;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1>x2 && y1>y2)
while (i>x2 && j>y2)
{
i--;
j--;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
}
else
{
if (opuse(x1,y1,x2,y2)==1)
{
ok=1;
i=x1;
j=y1;
if (x1>x2 && y1<y2)
while (i>=x2 && j<=y2)
{
i--;
j++;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1<y2)
while (i<=x2 && j<=y2)
{
i++;
j++;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)

67
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1>y2)
while (i<=x2 && j>=y2)
{
i++;
j--;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1>x2 && y1>y2)
while (i>=x2 && j>=y2)
{
i--;
j--;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
}
}
return 0;
}

int mutareregina(int x1,int y1,int x2,int y2) // mutarea reginei pe table de sah respectind liitele
{
int i,j,ok=1;
if (t[x2][y2]==0)
{
if (y1==y2)
{
if (x1<x2)
for (i=x1+1;i<=x2;i++)
{
if (t[i][y1]!=0)
ok=0;
}
else
for (i=x1-1;i>=x2;i--)
{
if (t[i][y1]!=0)
ok=0;
}
if (ok==1)
return 1;
}
if (x1==x2)
{
if (y1<y2)
for (i=y1+1;i<=y2;i++)
{
if (t[x1][i]!=0)
ok=0;
}

68
else
for (i=y1-1;i>=y2;i--)
{
if (t[x1][i]!=0)
ok=0;
}
if (ok==1)
return 1;
}
//--------------------------------------------------------------------------------------------
ok=1;
i=x1;
j=y1;
if (x1>x2 && y1<y2)
while (i>x2 && j<y2)
{
i--;
j++;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1<y2)
while (i<x2 && j<y2)
{
i++;
j++;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1>y2)
while (i<x2 && j>y2)
{
i++;
j--;
if (t[i][j]!=0)
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1>x2 && y1>y2)
while (i>x2 && j>y2)
{
i--;
j--;
if (t[i][j]!=0)
{
ok=0;

69
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
}
else
{
if (opuse(x1,y1,x2,y2)==1)
{
if (y1==y2)
{
if (x1<x2)
for (i=x1+1;i<x2;i++)
{
if (t[i][y1]!=0)
ok=0;
}
else
for (i=x1-1;i>x2;i--)
{
if (t[i][y1]!=0)
ok=0;
}
if (ok==1)
return 1;
}
if (x1==x2)
{
if (y1<y2)
for (i=y1+1;i<y2;i++)
{
if (t[x1][i]!=0)
ok=0;
}
else
for (i=y1-1;i>y2;i--)
{
if (t[x1][i]!=0)
ok=0;
}
if (ok==1)
return 1;
}
//--------------------------------------------------------------------------------------------
ok=1;
i=x1;
j=y1;
if (x1>x2 && y1<y2)
while (i>=x2 && j<=y2)
{
i--;
j++;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1<y2)
while (i<=x2 && j<=y2)
{
i++;
j++;
if (t[i][j]!=0 && i!=x2 )
{

70
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1<x2 && y1>y2)
while (i<=x2 && j>=y2)
{
i++;
j--;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
i=x1;
j=y1;
if (x1>x2 && y1>y2)
while (i>=x2 && j>=y2)
{
i--;
j--;
if (t[i][j]!=0 && i!=x2 )
{
ok=0;
}
if (i==x2 && j==y2)
{
if (ok==1)
{
return 1;
}
}
}
}
}
return 0;
}

int mutarerege(int x1,int y1,int x2,int y2) // muatrea regelui dupa felul sau respectind limitele
{
int i,j;
if (t[x2][y2]==0)
{
i=x1;
j=y1;
i++;
j++;
if (i==x2 && j==y2) //conditii de mutare a regelui
return 1;
i=x1;
j=y1;
i--;
j++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i++;
j--;
if (i==x2 && j==y2)
return 1;
i=x1;

71
j=y1;
i--;
j--;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i--;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
j++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
j--;
if (i==x2 && j==y2)
return 1;
}
else
{
if (opuse(x1,y1,x2,y2)==1)
{
i=x1;
j=y1;
i++;
j++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i--;
j++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i++;
j--;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i--;
j--;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
i--;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
j++;
if (i==x2 && j==y2)
return 1;
i=x1;
j=y1;
j--;
if (i==x2 && j==y2)
return 1;
}
}
return 0;
}

72
void schimbarepion(int x1,int y1) // are loc scimbarea pionuilui cind a ajun in momentul final pe orice alta piesa
{
int ok=0;
char ch;
while (ok==0)
{
cout<<"\ \ \ \ Cu ce doriti sa inlocuiti pionul ?(T,C,N,Q):";
cin>>ch;
if (ch=='t')
ch='T';
if (ch=='c')
ch='C';
if (ch=='n')
ch='N';
if (ch=='q') // interscimbarea pionului cu a quen
ch='Q';
if (ch=='T')
{
if (t[x1][y1]>0)
{
t[x1][y1]=2;
scriere(x1,y1);
alb(lin[x1],col[y1]);
ok=1;
}
if (t[x1][y1]<0)
{
t[x1][y1]=-2;
scriere(x1,y1);
neg(lin[x1],col[y1]);
ok=1;
}
}
if (ch=='C')
{
if (t[x1][y1]>0)
{
t[x1][y1]=3;
scriere(x1,y1);
alb(lin[x1],col[y1]);
ok=1;
}
if (t[x1][y1]<0)
{
t[x1][y1]=-3;
scriere(x1,y1);
neg(lin[x1],col[y1]);
ok=1;
}
}
if (ch=='N')
{
if (t[x1][y1]>0)
{
t[x1][y1]=4;
scriere(x1,y1);
alb(lin[x1],col[y1]);
ok=1;
}
if (t[x1][y1]<0)
{
t[x1][y1]=-4;
scriere(x1,y1);
neg(lin[x1],col[y1]);
ok=1;
}
}
if (ch=='Q')
{
if (t[x1][y1]>0)
{
t[x1][y1]=5;
scriere(x1,y1);
alb(lin[x1],col[y1]);
ok=1;
}
if (t[x1][y1]<0)

73
{
t[x1][y1]=-5;
scriere(x1,y1);
neg(lin[x1],col[y1]);
ok=1;
}
}
}
}

int sah(int xx1,int yy1) // programul care ruleaza sah si conditiile necesare
{
int i,j;
if (t[xx1][yy1]>0)
{
for (i=1;i<=8;i++)
{
for (j=1;j<=8;j++)
{
if (t[i][j]<0)
{
if (t[i][j]==-1)
{
if (mutarepioninvers(i,j,xx1,yy1)==1) //sah pion
{
return 1;
}
}
if (t[i][j]==-2)
{
if (mutaretura(i,j,xx1,yy1)==1) //sah tura
{
return 1;
}
}
if (t[i][j]==-3)
{
if (mutarecal(i,j,xx1,yy1)==1) // sah cal
{
return 1;
}
}
if (t[i][j]==-4)
{
if (mutarenebun(i,j,xx1,yy1)==1) //sah nebun
{
return 1;
}
}
if (t[i][j]==-5)
{
if (mutareregina(i,j,xx1,yy1)==1) //sah regina
{
return 1;
}
}
if (t[i][j]==-6)
{
if (mutarerege(i,j,xx1,yy1)==1)
{
return 1;
}
}
}
}
}
}
if (t[xx1][yy1]<0)
{
for (i=1;i<=8;i++)
{
for (j=1;j<=8;j++)
{
if (t[i][j]>0)
{
if (t[i][j]==1)
{
if (mutarepioninvers(i,j,xx1,yy1)==1)

74
{
return 1;
}
}
if (t[i][j]==2)
{
if (mutaretura(i,j,xx1,yy1)==1)
{
return 1;
}
}
if (t[i][j]==3)
{
if (mutarecal(i,j,xx1,yy1)==1)
{
return 1;
}
}
if (t[i][j]==4)
{
if (mutarenebun(i,j,xx1,yy1)==1)
{
return 1;
}
}
if (t[i][j]==5)
{
if (mutareregina(i,j,xx1,yy1)==1)
{
return 1;
}
}
if (t[i][j]==6)
{
if (mutarerege(i,j,xx1,yy1)==1)
{
return 1;
}
}
}
}
}
}
return 0;
}

int verifrocada(int x1,int y1,int x2,int y2) //racordarea mre


{
if (t[x1][y1]>0)
if (x1==x2)
if (t[x1][y1]==6)
{
if (t[x2][y2]==2)
{
if (y2-y1==3)
{
if (t[x1][y1+1]==0 && t[x1][y1+2]==0)
{
return 1;
}
}
if (y1-y2==4)
{
if (t[x1][y1-1]==0 && t[x1][y1-2]==0 && t[x1][y1-3]==0)
{
return 1;
}
}
}
}
if (t[x1][y1]<0)
{
if (x1==x2)
if (t[x1][y1]==-6)
{
if (t[x2][y2]==-2)
{
if (y1-y2==3)

75
{
if (t[x1][y1-1]==0 && t[x1][y1-2]==0)
{
return 1;
}
}
if (y2-y1==4)
{
if (t[x1][y1+1]==0 && t[x1][y1+2]==0 && t[x1][y1+3]==0)
{
return 1;
}
}
}
}
}
return 0;
}

void rocada(int x1,int y1,int x2,int y2) //reacordare mica


{
if (t[x1][y1]>0)
if (x1==x2)
if (t[x1][y1]==6)
{
if (t[x2][y2]==2)
{
if (y2-y1==3)
{
if (t[x1][y1+1]==0 && t[x1][y1+2]==0)
{
t[x1][y1+1]=2;
t[x1][y1+2]=6;
t[x1][y1]=0;
t[x2][y2]=0;
a[lin[x1]][col[y1+1]]='T';
scriere(x1,y1+1);
a[lin[x1]][col[y1+2]]='R';
scriere(x1,y1+2);
stergere(lin[x1],col[y1]);
stergere(lin[x2],col[y2]);
}
}
if (y1-y2==4)
{
if (t[x1][y1-1]==0 && t[x1][y1-2]==0 && t[x1][y1-3]==0)
{
t[x1][y1-1]=2;
t[x1][y1-2]=6;
t[x1][y1]=0;
t[x2][y2]=0;
a[lin[x1]][col[y1-1]]='T';
scriere(x1,y1-1);
a[lin[x1]][col[y1-2]]='R';
scriere(x1,y1-2);
stergere(lin[x1],col[y1]);
stergere(lin[x2],col[y2]);
}
}
}
}
if (t[x1][y1]<0)
{
if (x1==x2)
if (t[x1][y1]==-6)
{
if (t[x2][y2]==-2)
{
if (y1-y2==3)
{
if (t[x1][y1-1]==0 && t[x1][y1-2]==0)
{
t[x1][y1-1]=-2;
t[x1][y1-2]=-6;
t[x1][y1]=0;
t[x2][y2]=0;
a[lin[x1]][col[y1-1]]='T';
scriere(x1,y1-1);

76
a[lin[x1]][col[y1-2]]='R';
scriere(x1,y1-2);
stergere(lin[x1],col[y1]);
stergere(lin[x2],col[y2]);
}
}
if (y2-y1==4)
{
if (t[x1][y1+1]==0 && t[x1][y1+2]==0 && t[x1][y1+3]==0)
{
t[x1][y1+1]=-2;
t[x1][y1+2]=-6;
t[x1][y1]=0;
t[x2][y2]=0;
a[lin[x1]][col[y1+1]]='T';
scriere(x1,y1+1);
a[lin[x1]][col[y1+2]]='R';
scriere(x1,y1+2);
stergere(lin[x1],col[y1]);
stergere(lin[x2],col[y2]);
}
}
}
}
}
}

int mutare(int coox1,int cooy1,int coox2,int cooy2) // mutarea pieselor in parte


{
if (t[coox1][cooy1]==1)
{
if (mutarepion(coox1,cooy1,coox2,cooy2)==1)
return 1;
else
return 0;
}
if (t[coox1][cooy1]==2)
{
if (mutaretura(coox1,cooy1,coox2,cooy2)==1)
return 1;
else
return 0;
}
if (t[coox1][cooy1]==3)
{
if (mutarecal(coox1,cooy1,coox2,cooy2)==1) //muatare cal
return 1;
else
return 0;
}
if (t[coox1][cooy1]==4)
{
if (mutarenebun(coox1,cooy1,coox2,cooy2)==1) //muatere nebun
return 1;
else
return 0;
}
if (t[coox1][cooy1]==5)
{
if (mutareregina(coox1,cooy1,coox2,cooy2)==1) // muatare regina
return 1;
else
return 0;
}
if (t[coox1][cooy1]==6)
{
if (mutarerege(coox1,cooy1,coox2,cooy2)==1) //mutare rege
{
t[coox2][cooy2]=6;
if (sah(coox2,cooy2)==0)
return 1;
t[coox2][cooy2]=0;
}
return 0;
}
if (t[coox1][cooy1]==-1)
{
if (mutarepion(coox1,cooy1,coox2,cooy2)==1) // muatare pion

77
return 1;
else
return 0;
}
if (t[coox1][cooy1]==-2)
{
if (mutaretura(coox1,cooy1,coox2,cooy2)==1) // mutarea turnei
return 1;
else
return 0;
}
if (t[coox1][cooy1]==-3)
{
if (mutarecal(coox1,cooy1,coox2,cooy2)==1) // muatare a calului
return 1;
else
return 0;
}
if (t[coox1][cooy1]==-4)
{
if (mutarenebun(coox1,cooy1,coox2,cooy2)==1) /muatarea nebunului
return 1;
else
return 0;
}
if (t[coox1][cooy1]==-5)
{
if (mutareregina(coox1,cooy1,coox2,cooy2)==1) // muatarea reginei
return 1;
else
return 0;
}
if (t[coox1][cooy1]==-6)
{
if (mutarerege(coox1,cooy1,coox2,cooy2)==1) // muatarea regelui
{
t[coox2][cooy2]=-6;
if (sah(coox2,cooy2)==0)
return 1;
t[coox2][cooy2]=0;
}
return 0;
}
}

int sahmat(int x,int y) // programul de implemintare a sah mat


{
int i,j,ok=1,i2,j2,xx,yy,var,var2;
if (t[x][y]>0)
{
for (i=1;i<=8;i++)
{
for (j=1;j<=8;j++)
{
for (i2=1;i2<=8;i2++)
{
for (j2=1;j2<=8;j2++)
{
if (t[i2][j2]>0)
{
if (t[i2][j2]==1)
{
if (mutarepion(i2,j2,i,j)==1) // conditia de muate a pionului
{
var=t[i][j];
t[i][j]=1;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=1;
t[i][j]=var;
}
}
if (t[i2][j2]==2)
{
if (mutaretura(i2,j2,i,j)==1) //conditie de muatare a turei

78
{
var=t[i][j];
t[i][j]=2;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=2;
t[i][j]=var;
}
}
if (t[i2][j2]==3)
{
if (mutarecal(i2,j2,i,j)==1) // conditie de muatare a calului
{
var=t[i][j];
t[i][j]=3;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=3;
t[i][j]=var;
}
}
if (t[i2][j2]==4)
{
if (mutarenebun(i2,j2,i,j)==1) // conditia de muate a nebunului
{
var=t[i][j];
t[i][j]=4;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=4;
t[i][j]=var;
}
}
if (t[i2][j2]==5)
{
if (mutareregina(i2,j2,i,j)==1) // conditia de muate a reginei
{
var=t[i][j];
t[i][j]=5;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=5;
t[i][j]=var;
}
}
if (t[i2][j2]==6)
{
if (mutarerege(i2,j2,i,j)==1)
{
xx=i;
yy=j;
var=t[xx][yy];
t[i2][j2]=0;
t[xx][yy]=6;
if (sah(xx,yy)==0)
{
ok=0;
}
t[xx][yy]=var;
t[i2][j2]=6;
}
}
}
}
}
}

79
}
}
if (t[x][y]<0)
{
for (i=1;i<=8;i++)
{
for (j=1;j<=8;j++)
{
for (i2=1;i2<=8;i2++)
{
for (j2=1;j2<=8;j2++)
{
if (t[i2][j2]<0)
{
if (t[i2][j2]==-1)
{
if (mutarepion(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-1;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=-1;
t[i][j]=var;
}
}
if (t[i2][j2]==-2)
{
if (mutaretura(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-2;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=-2;
t[i][j]=var;
}
}
if (t[i2][j2]==-3)
{
if (mutarecal(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-3;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=-3;
t[i][j]=var;
}
}
if (t[i2][j2]==-4)
{
if (mutarenebun(i2,j2,i,j)==1) // mutare nebun
{
var=t[i][j];
t[i][j]=-4;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=-4;
t[i][j]=var;
}
}
if (t[i2][j2]==-5)
{
if (mutareregina(i2,j2,i,j)==1) // mutare regina
{

80
var=t[i][j];
t[i][j]=-5;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=0;
}
t[i2][j2]=-5;
t[i][j]=var;
}
}
if (t[i2][j2]==-6)
{
if (mutarerege(i2,j2,i,j)==1) // mutare rege
{
xx=i;
yy=j;
var=t[xx][yy];
t[i2][j2]=0;
t[xx][yy]=-6;
if (sah(xx,yy)==0)
{
ok=0;
}
t[xx][yy]=var;
t[i2][j2]=-6;
}
}
}
}
}
}
}
}
if (ok==1)
return 1;
else
return 0;
}

int pat(int x,int y) // conditiile pentru pat


{
int i,j,i2,j2,ok=0,xx,yy,var;
if (t[x][y]>0)
{
for (i=1;i<=8;i++)
{
for (j=1;j<=8;j++)
{
for (i2=1;i2<=8;i2++)
{
for (j2=1;j2<=8;j2++)
{
if (t[i2][j2]>0)
{
if (t[i2][j2]==1)
{
if (mutarepion(i2,j2,i,j)==1) // conditie de mutare pion
{
var=t[i][j];
t[i][j]=1;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=1;
t[i][j]=var;
}
}
if (t[i2][j2]==2)
{
if (mutaretura(i2,j2,i,j)==1) // conditie de muatare regina
{
var=t[i][j];
t[i][j]=2;
t[i2][j2]=0;
if (sah(x,y)==0)

81
{
ok=1;
}
t[i2][j2]=2;
t[i][j]=var;
}
}
if (t[i2][j2]==3)
{
if (mutarecal(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=3;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=3;
t[i][j]=var;
}
}
if (t[i2][j2]==4)
{
if (mutarenebun(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=4;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=4;
t[i][j]=var;
}
}
if (t[i2][j2]==5)
{
if (mutareregina(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=5;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=5;
t[i][j]=var;
}
}
if (t[i2][j2]==6)
{
if (mutarerege(i2,j2,i,j)==1)
{
xx=i;
yy=j;
var=t[xx][yy];
t[i2][j2]=0;
t[xx][yy]=6;
if (sah(xx,yy)==0)
{
ok=1;
}
t[xx][yy]=var;
t[i2][j2]=6;
}
}
}
}
}
}
}
}
if (t[x][y]<0)
{
for (i=1;i<=8;i++)

82
{
for (j=1;j<=8;j++)
{
for (i2=1;i2<=8;i2++)
{
for (j2=1;j2<=8;j2++)
{
if (t[i2][j2]<0)
{
if (t[i2][j2]==-1)
{
if (mutarepion(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-1;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=-1;
t[i][j]=var;
}
}
if (t[i2][j2]==-2)
{
if (mutaretura(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-2;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=-2;
t[i][j]=var;
}
}
if (t[i2][j2]==-3)
{
if (mutarecal(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-3;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=-3;
t[i][j]=var;
}
}
if (t[i2][j2]==-4)
{
if (mutarenebun(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-4;
t[i2][j2]=0;
if (sah(x,y)==0)
{
ok=1;
}
t[i2][j2]=-4;
t[i][j]=var;
}
}
if (t[i2][j2]==-5)
{
if (mutareregina(i2,j2,i,j)==1)
{
var=t[i][j];
t[i][j]=-5;
t[i2][j2]=0;
if (sah(x,y)==0)
{

83
ok=1;
}
t[i2][j2]=-5;
t[i][j]=var;
}
}
if (t[i2][j2]==-6)
{
if (mutarerege(i2,j2,i,j)==1)
{
xx=i;
yy=j;
var=t[xx][yy];
t[i2][j2]=0;
t[xx][yy]=-6;
if (sah(xx,yy)==0)
{
ok=1;
}
t[xx][yy]=var;
t[i2][j2]=-6;
}
}
}
}
}
}
}
}
if (ok==1)
return 1;
else
return 0;
}

int main() // secventa programului principal care le include pe restu


{
int i,j,ok,x1,x2,y1,y2,albe[4]={0,1,1,1},negre[4]={0,1,1,1};
char p1[256],p2[256],charm;
xra=8;
yra=5;
xrn=8;
yrn=4;
cout<<"\ \ \ \ Jucatorul nr. 1:";
cin>>p1;
cout<<"\ \ \ \ Jucatorul nr. 2:";
cin>>p2;
cout<<endl;
cout<<"\ \ \ \ Reguli:";
cout<<endl;
cout<<endl;
cout<<"\ \ \ \ Acest joc nu accepta en passant.";
cout<<endl;
cout<<"\ \ \ \ Pentru a deselecta o piesa introduceti coordonatele piesei din nou.";
cout<<endl;
cout<<"\ \ \ \ Ordinea coordonatelor este aleatorie.";
cout<<endl;
cout<<endl;
cout<<"\ \ \ \ Legenda:";
cout<<endl;
cout<<endl;
cout<<"\ \ \ \ T=tura";
cout<<endl;
cout<<"\ \ \ \ P=pion";
cout<<endl;
cout<<"\ \ \ \ N=nebun";
cout<<endl;
cout<<"\ \ \ \ C=cal";
cout<<endl;
cout<<"\ \ \ \ Q=regina";
cout<<endl;
cout<<"\ \ \ \ R=rege";
cout<<endl<<endl;
cout<<"\ \ \ \ Jocul incepe:";
cout<<endl<<endl;
//--------------------------------------------------------------------------------------------
//Test
i=2;

84
for (j=1;j<=8;j++)
{
t[i][j]=-1;
}
i=7;
for (j=1;j<=8;j++)
{
t[i][j]=1;
}
x1=1;
x2=8;
y1=1;
y2=8;
t[x1][y1]=-2;
t[x1][y2]=-2;
t[x2][y1]=2;
t[x2][y2]=2;

y1=2;
y2=7;
t[x1][y1]=-3;
t[x1][y2]=-3;
t[x2][y1]=3;
t[x2][y2]=3;

y1=3;
y2=6;
t[x1][y1]=-4;
t[x1][y2]=-4;
t[x2][y1]=4;
t[x2][y2]=4;

y1=4;
y2=5;
t[x1][y1]=-5;
t[x1][y2]=-6;
t[x2][y1]=5;
t[x2][y2]=6;
//Test
//--------------------------------------------------------------------------------------------TESTPAT
/*x1=7;
y1=4;
t[x1][y1]=2;
y1=6;
t[x1][y1]=2;
x1=1;
y1=5;
t[x1][y1]=-6;
x1=8;
t[x1][y1]=6;
x1=2;
y1=1;
t[x1][y1]=2;
x1=3;
y1=7;
t[x1][y1]=-1;
x1=5;
t[x1][y1]=2;*/
//--------------------------------------------------------------------------------------------negru
/*x1=2;
y1=4;
t[x1][y1]=-2;
y1=6;
t[x1][y1]=-2;
x1=1;
y1=5;
t[x1][y1]=-6;
x1=8;
t[x1][y1]=6;
x1=7;
y1=1;
t[x1][y1]=-2;
x1=5;
y1=7;
t[x1][y1]=1;
x1=2;
t[x1][y1]=-2;*/
//--------------------------------------------------------------------------------------------TESTPAT

85
for (i=2;i<=42;i++)
{
if(i==2 || i==42)
{
x1=i;
strcpy(a[i]," --------------------------------------------------------------- ");
}
else
{
if(i-5==x1)
{
strcpy(a[i]," |-------|-------|-------|-------|-------|-------|-------|-------|");
x1=i;
}
else
strcpy(a[i]," | | | | | | | | |");
}
}
//--------------------------------------------------------------------------------------------
ok=1;
for(i=1;i<=8;i++)
{
if (ok==1)
ok=0;
else
ok=1;
for(j=1;j<=8;j++)
{
if (ok==1)
ok=0;
else
ok=1;
if (ok==1)
{
if (t[i][j]==0)
casutaalban(lin[i],col[j]);
else
casutaalbao(lin[i],col[j]);
}
}
}
//--------------------------------------------------------------------------------------------
i=lin[0];
charm='A';
for (j=1;j<=8;j++)
{
a[i][col[j]]=charm;
charm++;
}
i=lin[9];
charm='A';
for (j=1;j<=8;j++)
{
a[i][col[j]]=charm;
charm++;
}
j=col[0];
charm='1';
for (i=1;i<=8;i++)
{
a[lin[i]][j]=charm;
charm++;
}
j=col[9];
charm='1';
for (i=1;i<=8;i++)
{
a[lin[i]][j]=charm;
charm++;
}
//--------------------------------------------------------------------------------------------
//Test //de aici se incepe incapsularea pieselor in locul lor pe table cu denumire si restu
i=lin[2];
for (j=1;j<=8;j++)
{
a[i][col[j]]='P';
neg(i,col[j]);
}

86
i=lin[7];
for (j=1;j<=8;j++)
{
a[i][col[j]]='P';
alb(i,col[j]);
}

x1=lin[1];
x2=lin[8];
y1=col[1];
y2=col[8];
a[x1][y1]='T';
a[x1][y2]='T';
a[x2][y1]='T';
a[x2][y2]='T';

y1=col[2];
y2=col[7];
a[x1][y1]='C';
a[x1][y2]='C';
a[x2][y1]='C';
a[x2][y2]='C';

y1=col[3];
y2=col[6];
a[x1][y1]='N';
a[x1][y2]='N';
a[x2][y1]='N';
a[x2][y2]='N';

y1=col[4];
y2=col[5];
a[x1][y1]='Q';
a[x1][y2]='R';
a[x2][y1]='Q';
a[x2][y2]='R';
//--------------------------------------------------------------------------------------------
i=lin[1]; // scris alb si negru la fiecare pissa pentru a le deferia
for(j=1;j<=8;j++)
{
neg(i,col[j]);
}
i=lin[8];
for(j=1;j<=8;j++)
{
alb(i,col[j]);
}
//Test
//--------------------------------------------------------------------------------------------
int sw=2,okk,xx,yy,okkk,dis,ok10,sahh=0,v,v2,sm=0;
ok=1;
while(ok==1)
{
afisare();
if(sw==1)
sw=2;
else
sw=1;
if (sw==1)
cout<<"\ \ \ \ "<<p1<<" este randul tau:"<<endl;
else
cout<<"\ \ \ \ "<<p2<<" este randul tau:"<<endl;
okk=0;
while(okk==0)
{
if (verificarecoo()==1)
if (sw==1)
{
aranjare();
if(t[coox][cooy]>0)
okk=1;
else
cout<<"\ \ \ \ Coordonate gresite:";
}
else
{
aranjare();
if(t[coox][cooy]<0)

87
okk=1;
else
cout<<"\ \ \ \ Coordonate gresite:";
}
else
cout<<"\ \ \ \ Coordonate gresite:";
}
okkk=0;
select(lin[coox],col[cooy]);
xx=coox;
yy=cooy;
dis=1;
ok10=0;
while(okkk==0)
{
afisare();
if (sahh==1)
cout<<"\ \ \ \ Esti in sah. Reincercati:";
sahh=0;
if (dis==1)
{
xx=coox;
yy=cooy;
cout<<"\ \ \ \ Mutare pe coordonatele:";
}
if (ok10==1 && dis==0)
cout<<"\ \ \ \ Mutare nepermisa. Reincercati:";
dis=0;
ok10=0;
if (verificarecoo()==1)
{
aranjare();
if (coox==xx && cooy==yy)
{
dis=1;
deselect(lin[coox],col[cooy]);
okk=0;
afisare();
cout<<"\ \ \ \ Introduceti coordonate noi:";
while(okk==0)
{
if (verificarecoo()==1)
if (sw==1)
{
aranjare();
if(t[coox][cooy]>0)
okk=1;
else
cout<<"\ \ \ \ Coordonate gresite:";
}
else
{
aranjare();
if(t[coox][cooy]<0)
okk=1;
else
cout<<"\ \ \ \ Coordonate gresite:";
}
else
cout<<"\ \ \ \ Coordonate gresite:";
}
select(lin[coox],col[cooy]);
}
}
if(mutare(xx,yy,coox,cooy)==1)
{
if (sw==1)
{
if (xx==8 && yy==1)
albe[1]=0;
if (xx==8 && yy==5)
{
albe[2]=0;
}
if (xx==8 && yy==8)
albe[3]=0;
}
else

88
{
if (xx==8 && yy==1)
negre[1]=0;
if (xx==8 && yy==4)
negre[2]=0;
if (xx==8 && yy==8)
negre[3]=0;
}
if (t[xx][yy]==6)
{
xra=coox;
yra=cooy;
}
if (t[xx][yy]==-6)
{
xrn=coox;
yrn=cooy;
}
if (sw==1)
{
if (sah(xra,yra)==0)
{
v2=t[coox][cooy];
t[coox][cooy]=t[xx][yy];
t[xx][yy]=0;
if (sah(xra,yra)==0)
{
okkk=1;
deselect(lin[xx],col[yy]);
stergere(lin[xx],col[yy]);
scriere(coox,cooy);
}
else
{
t[xx][yy]=t[coox][cooy];
t[coox][cooy]=v2;
}
}
else
{
sahh=1;
v=t[coox][cooy];
t[coox][cooy]=9;
if (sah(xra,yra)==0)
{
sahh=0;
okkk=1;
t[coox][cooy]=t[xx][yy];
t[xx][yy]=0;
deselect(lin[xx],col[yy]);
stergere(lin[xx],col[yy]);
scriere(coox,cooy);
}
else
{
t[coox][cooy]=v;
}
}
}
else
{
if (sah(xrn,yrn)==0)
{
v2=t[coox][cooy];
t[coox][cooy]=t[xx][yy];
t[xx][yy]=0;
if (sah(xrn,yrn)==0)
{
okkk=1;
deselect(lin[xx],col[yy]);
stergere(lin[xx],col[yy]);
scriere(coox,cooy);
}
else
{
t[xx][yy]=t[coox][cooy];
t[coox][cooy]=v2;
}

89
}
else
{
sahh=1;
v=t[coox][cooy];
t[coox][cooy]=9;
if (sah(xrn,yrn)==0)
{
sahh=0;
okkk=1;
t[coox][cooy]=t[xx][yy];
t[xx][yy]=0;
deselect(lin[xx],col[yy]);
stergere(lin[xx],col[yy]);
scriere(coox,cooy);
}
else
{
t[coox][cooy]=v;
}
}
}

}
else
{
ok10=1;
if (sw==1)
{
if (xx==8 && yy==5)
{
if (albe[1]==1 && albe[2]==1 && coox==8 && cooy==1)
{
if (verifrocada(xx,yy,coox,cooy)==1)
{
albe[1]=0;
albe[2]=0;
deselect(lin[xx],col[yy]);
rocada(xx,yy,coox,cooy);
okkk=1;
}
}
else
{
if (albe[2]==1 && albe[3]==1 && coox==8 && cooy==8)
{
if (verifrocada(xx,yy,coox,cooy)==1)
{
albe[2]=0;
albe[3]=0;
deselect(lin[xx],col[yy]);
rocada(xx,yy,coox,cooy);
okkk=1;
}
}
}
}
}
else
{
if (xx==8 && yy==4)
{
if (negre[1]==1 && negre[2]==1 && coox==8 && cooy==1)
{
if (verifrocada(xx,yy,coox,cooy)==1)
{
negre[1]=0;
negre[2]=0;
deselect(lin[xx],col[yy]);
rocada(xx,yy,coox,cooy);
okkk=1;
}
}
else
{
if (negre[2]==1 && negre[3]==1 && coox==8 && cooy==8)
{
if (verifrocada(xx,yy,coox,cooy)==1)

90
{
negre[2]=0;
negre[3]=0;
deselect(lin[xx],col[yy]);
rocada(xx,yy,coox,cooy);
okkk=1;

}
}
}
}
}
}
}
i=1;
for (j=1;j<=8;j++)
{
if (sw==1)
{
if (t[i][j]==1)
{
schimbarepion(i,j);
}
}
else
{
if (t[i][j]==-1)
{
schimbarepion(i,j);
}
}
}
flip();
if (sw==1)
{
if (sah(xrn,yrn)==1)
{
if(sahmat(xrn,yrn)==1)
{
ok=0;
sm=1;
}
}
}
else
{
if (sah(xra,yra)==1) /// conditia sah
{
if (sahmat(xra,yra)==1) // conditia de sah mat
{
ok=0;
sm=1;
}
}
}
if (sw==1)
{
if (pat(xrn,yrn)==0)
{
ok=0;
}
}
else
{
if (pat(xra,yra)==0)
{
ok=0;
}
}
}
afisare();
if (sm==1)
{
cout<<"\ \ \ \ SAH MAT !!!"<<endl<<endl;
cout<<"\ \ \ \ Castigator ";
if (sw==1)
cout<<p1<<" !!!";
else

91
cout<<p2<<" !!!";
}
else
cout<<"\ \ \ \ PAT !!! Remiza.";

//--------------------------------------------------------------------------------------------
}

Rezultatul Programului:

Dupa citeva miscari :

92
93
Concluzie

Efectund Teza de an me-am mbuntit stilul de lucru i am nsuit mai bine


tehnicile de prelucrare, folosite n lucrrile de laborator, am insusit mai bine
materialul pentru a putea cerceta si efectua teza, am descoperit cite ceva nou. Scopul
principal in aceasta lucrare a fost sa studiez capitolele bazate pe simularea, tipuri de
simulare, deciziile, tipuri de decizii, strategiile, tipuri de strategii toate acestea l-eam
combinata pentru a construi o masina multi-decizionala bazata pe decizii strategice,
acest joc numit sah mi sa parut ca poate fi un bun exemplu si poate fi exprimat ca o
masina multi-decizionale in limbajul C/C++, acest joc sah l-am implimentat intr-un
program, la care am creat functii de analiza a miscarilor, , se salveaza toate miscarile
la care algoritmul de cautare a toate solutiilor favorabile de miscare creat pe baza
tehnicii BackTracking, si sunt propuse pentru miscare, la care am implimentat inca
un algoritm de cautare a celei mai bune solutie posibile, stabilita din precedente, dupa
cum este selectata ca miscare cu prioritate, la care functiea de tip miscare selecteaza
miscare cu prioaritate. Sunt implimentate regulile de baza a jocului sah pe aceste
reguli functioneaza miscarile ambilor, pe simularea deciziei strategice folosite

94
precedent de catre utilizator, multe jocuri petrecute in acest program cu diferiti
utilizatori, permite capacitati mai mari de cistig, si decizii mai bune din punct de
vedere strategic.

Introducere

n rezolvarea unei probleme cu calculatorul este important definirea strategiei de


rezolvare a problemei si definirea optim a algoritmului. Exist cteva metode speciale de
elaborare a algoritmilor. Alegerea uneia sau alteia fiind fcuta n concordant cu specificul
problemei de rezolvat si cu eficienta algoritmului. Fiecare algoritm are un context n care
el poate fi folosit.

Dac s ne amintim din definiia algoritmului care este compus dintr-o multime
finit de parti, fiecare necesitnd una sau mai multe operatii. Pentru a fi implementabile pe
calculator, aceste operasii trebuie s fie n primul rnd definite, adic sa fie foarte clar ce
anume trebuie executat. n al doilea rnd, operatiile trebuie sa fie efective, ceea ce
nseamn c n principiu, cel putin o persoana dotat cu creion si hrtie trebuie s poat
efectua orice pas ntr-un timp finit. De exemplu, aritmetica cu numere ntregi este efectiv.
Aritmetica cu numere reale nu este ns efectiva, deoarece unele numere sunt exprimabile
prin secvete infinite. Vom considera c un algoritm trebuie s se termine dup un numar
finit de operaii, ntr-un timp rezonabil de lung.

Programul este exprimarea unui algoritm ntr-un limbaj de programare. Este bine ca
nainte de a nva concepte generale, s fi acumulat deja o anumita experien practic n
domeniul respectiv.

Actul de creare a unui algoritm este o art care nu va putea fi niciodata pe deplin
automatizat. Este n fond vorba de mecanismul universal al creativitii umane, care
produce noul printr-o sintez extrem de complex. Utiliznd aceste tehnici, acumulnd i o
anumit experien, vom putea pe viitor elabora noi algoritmi, mai eficieni.

95
Bibliografie
Herbert Schildt - C++ - Manual complet, editura Teora, Bucuresti 1997
http://rac.rosoftware.com/docs/other/IntroC_part3.pdf
Borland C++ Builder 5 Online Help
http://www.unixinside.org/papers/C++-Book/cap1.html
http://ro.wikibooks.org/wiki/Sah/Reguli_de_baza
http://en.wikipedia.org/wiki/Chess
http://info.tm.edu.ro:8080/~asimulescu/public/clasa11D/Backtracking_1.pdf
http://89.121.249.92/2010-2011/Catedre/Informatica/11/Teorie_back.pdf
http://software.ucv.ro/~cstoica/TP/backtracking.pdf
http://ro.wikipedia.org/wiki/%C8%98ah_(joc)

96

S-ar putea să vă placă și