tablice w cgi

0

Program cgi w jezyku c udajacy kostke rubika. Problem nie jest przesadnie zlozony, ale mam z nim pewnien klopot.
Zabawa - w moim wykonaniu - polega na tym, ze dysponuje 6 tablicami typu char, ktore przechowuja literki odpowiadajace poszczegolnym kolorom (g-green,y-yellow, itd), literki te pozwalaja mi 'sterowac' 36 gifami, ktore odpowiednio ustawione, wygladaja na calkiem ladna kostke.
mam tez forme, w ktorej wybieram pole (tj konkretny 'kwadracik' kostki - na razie z jednej sciany), oraz kierunek przesuniecia (gora,dol,lewo,prawo).
dane wybrane z formy pozwalaja mi wywolac jedna z 12 funkcji do przesuwania.
wszystkie te funkcje dzialaja podobnie - 1. kopiuja interesujace nas trojki pol z okreslonych tablic wyjsciowych do 4 tablic tymczasowych; 2. podmieniaja to co ma zostac podmienione; 3 jesli trzeba to 'transponuja' scianke, ktora tego wymaga.
rozwiazanie, jak sadze, malo optymalne i blyskotliwe, ale potencjalnie dzialajace - sprawdzilam piszac program - nie cgi -
przy okazji cgi wlasnie - zaczynaja sie problemy:

  • kostka istnieje, forma pobiera dane
    ALE
  • funkcje przesuwajace dzialaja, ale nie wspoldzialaja - tj kazde kolejne wywolanie operuje na kostce, ktorej pola sa ulozone tak, jak na samym poczatku (wartosci poczatkowe dla zadeklarowanych tablic)

dlaczego moje cgi nie potrafi zapamietac, ze elementy w tablicach zostaly inaczej ulozone?

zamieszczam okrojony, chodz nadal obszerny fragment kodu:

#include <stdio.h>
#include <stdlib.h>
extern char **environ;
void gora1(char lewap[3][3], char prawat[3][3], char dol[3][3], char gora[3][3], char lewat[3][3]); 
void dol1(char lewap[3][3], char prawat[3][3], char dol[3][3], char gora[3][3], char lewat[3][3]); 
void prawo1(char lewap[3][3],char prawap[3][3],char gora[3][3],char lewat[3][3],char prawat[3][3]);
void lewo1(char lewap[3][3],char prawap[3][3],char gora[3][3],char lewat[3][3],char prawat[3][3]);
void wypisz_strone (char lewap[3][3],char prawap[3][3],char dol[3][3],char gora[3][3],char lewat[3][3],char prawat[3][3]);

int main (int argc, char **argv, char **envp)
{
    char lewap[3][3]={
      'R','R','R',
      'R','R','R',
      'R','R','R'
      };
    char prawap[3][3]={
      'G','G','G',
      'G','G','G',
      'G','G','G'
      };
    char gora[3][3]={
      'B','B','B',
      'B','B','B',
      'B','B','B'
      };
    char dol[3][3]={
      'U','U','U',
      'U','U','U',
      'U','U','U'
      };
    char lewat[3][3]={
      'Y','Y','Y',
      'Y','Y','Y',
      'Y','Y','Y'
      };
    char prawat[3][3]={
      'O','O','O',
      'O','O','O',
      'O','O','O'
      };
    wypisz_strone(lewap,prawap,dol,gora,lewat,prawat);
    return 0;
}
   
