Gra kółko i krzyżyk w C++ (Tic Tac Toe). Autorski algorytm. Komputer nie do pokonania. Kod źródłowy + komentarze.

[b]Projekt gry kółko i krzyżyk (ang. Tic Tac Toe) wykonany w C++ przy użyciu funkcji. Projekt dla I roku studiów Informatycznych.[/b] Gra oferuje: możliwość gry z komputerem lub dla dwóch graczy możliwość wyboru czy gramy kółkiem czy krzyżykiem komunikat o wygranej jednego z graczy z podświetleniem jego trzech znaków w jednej linii w przypadku gry z komputerem możemy wybrać kto zaczyna lub zdecydować się na losowy wybór autorski algorytm gry komputera (komputer jest nie do pokonania, przynajmniej tak wykazały liczne testy programu) algorytm komputera umożliwia mu wygranie z graczem jeśli ten popełni błędy strategiczne (komputer stosuje kilka strategi zaobserwowanych przy normalnej grze w kółko i krzyżyk) [b]Projekt uruchamiany pod Visual Studio 2008.

[b]Projekt gry kółko i krzyżyk (ang. Tic Tac Toe) wykonany w C++ przy użyciu funkcji. Projekt dla I roku studiów Informatycznych.[/b]

Gra oferuje:

  • możliwość gry z komputerem lub dla dwóch graczy
  • możliwość wyboru czy gramy kółkiem czy krzyżykiem
  • komunikat o wygranej jednego z graczy z podświetleniem jego trzech znaków w jednej linii
  • w przypadku gry z komputerem możemy wybrać kto zaczyna lub zdecydować się na losowy wybór
  • autorski algorytm gry komputera (komputer jest nie do pokonania, przynajmniej tak wykazały liczne testy programu)
  • algorytm komputera umożliwia mu wygranie z graczem jeśli ten popełni błędy strategiczne (komputer stosuje kilka strategi zaobserwowanych przy normalnej grze w kółko i krzyżyk)

[b]Projekt uruchamiany pod Visual Studio 2008.[/b]

[code=cpp]/* The MIT License

Copyright (c) 2009 Webook.pl

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // kolko_i_krzyzyk.cpp : Defines the entry point for the console application. //

#include “stdafx.h” #include //#include #include #include // time(NULL) #include // #include <Windows.h> // zawiera funkcje Sleep() //#include<stdio.h> // zawiera funkcje getchar() using namespace std; // otwarcie przestrzeni nazw

// funkcje uzyte w programie void start_game(int komunikat); void menu_glowne(); void clear_screen(); void menu_1(int komunikat_m1); void run_game(int opcja); void pokaz_plansze(); void run_game_start(int kto_zaczyna, int ustaw_preferencje_g1, int ustaw_preferencje_g2, int dwoch_graczy, int pole_zajete=0); int wstaw_znaczek(char nr_pola_char, string znaczek); void spr_wygrana(); void ruch_komputera(); int rk_spr_przeciwnika(int p1, int p2, int p3, string znaczek); int rk_obrona(string znaczek); int rk_wstaw_znaczek(int nr_pola, string znaczek, int do_pola); int rk_wstaw_znaczek_jesli_dwa_pola_zajete(int nr_pola1, int nr_pola2, string znaczek, int do_pola); int rk_wstaw_znaczek_jesli_3wolne_2komputera(int p1, int p2, int p3, int pk1, int pk2, int do_pola);

// zmienne globalne w programie string tablica[] = {“0”,“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”}; // zawiera nr pol do ktorych mozna wstawic X lub O string tablica_gry[10] = {“OFF”," “,” “,” “,” “,” “,” “,” “,” “,” “}; // bedzie zawierac wstawione X, O, pierwsze pole dajemy OFF poniewaz nie bedziemy uzywac elementu tablicy o indexie 0 string imie_g1; // imie gracza 1 string imie_g2 = “KOMPUTER”; // jesli drugi gracz nie gra to domyslnie przeciwnikiem jest komputer wiec jako imie wstawiamy komputer string znaczek_g1; // znak X lub O dla gracza 1 string znaczek_g2; string wygral; // zawiera znaczek ktory wygral, na jego podstawie okreslimy do kogo nezley ten znaczek i wyswietlimy imie gracza ktory wygra (wszystko w funkcji spr_wygrana) int koniec_gry=0; // zawiera informacje czy gra zostala zakonczona, 1 - tak, 0 - nie int rk_nr_ruchu=0; // zawiera nr ruchu komputera int tablica_wygranych_znakow[10]; // zawiera w danych indexa wartosc 1 jesli dane pole nalezy do linii wygranej np. xxx wtedy taki znak x bedzie mial czerwony kolor

int _tmain(int argc, _TCHAR* argv[]) { start_game(0); //system(“pause”); return 0; }

// //

void start_game(int komunikat) {

char m_opcja; // zawiera wybor zakladki z glownego menu	
//komunikat - zawiera informacje o tym czy wybrano niepoprawna opcje z menu, jesli 1 to wyswietla komunikat o zlym wyborze opcji z menu

menu_glowne();

// komunikaty o blednym wyborze z menu
if(komunikat == 1) {
	cout<<"+ Nie poprawny wybor! Podaj nr jeszcze raz.nn";
}


cin>>m_opcja;
cin.ignore(1000, 'n'); // kasuje ostatnie 1000 znakow z bufora aby zabezpieczyc sie przed niepoprawnym podaniem wyboru z menu

if(m_opcja == '1') { // porownuje typ char, 1 musi byc w apostrofach podczas porownania ciagu
	// gra gracz vs komputer
		menu_1(0);
		//system("pause");
		
} else if(m_opcja == '2') {
	// gra dla dwoch graczy
		run_game(3);
		//system("pause");
} else if(m_opcja == '3') { // wyjscie
	

} else {			
		start_game(1); // wyswietla na nowo menu + komunikat o zlym wyborze z menu		
			
}

}

/**********************************************************************************************/

