Problem z stała modyfikacją pola.

0

Witam,
to mój pierwszy większy projekt. Cześć rzeczy w tym programie to sztuki dla sztuki (np. funkcja zaprzyjaźnione). Wyniki to z przyczyn edukacyjnych, ale do rzeczy. Poniższy program prezentuje plansze 2D, w której przemieszcza się za pomocą wyboru współrzędnej (2) i klawiszy wsad (3). Przemieszczenie pierwszym sposobem powoduje zmianę wartości zmiennych: pol_x, pol_y; Natomiast podobnego efektu nie mogę uzyskać przy 2 metodzie. Jest to konieczne gdyż służy do porównania położenia obiektu pojawiającego się losowo ( [o] ), ze sterowanym ( [x] ) i wywołaniu komunikatu (tu: bazinga) . Próbowałem operować na wskaźnikach, jednak nie odniosło to pozytywnego skutku.
By program działał poprawnie, najpierw trzeba określić położenie za pomocą przemieszczenia.

#include <iostream>
#include <time.h>
#include "obiekt.h"

//************************************************DEKLARACJE GLOBALNE
using namespace std;
void rysuj(void);

int pol_x, pol_y;
int *wsk_x = &pol_x;
int *wsk_y = &pol_y;
int x_1=0, y_1=0;
int wymiar;

int main()
{
int y2,x2;


//******************************************************DEKLARACJA PLANSZY
cout << "Podaj rozmiar planszy:\n";
while(true)
{
    cin >> wymiar;
    if(wymiar <=18)
        break;
    else
        cout << "Wymiar planszy nie moze przekraczac 18\n";
}
int plansza[wymiar][wymiar];
cout << endl;

vector2 ruch;
pozycja(ruch);

//*****************************************************************LOSOWE OBIEKTY

srand ( time(NULL) );
x_1 = (rand() % wymiar) + 1;
y_1 = (rand() % wymiar) + 1;

//*********************************************************MENU
char wybor;
cout << "menu\n";
cout << x_1 << "\n\n";

while(true)
{
//*********ETYKIETA
menu:
//*********ETYKIETA
    cout << "1.Wyswietl wspolrzedne\n2.Przemieszczenie\n3.Ruch\n4.Wyjscie\n\n";
    cin >> wybor;
    switch(wybor)
    {
        case '1':
            cout << ruch.przemieszczenie_x(x2) << "\n";
            cout << ruch.przemieszczenie_y(y2) << "\n";
            break;
//**********************************************************MENU-RUCH
        case '2':
            cout << "Podaj wspolrzedne: x i y:\n";
            cin >> x2;
            cin >> y2;
            pol_x = (ruch.przemieszczenie_x(x2) );
            pol_y = (ruch.przemieszczenie_y(y2) );
            rysuj();
            if(pol_x==x_1 && pol_y==y_1)
                cout << "bazinga!";
            cout << "\n";
            break;
//**************************************************************MENU-RUCH
        case '3':
            char kursor;
            cout << "Uzyj WSAD, by sie przemiescic:\n";
            while(true)
            {
                cin >> kursor;
                switch(kursor)
                {

                    case 'S || s':
                        pol_x = pol_x +1;
                        rysuj();
                        break;
                    case 'W || w':
                        pol_x = pol_x -1;
                        rysuj();
                        break;
                    case 'A || a':
                        pol_y = pol_y -1;
                        rysuj();
                        break;
                    case 'D || d':
                        pol_y = pol_y +1;
                        rysuj();
                        break;
                    default:
                        goto menu; //->50

                }
                if(pol_x==x_1 && pol_y==y_1)
                    cout << "bazinga!";

            }

            break;
//*******************************************************************MENU-KONIEC
        case '4':
            return 0;
        default:
            break;

    }
}
}

void pozycja(vector2 & ruch )
{
    cout << "x = " << ruch.x << "\n";
    cout << "y = " << ruch.y << "\n";
}

//******************************************************PLANSZA

