Documente Academic
Documente Profesional
Documente Cultură
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
Tema:___________________________________________________________________
_____________________________________________________________________________________
_____________________________________________________________________________________
_____________________________________________________________________________________
_____________________________________________________________________________________
_____________________________________________________________________________________
_____________________________________________________________________________________
_____________________________________________________________________________________
Semntura studentului_______________
2
Sarcina lucrrii
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
4
Anexa 2. Rezultatele rulrii programului ..85
Concluzia....................................................................................................................87
Biografia.....................................................................................................................89
5
Capitolul I
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
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:
chn - este o expresie care fiind 0 (caracterul avand codul ASCII 0) este considerata falsa
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).
|| -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.
! -negatie logica; Returneaza adevarat daca expresia este nula, fals in caz contrar. (!E) este
echivalent cu (E == 0).
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.
< -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):
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.
o int x = 3;
o int y = 4;
o if(x = y)
o else
o printf(Conditie falsa);
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
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:
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:
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,
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
- 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..
11
printf(strBuffer);
Instrctiunea for:
<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):
strSir[iIndex] = UpCase(strSir[iIndex]);
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:
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).
int iBytesRead;
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:
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 ()
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.
14
Capitolul III
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:
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.
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
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
Mulimile A1, A2, An sunt mulimi finite, iar elementele lor se afl ntr-o
ordine bine stabilit
Prezentarea algoritmului
Pentru uurarea nelegerii metodei vom prezenta o rutin unic, aplicabil oricrei
17
probleme, rutin care utilizeaz noiunea de stiv.
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)
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:
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:
19
Pe linia a treia putem amplasa o regin chiar pe prima coloan:
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
}
#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.
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.
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
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;
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.
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.
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.
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
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:
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.
; //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])
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())
break;
case 0 :
if ( ( j-piesa[cp].da_c() ) > 0 )
if ( i!=piesa[cp].da_l() )
if ( ( piesa[cp].da_c() -j ) > t )
break; }
break;
36
if(c<0) for( k = piesa[cp].da_c()-1; k>j ; k-- ) }
else
break;
else
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
else
else
if( piesa[tr].da_mutare() != 0 )
piesa[tr].muta( k, piesa[cp].da_c() );
37
// rocada
else
break;
case 'd': char ch;//retine 't' daca regina muta pe orizontala sau pe verticala si 'n' daca regina adopta o mutare de nebun
else
else
switch(ch)
case 't' : }
case 'n' :
l= i - piesa[cp].da_l();
c= j - piesa[cp].da_c();
if(c>0)
else
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;
else
if(!ac) return 1;
else continue;
continue;
case 't':
39
else
if(!ac) return 1;
else continue;
continue;
else
if(!ac) return 1;
else continue;
continue;
return 1;
else continue;
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.
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.
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.
k++;}
if( k==32 )
return 1;
return 0;
41
Capitolul VII
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.
class piese
~piese() ;
int da_l() ;
int da_c() ;
char da_p() ;
int da_cul() ;
int da_mutare()
void transformare();
int en() ;
void pune_en()
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 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.
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.
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.
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 .
l=i;
c=j;
afiseaza_piesa(l,c,culoare,piesa);
mutare++;
else en_pas=0;
45
ultim=this;
};
Transformarea pionului
void piese::transformare()
break;
case 75 : if(i>0)
break;
} // muta conturul asupra piesei dorite si se opreste cand este apasat ENTER
switch(i)
setfillstyle(SOLID_FILL,12);
};
46
Capitolul VIII
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.
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();
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)
case '6':
case '4' :
case '2' :
case '5':
case 13:
else
48
if(cp==ps) continue;
else
else
if(mutare_valida(i,j,cp,piesa))
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>//
fclose(F);//inchidem fisierul
50
int ctrl(int i,int j)//functiea int ce retureaza
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
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
}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++)
}
// 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();
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;
}
}
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 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++;
}
}
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;
}
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 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;
}
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;
}
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;
}
}
}
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;
}
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;
}
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]);
}
}
}
}
}
}
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;
}
}
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;
}
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;
}
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:
92
93
Concluzie
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
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