Kółko i krzyżyk, niedziałający warunek

0

Witam, jestem tutaj nowy i próbuję napisać prostą grę, kółko i krzyżyk. Może z grubsza zasady dla jasności: Gramy na planszy 9x9 i warunkiem zwycięstwa jest postawienie 5ciu takich samych znaczków w górę, dół, lub na skosy. Nie wszystko jest jeszcze zrobione ale nie chcę iść dalej niczym nie uporam się z niniejszym problemem, otóż po stworzeniu "szkicu" gry zacząłem dodawać warunki zwycięstwa (konkretnie pierwszy). Chciałem dodać warunek który będzie nam sprawdzał czy mamy pięć takich samych symboli w jednym wierszu. Jeżeli tak, metoda GameOver() zwraca true i gra się kończy, lecz jeżeli warunek nie zostanie spełniony zwraca ona false i gramy dalej. Problem polega na tym, że warunek zwraca poprawne wartości tylko jeżeli postawimy krzyżyk lub kółko w polach 1,2,3,4,5. Jeżeli wprowadzimy np 2,3,4,5,6 metoda ciągle będzie zwracać false, dopóki nie pojawi się kompletny ciąg 1,2,3,4,5. Proszę o wyrozumiałość, gdyż jestem na początku swojej drogi z C++. Oto kod i bardzo proszę o pomoc. Pozdrawiam

#include <iostream>
#include <string>
#include <ios>
using namespace std;

#define SIZE 9
enum Figure { o, x };
class Point
{
public:
	char element = '\0';
	Point(char c)
	{
		this->element = c;
	}
	Point()
	{
		this->element = '\0';
	}
};

class Place
{
public:
	Point place[SIZE*SIZE+1];

	Place()
	{

	}

	void MakeStep(int i, Figure f)
	{
		place[i] = (f == Figure::o ? 'O' : 'X'); // zmienna1 != zmienna2 ? true : false;
	}
	bool GameOver()
	{
		// Sprawdzamy wiersze
		for (int i = 1; i <= SIZE*SIZE; i=+SIZE)
		{
			if ((place[i].element == 'O') && (place[i + 1].element == 'O') && (place[i + 2].element =='O') && (place[i + 3].element == 'O') && (place[i + 4].element == 'O'))
			{
				cout << "Wygral Gracz: O";
				return true;
			}
			else if ((place[i].element == 'X') && (place[i + 1].element == 'X') && (place[i + 2].element == 'X') && (place[i + 3].element == 'X') && (place[i + 4].element == 'X'))
			{
				cout << "Wygral Gracz: X";
				return true;
			}
			else return false;
		}
		return false;
	}
	
	void ShowPlace()
	{
		system("cls");
		for (int i = 1; i <= SIZE*SIZE; i++)
		{
			cout << " " << place[i].element << " ";
			if (i % SIZE) cout << "|"; 
			else if (i != SIZE*SIZE)
			{	
				string poprzeczka = "+---";
				cout << "\n---";
				for (int i = 0; i < SIZE - 1; i++)
				{
					cout << poprzeczka;
				}
				cout << "\n";
			}
			else cout << endl;
		}
		
	}
	void FillPlace()
	{
		for (int i = 0; i <= SIZE*SIZE + 1; i++)
		{
			place[i].element = '0';
		}
	}
};

void main()
{
	Place *place = new Place();

	place->FillPlace();
	int i = 0;
	place->ShowPlace();
	while (!place->GameOver())
	{
		int a;
		cin >> a;
		place->MakeStep(a, i % 2 == 0 ? Figure::o : Figure::x);
		place->ShowPlace();
		i++;
	}
	cin.get();
	cin.get();
};

0

Właśnie chodzi mi o to aby kod był jak najbardziej uniwersalny i przy zmianie #define SIZE 9; na inną wartość gra powiększała planszę i nadal działała

0

