Kostka do gry c++

Kostka do gry c++
MI
  • Rejestracja:około 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:58
0

Hej wszystkim, znowu mam problem, tym razem muszę napisać program symulujący poruszanie się kostki, najgorsze jest to że muszę użyć do tego napisanej prze zemnie klasy do przewracania kostki, lecz niestety nie mam pojęcia w jaki sposób się do tego zabrać, mniej więcej tak :

Dane wejściowe: N S N S S W E

kostka musi przewrócić się do przodu, tyłu przodu, tyłu, tyłu, w lewo,w prawo
Kostka zawsze startuje z tej samej pozycji,
a danymi wyjściowymi musi być cyfra znajdująca się na górze kostki, po tych wszystkich obrotach

BO
Co te literki oznaczają? I próbowałeś coś sam napisać?
MI
literki to z angielskiego nazwy kierunków cały czas próbuję coś napisać ale nie do końca wychodzi
AK
Wszyscy tak mówią jak chcą wyłudzić rozwiązanie. Pokaż kod tych prób.
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

No to pokaż tą swoją klasę do przewracania kostki :)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
MI
  • Rejestracja:około 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:58
0
Kopiuj
class kostka{
private:
int sciana[6];
public:
kostka(){
(*this).sciana[0]=1; //top
(*this).sciana[1]=2; //n
(*this).sciana[2]=4; //w
(*this).sciana[3]=3; //e
(*this).sciana[4]=5; //s
(*this).sciana[5]=6; //bot
}
void rzut(char x){
int tmp;
if (x=='S')
{
tmp=(*this).sciana[0];
(*this).sciana[0]=(*this).sciana[1];
(*this).sciana[1]=(*this).sciana[5];
(*this).sciana[5]=(*this).sciana[4];
(*this).sciana[4]=tmp;
}
if (x=='N')
{
tmp=(*this).sciana[4];
(*this).sciana[4]=(*this).sciana[5];
(*this).sciana[5]=(*this).sciana[1];
(*this).sciana[1]=(*this).sciana[0];
(*this).sciana[0]=tmp;
}
AK
Już widziałem te nawiaski koło this. Kto was tego uczy ?!?!?!?
MI
profesor na uniwersytecie Mikołaja Kopernika
Spine
a wcięć też Was tak nauczył?
AK
Aha, witam kolegę o wielomianu. Już byłeś informowany, że to totalnie zbędne i nieczytelne
AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
1

Idea (abstrakcja) kostki jest zła. (o brzydkim kodzie było w komentarzu).
Jak rzucisz kostką, to nie spiłowujesz ścianek i nie malujesz od nowa.

Tu trzeba jakiejś drugiej abstrakcji, nazwijmy ją Widok czy Pozycja. Tak natychmiast nie umiem podać jej idei. Ale na pewno by zwracała klasę Kostka_w pozycji, i coś takiego ci trzeba do obracania.
(taka ilustracja z życia: kostka w kieszeni istnieje, ale nie ma żadnej pozycji)


Bo C to najlepszy język, każdy uczeń ci to powie
Spine
  • Rejestracja:około 22 lata
  • Ostatnio:2 minuty
  • Postów:6656
0

Wyobraź sobie jak wygląda kostka do gry.
Każda operacja zmienia wartość zwracaną przez kostkę.
Poruszasz się cyklicznie wokół kostki.
Rozpisz sobie cykle i opracuj ten algorytm.
Twoja kostka zawsze zmienia wartość względem wskazywanej cyfry - ta ściana zawsze jest na górze.

Kostka


🕹️⌨️🖥️🖱️🎮
edytowany 6x, ostatnio: Spine
MI
  • Rejestracja:około 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:58
0
Kopiuj
#include <iostream>

using namespace std;

class kostka{
    
private:
    int sciana[6];
public:
    
kostka()
{
    sciana[0]=1; 
    sciana[1]=2;
    sciana[2]=4; 
    sciana[3]=3;
    sciana[4]=5;
    sciana[5]=6;
}
    void rzut(char x){
        int tmp;
            if (x=='S')
        {
        tmp=sciana[0];
        sciana[0]=sciana[1];
        sciana[1]=sciana[5];
        sciana[5]=sciana[4];
        sciana[4]=tmp;
        }
    if (x=='N')
    {
        tmp=sciana[4];
        sciana[4]=sciana[5];
        sciana[5]=sciana[1];
        sciana[1]=sciana[0];
        sciana[0]=tmp;
    }
    if (x=='W')
    {
        tmp=sciana[4];
        sciana[0]=sciana[3];
        sciana[3]=sciana[5];
        sciana[5]=sciana[2];
        sciana[2]=tmp;
    }
    if (x=='E')
    {
    tmp=sciana[4];
    sciana[0]=sciana[2];
    sciana[2]=sciana[5];
    sciana[5]=sciana[3];
    sciana[3]=tmp;
    }
};

Poprawiłem trochę kod, ale rozumiem że to nie jest dobry sposób ?

AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
0

Jak ja rozumiem fizykę tej kostki, do określenia pozycji nie wystarczy 'S', to że jakaś ściana jest skierowana na południe niczego nie przesądza, dalej jest mowa o czterech możliwych pozycjach.

Prawie na pewno do określenia pozycji kostki potrzebne są DWIE dane.


Bo C to najlepszy język, każdy uczeń ci to powie
MI
Napisz program symulujący poruszanie sześciennej kostki do gry po płaskim stole. Możesz założyć, że kostka nie śliga się ani nie skacze. Każdy ruch jest obrotem o 90 stopni w wybranym kierunku. W ustawieniu początkowym ścianka oznaczona numerem 1 zwrócona jest do góry, ścianka oznaczona numerem 2 na północ (N), zaś ścianka oznaczona numerem 3 na zachód (W), patrz rysunek. Dodatkowo kostka ma tę własność, że suma wartości dwóch przeciwległych ścianek wynosi 7. Program powinien wczytać ze standardowego wejścia sekwencję ruchów w postaci N, S, E lub W, a następnie wydrukować
MI
a następnie wydrukować na standardowe wyjście liczbę oczek znajdującą się na górnej ściance kostki. Czy aby na pewno potrzebne są jeszcze inne dane ?
AK
Aha. Czyli nazwę rzut() masz złą, to jest obrot(). Nazwy SĄ WAŻNE, kierunkują myślenie.
MI
Przepraszam, ma Pan rację już poprawiłem, nie mam pojęcia w jaki sposób zrobić aby dobrze wyświetlało, w funkcji main zrobiłem wczytywanie do tablicy (max 20 znaków) lecz nie wiem w jaki sposób wyjąć dane do określenia ostatecznej pozycji
AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
0

Ja to jestem za głupi, żeby do 6 liczyć. Musze to sobie z sensem przepisać.

O! Coś takiego czuję, ze komfortowo bym obracał

Kopiuj
#include <vector>
#include <array> 
#include <map> 
#include <exception>
#include <stdexcept>
enum Kier3d { b, N, S, E, W, t };   // Nie gwarantuję za kolejność, ale zarazem wiem, że **obecnie **nie jest **mi **potrzebna

class KostkaPozycja {  /// zmiana nazwy klasy
  	std::map<Kier3d, int> sciana;
public:
	KostkaPozycja() {
		sciana[N] = 1;
		// ....
	}
	void Obrot(char kier4) {
		switch(kier4) {
		case 'S': //...
			break;

		}
	};
};

@jvoytech widzę Twój post, moja propozycja jest inna.
@mikko Propozycja Kolegi na operator << jest godna polecenia, dla moje klasy by też tzreba zrobić odpowiednik


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 3x, ostatnio: AnyKtokolwiek
JV
"printfy" na wyjście albo operator<< tym przypadku do debugowania jest idealny, dlatego go dałem bo łatwiej widać ułożenie kostki a w debugerze to nie za bardzo. Do zadania pewnie nie jest w ogóle potrzebny, jedynie jako ekstra ficzer.
JV
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 miesiące
  • Postów:242
0

Ja bym zaczął od sensowniejszego nadawania nazw zmiennym bo posługiwanie się liczbami to życie w udręce. Może jakieś enumy, albo coś w tym stylu:

Kopiuj
#include <iostream>

class Kostka {
  private:
    int top{1};
    int north{2};
    int west{3};
    int east{4};
    int south{5};
    int bottom{6};

  public:
    void rzut(char x) {
        int tmp;
        if (x == 'S') {
            tmp    = top;
            top    = north;
            north  = bottom;
            bottom = south;
            south  = tmp;
        }
    }

    friend std::ostream& operator<<(std::ostream& os, const Kostka& obj) {
        return os << "  " << obj.north << '\n'
                  << obj.west << ' ' << obj.top << ' ' << obj.east << "\n  "
                  << obj.south << "\n  " << obj.bottom << '\n';
    }
};

int main() {
    Kostka kostka;
    std::cout << kostka << std::endl;
    kostka.rzut('S');
    std::cout << kostka << std::endl;
    return 0;
}
Kopiuj
  2
3 1 4
  5
  6

  6
3 2 4
  1
  5
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:4 minuty
  • Postów:4927
2

Nie przypomina Wam to jakiejś dziwnej Maszyny Turinga, albo automatu? Sześc stanów wewnętrznych (1, 2, 3, 4, 5, 6) i cztery ruchy: N, S, W, E, ruch to będzxie para: (stan, kierunek), język będzie wyglądał tak:
Start: 1,
(1, N) -> 5;
(1, S) -> 2;
(1, W) -> 3;
(1, E) -> 4;
(2, N) -> 1;
(2, S) -> 6;
(2, W) -> 3;
(2, E) -> 4;
...........;
I tak dalej, nie Potrzebujesz zapamiętywać, co się dzieje z pozostałymi ścianami kostki, ważne są zmiany stanów wewnętrznych, w zależności od ruchu; abstrakcja jest zamknieta w klasie i metodach, a Drukujesz co tam trzeba, stany, ruchy...
PS Nie wiem jak jest Twoja kostka, ja mam na biurku normalną, z zestawu do gry w kości wyjąłem:)


AK
Ciekawe ... szkoda o tej porze nie funkcjonuję dostatecznie sprawnie ...
MI
  • Rejestracja:około 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:58
0

Czy ktoś z Was jest w stanie mi pomóc z tym mechanizmem do wprowadzania i wświetlania wyniku ? Męczę się już na róźne sposoby ale nie przynosi to żadnego efektu

AK
Co złego masz do << od @jvoytech ?
MI
A czy ja powiedziałem że mam coś złego ? Grzecznie zapytałem czy jest ktoś w stanie mi pomóc nie z obracaniem kostki lecz z wynikami, to znaczy na wejscie podam N N E E N i żeby mi to jakoś wypisało watość top z kostki po tych obrotach
JV
trzeba dodać gettera do klasy int getTop() { return top; } i wywołać po wszystkich rzutach
MI
Coś nie działa, jakaś wskazówka ?
JV
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 miesiące
  • Postów:242
0

@mikko: "coś nie działa" nie wiele mi mówi. U mnie działa:

Kopiuj
#include <iostream>

class Kostka {
  private:
    int top{1};
    int north{2};
    int west{3};
    int east{4};
    int south{5};
    int bottom{6};

  public:
    void rzut(char x) {
        int tmp;
        if (x == 'S') {
            tmp    = top;
            top    = north;
            north  = bottom;
            bottom = south;
            south  = tmp;
        }
    }

    int getTop() { return top; }
};

int main() {
    Kostka kostka;
    kostka.rzut('S');
    kostka.rzut('S');
    std::cout << kostka.getTop() << std::endl;
    return 0;
}
edytowany 1x, ostatnio: jvoytech
Zobacz pozostały 1 komentarz
JV
jaki tam Pan, zwykły cham jestem. Zdajesz sobie sprawę, że ten program potrafi tylko obracać w kierunku S, resztę trzeba dopisać, mi się już nie chciało
MI
Nie jestem złośliwy, jeśli mamy kostkę z 1 u góry i obrócimy w raz w kierunku dowolnym6 nam nie wypadnie, a w tym konkretnym przypadku powinna wypaść 2
JV
usuń jeden rzut w kierunku S (linia 29) i będziesz miał 2, czyli prawidłowo. Inne kierunki program nie obsługuje bo je musisz sobie zaimplementować
MI
Boże, naprawdę już nie myślę, dodałem resztę implementacji i faktycznie jest okej
JV
super, ale może jakieś przerwy by wypadało robić :), tak co 20 min w stylu pomodoro?
MA
  • Rejestracja:około 5 lat
  • Ostatnio:prawie 2 lata
  • Postów:134
0

Działająca (prawdopodobnie poprawnie), klasa kostki. Takie coś podobnego, jak pisał @AnyKtokolwiek

Kopiuj
class Dice{
public:
    enum Pos{W=0,N,E,S,T,B};
    Dice(){position = Pos::T;}
    void rotate(Pos p){
        switch(p){
            case W: case E: case S: case N:
                position = dice.at(position)[static_cast<int>(p)];
                break;
            case B: case T:
                break;
        }
    }
    Pos getPos(){return position;}
private:
// N
//WTE
// S 
// B
//map -> vector = west(0),north(1),east(2),south(3) - for rotate
    const map<Pos,vector<Pos>> dice = {
        {T,{W,N,E,S}},
        {W,{B,N,T,S}},
        {N,{W,B,E,T}},
        {E,{T,N,B,S}},
        {S,{W,T,E,B}},
        {B,{W,S,E,N}},
    };
    Pos position;
};

MI
  • Rejestracja:około 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:58
0

Chyba już naprawdę jestem zmęczony, robię nawet identycznie jak u mnie i nie działa to w żaden sposób, a jak zrobić aby rzuty były sterowane literami od nazw ? jak to getlinem odczytać i wprowadzić do programu

JV
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 miesiące
  • Postów:242
0

po co ci getline, zwykły operator >> wystarczy:

Kopiuj
    char c;
    while (std::cin >> c) {
        if (c != 'N' && c != 'S' && c != 'W' && c != 'E') {
            break;
        }
        kostka.rzut(c);
    }
    std::cout << kostka.getTop() << std::endl;

wejście można podać w dwojaki sposób:

Kopiuj
c:\> echo "SS" | ./kostka.exe
6
c:\> ./kostka.exe < kierunki.txt
6

jak chcesz interaktywnie to trzeba do kodu dodać znaki zachęty i potwierdzenia oraz wypadałoby tak zrobić, żeby program nie reagował na wielkość liter

edytowany 1x, ostatnio: jvoytech
MI
Niestety musi być interaktywnie, ale bez udziwnień, program się włącza użytkownik wpisuje N W E W E N i program musi tylko wypisać co się znalazło na górze kostki, wydawało mi się, że najlepiej zrobić to za pomocą getline, ale możliwe że jestem w błędzie litery na 100% będą wprowadzane tylko duże
JV
w takie razie getline będzie ok. Przed kodem, który napisałem dodaj jakąś linię zachęty, wczytaj do stringa, zrób z niego stringstreama i jego daj w warunku while zamiast std::cin.
MI
udało się wszystko działa, bardzo dziękuję za pomoc

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.