void menu_glowne() { clear_screen();

cout<<"MENU:nWybierz numer i nacisnij enter.nn"
	<< "1. Nowa gra z komputeremn"
	<< "2. Nowa gra dla dwoch osob (losowy gracz rozpoczyna)n" // run_game(3);
	<< "3. Wyjscienn";

}

/**********************************************************************************************/

void clear_screen() { // czyscimy ekran i pozostawiamy tylko linie z nazwa programu system(“cls”); cout«"====== Kolko i krzyzyk v1.05 19.11.2009 Webook.pl ======nn”; }

/**********************************************************************************************/

void menu_1(int komunikat_m1) { clear_screen(); cout«“1. Nowa gra (wybierz literke a, b lub c i nacisnij enter)n” «" a) zaczyna graczn" // 0 «" b) zaczyna komputern" // 1 «" c) losuj do kogo nalezy pierwszy ruchn" // 2 «" e) wyjscie do menu glownegonn";

if(komunikat_m1 == 1) {
	cout<<"Nie poprawny wybor opcji!n";
} else if(komunikat_m1 == 2) { 
	cout<<"Nie poprawna opcja uruchomienia nowej gry!n";
}

char m1;
cin>>m1;	
cin.ignore(1000, 'n');

if(m1 == 'a') { // zaczyna gracz
	run_game(0);	
} else if(m1 == 'b') { // zaczyna komputer
	run_game(1);
} else if(m1 == 'c') { // losuj do kogo nalezy pierwszy ruch
	run_game(2);
} else if(m1 == 'e') {
	start_game(0);		
} else {
	menu_1(1);		
}

}

/**********************************************************************************************/

void run_game(int opcja) { // opcja zawiera informacje o tym kto zaczyna pierwszy ruch /* 0 - zaczyna gracz 1 - zaczyna komputer 2 - losowo zaczyna gracz 3 - gra dla dwoch osob */

pokaz_plansze();

switch(opcja) {
	case 0:
		run_game_start(0, 1, 0, 0);
		break;
	case 1:
		run_game_start(1, 1, 0, 0);
		break;
	case 2:
		run_game_start(2, 1, 0, 0);
		break;
	case 3:
		run_game_start(2, 1, 1, 1);
		break;
	default:
		menu_1(2);
		break;
}


//system("pause");

}

/**********************************************************************************************/

void pokaz_plansze() {

clear_screen();

cout<<"     |     |     n"
	<<"  ";
	if(tablica_wygranych_znakow[1]==1) { // jesli znak w polu jeden nalezy do 3 znakow zwycieskich to go kolorujemy na czerwono
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[1];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[1];
	}
	cout<<"  |  ";
	if(tablica_wygranych_znakow[2]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[2];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[2];
	}
	cout<<"  |  ";
	if(tablica_wygranych_znakow[3]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[3];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[3];
	}
	cout<<"  n"
	<<"    "<<tablica[1]<<"|    "<<tablica[2]<<"|    "<<tablica[3]<<"n"		
	<<"----- ----- -----n"
	<<"     |     |     n"
	<<"  ";
	if(tablica_wygranych_znakow[4]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[4];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[4];
	}
	cout<<"  |  ";
	if(tablica_wygranych_znakow[5]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[5];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[5];
	}
	cout<<"  |  ";
	if(tablica_wygranych_znakow[6]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[6];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[6];
	}
	cout<<"  n"
	<<"    "<<tablica[4]<<"|    "<<tablica[5]<<"|    "<<tablica[6]<<"n"
	<<"----- ----- -----n"
	<<"     |     |     n"
	<<"  ";
	if(tablica_wygranych_znakow[7]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[7];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[7];
	}
	cout<<"  |  ";
	if(tablica_wygranych_znakow[8]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[8];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[8];
	}
	cout<<"  |  ";
	if(tablica_wygranych_znakow[9]==1) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
		cout<<tablica_gry[9];
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	} else {
		cout<<tablica_gry[9];
	}
	cout<<"  n"
	<<"    "<<tablica[7]<<"|    "<<tablica[8]<<"|    "<<tablica[9]<<"nnn";

}