void wypisz_strone (char lewap[3][3],char prawap[3][3],char dol[3][3],char gora[3][3],char lewat[3][3],char prawat[3][3]) 
{
 char *form_data;        
 
 int i, j, k;
 int strzalka=0;
 int pole=0;

 
 form_data=NULL;
 
 form_data = getenv ("QUERY_STRING");
  if (NULL != form_data) {
    if (2 == sscanf (form_data, "strzalka=%d&pole=%d", &strzalka, &pole));
    }

  if ((strzalka ==1) && ((pole==1) || (pole==4) || (pole==7)))
     gora1(lewap,prawat,dol,gora,lewat);
  
 if ((strzalka ==2) && ((pole==1) || (pole==4) || (pole==7)))
     dol1(lewap,prawat,dol,gora,lewat);

 if ((strzalka ==3) && ((pole==1) || (pole==2) || (pole==3)))
     prawo1(lewap,prawap,gora,lewat,prawat);
    
  if ((strzalka ==4) && ((pole==1) || (pole==2) || (pole==3)))
     lewo1(lewap,prawap,gora,lewat,prawat);
                                      
printf ("Content-type: text/html\n\n");
printf ("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"pl-PL\" lang=\"pl-PL\">\n");
printf ("<head><title>kosteczka</title>\n");
printf ("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\" />\n"); 
printf ("<link rel=\"stylesheet\" media=\"all\" type=\"text/css\" href=\"styl.css\" />\n"); 
printf ("</head><body><h1> przepiekna kosteczka </h1>\n"); 
printf ("<div class=\"gora\">\n"); 
k=1;
for(i=0;i<3;i++){
         for(j=0;j<3;j++) {
            printf ("<img id=\"gora%d\" src=\"D%c.gif\" alt=\"kostka\"  />\n",k,gora[i][j]);
            k++;
            }
}
printf ("<div class=\"lewa\">\n");
k=1;
for(i=0;i<3;i++){
         for(j=0;j<3;j++) {
            printf ("<img id=\"lewap%d\" src=\"L%c.gif\" alt=\"kostka\"  />\n",k,lewap[i][j]);
            k++;
            }
}

printf ("</div>\n");
printf ("<div class=\"prawa\">\n");
k=1;
for(i=0;i<3;i++){
         for(j=0;j<3;j++) {
            printf ("<img id=\"prawap%d\" src=\"R%c.gif\" alt=\"kostka\"  />\n",k,prawap[i][j]);
            k++;
            }
}
printf ("</div>\n");
printf ("<div class=\"dol\">\n");
k=1;
for(i=0;i<3;i++){
         for(j=0;j<3;j++) {
            printf ("<img id=\"dol%d\" src=\"D%c.gif\" alt=\"kostka\"  />\n",k,dol[i][j]);
            k++;
            }
}
printf ("</div>\n");
printf ("<div class=\"tyll\">\n");
k=1;
for(i=0;i<3;i++){
         for(j=0;j<3;j++) {
            printf ("<img id=\"lewat%d\" src=\"R%c.gif\" alt=\"kostka\"  />\n",k,lewat[i][j]);
            k++;
            }
}
printf ("</div>\n");
printf ("<div class=\"tylr\">\n");
k=1;
for(i=0;i<3;i++){
         for(j=0;j<3;j++) {
            printf ("<img id=\"prawat%d\" src=\"L%c.gif\" alt=\"kostka\"  />\n",k,prawat[i][j]);
            k++;
            }
}
printf ("<div/>\n");
printf ("</div>\n");
printf ("<div class=\"forma\">\n");
printf ("<form method=\"get\" action=\"kosteczka.cgi\">\n");
printf ("<p> <input type=\"radio\" name=\"strzalka\" value=\"1\" /> gora\n");
printf ("<input type=\"radio\" name=\"strzalka\" value=\"2\" /> dol\n");
printf ("<input type=\"radio\" name=\"strzalka\" value=\"3\" /> prawo\n");
printf ("<input type=\"radio\" name=\"strzalka\" value=\"4\" /> lewo </p>\n");
printf ("<p> ktore pole chcesz przesunac? <input type=\"text\" name=\"pole\" value=\"\" maxlength=\"1\" />\n"); 
printf("</p>\n"); 
printf ("<p> <input type=\"submit\" name=\"potwierdz\" value=\"potwierdz\" /></p></form>\n");
printf ("<form method=\"get\" action=\"kosteczka.cgi\">\n");
printf ("<p> <input type=\"submit\" name=\"pomieszaj\" value=\"pomieszaj\" /> </p>\n");
printf ("<p> <input type=\"submit\" name=\"nowa\" value=\"nowa\" /> </p></form></div>\n");
printf ("<div> pola, ktore mozesz przesuwac znajduja sie po lewej stronie \"czola\" kostki, ponumerowane sa od 1 do 9 </div>");

if (NULL != form_data) {
  printf ("<p>\n");
  printf ("form_data: %s\n", form_data);
  printf ("</p>\n");
  printf("<p>\n");
  printf ("strzalka: %d\n", strzalka);
  printf ("</p>\n");
  printf("<p>\n");
  printf ("pole: %d\n", pole);
  printf ("</p>\n");
  
   }
printf ("</body></html>\n");
}

