Problem z metodą sprawdzającą skos w grze logicznej

0

Witam. Mam do napisania grę logiczną, która nazywa się "studnia". Plansza 6x8 i zrzucamy z góry koraliki które trzeba układać tak aby były uzyskać 4 tego samego koloru w pionie, poziomie lub skosie. Mój problem dotyczy tego ostatniego. Napisałem funkcję, która sprawdza czy na planszy istnieje jakiś skos, ale nie działa poprawnie. Może ktoś pomoże?

 bool game::check_slant(char par_player){
	int i,j,ile=0;
	for(i=board_width-1; i>=0; i--)
		for(j=board_height-1; j>=0; j--){
			ile=0;
			if(board[i][j]==par_player && board[i-1][j+1]==par_player){
				for(int k=i; k>=0; k--)
					for(int l=j; l<=board_height-1; l++) {
						if(board[k][l]==par_player)
							ile++;
						if(ile==how_many_wins)
							return true;
					}
			}

			else if(board[i][j]==par_player && board[i+1][j-1]==par_player){
				for(int k=i; k<=board_width-1; k++)
					for(int l=j; l>=0; l--) {
						if(board[k][l]==par_player)
							ile++;
						if(ile==how_many_wins)
							return true;
					}
			}

			ile=0;
			if(board[i][j]==par_player && board[i-1][j-1]==par_player) {
				for(int k=i; k>=0; k--)
					for(int l=j; l>=0; l--) {
						if(board[k][l]==par_player)
							ile++;
						if(ile==how_many_wins)
							return true;
					}
			}

			else if(board[i][j]==par_player && board[i+1][j+1]==par_player) {
				for(int k=i; k<=board_width-1; k++)
					for(int l=j; l<=board_height-1; l++) {
						if(board[k][l]==par_player)
							ile++;
						if(ile==how_many_wins)
							return true;
					}
			}
		}
		return false;
}
1

po cholerę tyle zagnieżdżeń forów (naliczyłem 4), przecież to jest proste jak konstrukcja cepa.
Po pierwsze nie musisz sprawdzać wszystkich możliwości. Wystarczy jeśli sprawdzisz możliwości powstałe po oddaniu ostatniego ruchu.
Testujesz wzdłuż poszczególnych kierunków, więc wystarczy pojedyncze zagnieżdżenie for by wykonać test (złożoność liniowa, a nie n4).

1

Kiedyś pisałem taką gierkę, kilka istotnych fragmentów, może cię zainspiruje:

enum Player {
    PLAYER_BLUE,
    PLAYER_RED,
    NO_PLAYER
};

class Board {
private:
    Player *tokens;

public:
    const unsigned width;
    const unsigned height;

    Board(unsigned width, unsigned height) : width(width), height(height), tokens(new Player[width * height]) {}
    ~Board() { delete[] tokens; }

    Player *operator [] (unsigned y) { return tokens + y * width; }
    const Player *operator [] (unsigned y) const { return tokens + y * width; }
};

enum Direction {
    DIR_BEGIN = 0,

    DIR_UP_DOWN = 0,
    DIR_LEFT_RIGHT,
    DIR_LEFTUP_RIGHTDOWN,
    DIR_RIGHTUP_LEFTDOWN,
    
    DIR_END
};

const struct {
    int x;
    int y;
} directions[] = {
    {  0, 1, }, // DIR_UP_DOWN
    {  1, 0, }, // DIR_LEFT_RIGHT
    { -1, 1, }, // DIR_LEFTUP_RIGHTDOWN
    {  1, 1, }, // DIR_RIGHTUP_LEFTDOWN
};

bool IsInsideRange(int x, unsigned begin, unsigned end)
{
    return (unsigned)(x - begin) < (end - begin);
}

unsigned CountHalfLineLen(const Board &board, Player player, unsigned start_x, unsigned start_y, int dir_x, int dir_y)
{
    unsigned ret = 0;
    for (;;) {
        start_x += dir_x;
        if (!IsInsideRange(start_x, 0, board.width) break;
        start_y += dir_y;
        if (!IsInsideRange(start_y, 0, board.height) break;
        
        if (board[start_y][start_x] != player) break;

        ret++;
    }
    return ret;
}


/* ... */

int pos_x = ...; // numer kolumny wrzuconego żetonu
int pos_y = ...; // numer wiersza wrzuconego żetonu
int win_len = ...; // długość wygrywającej linii

bool win = false;
for (unsigned dir = DIR_BEGIN; dir < DIR_END && !win; dir++) {
    unsigned len = 1;
    len += CountHalfLineLen(board, player, pos_x, pos_y, directions[dir].x, directions[dir].y);
    len += CountHalfLineLen(board, player, pos_x, pos_y, -directions[dir].x, -directions[dir].y);

    win = (len >= win_len);
}

if (win) {
    /* --- > WYGRANA < --- */
}

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