/**********************************************************************************************/

void run_game_start(int kto_zaczyna, int ustaw_preferencje_g1, int ustaw_preferencje_g2, int dwoch_graczy, int pole_zajete) {

if(ustaw_preferencje_g1) { // podaj dane gracza 1
	koniec_gry = 0; // podczas pierwszego uruchomienia gry kasujemy zapis informacji o koncu gry ktory moglbyc utworzony w czasie poprzedniej gry
	cout<<"GRACZ 1, prosze podaj swoje imie: ";
	cin>>imie_g1;

	cout<<"nA teraz "<<imie_g1<<" wybierz czym chcesz grac:n1) O - kolkon2) X - krzyzykn";
	char znaczek_g1_wybor;
	cin>>znaczek_g1_wybor;
	cin.ignore(1000, 'n');

	if(znaczek_g1_wybor == '1') {
		znaczek_g1 = "O";
		znaczek_g2 = "X"; // automatycznie przypisujemy przeciwny znaczek dla drugiego gracza, przyda sie jesli wybrano gre na dwoch graczy lub jako znaczek przypisany dla komputera
	} else if(znaczek_g1_wybor == '2') {
		znaczek_g1 = "X";
		znaczek_g2 = "O";
	} else {
		znaczek_g1 = "X";
		znaczek_g2 = "O";
		cout<<"Blednie wybrales znak! Dlatego przydzielono Ci domyslny znak X!n";
		Sleep(1500);
	}
	//cout<<"n";
	cout<<"Do pierwszego gracza zostal przypisany znak: "<<znaczek_g1;
	cout<<"nczekaj...nn";
	Sleep(1500);
}

if(ustaw_preferencje_g2) { // podaj dane gracza 2 jesli wybrano gre dla dwoch graczy
	cout<<"GRACZ 2, prosze podaj swoje imie: ";
	cin>>imie_g2;
	//cout<<"n";
	cout<<"Do drugiego gracza zostal przypisany znak: "<<znaczek_g2<<"nczekaj...nn";
	Sleep(3000);
}


int los; // zawiera 0 lub 1, decyduje kto rozpoczyna pierwszy ruch gracz1 czy (komputer lub gracz 2 [w zaleznosci czy wlaczono tryb dwoch graczy])
if(kto_zaczyna == 2) { // jesli losujemy ruch to generujemy dla kogo
	srand(time(NULL));
	los = rand() %2;
}


// wyswietl plansze
pokaz_plansze();

spr_wygrana();

if(koniec_gry == 0) { // jesli jeszcze nikt nie wygral to gra toczy sie dalej
	// jesli pole w ktore cos wstawiamy jest zajete to wyswietl komunikat
	if(pole_zajete) {
		cout<<"Wybrane pole jest zajete lub podales niepoprawny jego numer (zakres od 1 do 9)!nn";
	}

	char nr_pola = 0; // bedzie zawierac pobrany nr pola do ktorego nalezy wstawic dany znak przekazany do funkcji wstaw_znaczek()
	if(kto_zaczyna == 0) { // ruch gracz1
		
		cout<<imie_g1<<" wybierz nr pola w ktorym chcesz wstawic "<<znaczek_g1<<": ";		
		//cin>>nr_pola;			
		nr_pola = getchar();
		cin.ignore(1000, 'n');
				
		if(wstaw_znaczek(nr_pola, znaczek_g1)) { // zwraca 1 jesli wstawiono poprawnie znaczek, wtedy ruch dla przeciwnika		
			run_game_start(1,0,0,dwoch_graczy); // teraz wywolujemy ruch dla komputera lub gracza2 w zaleznosci czy wlaczony jest tryb dwoch graczy
		} else { // nie wstawiono znaczka poniewaz pole jest zajete, wywolamy od nowa ta funkcje z komunikatem o zajetym polu
			run_game_start(0,0,0,dwoch_graczy,1);
		}

	} else if(kto_zaczyna == 1 && dwoch_graczy == 0) { // ruch komputera, tryb dwoch graczy wylaczony
		cout<<"ruch komputera...n";
		Sleep(1000);
		ruch_komputera();
		run_game_start(0,0,0,dwoch_graczy); // przekazujemy ruch do gracza 1

	} else if(kto_zaczyna == 1 && dwoch_graczy == 1) {  // ruch gracza2, tryb dwoch graczy wlaczony
		
		cout<<imie_g2<<" wybierz nr pola w ktorym chcesz wstawic "<<znaczek_g2<<": ";		
		//cin>>nr_pola;			
		nr_pola = getchar();
		cin.ignore(1000, 'n');

		if(wstaw_znaczek(nr_pola, znaczek_g2)) { // zwraca 1 jesli wstawiono poprawnie znaczek, wtedy ruch dla przeciwnika		
			run_game_start(0,0,0,dwoch_graczy); // teraz wywolujemy ruch dla komputera lub gracza2 w zaleznosci czy wlaczony jest tryb dwoch graczy
		} else { // nie wstawiono znaczka poniewaz pole jest zajete, wywolamy od nowa ta funkcje z komunikatem o zajetym polu
			run_game_start(1,0,0,dwoch_graczy,1);
		}

	} else if(kto_zaczyna == 2 && ustaw_preferencje_g2 == 0) { // losowo zaczyna gre miedzy gracz1 a komputer
		run_game_start(los,0,0,0);
	} else if(kto_zaczyna == 2 && ustaw_preferencje_g2 == 1) { // losowa gra miedzy gracz1 a gracz2
		run_game_start(los,0,0,1);
	} else {
		cout<<"Nie oczekiwana konfiguracja gry!";
		system("pause");
	}
}

}