void gora1(char lewap[3][3], char prawat[3][3], char dol[3][3], char gora[3][3], char lewat[3][3]) 
{  char tymcz1[3],tymcz2[3],tymcz3[3],tymcz4[3]; 
   char transp[3][3];
   int i,j; 
   
               for(i=0; i<3; i++) 
                        tymcz1[i]=lewap[i][0];
               for(i=0; i<3; i++) 
                        tymcz2[i]=dol[0][i];
               for(i=0; i<3; i++) 
                        tymcz3[i]=prawat[i][0];                       
               for(i=0; i<3; i++) 
                        tymcz4[i]=gora[0][i]; 
                        
               for(i=0; i<3; i++) 
                        for(j=2;j>=0;j--)
                        lewap[i][0]=tymcz2[j];
               for(i=0; i<3; i++) 
                        dol[0][i]=tymcz3[i];
               for(i=0; i<3; i++) 
                        for(j=2;j>=0;j--)
                        prawat[i][0]=tymcz4[j];
              for(i=0; i<3; i++) 
                        gora[0][i]=tymcz1[i];
              
              for(i=0; i<3; i++)
                       for(j=0; j<3; j++)
                                transp[i][j]=lewat[i][j];
              
              lewat[0][0]=transp[2][0];
              lewat[0][1]=transp[1][0];
              lewat[0][2]=transp[0][0];
              lewat[1][0]=transp[2][1];
              lewat[1][1]=transp[1][1];
              lewat[1][2]=transp[0][1];
              lewat[2][0]=transp[2][2];
              lewat[2][1]=transp[1][2];
              lewat[2][2]=transp[0][2];                            
             
              }     
0

zaloze sie ze przekazujesz owa kostke do tych funkcji przez wartosc a nie wskaznik/referencje

0

Wynikiem mojej walki z zasugerowanymi wczesniej (niezwykle trafnie) wskaznikami, jest dzialajacy program w czystym ansi c pod konsola. Niestety w przypadku cgi program zachowuje sie bez zmian. Przesuniecie pol kazdorazowo odbywa sie na kostce, bedacej w stanie wejsciowym.

program, ktory napisalam:

#include <stdio.h>
#include <stdlib.h>

void gora1(char tab1[][3], char tab2[][3], char tab3[][3], char tab4[][3], char tab5[][3]);