void rysuj(void)
{

    int n=wymiar;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if (i==pol_x && j==pol_y)
            {
                 cout.width( 4 );
                 cout << "[x]";
                 continue;
            }
            if(i==x_1 && j==y_1)
            {
                cout.width(4);
                cout << "[o]";
                continue;
            }
            cout.width( 4 );
            cout << "[ ]";
        }
        cout << "\n";
    }

}

//*****************************************KLASA

#ifndef OBIEKT_H_INCLUDED
#define OBIEKT_H_INCLUDED
using namespace std;

class vector2
{
    private:
        int x,y;
    public:
        vector2() : x(0), y(0) {}
        friend void pozycja(vector2& ruch );

        int przemieszczenie_x(int x2);
        int przemieszczenie_y(int y2);
};

int vector2::przemieszczenie_x(int x2)
{
    x = x +x2;
    return (x2);
}

int vector2::przemieszczenie_y(int y2)
{
    y = y + y2;
    return (y2);
}
#endif // OBIEKT_H_INCLUDED
0

Piszę z telefonu, więc nie przyglądałem się zbytnio kodowi, ale nie da się tworzyć tablic dynamicznych tak, jak to robisz.

Edit: skąd masz ten dziwny warunek w switchu? W ten sposób tego nie da się wykonać.

0
Patryk27 napisał(a):

Edit: skąd masz ten dziwny warunek w switchu? W ten sposób tego nie da się wykonać.

Chodzi o ten fragment:
*foo/

/
if(pol_x==x_1 && pol_y==y_1)
cout << "bazinga!";
  • ?foo//

Nie to jest tu problemem. Zmienna nie jest w ogóle modyfikowana. Próbuje to zrobić tym poleceniem:

  
pol_x = pol_x +1;
rysuj(); 
break;
0

Chodzi mi o to:
case 'S || s':
A dokładniej o sam warunek - tak się nie da zrobić.
Kompilator traktuje to wyrażenie jako jedną całość.
Poczytaj o switchu, to zrozumiesz jak to zrobić poprawnie.

8

W tym kodzie aż roi się od antywzorców:

  1. zmienne globalne;
  2. programowanie zorientowane faraonowo - większość kodu znajduje się w funkcji main, gdzie wszechwiedzący pan i władca kontroluje każdy szczegół programu;
  3. ogromny switch;
  4. komentarze, które opisują kontrolę przepływu;
  5. nawet dla goto nie zabrakło miejsca;
  6. klasa praktycznie nic nie robi, jej szczegóły implementacji rozproszone są po całym programie.

Wyeliminuj wszystkie antywzorce, a na pewno znajdziesz miejsce wystąpienia problemu.

Przykładowy sposób eliminacji:

  1. klasa może przechowywać aktualne położenie.
  2. podziel kod na dosyć krótkie funkcje, które mają dobrze zdefiniowane zachowanie (najwyżej 10-15 linijek). Umieść je w środku klasy.
  3. kod powinien być czytelny bez użycia komentarzy - nadaj odpowiednie nazwy metod.
  4. goto zastąp pętlą (gdy już usuniesz ogromnego switcha).
  5. pod żadnym pozorem nie pozwól funkcji main poznać szczegółów implementacji klasy.
0
Patryk27 napisał(a):

Chodzi mi o to:
case 'S || s':
A dokładniej o sam warunek - tak się nie da zrobić.
Kompilator traktuje to wyrażenie jako jedną całość.
Poczytaj o switchu, to zrozumiesz jak to zrobić poprawnie.

Zmiana warunku na: case 'S', nie powoduje rozwiązania mojego problemu. Kompilator natomiast pozwala na takie przypisanie, a co najważniejsze - ta część działa.

0

a co najważniejsze - ta część działa.

Kompilator powinien wywalić warning/error (albo error, ponieważ C++ nie obsługuje string-switch albo warning, ponieważ niejawnie porównuje tylko pierwszy znak); najwyraźniej niejawnie porównywany jest tylko pierwszy znak.

0
Oak napisał(a):

