Kostka do gry c++

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

0

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

0
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;
}
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)

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

0
#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 ?

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.

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ł

#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

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:

#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;
}
  2
3 1 4
  5
  6

  6
3 2 4
  1
  5
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:)

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

0

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

#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;
}
0

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

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;
};

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

0

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

    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:

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

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