/**********************************************************************************************/

int wstaw_znaczek(char nr_pola_char, string znaczek) {

int wstawiono=0; // 1- tak, 0 - nie (pole jest zajete)	
int nr_pola = static_cast<int>(nr_pola_char); // zamiana typu char na int
nr_pola = nr_pola-48; // odejmujemy 48 aby w przypadku gdy wybierzemy pole 1 (zapis ACII 49 odjac 48 daje nam liczbe 1)
if(nr_pola < 1 || nr_pola > 9) {
	wstawiono = 0; // jesli nr pola jest niewlasciwy to odrazu blokujemy wybor takiego pola
} else if(tablica_gry[nr_pola] == " ") {
	tablica[nr_pola] = " "; // kasujemy wyswietlanie nr pola do ktorego mozna wstawiac znaczki	
	tablica_gry[nr_pola] = znaczek; // wstawiamy odpowiedni znak w dane pole
	wstawiono = 1;
} else { // w to pole jest juz wstawiony znaczek
	wstawiono = 0;
}

return wstawiono;

}

/**********************************************************************************************/

void spr_wygrana() {

// poziome sprawdzenie czy wystepuja 3 znaczki obok siebie
if((tablica_gry[1] == tablica_gry[2] && tablica_gry[2] == tablica_gry[3]) && tablica_gry[1] != " ") {
	wygral = tablica_gry[1];
	koniec_gry = 1;
	tablica_wygranych_znakow[1]=1;
	tablica_wygranych_znakow[2]=1;
	tablica_wygranych_znakow[3]=1;		
} else if((tablica_gry[4] == tablica_gry[5] && tablica_gry[5] == tablica_gry[6]) && tablica_gry[4] != " ") {
	wygral = tablica_gry[4];
	koniec_gry = 1;
	tablica_wygranych_znakow[4]=1;
	tablica_wygranych_znakow[5]=1;
	tablica_wygranych_znakow[6]=1;
} else if((tablica_gry[7] == tablica_gry[8] && tablica_gry[8] == tablica_gry[9]) && tablica_gry[7] != " ") {
	wygral = tablica_gry[7];
	koniec_gry = 1;
	tablica_wygranych_znakow[7]=1;
	tablica_wygranych_znakow[8]=1;
	tablica_wygranych_znakow[9]=1;

// pionowe sprawdzenie
} else if((tablica_gry[1] == tablica_gry[4] && tablica_gry[4] == tablica_gry[7]) && tablica_gry[1] != " ") {
	wygral = tablica_gry[1];
	koniec_gry = 1;
	tablica_wygranych_znakow[1]=1;
	tablica_wygranych_znakow[4]=1;
	tablica_wygranych_znakow[7]=1;
} else if((tablica_gry[2] == tablica_gry[5] && tablica_gry[5] == tablica_gry[8]) && tablica_gry[2] != " ") {
	wygral = tablica_gry[2];
	koniec_gry = 1;
	tablica_wygranych_znakow[2]=1;
	tablica_wygranych_znakow[5]=1;
	tablica_wygranych_znakow[8]=1;
} else if((tablica_gry[3] == tablica_gry[6] && tablica_gry[6] == tablica_gry[9]) && tablica_gry[3] != " ") {
	wygral = tablica_gry[3];
	koniec_gry = 1;
	tablica_wygranych_znakow[3]=1;
	tablica_wygranych_znakow[6]=1;
	tablica_wygranych_znakow[9]=1;

// sprawdzenie po skosie
} else if((tablica_gry[1] == tablica_gry[5] && tablica_gry[5] == tablica_gry[9]) && tablica_gry[1] != " ") {
	wygral = tablica_gry[1];
	koniec_gry = 1;
	tablica_wygranych_znakow[1]=1;
	tablica_wygranych_znakow[5]=1;
	tablica_wygranych_znakow[9]=1;
} else if((tablica_gry[3] == tablica_gry[5] && tablica_gry[5] == tablica_gry[7]) && tablica_gry[3] != " ") {
	wygral = tablica_gry[3];
	koniec_gry = 1;
	tablica_wygranych_znakow[3]=1;
	tablica_wygranych_znakow[5]=1;
	tablica_wygranych_znakow[7]=1;
}

// sprawdzamy czy sa jeszcze puste pola aby moc kontynuowac gre lub zakonczyc ja remisem
int znaleziono_puste_pola = 0;
for(int a=1;a<=9;a++) {
	if(tablica_gry[a] == " ") { // znaleziono puste pola wiec gra moze toczyc sie dalej
		znaleziono_puste_pola = 1;
		break;
	}
}

if(koniec_gry) { // ktos wygral to wyswietlamy wynik
	string imie_wygranego;
	if(wygral == znaczek_g1) { // jesli znaczek np. X nalezal do gracza1 to wygral gracz1 w przeciwnym wypadku znaczek X musial nalezec do gracza2
		imie_wygranego = imie_g1;
	} else {
		imie_wygranego = imie_g2;
	}
	
	for(int i=0;i<=5;i++) {
		pokaz_plansze();
		Sleep(500); // nazwa funkcji z duzej litery, wyswietlamy napis po 500ms
		cout<<"Wygral "<<imie_wygranego<<"! ("<<5-i<<")n";
		if(imie_wygranego == "KOMPUTER") {
			cout<<"Komputer pokonal Cie w "<<rk_nr_ruchu<<" ruchach.";
		}
		cout<<"nn";
		Sleep(1000);
	}		
}


if(znaleziono_puste_pola == 0 && koniec_gry == 0) { // nieznaleziono pustych pol i nikt nie zdobyl 3 znaczkow obok siebie wiec gra konczy sie remisem
	
	for(int j=0;j<=5;j++) {
		pokaz_plansze();
		Sleep(500); // nazwa funkcji z duzej litery, wyswietlamy napis po 500ms
		cout<<"Remis pomiedzy graczami "<<imie_g1<<" vs "<<imie_g2<<"! ("<<5-j<<")nn";
		Sleep(1000);
	}

	koniec_gry = 1; // ustalamy wartosc na koniec_gry=1 aby zablokowac pytanie sie o dalszy ruch ktoregos z graczy, inicjujemy ta wartosc na samym koncu poniewaz wczesniej mogla miec wartosc 0 gdy byl remis co umozliwilo wykonanie tego if'a
}



if(koniec_gry) {
	cout<<"nnCzy chcesz rozpoczac nowa gre?n1) tak - wybierz tryb z menu glownegon2) nie - wyjscie z programunn";
	int nowa_gra;
	cin>>nowa_gra;
	if(nowa_gra == 1) {
		// resetujemy pola tablicy na domyslne wartosci
		//tablica[10] = {"0","1","2","3","4","5","6","7","8","9"}; // zawiera nr pol do ktorych mozna wstawic X lub O
		//tablica_gry[10] = {"OFF"," "," "," "," "," "," "," "," "," "};
		
		tablica[1] = "1";
		tablica[2] = "2";
		tablica[3] = "3";
		tablica[4] = "4";
		tablica[5] = "5";
		tablica[6] = "6";
		tablica[7] = "7";
		tablica[8] = "8";
		tablica[9] = "9";
		for(int b=0;b<=9;b++) {			
			tablica_gry[b] = " ";
			tablica_wygranych_znakow[b]=0; // resetujemy info o polach ktore nalezaly do wygranej linii, dzieki temu przy kolejnej rozgrywce nie beda juz kolorowane te same pola tylko te ktore wygraja druga rozgrywke
		}			
		
		rk_nr_ruchu = 0; // resetujemy zapamietana liczbe ruchow komputera

		start_game(0); // uruchamiamy glowne menu gry
	}
}

}