Przykładowy sposób eliminacji:

  1. klasa może przechowywać aktualne położenie.
  2. podziel kod na dosyć krótkie funkcje, które mają dobrze zdefiniowane zachowanie (najwyżej 10-15 linijek). Umieść je w środku klasy.
  3. kod powinien być czytelny bez użycia komentarzy - nadaj odpowiednie nazwy metod.
  4. goto zastąp pętlą (gdy już usuniesz ogromnego switcha).
  5. pod żadnym pozorem nie pozwól funkcji main poznać szczegółów implementacji klasy.

1.Funkcję void rysuj(void) i zmienne int pol_x, pol_y dać do klasy?
2.Robić osobne funkcję dla chociażby losowania obiektu?
3.Czytałem że to dobra praktyka, nazwą chyba nic nie można zarzucić?
4.Z tym miałem problem, gdyż nie widziałem jak opuścić 2 switche.
5.Wszystkie mają być private, a dostępność poprzez funckję?

Ile byś tu widział klas?

0
Kulis18 napisał(a):

1.Funkcję void rysuj(void) i zmienne int pol_x, pol_y dać do klasy?
2.Robić osobne funkcję dla chociażby losowania obiektu?
3.Czytałem że to dobra praktyka, nazwą chyba nic nie można zarzucić?
4.Z tym miałem problem, gdyż nie widziałem jak opuścić 2 switche.
5.Wszystkie mają być private, a dostępność poprzez funckję?

Ile byś tu widział klas?

Zgadza się.
Klasa prawdopodobnie jedna lub dwie (jedna do interakcji z użytkownikiem, a druga z całą resztą).
Co do punktu 4. to możesz utworzyć po jednej metodzie dla każdego przypadku switcha. Powinien wyglądać mniej więcej tak:

switch(wybor) {
    case '1': plansza.wyswietlWspolrzedne(); break;
    case '2': plansza.przemieszczenie(); break;
    /* ... */
}
0
Oak napisał(a):

Zgadza się.
Klasa prawdopodobnie jedna lub dwie (jedna do interakcji z użytkownikiem, a druga z całą resztą).
Co do punktu 4. to możesz utworzyć po jednej metodzie dla każdego przypadku switcha. Powinien wyglądać mniej więcej tak:

switch(wybor) {
    case '1': plansza.wyswietlWspolrzedne(); break;
    case '2': plansza.przemieszczenie(); break;
    /* ... */
}

Jak zwrócić 2 wartości dla funkcji: plansza.wyswietlWspolrzedne() ? Odwołać się do prywatnych wartości w klasie poprzez adres, przesłać je do funkcji plansza.wyswietlWspolrzedne() i dokonać przypisanie do wskaźników?

0
Kulis18 napisał(a):

Jak zwrócić 2 wartości dla funkcji: plansza.wyswietlWspolrzedne() ? Odwołać się do prywatnych wartości w klasie poprzez adres, przesłać je do funkcji plansza.wyswietlWspolrzedne() i dokonać przypisanie do wskaźników?

Najpierw zastanów się, czy nie da się obejść bez zwracania. Nie wiem co próbujesz zrobić, ale nie wydaje mi się, aby zwracanie czegokolwiek przez taką funkcję było konieczne. Jeżeli naprawdę tego potrzebujesz to możesz zwrócić obiekt (np. punkt).

0

Po zastosowaniu się do zaleceń starszych i mądrzejszych, uzyskałem następujący kod. Nie mogą sobie poradzić jeszcze ze sterowaniem. Przy próbie użycia instrukcji if, funkcja rysuj() m.in. rysowała mi kilka plansz. Wobec tych trudności wybrałem sposób mniej efektywny, aczkolwiek działający - mianowicie: w funkcji sterowanie() wywołałem 2 funkcję oparte na switch(małe i duże litery). Proszę o sugestię odnośnie optymalizacji kody. Z chęcią bym też zmienił warunek przerywający pętla (obecnie z), najchętniej na ESC, jakieś propozycje?

#include <iostream>
#include "plansza.h"

using namespace std;

