Witam,
piszę program do gry w kółko i krzyżyk (użytkownik + komputer).
Pierwsza opcja, to losowe ruchy komputera i to udało mi się napisać, ale napotkałem problem z opcją drugą, w której komputer powinien maksymalizować swoje szanse na wygraną.
Przeczytałem teorię o algorytmie minimax, ale nie umiem tego przełożyć na język c w tym konkretnym przypadku :(.
Mój program sprawdza, czy może dostawić trzeci krzyżyk w rzędzie (krzyżyk to komputer), a jeśli nie, to czy może zablokować kółko. Kolejnym krokiem jest wpisywanie krzyżyka w pole środkowe, jeśli pole to jest wolne, ale na tym skończyły się już moje umiejętności.
Byłbym bardzo wdzięczny za pomoc i podpowiedź, jak napisać taki program bez rozpatrywania 9! przypadków.
#include <stdlib.h>
#include <stdio.h>
#include "winbgi2.h"
#include <time.h>
void pole_do_gry();
void poziom_latwy();
void poziom_trudny();
void main()
{
printf("Prosze wybrac poziom\nJesli chcesz, aby komputer wybieral miejsca losowo wpisz \"L\" \nJesli chcesz, aby komputer wybieral miejsce, aby miec jak najwieksza szanse na wygrana wpisz \"T\" \n");
char poziom;
wybierz_poziom_ponownie:
scanf("%c",&poziom);
if (poziom == 'l' || poziom == 'L' || poziom == 't' || poziom == 'T')
{
if (poziom == 'l' || poziom == 'L')
{
pole_do_gry();
poziom_latwy();
}
else
{
pole_do_gry();
poziom_trudny();
}
}
goto wybierz_poziom_ponownie;
wait();
}
//Program rysuje planszę do gry.
void pole_do_gry()
{
graphics(750, 750);
line(250, 20, 250, 730);
line(500, 20, 500, 730);
line(20, 250, 730, 250);
line(20, 500, 730, 500);
}
//Gra losowa
void poziom_latwy()
{
char POLE[3][3] = { { '0', '0', '0' }, { '0', '0', '0' }, { '0', '0', '0' } };
int a, b, x;
poczatek:
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (POLE[i][j] == '0')
{
x = 0;
goto dalej;
}
else
{
x = 1;
}
}
}
dalej:
if (x == 0)
{
wroc:
printf("Podaj wspolrzedne pola, w ktorym chcesz narysowac kolko");
wroc_1:
scanf("%d %d", &a, &b);
if (a > 3 || b > 3 || a < 1 || b < 1)
{
printf("Podaj wspolrzedne a i b z przedzialu <1;3>");
goto wroc_1;
}
if (POLE[a-1][b-1] == 'k' || POLE[a-1][b-1] == 'o')
{
printf("To pole jest zajete\n");
goto wroc;
}
else
{
circle(a * 250 - 125, b * 250 - 125, 100);
POLE[a-1][b-1] = 'o';
}
for (int i = 0; i<3; i++)
{
if (POLE[i][0] == POLE[i][1] && POLE[i][0] == POLE[i][2] && POLE[i][0] != '0')
{
goto koniec;
}
if (POLE[0][i] == POLE[1][i] && POLE[0][i] == POLE[2][i] && POLE[0][i] != '0')
{
goto koniec;
}
}
if (POLE[0][0] == POLE[1][1] && POLE[1][1] == POLE[2][2] && POLE[0][0] != '0')
{
goto koniec;
}
if (POLE[0][2] == POLE[1][1] && POLE[1][1] == POLE[2][0] && POLE[0][2] != '0')
{
goto koniec;
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (POLE[i][j] == '0')
{
goto komp;
}
}
}
goto koniec;
komp:
cofnij:
srand(time(NULL));
a = rand() % 3 + 1;
b = rand() % 3 + 1;
if (POLE[a-1][b-1] == 'k' || POLE[a-1][b-1] == 'o')
{
goto cofnij;
}
else
{
line((a * 250) - 230, (b * 250) - 230, (a * 250) - 20, (b * 250) - 20);
line((a * 250) - 20, (b * 250) - 230, (a * 250) - 230, (b * 250) - 20);
POLE[a-1][b-1] = 'k';
}
for (int i = 0; i<3; i++)
{
if (POLE[i][0] == POLE[i][1] && POLE[i][0] == POLE[i][2] && POLE[i][0] != '0')
{
goto koniec;
}
if (POLE[0][i] == POLE[1][i] && POLE[0][i] == POLE[2][i] && POLE[0][i] != '0')
{
goto koniec;
}
}
if (POLE[0][0] == POLE[1][1] && POLE[1][1] == POLE[2][2] && POLE[0][0] != '0')
{
goto koniec;
}
if (POLE[0][2] == POLE[1][1] && POLE[1][1] == POLE[2][0] && POLE[0][2] != '0')
{
goto koniec;
}
}
else
{
goto koniec;
}
goto poczatek;
koniec:;
printf("KONIEC GRY");
}
void poziom_trudny()
{
char POLE[3][3] = { { '0', '0', '0' }, { '0', '0', '0' }, { '0', '0', '0' } };
int a, b, x;
poczatek:
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (POLE[i][j] == '0')
{
x = 0;
goto dalej;
}
else
{
x = 1;
}
}
}
dalej:
if (x == 0)
{
wroc:
printf("Podaj wspolrzedne pola, w ktorym chcesz narysowac kolko");
wroc_1:
scanf("%d %d", &a, &b);
if (a > 3 || b > 3 || a < 1 || b < 1)
{
printf("Podaj wspolrzedne a i b z przedzialu <1;3>");
goto wroc_1;
}
if (POLE[a - 1][b - 1] == 'k' || POLE[a - 1][b - 1] == 'o')
{
printf("To pole jest zajete\n");
goto wroc;
}
else
{
circle(a * 250 - 125, b * 250 - 125, 100);
POLE[a - 1][b - 1] = 'o';
}
for (int i = 0; i < 3; i++)
{
if (POLE[i][0] == POLE[i][1] && POLE[i][0] == POLE[i][2] && POLE[i][0] != '0')
{
goto koniec;
}
if (POLE[0][i] == POLE[1][i] && POLE[0][i] == POLE[2][i] && POLE[0][i] != '0')
{
goto koniec;
}
}
if (POLE[0][0] == POLE[1][1] && POLE[1][1] == POLE[2][2] && POLE[0][0] != '0')
{
goto koniec;
}
if (POLE[0][2] == POLE[1][1] && POLE[1][1] == POLE[2][0] && POLE[0][2] != '0')
{
goto koniec;
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (POLE[i][j] == '0')
{
goto komp;
}
}
}
goto koniec;
komp:
//wstawianie krzyzyka z prawej strony jesli sa dwa krzyzyki pod rzad
for (int j = 1; j < 4; j++)
{
if (POLE[1 - 1][j - 1] == 'k' && POLE[2 - 1][j - 1] == 'k' && POLE[3 - 1][j - 1] != 'o')
{
line((3 * 250) - 230, (j * 250) - 230, (3 * 250) - 20, (j * 250) - 20);
line((3 * 250) - 20, (j * 250) - 230, (3 * 250) - 230, (j * 250) - 20);
POLE[3 - 1][j - 1] = 'k';
goto koniec;
}
}
//wstawianie krzyzyka z lewej strony jesli sa dwa krzyzyki pod rzad
for (int j = 1; j < 4; j++)
{
if (POLE[2 - 1][j - 1] == 'k' && POLE[3 - 1][j - 1] == 'k'&& POLE[1 - 1][j - 1] != 'o')
{
line((1 * 250) - 230, (j * 250) - 230, (1 * 250) - 20, (j * 250) - 20);
line((1 * 250) - 20, (j * 250) - 230, (1 * 250) - 230, (j * 250) - 20);
POLE[1 - 1][j - 1] = 'k';
goto koniec;
}
}
//wstawianie krzyzyka na dole jesli sa dwa krzyzyki jedno nad drugim
for (int j = 1; j < 4; j++)
{
if (POLE[j - 1][1 - 1] == 'k' && POLE[j - 1][2 - 1] == 'k'&& POLE[j - 1][3 - 1] != 'o')
{
line((j * 250) - 230, (3 * 250) - 230, (j * 250) - 20, (3 * 250) - 20);
line((j * 250) - 20, (3 * 250) - 230, (j * 250) - 230, (3 * 250) - 20);
POLE[j - 1][3 - 1] = 'k';
goto koniec;
}
}
//wstawianie krzyzyka na gorze jesli sa dwa krzyzyki jedno nad drugim
for (int j = 1; j < 4; j++)
{
if (POLE[j - 1][2 - 1] == 'k' && POLE[j - 1][3 - 1] == 'k'&& POLE[j - 1][1 - 1] != 'o')
{
line((j * 250) - 230, (1 * 250) - 230, (j * 250) - 20, (1 * 250) - 20);
line((j * 250) - 20, (1 * 250) - 230, (j * 250) - 230, (1 * 250) - 20);
POLE[j - 1][1 - 1] = 'k';
goto koniec;
}
}
//wstawianie krzyzyka jesli sa dwa krzyzyki po bokach
for (int j = 1; j < 4; j++)
{
if (POLE[1 - 1][j - 1] == 'k' && POLE[3 - 1][j - 1] == 'k'&& POLE[2 - 1][j - 1] != 'o')
{
line((2 * 250) - 230, (j * 250) - 230, (2 * 250) - 20, (j * 250) - 20);
line((2 * 250) - 20, (j * 250) - 230, (2 * 250) - 230, (j * 250) - 20);
POLE[2 - 1][j - 1] = 'k';
goto koniec;
}
}
//wstawianie krzyzyka po srodku jesli jest jeden krzyzyk na dole a drugi na gorze
for (int j = 1; j < 4; j++)
{
if (POLE[j - 1][1 - 1] == 'k' && POLE[j - 1][3 - 1] == 'k' && POLE[j - 1][2 - 1] != 'o')
{
line((j * 250) - 230, (2 * 250) - 230, (j * 250) - 20, (2 * 250) - 20);
line((j * 250) - 20, (2 * 250) - 230, (j * 250) - 230, (2 * 250) - 20);
POLE[j - 1][2 - 1] = 'k';
goto koniec;
}
}
//wstawianie jesli na przekatnej sa dwa krzyzyki pod rzad
if (POLE[1 - 1][1 - 1] == 'k' && POLE[2 - 1][2 - 1] == 'k' && POLE[3 - 1][3 - 1] != 'o')
{
line((3 * 250) - 230, (3 * 250) - 230, (3 * 250) - 20, (3 * 250) - 20);
line((3 * 250) - 20, (3 * 250) - 230, (3 * 250) - 230, (3 * 250) - 20);
POLE[3 - 1][3 - 1] = 'k';
goto koniec;
}
if (POLE[2 - 1][2 - 1] == 'k' && POLE[3 - 1][3 - 1] == 'k' && POLE[1 - 1][1 - 1] != 'o')
{
line((1 * 250) - 230, (1 * 250) - 230, (1 * 250) - 20, (1 * 250) - 20);
line((1 * 250) - 20, (1 * 250) - 230, (1 * 250) - 230, (1 * 250) - 20);
POLE[1 - 1][1 - 1] = 'k';
goto koniec;
}
if (POLE[3 - 1][1 - 1] == 'k' && POLE[2 - 1][2 - 1] == 'k' && POLE[1 - 1][3 - 1] != 'o')
{
line((1 * 250) - 230, (3 * 250) - 230, (1 * 250) - 20, (3 * 250) - 20);
line((1 * 250) - 20, (3 * 250) - 230, (1 * 250) - 230, (3 * 250) - 20);
POLE[1 - 1][3 - 1] = 'k';
goto koniec;
}
if (POLE[1 - 1][3 - 1] == 'k' && POLE[2 - 1][2 - 1] == 'k' && POLE[3 - 1][1 - 1] != 'o')
{
line((3 * 250) - 230, (1 * 250) - 230, (3 * 250) - 20, (1 * 250) - 20);
line((3 * 250) - 20, (1 * 250) - 230, (3 * 250) - 230, (1 * 250) - 20);
POLE[3 - 1][1 - 1] = 'k';
goto koniec;
}
//wstawianie krzyzyka z prawej strony jesli sa dwa kolka pod rzad
for (int j = 1; j < 4; j++)
{
if (POLE[1 - 1][j - 1] == 'o' && POLE[2 - 1][j - 1] == 'o' && POLE[3 - 1][j - 1] != 'k')
{
line((3 * 250) - 230, (j * 250) - 230, (3 * 250) - 20, (j * 250) - 20);
line((3 * 250) - 20, (j * 250) - 230, (3 * 250) - 230, (j * 250) - 20);
POLE[3 - 1][j - 1] = 'k';
goto poczatek;
}
}
//wstawianie krzyzyka z lewej strony jesli sa dwa kolka pod rzad
for (int j = 1; j < 4; j++)
{
if (POLE[2 - 1][j - 1] == 'o' && POLE[3 - 1][j - 1] == 'o' && POLE[1 - 1][j - 1] != 'k')
{
line((1 * 250) - 230, (j * 250) - 230, (1 * 250) - 20, (j * 250) - 20);
line((1 * 250) - 20, (j * 250) - 230, (1 * 250) - 230, (j * 250) - 20);
POLE[1 - 1][j - 1] = 'k';
goto poczatek;
}
}
//wstawianie krzyzyka na dole jesli sa dwa kolka jedno nad drugim
for (int j = 1; j < 4; j++)
{
if (POLE[j - 1][1 - 1] == 'o' && POLE[j - 1][2 - 1] == 'o' && POLE[j - 1][3 - 1] != 'k')
{
line((j * 250) - 230, (3 * 250) - 230, (j * 250) - 20, (3 * 250) - 20);
line((j * 250) - 20, (3 * 250) - 230, (j * 250) - 230, (3 * 250) - 20);
POLE[j - 1][3 - 1] = 'k';
goto poczatek;
}
}
//wstawianie krzyzyka na gorze jesli sa dwa kolka jedno nad drugim
for (int j = 1; j < 4; j++)
{
if (POLE[j - 1][2 - 1] == 'o' && POLE[j - 1][3 - 1] == 'o' && POLE[j - 1][1 - 1] != 'k')
{
line((j * 250) - 230, (1 * 250) - 230, (j * 250) - 20, (1 * 250) - 20);
line((j * 250) - 20, (1 * 250) - 230, (j * 250) - 230, (1 * 250) - 20);
POLE[j - 1][1 - 1] = 'k';
goto poczatek;
}
}
//wstawianie krzyzyka jesli sa dwa kolka po bokach
for (int j = 1; j < 4; j++)
{
if (POLE[1 - 1][j - 1] == 'o' && POLE[3 - 1][j - 1] == 'o' && POLE[2 - 1][j - 1] != 'k')
{
line((2 * 250) - 230, (j * 250) - 230, (2 * 250) - 20, (j * 250) - 20);
line((2 * 250) - 20, (j * 250) - 230, (2 * 250) - 230, (j * 250) - 20);
POLE[2 - 1][j - 1] = 'k';
goto poczatek;
}
}
//wstawianie krzyzyka po srodku jesli jest jedno kolko na dole a drugie na gorze
for (int j = 1; j < 4; j++)
{
if (POLE[j - 1][1 - 1] == 'o' && POLE[j - 1][3 - 1] == 'o' && POLE[j - 1][2 - 1] != 'k')
{
line((j * 250) - 230, (2 * 250) - 230, (j * 250) - 20, (2 * 250) - 20);
line((j * 250) - 20, (2 * 250) - 230, (j * 250) - 230, (2 * 250) - 20);
POLE[j - 1][2 - 1] = 'k';
goto poczatek;
}
}
//wstawianie jesli na przekatnej sa dwa kolka pod rzad
if (POLE[1 - 1][1 - 1] == 'o' && POLE[2 - 1][2 - 1] == 'o' && POLE[3 - 1][3 - 1] != 'k')
{
line((3 * 250) - 230, (3 * 250) - 230, (3 * 250) - 20, (3 * 250) - 20);
line((3 * 250) - 20, (3 * 250) - 230, (3 * 250) - 230, (3 * 250) - 20);
POLE[3 - 1][3 - 1] = 'k';
goto poczatek;
}
if (POLE[2 - 1][2 - 1] == 'o' && POLE[3 - 1][3 - 1] == 'o' && POLE[1 - 1][1 - 1] != 'k')
{
line((1 * 250) - 230, (1 * 250) - 230, (1 * 250) - 20, (1 * 250) - 20);
line((1 * 250) - 20, (1 * 250) - 230, (1 * 250) - 230, (1 * 250) - 20);
POLE[1 - 1][1 - 1] = 'k';
goto poczatek;
}
if (POLE[3 - 1][1 - 1] == 'o' && POLE[2 - 1][2 - 1] == 'o' && POLE[1 - 1][3 - 1] != 'k')
{
line((1 * 250) - 230, (3 * 250) - 230, (1 * 250) - 20, (3 * 250) - 20);
line((1 * 250) - 20, (3 * 250) - 230, (1 * 250) - 230, (3 * 250) - 20);
POLE[1 - 1][3 - 1] = 'k';
goto poczatek;
}
if (POLE[1 - 1][3 - 1] == 'o' && POLE[2 - 1][2 - 1] == 'o' && POLE[3 - 1][1 - 1] != 'k')
{
line((3 * 250) - 230, (1 * 250) - 230, (3 * 250) - 20, (1 * 250) - 20);
line((3 * 250) - 20, (1 * 250) - 230, (3 * 250) - 230, (1 * 250) - 20);
POLE[3 - 1][1 - 1] = 'k';
goto poczatek;
}
//wstawianie krzyzyka w srodek jestli jest wolny
if (POLE[1][1] != 'k' && POLE[1][1] != 'o')
{
line((2 * 250) - 230, (2 * 250) - 230, (2 * 250) - 20, (2 * 250) - 20);
line((2 * 250) - 20, (2 * 250) - 230, (2 * 250) - 230, (2 * 250) - 20);
POLE[1][1] = 'k';
goto poczatek;
}
//wybor losowo miejsca, gdy nie jest spelniony zaden z warunkow algorytmow
cofnij:
srand(time(NULL));
a = rand() % 3 + 1;
b = rand() % 3 + 1;
if (POLE[a - 1][b - 1] == 'k' || POLE[a - 1][b - 1] == 'o')
{
goto cofnij;
}
else
{
line((a * 250) - 230, (b * 250) - 230, (a * 250) - 20, (b * 250) - 20);
line((a * 250) - 20, (b * 250) - 230, (a * 250) - 230, (b * 250) - 20);
POLE[a - 1][b - 1] = 'k';
}
// sprawdzenie czy ktos wygral
for (int i = 0; i < 3; i++)
{
if (POLE[i][0] == POLE[i][1] && POLE[i][0] == POLE[i][2] && POLE[i][0] != '0')
{
goto koniec;
}
if (POLE[0][i] == POLE[1][i] && POLE[0][i] == POLE[2][i] && POLE[0][i] != '0')
{
goto koniec;
}
}
if (POLE[0][0] == POLE[1][1] && POLE[1][1] == POLE[2][2] && POLE[0][0] != '0')
{
goto koniec;
}
if (POLE[0][2] == POLE[1][1] && POLE[1][1] == POLE[2][0] && POLE[0][2] != '0')
{
goto koniec;
}
}
else
{
goto koniec;
}
goto poczatek;
koniec:;
printf("KONIEC GRY");
}