tu chodzi o algorytm a nie o kod... i zapewne chodzi o https://pl.wikipedia.org/wiki/Gomoku i modyfikacje tej gry (w swoim rozwiązaniu przyjąłem zasadę do zliczania pkt. tak jak dawniej grałem pÓÓÓÓki ktoś nie zablokuje...)

gdy postawisz znak to liczysz od tego miejsca (włącznie z nim) w przeciwnych kierunkach na linii oczywiście nie wychodząc poza obręb "planszy" - więc: lewo-prawo, góra-dół, l.g-d.p, l.d-g.p - szukaj błędu w tym algorytmie...

u Ciebie jest prosta implementacja bo do pierwszego skreślenia...

0

ps. wcisnąłem CRT+F na szybkiego zerkając na kod (jemu samemu nie chce mi się przyglądać ;p) - nie pobierasz współrzędnych planszy tylko jeden parametr - może co krok jako debugowanie wyświetlaj sobie planszę - ja akurat pisałem to w wersji graficznej, to, że w java nie robi różnicy ;p

0

Czyżby sprawę miało załatwić usunięcie linijki z "else return...."? ;)

Btw. może lepiej byłoby zrobić planszę jako tablicę dwuwymiarową.

0

Dziękuję bardzo za wszystkie sugestie, usunięcie else return... faktycznie daje zamierzony efekt. muszę jeszcze tylko zabezpieczyć ten algorytm przed sprawdzaniem warunku poza wierszem. Ma ktoś jakiś pomysł ? chodzi o to ze ciąg kółek lub krzyżyków w polach o numerach np. 7,8,9(nowy wiersz)10,11 również zwraca wartość true i gra nam się kończy zwycięstwem. Co do dwuwymiarowej tablicy, takie było moje pierwotne założenie ale zrezygnowałem z tego z racji na zbytnią komplikację warunków wygranej. Jak mówiłem dopiero zaczynam z C++

0

if(i%9<=5) { tutaj wykonujesz sprawdzanie }

Taki warunek zapewni, że dla każdego wiersza sprawdzany będzie maksymalnie 5 od końca element (ze względu na resztę z dzielenia przez 9 w tym przypadku (uogólniając można napisać i%SIZE)

0

Niestety używając do mojego kodu tego warunku efekt jest taki, że w wierszu niżej wygrywa się posiadając 4 takie same symbole (o ile wiersz wyżej takim się kończy) jakieś dodatkowe sugestie ?

0

Małe niedopatrzenie: powinno być i%9<=5 && i%9>0 (wtedy dla ostatniej kolumny w danym wierszu nie będzie robił sprawdzenia, bo np 9 mod 9 = 0 ;]

0

Mały przykład dla poziomych wierszy:

{
    // plansza 4 x 4 i trzy pola wygrywają
    constexpr int SIZE = 4;
    constexpr int LENGTH_WIN_STRING = 3;

    std::array<int, SIZE * SIZE> arr{};
    arr[0] = 1; 
    arr[1] = 1;   // wiersz 1 ma dwa błędne pola, więc nie ma wygranego ciągu
    arr[7] = 1;   // wiersz 2 ostatnie jest błędne, więc jest wygrany ciąg
    arr[8] = 1;   // wiersz 3 pierwsze jest błędne, więc jest wygrany ciąg
    arr[13] = 1; // wiersz 4 ma drugie pole błędne, więc nie ma wygranego ciągu

    for (int i = 0; i < SIZE; ++i)
    {
        for (int j = i * SIZE; j < (SIZE + i * SIZE) && j < (SIZE * SIZE - 2); ++j)
        {
            bool isCheckLineCorrect = (j % SIZE) <= (SIZE - LENGTH_WIN_STRING);
            bool isWinString = (arr[j] == 0) && (arr[j + 1] == 0) && (arr[j + 2] == 0);

            if ( isWinString && isCheckLineCorrect) {
                std::cout << "Wygrałeś w wierszu nr: " << i + 1 << '\n';
            }
        }    
    }
} 

1 użytkowników online, w tym zalogowanych: 0, gości: 1