int main()
{
    vector2 ruch;
    char wybor;
    cout << "MENU:\n";
    ruch.tworzenie_planszy();
    ruch.losowy_pkt();
    while(true)
    {
        cout << "1.Wyswietl wspolrzedne\n2.Przemieszczenie\n3.Ruch\n4.Wyjscie\n\n";
        cin >> wybor;
        switch(wybor)
        {
            case '1':
                ruch.wyswietl_wspolrzedne();
                break;
            case '2':
                ruch.podaj_wspolrzedne();
                break;
            case '3':
                ruch.sterowanie();
                break;
            case '4':
                return 0;
            default:
                break;
        }
    }
}


#ifndef PLANSZA_H_INCLUDED
#define PLANSZA_H_INCLUDED

using namespace std;


class vector2
{
    private:
        int x,y;
    public:
        int pol_x, pol_y;
        int wymiar;
        int x_1, y_1;
        char kursor;
        bool deklaracja_pozycji;

        vector2() : x(0), y(0) {}


        void rysuj(void);
        void tworzenie_planszy(void);
        void losowy_pkt(void);
        void wyswietl_wspolrzedne(void);
        void podaj_wspolrzedne(void);
        void sterowanie(void);
        void wybor_male(void);
        void wybor_duze(void);
        void nakladanie(void);


};

void vector2::rysuj(void)
{

    int n=wymiar;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if (i==pol_x && j==pol_y)
            {
                 cout.width( 4 );
                 cout << "[x]";
                 continue;
            }
            if(i==x_1 && j==y_1)
            {
                cout.width(4);
                cout << "[o]";
                continue;
            }
            cout.width( 4 );
            cout << "[ ]";
        }
        cout << "\n";
    }

}

void vector2::losowy_pkt(void)
{
    srand ( time(NULL) );
    x_1 = (rand() % wymiar) + 1;
    y_1 = (rand() % wymiar) + 1;
}

void vector2::tworzenie_planszy(void)
{
    cout << "Podaj rozmiar planszy:\n";
    while(true)
    {
        cin >> wymiar;
        if(wymiar <=18)
            break;
        else
            cout << "Wymiar planszy nie moze przekraczac 18\n";
    }
    int plansza[wymiar][wymiar];
    cout << endl;

}

void vector2::wyswietl_wspolrzedne(void)
{
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
}

void vector2::podaj_wspolrzedne(void)
{
    deklaracja_pozycji = true;
    cout << "Podaj wspolrzedne: x i y:\n";
    cin >> x;
    cin >> y;
    pol_x = x;
    pol_y = y;
    rysuj();
    if(pol_x==x_1 && pol_y==y_1)
        nakladanie();

}

void vector2::sterowanie(void)
{

    if(deklaracja_pozycji != true)
        pol_x = 1,pol_y = 1;
    rysuj();
    cout << "Uzyj WSAD, by sie przemiescic. By zakonczyc wcisnij 'z;':\n";
    while(true)
        {
            cin >> kursor;
            wybor_male();
            wybor_duze();
            if(pol_x==x_1 && pol_y==y_1)
                nakladanie();
            if(kursor == 'z' )
                break;

        }
}

void vector2::wybor_male(void)
{
    switch(kursor)
    {
    case 's':
        pol_x = pol_x +1;
        rysuj();
        break;
    case 'w':
        pol_x = pol_x -1;
        rysuj();
        break;
    case 'a':
        pol_y = pol_y -1;
        rysuj();
        break;
    case 'd':
        pol_y = pol_y +1;
        rysuj();
        break;
    }

}

void vector2::wybor_duze(void)
{
    switch(kursor)
    {
    case 'S':
        pol_x = pol_x +1;
        rysuj();
        break;
    case 'W':
        pol_x = pol_x -1;
        rysuj();
        break;
    case 'A':
        pol_y = pol_y -1;
        rysuj();
        break;
    case 'D':
        pol_y = pol_y +1;
        rysuj();
        break;
    }

}

void vector2::nakladanie(void)
{
    cout << "bazinga" << endl;
}
#endif // PLANSZA_H_INCLUDED
0

Zamiast dwóch funkcji możesz zrobić coś w tym stylu:
case 's':
case 'S':
/tutaj kod dla litery 's'/'S'

0