/**********************************************************************************************/

void ruch_komputera() {

// sprawdzenie czy komputer jako pierwszy podejmuje ruch
int pierwszy_ruch = 1;
for(int b=1;b<=9;b++) {			
	if(tablica_gry[b] != " ") {
		pierwszy_ruch = 0; // jesli ktorekolwiek pole jest zajete to znaczy ze komputer wykonuje drugi ruch
	} 
}


if(pierwszy_ruch) { // komputer stawia jako pierwszy znak
	
	srand(time(NULL));
	int los = rand() %4;

	switch(los) {
		case 0:
			tablica[1] = " ";
			tablica_gry[1] = znaczek_g2;
			break;
		case 1:
			tablica[3] = " ";
			tablica_gry[3] = znaczek_g2;
			break;
		case 2:
			tablica[7] = " ";
			tablica_gry[7] = znaczek_g2;
			break;
		default:
			tablica[9] = " ";
			tablica_gry[9] = znaczek_g2;
			break;
	}
	

} else { // komputer wykonuje ruch po graczu
	
	if(rk_obrona(znaczek_g2) == 0) { // jesli zero to znaczy ze komputer nie znalazl sytuacji w ktorej moglby wygrac jednym ruchem
			
		if(rk_obrona(znaczek_g1) == 0) { // jesli zwroci 0 to znaczy ze komputer nie wykonal ruchu blokujacego przeciwnika i moze probowac atakowac
							
			
			if(rk_nr_ruchu==0) { // to jest pierwszy ruch komputera, wykonywany po ruchu gracza1
				
				if(wstaw_znaczek('5', znaczek_g2)) { // jesli wolny srodek to wstaw

				// stawiamy znak naprzeciw
				} else if(rk_wstaw_znaczek(1,znaczek_g1,9)) {
				} else if(rk_wstaw_znaczek(3,znaczek_g1,7)) { 
				} else if(rk_wstaw_znaczek(7,znaczek_g1,3)) { 
				} else if(rk_wstaw_znaczek(9,znaczek_g1,1)) { 


				// stawiamy znak obok pola jesli przeciwnik dal znak w narozniku
				} else if(rk_wstaw_znaczek(1,znaczek_g1,2)) {
				} else if(rk_wstaw_znaczek(3,znaczek_g1,6)) { 
				} else if(rk_wstaw_znaczek(7,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(9,znaczek_g1,8)) { 


				// stawiamy znak na wzor L
				} else if(rk_wstaw_znaczek(1,znaczek_g1,8)) {
				} else if(rk_wstaw_znaczek(3,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(7,znaczek_g1,6)) { 
				} else if(rk_wstaw_znaczek(9,znaczek_g1,2)) { 
				
				// stawiamy znak obok znaku przeciwnika
				} else if(rk_wstaw_znaczek(1,znaczek_g1,2)) {
				} else if(rk_wstaw_znaczek(3,znaczek_g1,6)) { 
				} else if(rk_wstaw_znaczek(7,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(9,znaczek_g1,8)) { 
				
				
				// 17.10.2009
				} else if(rk_wstaw_znaczek(8,znaczek_g1,6)) {
				} else if(rk_wstaw_znaczek(8,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(6,znaczek_g1,8)) { 
				} else if(rk_wstaw_znaczek(6,znaczek_g1,2)) { 
				} else if(rk_wstaw_znaczek(2,znaczek_g1,6)) {
				} else if(rk_wstaw_znaczek(2,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(4,znaczek_g1,2)) { 
				} else if(rk_wstaw_znaczek(4,znaczek_g1,8)) {
				
				// blokowanie strategii x w 4,8 wstawiamy do 7
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(4,8,znaczek_g1,7)) {
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(6,8,znaczek_g1,9)) {
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(2,6,znaczek_g1,3)) {
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(4,2,znaczek_g1,1)) {
				
				// jesli znak przeciwnika w innym polu niz na rogach planszy
				} else {
					
					// wstawiamy znaczek do pierwszego wolnego pola
					for(int i=1;i<=9;i++) {			
						if(tablica_gry[i] == " ") {
							tablica_gry[i] = znaczek_g2;
							tablica[i] = " ";
							break;
						} 
					}

				}
			} else {
				
				/*if(wstaw_znaczek('5', znaczek_g2)) {
				} else*/  
				

				if(rk_nr_ruchu == 1 && wstaw_znaczek('5', znaczek_g2)) { // jesli rk_nr_ruchu == 1 bedzie falszywe to juz nie wykonuje sie drugi czlon po && poniewaz wartosc koniunkcji bedzie i tak falszywa
				
				
				// jesli srodek zajety przez komputer i sa wolne w kolo pola
				//} else if(tablica_gry[5] == znaczek_g2 && (tablica_gry[1]==" " || tablica_gry[2]==" " || tablica_gry[3]==" " || tablica_gry[4]==" " || tablica_gry[6]==" " || tablica_gry[7]==" " || tablica_gry[8]==" " || tablica_gry[9]==" ")) { // jesli srodek zajety przez komp
				

				
				// 19.11.2009 - proba zagrania strategia ktora sprawi ze przeciwnik nie bedzie mogl zablokowac ruchu komputera
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(1,4,9, 5,7, 1)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(1,8,9, 5,7, 9)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(3,4,6, 5,9, 3)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(3,7,8, 5,9, 7)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(1,6,9, 5,3, 9)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(1,2,9, 5,3, 1)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(3,7,8, 5,1, 7)) {
				} else if(rk_wstaw_znaczek_jesli_3wolne_2komputera(2,3,7, 5,1, 3)) {


					// 17.11.2009
					// skuteczna metoda na to aby komputer nie przegrywal
					// nalezy doprowadzic do sytuacji w ktorej wymusimy na graczu koniecznosc blokady komputera,
					// tymsamym nie bedzie on mogl grac wedlug swojej strategii lecz bedzie zajety blokowaniem komputera
					// co w efekcie doprowadza do remisu, chyba ze gracz popelni blad to wtedy komputer to wykorzysta i wygra ;)
				} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(2," ",8)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(8," ",2)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(4," ",6)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(6," ",4)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(1," ",9)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(9," ",1)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(3," ",7)) {
					} else if(tablica_gry[5] == znaczek_g2 && rk_wstaw_znaczek(7," ",3)) {
					

				

				// blokowanie strategii x w 4,8 wstawiamy do 7
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(4,8,znaczek_g1,7)) {
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(6,8,znaczek_g1,9)) {
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(2,6,znaczek_g1,3)) {
				} else if(rk_wstaw_znaczek_jesli_dwa_pola_zajete(4,2,znaczek_g1,1)) {

				// 17.10.2009
				} else if(rk_wstaw_znaczek(8,znaczek_g1,6)) {
				} else if(rk_wstaw_znaczek(8,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(6,znaczek_g1,8)) { 
				} else if(rk_wstaw_znaczek(6,znaczek_g1,2)) { 
				} else if(rk_wstaw_znaczek(2,znaczek_g1,6)) {
				} else if(rk_wstaw_znaczek(2,znaczek_g1,4)) { 
				} else if(rk_wstaw_znaczek(4,znaczek_g1,2)) { 
				} else if(rk_wstaw_znaczek(4,znaczek_g1,8)) { 



				
				} else if(rk_wstaw_znaczek(1,znaczek_g2,9)) { // jesli pole 1 zajmuje znak komputera to wstaw znak komputera do pola 9					
				} else if(rk_wstaw_znaczek(3,znaczek_g2,7)) { 
				} else if(rk_wstaw_znaczek(7,znaczek_g2,3)) { 
				} else if(rk_wstaw_znaczek(9,znaczek_g2,1)) {



				//jesli srodkowe pole zajete przez komputer i ktorys z naroznikow jest wolny to wykonaj cialo
				} else if(tablica_gry[5] == znaczek_g2 && (tablica_gry[1]==" " || tablica_gry[3]==" " || tablica_gry[7]==" " || tablica_gry[9]==" ")) {
					
					
					srand(time(NULL));
					int los = rand() %4;
					int nr_p; // nr naroznika do ktorego wstawic znak komputera  
					switch(los) {
						case 0:
							nr_p = 1;
							break;
						case 1:
							nr_p = 3;
							break;
						case 2:
							nr_p = 7;
							break;
						default:
							nr_p = 9;								
					}
					if(rk_wstaw_znaczek(5,znaczek_g2,nr_p)) {
					} else if(rk_wstaw_znaczek(5,znaczek_g2,1)) {
					} else if(rk_wstaw_znaczek(5,znaczek_g2,3)) {
					} else if(rk_wstaw_znaczek(5,znaczek_g2,7)) {
					} else if(rk_wstaw_znaczek(5,znaczek_g2,9)) {
					}
				
				// tworzenie trojkata dla komputera [dziala to tak jak w opisie ponizej dla blokowania gracza X]
				} else if(rk_spr_przeciwnika(5,7,9,znaczek_g2)) {
				} else if(rk_spr_przeciwnika(1,3,5,znaczek_g2)) {					
				} else if(rk_spr_przeciwnika(1,5,7,znaczek_g2)) {
				} else if(rk_spr_przeciwnika(3,5,9,znaczek_g2)) {

				/* blokowanie strategi gracza X
				[O _ _]
				[_ X _]
				[T _ X]
				w miejsce T nalezy wstawic O, wstawiamy w tej kominacji jak i w podobnych znak komputera
				*/
				} else if(rk_spr_przeciwnika(5,7,9,znaczek_g1)) {
				} else if(rk_spr_przeciwnika(1,3,5,znaczek_g1)) {					
				} else if(rk_spr_przeciwnika(1,5,7,znaczek_g1)) {
				} else if(rk_spr_przeciwnika(3,5,9,znaczek_g1)) {
				
				
				} else if(wstaw_znaczek('5', znaczek_g2)) { // jesli srodek pusty to wstaw znak

				// nie zastosowano zadnej z powyzszych strategii wiec losowo wstawiamy znak komputera do wolnego pola
				} else {
					
					// wstawiamy znaczek do pierwszego wolnego pola
					for(int f=1;f<=9;f++) {			
						if(tablica_gry[f] == " ") {
							tablica_gry[f] = znaczek_g2;
							tablica[f] = " ";
							break;
						} 
					}					

				}
			}

		}
	}
}


rk_nr_ruchu++; // zwieksza licznik ruchow jakie wykonal komputer

}

/**********************************************************************************************/

// funkcja sprawdza czy w danych trzech polach sa dwa takie same znaki, jesli tak to w trzecim wolnym polu wstawia znak komputera // oznacza to ze w przypadku dwoch znakow przeciwnika np. [x x] zostanie zablokowany jego ruch [xox], // natomiast w przypadku dwoch znakow komputera [o o] zostanie wstawiony trzeci znak ktory spowoduje wygrana [ooo] // parametr znaczek okresla czy sprawdzamy znaczki gracza 1 lub komputera int rk_spr_przeciwnika(int p1, int p2, int p3, string znaczek) { int zablokowano_ruch = 0; // zawiera informacje o zablokowaniu ruchu. Jesli znaleziono dwa X lub O obok siebie i wstawiono O to zmienna przyjmie wartosc 1 co oznacza ze zablokowano ruch przeciwnika lub wstawiono 3 znak komputera ktory powoduje wygranie gry. Wartosc 0 oznacza ze nie ma koniecznosci w danym wierszu lub kolumnie wstawiac znaku by blokowac przeciwnika

if(tablica_gry[p1]==tablica_gry[p2] && tablica_gry[p1]==znaczek && tablica_gry[p3] == " ") { //[xx ] jesli pierwsze i drugie pole jest zajete przez przeciwnika a trzecie pole jest wolne to wstawiamy znaczek_g2 (znak komputera) w wolne pole p3 aby zablokowac gracza1 lub uzupelnic 3 znak komputera aby wygral (zalezne od parametru znaczek)
	tablica_gry[p3] = znaczek_g2;
	tablica[p3] = " "; // wymazanie nr pola po wstawieniu do niego znaczka
	zablokowano_ruch = 1;
} else if(tablica_gry[p1]==tablica_gry[p3] && tablica_gry[p1]==znaczek && tablica_gry[p2] == " ") { //[x x]
	tablica_gry[p2] = znaczek_g2;
	tablica[p2] = " ";
	zablokowano_ruch = 1;
} else if(tablica_gry[p2]==tablica_gry[p3] && tablica_gry[p2]==znaczek && tablica_gry[p1] == " ") { //[ xx]
	tablica_gry[p1] = znaczek_g2;
	tablica[p1] = " ";
	zablokowano_ruch = 1;
}

return zablokowano_ruch;

}

/**********************************************************************************************/

// znaczek przekazuje informacje dla jakich znakow sprawdzamy czy w danym np. wieresuz wystepuja dwa znaki obok siebie a trzecie pole jest puste // funkcje wykorzystamy aby najpierw sprawdzic czy komputer moze wygrac, pozniej wywolamy funkcje z znaczkiem przeciwnika aby sprawdzic czy mozna go zablokowac int rk_obrona(string znaczek) { int rk_obrona_return=0; // zawiera informacje czy komputer sie obronil czy nie, jesli zwraca 0 to komputer nie musi sie bronic i moze przejsc do ataku, jesli wynosi 1 to komputer wykonal ruch obronny i wtedy nie atakujejemy gracza

if(rk_spr_przeciwnika(1,2,3,znaczek)) { // sprawdzamy czy w polach 1,2,3 moze przeciwnik wygrac, jesli tak to go blokujemy
	rk_obrona_return=1; // wykonano ruch obronny
} else if(rk_spr_przeciwnika(4,5,6,znaczek)) {
	rk_obrona_return=1;
} else if(rk_spr_przeciwnika(7,8,9,znaczek)) {
	rk_obrona_return=1;
} else if(rk_spr_przeciwnika(1,4,7,znaczek)) {
	rk_obrona_return=1;
} else if(rk_spr_przeciwnika(2,5,8,znaczek)) {
	rk_obrona_return=1;
} else if(rk_spr_przeciwnika(3,6,9,znaczek)) {
	rk_obrona_return=1;
} else if(rk_spr_przeciwnika(1,5,9,znaczek)) {
	rk_obrona_return=1;
} else if(rk_spr_przeciwnika(3,5,7,znaczek)) {
	rk_obrona_return=1;	
}

	
return rk_obrona_return;

}

/**********************************************************************************************/

// funkcja wstawia do odpowiedniego pola znaczek g2, jesli pole do ktorego chcemy cos wstawic jest zajete to zwraca int 0 // jesli dane pole ma dany znaczek to wstaw znaczek komputera do pola o int do_pola int rk_wstaw_znaczek(int nr_pola, string znaczek, int do_pola) { int wstawiono=0;

if(tablica_gry[nr_pola] == znaczek && tablica_gry[do_pola] == " ") {
	tablica_gry[do_pola] = znaczek_g2; // wstawia znaczek komputera do pola
	tablica[do_pola] = " ";
	wstawiono = 1;
}

return wstawiono;

}

/**********************************************************************************************/

// jesli dwa pola zajete przez przeciwnika to wstaw swoj znak int rk_wstaw_znaczek_jesli_dwa_pola_zajete(int nr_pola1, int nr_pola2, string znaczek, int do_pola) { int wstawiono=0;

if(tablica_gry[nr_pola1] == znaczek && tablica_gry[nr_pola2] == znaczek && tablica_gry[do_pola] == " ") {
	tablica_gry[do_pola] = znaczek_g2; // wstawia znaczek komputera do pola
	tablica[do_pola] = " ";
	wstawiono = 1;
}

return wstawiono;

}

/**********************************************************************************************/

// 19.11.2009 int rk_wstaw_znaczek_jesli_3wolne_2komputera(int p1, int p2, int p3, int pk1, int pk2, int do_pola) { int wstawiono=0;

// jesli trzy pierwsze argumenty czyli nr tych pol sa wolne to oraz dwa kolejne argumenty czyli nr pol zajetych przez komputer to wstaw do_pola znak komputera
if(tablica_gry[p1] == " " &&  tablica_gry[p2] == " " &&  tablica_gry[p3] == " " && tablica_gry[pk1] == znaczek_g2 && tablica_gry[pk2] == znaczek_g2) {
	tablica_gry[do_pola] = znaczek_g2; // wstawia znaczek komputera do pola
	tablica[do_pola] = " ";
	wstawiono = 1;
}


return wstawiono;

}[/code]