int main (int argc, char **argv, char **envp)
{
    char lewap[3][3]={
      'R','R','R',
      'R','R','R',
      'R','R','R'
      };
    char prawap[3][3]={
      'G','G','G',
      'G','G','G',
      'G','G','G'
      };
    char gora[3][3]={
      'B','B','B',
      'B','B','B',
      'B','B','B'
      };
    char dol[3][3]={
      'U','U','U',
      'U','U','U',
      'U','U','U'
      };
    char lewat[3][3]={
      'Y','Y','Y',
      'Y','Y','Y',
      'Y','Y','Y'
      };
    char prawat[3][3]={
      'O','O','O',
      'O','O','O',
      'O','O','O'
      };
 int i,j; 
 int k, d;
 int strzalka=0;
 int pole=0, pom=0;
 
 
 for(d=0; d<3; d++) {
 printf("podaj pole ktore chcesz rzesunac (1,4,7)");
 scanf("%d",&pole);
 printf("\npodaj kierunek (1))"); 
 scanf("%d", &strzalka);
 
  if ((strzalka ==1) && ((pole==1) || (pole==4) || (pole==7)))
     gora1(lewap,prawat,dol,gora,lewat);
                                
 for(i=0; i<3; i++)
          for(j=0; j<3; j++) {
          printf("\n %d %d element tablicy lewap  to: %c", i, j, lewap[i][j]); 
          }
 for(i=0; i<3; i++)
          for(j=0; j<3; j++) {
          printf("\n %d %d element tablicy prawap  to:%c", i, j, prawap[i][j]); 
          }
 for(i=0; i<3; i++)
          for(j=0; j<3; j++) {
          printf("\n %d %d element tablicy gora  to:%c", i, j, gora[i][j]); 
          }
 for(i=0; i<3; i++)
          for(j=0; j<3; j++) {
          printf("\n %d %d element tablicy dol  to:%c", i, j, dol[i][j]); 
          }
 for(i=0; i<3; i++)
          for(j=0; j<3; j++) {
          printf("\n %d %d element tablicy lewat  to:%c", i, j, lewat[i][j]); 
          }
 for(i=0; i<3; i++)
          for(j=0; j<3; j++) {
          printf("\n %d %d element tablicy prawat  to:%c", i, j, prawat[i][j]); 
          }     
 }    
                           
    system("pause");
    return 0;
}
    
    
void gora1(char tab1[][3], char tab2[][3], char tab3[][3], char tab4[][3], char tab5[][3])
{  char tymcz1[3],tymcz2[3],tymcz3[3],tymcz4[3]; 
   char transp[3][3];
   int i,j; 
                    
               for(i=0; i<3; i++) 
                        tymcz1[i]=tab1[i][0];//*(tab1+(i*3)+0);
               for(i=0; i<3; i++) 
                        tymcz2[i]=tab3[0][i];//*(tab3+(0*3)+i);
               for(i=0; i<3; i++) 
                        tymcz3[i]=tab2[i][0];//*(tab2+(i*3)+0);                       
               for(i=0; i<3; i++) 
                        tymcz4[i]=tab4[0][i];//*(tab4+(0*3)+i); 
                        
               for(i=0; i<3; i++) 
                        for(j=2;j>=0;j--)
                        tab1[i][0]=tymcz2[j];
               for(i=0; i<3; i++) 
                        tab3[0][i]=tymcz3[i];
               for(i=0; i<3; i++) 
                        for(j=2;j>=0;j--)
                        tab2[i][0]=tymcz4[j];
              for(i=0; i<3; i++) 
                        tab4[0][i]=tymcz1[i];
              
              for(i=0; i<3; i++)
                       for(j=0; j<3; j++) 
                                transp[i][j]=tab5[i][j];//*(tab5+(i*3)+j);
              
              tab5[0][0]=transp[2][0];
              tab5[0][1]=transp[1][0];
              tab5[0][2]=transp[0][0];
              tab5[1][0]=transp[2][1];
              tab5[1][1]=transp[1][1];
              tab5[1][2]=transp[0][1];
              tab5[2][0]=transp[2][2];
              tab5[2][1]=transp[1][2];
              tab5[2][2]=transp[0][2];                           
             // wypisz_strone();
              } 
0

tym razem Ci pewnie nie pomoge.. ale skoro program w ansiC pod konsola dziala poprawnie, to ten kod jesli zostanie uzyty w binarce odpowiedzialnej za przetwarzanie cgi, to tez sila rzeczy musi dzialac poprawnie.. ostatecznie C to C i kod ten sam.. tak wiec w kodzie tworzacym "wersje dla cgi" musisz miec jeszcze jakis calkowicie inny problem.. albo moze podczas kompilacji wersji cgi np. akurat plik .o z tym kodem sie nie odswiezyl?