Dla każdego przypadku w switchu wywołujesz na końcu rysuj() - wyłącz ją poza switch.

0

Rady jak zwykle okazały się pomocne. Próbuje teraz zrobić zabezpieczenie, by nie można było się przesunąć poza planszę:

 
void vector2::wybor(void)
{
    switch(kursor)
    {
    case 's':
    case 'S':
        if(pol_x >= 1)
            pol_x = pol_x +1;
        break;
    case 'w':
    case 'W':
        if(pol_x >= 1)
            pol_x = pol_x -1;
        break;
    case 'a':
    case 'A':
        if(pol_y >= 1)
            pol_y = pol_y -1;
        break;
    case 'd':
    case 'D':
        if(pol_y >= 1)
            pol_y = pol_y +1;
        break;


    }
    rysuj();

}

Rozumuje to następująco: by uniemożliwić wyjście poza plansze, należy uniemożliwić wielkością pol_y, pol_x osiągnięcie wartości poniżej 0,1 (testowane obie wersje), a także powyżej zmiennej wielkość (ilość pól). Rozumowanie błędne, czy zapis?

0

Ja bym to uprościł:
zrobiłym funkcje/metody moveForward, moveBackward które wywołują metodę/funkcję move() z odpowiednimi parametrami (przekazałbym tutaj funktor testujacy legalność ruchu oraz wektor przesunięcia).
Czemu tak? Bo dzięki temu masz malutką funkcję do ktorej można potem łatwo wprowadzać nowe warunki poprawności ruchu.
Coś takiego mniej wiecej:

def move(self,vector,correctMoveCheck):
    if correctMoveCheck():
        self.coordinates.x+=vector[0]
        self.coordinates.y+=vector[1]

def moveForward(self):
    self.move(self.__forwardVector(),self.__forwardMovementCorrect)

def __forwardMovementCorrect(self):
    return self.x+1<costam

def __forwardVector(self):
    return (1,0)

edit: co więcej, dla wygody i zwięzlości zrobiłbym też mapę która dla odpowiedniego chara wywołuje odpowiednią funkcję move*() (w c++ można tu dać wskaźnik do funkcji/metody) i potem pobierać to z mapy i wywoływać, bez żadnych ifów.

0

Przyznam szczerze że niewiele rozumiem z twego zapisu.

0

Ok:
wyobraź sobie że warunek np.

if(pol_y >= 1)

wyciągasz do osobnej funkcji
Następnie operację

pol_x = pol_x +1;

też wyciągasz do osobnej funkcji
Dodatkowo w tej funkcji która "przesuwa" dodajesz sprawdzenie warunku czy przesunięcie jest poprawne, tak zeby operować na tym samym poziomie abstrakcji (bo masz tu dwa poziomy: jeden zajmuje się wybieraniem jaki ruch wykonać na podstawie inputu użytkownika, a drugi zajmuje się samym ruchem). Więc mamy funkcje:

void doPrzodu(){
  if(pol_x >= 1){
            pol_x = pol_x +1;
  }
}

Jak napiszesz wszystkie 4 funkcje to okaże się ze one w sumie wyglądają prawie tak samo! Różnią się tylko warunkiem i operacją przesunięcia. Można więc zrobić generalną funkcję:

void ruszSie(warunek,przesuniecie){
  if(warunek()){
            przesuniecie();
  }
}

Która przyjmuje jako argument funkcje testującą czy wolno się przesunąć i funkcję przesuwającą. Jaka z tego korzyść?

  1. Mamy kupę malutkich funkcje, które łatwo sie czyta i łatwo się zmienia.
  2. Możemy łatwo dodawać modyfikcje na różnych poziomach abstrakcji
0
void vector2::przemieszczenie(warunek, przesuniecie) // 1 z 4 funkcji przesuwających
{
    if(warunek())
        przesuniecie();
}

int vector2::warunek(void)
{
    if( ( (pol_x || pol_y) < 1) || ( (pol_x || pol_y) > wymiar )  )
        return 0;
    return 1;
}

void vector2::przesuniecie_plus_x()
{
    pol_x = pol_x +1;
}

void vector2::przesuniecie_minus_x()
{
    pol_x = pol_x -1;
}

void vector2::przesuniecie_plus_y()
{
    pol_y = pol_y +1;
}

void vector2::przesuniecie_minus_y()
{
    pol_y = pol_y -1;
}

To miałeś na myśli?

0
int vector2::warunek(void)
{
    if( ( (pol_x || pol_y) < 1) || ( (pol_x || pol_y) > wymiar )  )
        return 0;
    return 1;
}

Lepiej zmienić typ na bool, wtedy można to uprościć:

bool vector2::warunek(void)
{
    return ( ( (pol_x || pol_y) < 1) || ( (pol_x || pol_y) > wymiar )  )
}

Podobnie to:

pol_x = pol_x +1;

Na:

pos_x += 1;

Btw:

(pol_x || pol_y) < 1)

Co to jest?
Kompilator to nie człowiek i tego nie zrozumie.

0

Ja bym warunki podzielił na osobne funkcje mimo wszystko. Tak żeby łatwo było potem zmodyfikować pojedynczy warunek (np. przejście za lewą stronę ekrany teleportuje na drugą czy coś :P)
Tak samo przesuwanie zrobiłbym od razu w 2 płaszczyznach. Tzn zawsze robił:

pol_x+=wektorPrzesuniecia.x;
pol_y+=wektorPrzesuniecia.y;

A modyfikowal tylko wartości wektora ;)

0
Shalom napisał(a):

Ja bym warunki podzielił na osobne funkcje mimo wszystko. Tak żeby łatwo było potem zmodyfikować pojedynczy warunek (np. przejście za lewą stronę ekrany teleportuje na drugą czy coś :P)
Tak samo przesuwanie zrobiłbym od razu w 2 płaszczyznach. Tzn zawsze robił:

pol_x+=wektorPrzesuniecia.x;
pol_y+=wektorPrzesuniecia.y;

A modyfikowal tylko wartości wektora ;)

Muszę tu utworzyć strukturę: wektorprzesunięcia? Pytanie może wydawać się głupie, ale wolę się spytać niż nie przespać nocy... Mianowicie, jak poprawnie zadeklarować funkcję, która przyjmuje jako argumenty inną funkcję, np.

void przemieszczenie(warunek_x_rozmiar, przesuniecie_plus_x);

Dawałem tu nawiasy przy nazwie, typ zwracany - bezskutecznie.

0

@Shalom -owi, na ile go zrozumiałem, chodziło o coś mniej-więcej takiego
(ok, mocno zmieniłem jego kod, więc w sumie nie do końca o to mu chodziło. Ale wprowadzanie programowania funkcyjnego i wskaźników na funkcje/lambd to trochę przesada w tym momencie :] )

void move(vector direction) {
    if (canMoveTo(this.currentPosition + direction)) {
        this.currentPosition += direction;
    }
}

(Mój vector to zupełnie co innego niż Twój vector2, powinna być prościutką strukturą typu: , przechowującą informacje o współrzędnych x i y)

struct vector {
    int x;
    int y;
};

O co tu chodzi - funkcja move sprawdza czy można się ruszyć w danym kierunku, i - jeśli tak - wykonuje ruch.

0

Musisz przekazać wskaźnik do funkcji, dla

bool vector2::warunek(void)

byłoby to:

bool (*funkcja)(void)
0

Zakładając, że mamy planszę size x size można też zrobić:

void add(int &coord, int amount) {
	coord += amount;
	coord = (coord < 0) ? 0 :
	    (coord >= size) ? size-1 :
	                      coord;
}

void teleport(const Point &p) {
	add(current.x, p.x-current.x);
	add(current.y, p.y-current.y);
}

void moveUp() { add(current.y, -1); }
void moveDown() { add(current.y, 1); }
void moveLeft() { add(current.x, -1); }
void moveRight() { add(current.x, 1); }
0