0

Dbam o to, zeby wszystko ladnie odswiezac, wiec nie w tym problem. Tak czy inaczej, dziekuje za przypomnienie _

To cgi jest podejrzane. Tak jak pisalam wczesniej, zmienne sa pobierane z formularza i zapisywane tam, gdzie ich potrzebuje, ale program jakby nie zawsze potrafi z nich korzystac.

Na chwile zrezygnowalam z funkcji i wrzucilam te operacje, w nich zawarte, do maina - o zgrozo dzialo sie dokladnie to samo, co wczesniej. koszmar.

0

rzeklbym - niesamowite.. moje doswiadczenia z podobnymi 'cudami-niewidami' podpowiadaja ze to musi byc cos trywialnego na co w ogole nie zwracasz uwagi, bo to takie proste.. ale trudno mi zgadnac co:|

0

zasugerowano mi wlasnie, ze brakuje mi tam jasnej informacji o stanie, w jakim kostka sie znajduje.
takiej kostki ukrytej, ktora bylaby przekazywana z formy do cgi, za kazdym razem..
bo inaczej program zawsze bedzie startowal z ustawienia poczatkowego.
teraz musze sie zastanowic jak toto zrobic

0

o wlasnie.. to jest jeden z owych banalow:) problem stanu to podstawowa sprawa przy aplikacjach webowych.. odpowiedz: sesja i klucz sesji, albo wyryc stan w formularzu za pomoca <input type="hidden">

0

czy mozesz mi zasugerowac, gdzie znajde wiecej informacji o "wyryciu" stanu formularza przy pomocy inputa? nie wiedzialam, ze cos takiego da sie zrobic - tym bardziej nie wiem jak.

0

jak przygotowyjesz sobei stringa z tekstem html ktory poleci do klienta, to m.in. skaldasz formularz ktory potem do Ciebie bedzie odeslany. na tym formularzu mozesz umiescic:

<input name="nazwa_np_state" type="hidden" value="wartosc">

klient tego nie zobaczy jako pole do wprowadzenia i nie bedzie mogl tego zmienic ani wprowadzic. to pole ma na sztywno przypisana wartosci. przy wyslaniu formularza zostanie ono potraktowane jak wprowadzone o dokladnie tej wartosci i wyslane do Ciebie. efekt: do Ciebie zostaje odeslane cos, co Ty wygenerowalas. a wiec mozna np. wyryc we ten sposob aktualny stan kostki, a potem go otrzymac z powrotem, odcyfrowac go, wykonac operacje, wyryc nowy stan itd

np. stan poczatkowy moglabys zakodowac w value sobie tak:

<input name="nazwa_np_state" type="hidden" value="RRR/RRR/RRR:GGG/GGG/GGG:BBB/BBB/BBB:....">
0

Jutro to przegryze i, przede wszystkim, zastosuje.
Bardzo dziekuje za niezwykle klarowne wyjasnienia.

0

Jeśli chcesz uniknąć cheaterów, to użyj raczej sesji. Jeśli to klient wysyła stan kostki, to gwarantuję Ci, że wielu uda się ułożyć kostkę w pierwszym ruchu ;-)

0

teraz odpowiem sobie sama -> search the friendly web ;>

0

:) comment 'zlego czlowieka' jest bardzo trafny, nie chcialem jednak komplikowac zbytnio sprawy i przedstawic najprostsze rozwiazanie

0

na tym etapie w zupelnosci wystarczy mi rozwiazanie najprostsze. jak sie jednak przekonalam, nawet to najprostsze, przy braku doswiadczenia (o innych brakach nie wspominajac), moze sprawiac problemy.
Na razie probuje przekonac moj program do tego, aby z form_data pobral odpowiedniej dlugosci stringa, ktory powinien znalezc sie w zmiennej stan. koszmar -> cokolwiek zrobie, skutkuje to wspanialym errorem nr 500.