Panowie, mam wrażenie że pogubiłem się w tym wszystkim. Prezentowane przez was metodą powodują u mnie zaskoczenie, nawet co do składni. W poniższym kodzie kompilator, jakby wyrywkowo, wywala błędy o braku deklaracji np. warunek_x_1. Pomijając niezmieniony kod:

 
bool *przemieszczenie_plus_x(void);
        bool *przemieszczenie_minus_x(void);
        bool *przemieszczenie_minus_y(void);
        bool *przemieszczenie_plus_y(void);

        bool warunek_y_rozmiar();
        bool warunek_x_rozmiar();
        bool warunek_y_1();
        bool warunek_x_1();

        void przesuniecie_plus_x();
        void przesuniecie_minus_x();
        void przesuniecie_plus_y();
        void przesuniecie_minus_y();

void vector2::wybor(void)
{
    switch(kursor)
    {
    case 's':
    case 'S':
            *przemieszczenie_plus_x();
        break;
    case 'w':
    case 'W':
            *przemieszczenie_minus_x();
        break;
    case 'a':
    case 'A':
            *przemieszczenie_plus_y();
        break;
    case 'd':
    case 'D':
            *przemieszczenie_minus_y();
        break;


    }
    rysuj();

}

bool vector2::*przemieszczenie_plus_x()
{
    if(warunek_x_rozmiar())
        przesuniecie_plus_x();
}

bool vector2::*przemieszczenie_minus_x()
{
    if(warunek_x_1())
        przesuniecie_minus_x();
}

bool vector2::*przemieszczenie_plus_y()
{
    if(warunek_y_rozmiar())
        przesuniecie_plus_y();
}

bool vector2::*przemieszczenie_minus_y()
{
    if(warunek_y_1())
        przesuniecie_minus_y();
}

bool vector2::warunek_x_1(void)
{
    return pol_x < 1;
}

bool vector2::warunek_y_1(void)
{
    return pol_y < 1;
}

bool vector2::warunek_x_rozmiar(void)
{
    return pol_x > wymiar;
}

bool vector2::warunek_y_rozmiar(void)
{
    return pol_y > wymiar;
}
void vector2::przesuniecie_plus_x()
{
    pol_x = pol_x +1;
}

void vector2::przesuniecie_minus_x()
{
    pol_x = pol_x -1;
}

void vector2::przesuniecie_plus_y()
{
    pol_y = pol_y +1;
}

void vector2::przesuniecie_minus_y()
{
    pol_y = pol_y -1;
}

Spróbuje teraz z wersją kolegi Oak.

void add(int &coord, int amount) {
coord += amount;
coord = (coord < 0) ? 0 :
(coord >= size) ? size-1 :
coord;

Mam rozumieć coord to: pol_x, pol_y -> jak to sprzęgnąć w jedność?


 
void vector2::teleport(const int &p) {
        add(pol_x, p.x - pol_x);
        add(pol_y, p.y - pol_y);
}

Co to za typ point? Zastosowałem tu int. Nie bardzo wiem co też wpisać po "p.". Mam tylko zmienną określającą aktualne położenie.

0

Point (ang. punkt) to prosty nośnik danych.

struct Point {
    int x, y;
    Point(int x, int y) : x(x), y(y) {}
};

Dla ułatwienia porównań można jeszcze przeciążyć operator porównania (==).

struct Point {
    int x, y;
    Point(int x, int y) : x(x), y(y) {}
    
    friend bool operator==(const Point &p, const Point &q) {
        return p.x == q.x  &&  p.y == q.y;
    }
};

Dzięki temu możemy napisać:

if (current == destination)
    cout << "Zrobione!" << endl;

gdzie current oraz destination są punktami.

0

@Kulis18 nie nie nie, zupełnie nie rozumiesz o co chodzi. Chodziło o to żeby wszystko ładnie unifikować, a nie rozbić na 100 identycznych funkcji. Po to właśnie funkcje miały być przekazane jako argumenty!

0
Shalom napisał(a):

@Kulis18 nie nie nie, zupełnie nie rozumiesz o co chodzi. Chodziło o to żeby wszystko ładnie unifikować, a nie rozbić na 100 identycznych funkcji. Po to właśnie funkcje miały być przekazane jako argumenty!

Niestety, z tym były problemy.

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