stan jest 55 elementowa tablica charow, ktora wypelniam literkami. i na jej podstawie wypisuje kostke.
proby zmiany zawartosci zmiennej stan, przez funkcje przesuwajace pola konczyly sie fiaskiem.

slowem - katastrofa.
mimo wszystki, licze na dalsze wskazowki.

0

error500 sugeruje ze Twoj program wywala sie krytycznym bledem, np. ochrona pamieci, nullpointer, zapis za tablica i zniszzcenie ramki funkcji itp..

majac odczytane dane nadeslane z formularza, odczytanie 55 znakow spod konkrenej pozycji nie powinno byc specjalnie skomplikowane.. jestes pewna ze poprawnie ow stan jest zapisany na formularzu i ze popranie probujesz skopiowac te 55 charow z powrotem do Twojej zmiennej?

0

udalo mi sie uporac z przechowywaniem/przechwytywaniem stanu. juz mozna troszke sie kostka pobawic.

ale jak to zwykle bywa - po rozwiazaniu jednego problemu, zaraz pojawil sie kolejny.

void pomieszaj(char stan[55]) 
{
   int a,b,i,t; 
   
   for(i=0; i<162; i++) {
            a=rand()%53;
            b=rand()%53;
            t=stan[a];
            stan[a]=stan[b];
            stan[b]=t;
            }
 
}

to jest uproszczona funkjca tasujaca kostke. dziala...z tym, ze za kazdym razem tak samo!
czy jest jakis powod, przez ktory rand()%53 zawsze mialby losowac dokladnie te same liczby?

druga wersja funkcji tasujacej, jest taka:

void pomieszaj(char stan[55]) 
{
   int fkcja, ind, i; 
   
   for(i=0; i<20; i++){
            fkcja=rand()%4;
            ind=rand()%3;
            
            if ((fkcja==0) && (ind == 0))  gora1(stan);
            if ((fkcja==0) && (ind == 1))  gora2(stan);
            if ((fkcja==0) && (ind == 2))  gora3(stan);
            
            if ((fkcja==1) && (ind == 0))  dol1(stan);
            if ((fkcja==1) && (ind == 1))  dol2(stan);
            if ((fkcja==1) && (ind == 2))  dol3(stan);
            
            if ((fkcja==2) && (ind == 0))  prawo1(stan);
            if ((fkcja==2) && (ind == 1))  prawo2(stan);
            
            if ((fkcja==3) && (ind == 0))  lewo1(stan);
            if ((fkcja==3) && (ind == 1))  lewo2(stan);
            if ((fkcja==3) && (ind == 2))  lewo3(stan);
     }
 
}

funkcja ta, teoretycznie uwzglednia, ze kostke mozna ulozyc tylko wowczas, gdy jest ona poprawnie potasowana -> nie kazda permutacje da sie ulozyc. klopot jest taki, ze za kazdym razem dziala tak samo, i do tego oszukuje kolorki(tj. nagle okazuje sie, ze jednych jest wiecej niz innych).

Prosze o wszelkie sugestie.

0

z oszukiwaniem kolorków nie pomogę, ale z rand tak. owszem, "jest jakis powod, przez ktory rand()%53 zawsze mialby losowac dokladnie te same liczby" - musisz zainicjalizować generator losowy podczas startu programu jakąś zmienną wartością. Np pobierając bieżący czas:

srand(time(0));

(funkcja time jest w "time.h" / "ctime")

0

ciekawe. bardzo, bardzo ciekawe. powalcze z tym.

uklad sie zmienia, ale paskuda dalej oszukuje w kolorkach.

mimo wszystko - jestem wdzieczna za pomoc.

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