Borland C++ 4.0 Builderben: TETRIS GAME írás problémák
2003-09-25T18:51:41+02:00
2008-06-16T19:46:15+02:00
2022-07-01T05:46:25+02:00
  • Kedvet kaptam:)
    Mutasd a teljes hozzászólást!
  • ércsük
    Mutasd a teljes hozzászólást!
  • Hali!

    Egy kicsit megvédeném Petty-kp-t.

    1. Ennek itt tényleg semmi köze az OOP-hez, de - mint Petty-kp is említette - elbeszélgettünk ICQ-n, és onnan vontam le a következtetést. Sőt, azt is említettem, hogy nem olyan nagy baj ez, csak utána kell nézni (azaz, tényleg nem ártana egy C-s könyvet átolvasni, átrágni).

    2. Azért tanácsoltam Petty-kp-nek, hogy egy string-vektorba rakja bele először az alakzatok "alakjait" sorfolytonosan, mert így egyszerűbb a tényleges feltöltést a mátrixba elvégezni, ráadásul, egy esetleges későbbi bővítés szempontjából sem utolsó, ha - teszem azt - egy txt-fájlból kell beolvasni az új alakzatokat.
    Itt válaszolnék is egyből a kérdéseidre (nem Petty-kp helyett):
    Nem 3 elemű az alakzatstring tömb, csak - szerintem - Petty-kp ennyit másolt ide be.
    Azért 100 karakterből áll az alakzatstring tömb egy eleme, mert az alakzatok 5x5-ös mátrixban tárolódnak, és az alakzatstring egy eleme az alakzat mind a négy "forgatott" változatát tartalmazza: 5x5x4=100.
    Az i%5 valószínűleg az én hibám, rossz tanácsot adtam Petty-kp-nek.
    A kötözködésre csak annyit, hogy tényleg a hangsúly a _szokás_-on van.

    3. Én nagyon régen programoztam C-ben, akkor is csak azért mert kötelező volt. A forrás-részleteket Pascal-ban (Delphi-ben) adtam Petty-kp-nek. Nálam így nézett ki a feltöltés:
    const Alakzat: Array [0..6] of String = //Az alakzatokat tárolja string-ben ('0000000100001000011000000000000000001110010000000000000011000010000100000000000000010011100000000000', //L-alak (jobb irányú) '0000000100001000110000000000000100001110000000000000000001100010000100000000000000000011100001000000', //L-alak (bal irányú) '0000000110001100000000000000000000000110001100000000000000000110001100000000000001100011000000000000', //Négyzet-alak '0000001110001000000000000000000001000110000100000000000000000010001110000000000001000011000100000000', //T-alak '0000001100001100000000000000000001000110001000000000000000000110000110000000000000100011000100000000', //Z-alak '0000000110011000000000000000000010000110000100000000000000000011001100000000000001000011000010000000', //S-alak (inverz Z-alak) '0010000100001000010000000000000000001111000000000000000001000010000100001000000000000111100000000000'); //Egyenes ... for i:=0 to 27 do for j:=0 to 4 do for k:=0 to 4 do if Alakzat[i div 4,(i mod 4)*25+j*5+k+1]='0' then Alakzatok[i,j,k]:=0 else Alakzatok[i,j,k]:=1;

    De igazad van, tényleg lehet egyszerűsíteni rajta:
    for i:=0 to 27 do for j:=0 to 4 do for k:=0 to 4 do Alakzatok[i,j,k]:=Ord(Alakzat[i div 4,(i mod 4)*25+j*5+k+1])-Ord('0');
    Mutasd a teljes hozzászólást!
  • Jaj, összezavartok teljesen, mert szemantikailag itt-ott zagyvaság, amit én írtam az "garbage in = garbage out" úgyhogy inkább kérdezek; de ne nekem, hanem magadnak válaszold meg őket:

    miért 3 elemű az alakzatstring tömb?
    miért 100 karakterből áll az alakzatstring tömb egy eleme?
    mit akar jelenteni az az i%5?
    kötözködés: hogy _szokták_ indentálni a C kódot?
    Mutasd a teljes hozzászólást!
  • Sőt, ez teljesen rossz, Pongor Mester forog a sírjában! C-ben 0-val kezdjük az indexelést!

    Ugyanez helyesen:
    alakzatstring[0]="000000010000100001100000000000000000 111001000000000000001100001000010000000000000001001110000000 0000"; alakzatstring[1]="000000010000100011000000000000010000 111000000000000000000110001000010000000000000000001110000100 0000"; alakzatstring[2]="000000000000110011000000000000001000 011000010000000000000000001100110000000000000010000110000100 0000"; for (int i = 0; i < 28; i++) { for (int j = 0; j < 5; j++) { for (int k = 0; k < 5; k++) { alakzatok[i][j][k] = alakzatstring[i % 3][j * 5 + k] - '0'; } } }

    Jó tanács: vegyél elő egy C könyvet is, de azt is találsz neten elég sokat!
    Mutasd a teljes hozzászólást!
  • ja, és ennek itt semmi köze az OOP-hez...
    Mutasd a teljes hozzászólást!
  • Asszem ezzel csak tömör alakzatokat fogsz kapni...

    if (alakzatstring[i%5+1][(j-1)*5+k]==0)
    helyett ez kell:
    if (alakzatstring[i%5+1][(j-1)*5+k]=='0')

    de egyszerűbb, ha ehelyett azt írod, hogy:
    alakzatok[i][j][k] = alakzatstring[i%5+1][(j-1)*5+k] - '0';

    Mutasd a teljes hozzászólást!
  • Sziasztok!

    netangellel beszélgetttem icq-n, kaptam tőle sok jó tanácsot, mint tőletek is. Sajnos egy súlyosnak nevezhető hiányoság merült fel, ami nem más mint az OOP tudásának hiánya nálam.

    ő is irt egy megoldást az alakzatokra, melyet most megosztok veletek:


    char* alakzatstring[3]; int alakzatok [28][5][5]; alakzatstring[1]="0000000100001000011000000000000000001110010000000000000011000010000100000000000000010011100000000000"; alakzatstring[2]="0000000100001000110000000000000100001110000000000000000001100010000100000000000000000011100001000000"; alakzatstring[3]="0000000000001100110000000000000010000110000100000000000000000011001100000000000000100001100001000000"; for (int i=1;i<29;i++) { for (int j=1;j<6;j++) { for (int k=1;k<6;k++) { if (alakzatstring[i%5+1][(j-1)*5+k]==0) { alakzatok[i][j][k]=0; } else { alakzatok[i][j][k]=1; } } } } }


    Mint fentebb irtam, az OOP ismeretének hiánya miatt, nem tudom rendesen összekapcsolni a rutinokat, melyek az egyes feladatok elvégzéséért felelősek.
    azthiszem fogok én még sokat szenvedni ezzel a tetrissel mire működőképes játék lesz belőle. egy a bibi ezzel, 10. hó 30.ra már használható, de nem kötelezően teljes változatig el kell vele jutnom. a végső változat elkészítésének határidejét január 05.re tüzték ki.

    Bárminemű hozzászolást, segíteséget nagyon nagy örömmel fogadok.

    Elöre is köszönet: Peti

    petty-kp@freemail.hu
    Mutasd a teljes hozzászólást!
  • Üdv,

    Tényleg bugos egy kicsit, le is fagyott XP alatt amikor játszani akartam vele (mondjuk lehet hogy a C builderes kód ne szeret valamit).

    Egyébként szerintem írd be a kódba az elemek mátrixait, az úgyse fog sokat változni (be is lehet tölteni, az csak egy extra, szerintem először írd meg magát a programot, a fájlkezelést meg csak később vedd hozzá).

    A forgatásnál egyébként tényleg csak dimenziót kell váltani (ha ezt érted az x és y irányok felcserélésén), ez talán a tetris legnehezebb része. Ezenkívül csak egy nagy mátrix kell amibe tárolod az elemeket meg egy "gravity" függvény, amit ha ráálítasz egy Windows Timerre (van ilyen TImer komponens asszem már a C Builder 4 ben is), és ami lefelé mozgatja az elemeidet a mátrixban. Aztán már csak a billentyűket kell figyelni és mozgatni meg forgatni az aktuális elemet, és asszem kész is vagy mindennel (figyelni kell még a teljes sorokat is, de az már tényleg egyszerű ha jól csinálod a mátrixot).

    Szerintem a string csak bonyolítaná a dolgot, különösen a forgatás részét (ott ki kéne venni az elemet és az elforgatottat visszatenni).

    Na szóval én így csinálnám, persze ezt még sokféleképpen meg lehetne oldani...
    Mutasd a teljes hozzászólást!
  • A neten tényleg találtam pár kódot, hasztnálhatót sajnos elég keveset.
    amugy ezt a fajta feltöltést is proáltam, sajnos adott körülmények között nálam nem müködött. amugy 3D mátrixot szeretnék ily modon feltölteni Alakzat[5][5][5] őt, és nem müködött.

    Üdv: Peti
    Mutasd a teljes hozzászólást!
  • Mellesleg neten találsz elég sok Tetris forráskódot, lehet belőlük lopni
    Mutasd a teljes hozzászólást!
  • például:

    int matrix[3][5] = { { 1, 2, 3, 4, 5 }, { 8, 9, 7, 6, 0 }, { 11, 14, 16, 22, 87 } };

    Több dimenzióra értelemszerűen...
    Mutasd a teljes hozzászólást!
  • Én iram egy 3D -s Tetriszt.
    De a Transzformációs mátrixot 2D-hez is ajánlom.
    Az adatokat pedig nem mátrixxal hanem 4 koordinátával adnám meg a helyedben.
    Mutasd a teljes hozzászólást!
  • az igaz, hogy irtam, hogy "szabadon" választható, ha viszem a programozói környezetet, de komolyra forditva a szót, mondhatni iratlan szabály, ki nem mondott kötelezetség, Borland C++ Builder 4.0 ában irni a programot. sajnos, az én legnagyobb bánatomra.
    Mutasd a teljes hozzászólást!
  • Amúgy, csak mellékesen, miért nem írod pascalban, ha ahhoz jobban értesz? Sok ingyenes pascal fordító van, így be is viheted a tanárnak a "jogtiszta, eredeti" fejlesztőeszközt.
    Mutasd a teljes hozzászólást!
  • Szia, sziasztok!

    a string-es ötlet elég jónak hangzik.
    bár akkor is érdemes lenne egy fajta alakzat minden állását elöre elkésziteni és ezt igy elemenként egyben tárolni egy stringben és a string-eket pedig egy tömb-ben.
    és ekkor random választom ki az alakzatot, ami egy sorszám lenne, és a tömb adott elemét fognám és tölteném be mint aktuális elem...

    most nézem megint, amit te irtál, az kicsit bonyolult, nem is látom át, hogy azt hogy lehetne könnyen kezelni.
    meg egyszerübb szerintem mind a 4 alakot letárolni, és forgatásnál, csak dimenziót váltani.

    pascalos változat

    az eddig "kész" C++ os változat


    akit érdekel, nézze, meg, és kérem szoljon hozzá. hisz sajnos telis tele van hibákkal.
    a borland C++ 4.0 ás verzióbasn a képek, átmenetiek, ha megnézed, meglátod mire is gondolok ezzel.

    ha áttirnál valamit a programban, akkor kérlek ugy hogy 4.0 kompatibilis maradjon, mert nekem kényszerből azt kell használni, ugyanis a suliban csak az van meg, és ha pl 6 os Builderes progit vinék, azt nem fogadják el.

    Elöre is ksözönök minden segítséget, tanácsot: Peti
    Mutasd a teljes hozzászólást!
  • Hali!

    Esetleg lenne néhány ötletem, remélem valamennyire használható.
    1. Esetleg tárolhatnád az elemeket sztringként is, olyan módon, hogy egy elem egy sora lenne egy sztring. Ezzel megspórolhatnál egy dimenziót, meg - talán - egyszerűbb is kezelni. Tehát, pl. ('L'-alak esetén):
    alakzat[0][0]='1000'; alakzat[0][1]='1000'; alakzat[0][2]='1100'; alakzat[0][3]='0000';
    2. Nem kellene minden fázist tárolni, hiszen a többi fázis csak az "alap"-alakzat elforgatottja. Mivel, a játékos úgyis forgathatja az alakzatot, amit neked le kell programozni. Ha csak amiatt tárolnád az összes fázist, hogy véletlenszerűen tudd kirakni, akkor elég annyi, hogy véletlenszerűen kiválasztasz egy elemet, majd ezt "véletlenszer" elforgatod.

    Egyenlőre ennyi, esetleg kezdetnek jó lehet.
    Mutasd a teljes hozzászólást!
  • és hogy öszinte legyek , ebböl én semmit nem értek, csak használom...

    a fenti részel beovasom egy pszBuffer -be , ezt még értem. és beirja egy StringGrid1-be, de ez igazság szerint nekem nem kell. csak hogy beolvassam valahová, és onnan beletöltsem egy 4X4X4 es mátrix ba egy sor elemeit egyenként, mely sort egy randommal szeretnék kiválasztani. bár amig nem tudom hány soros a fájl, amit nem tudom hogy lehet megnézni, addig elég nehéz random generálni számot az alapján...

    KI tud erre valami használhatót mondani?
    az emlitett tetris.txt tartalma az első irásomban látható.
    bármi véleményt szivessen fogadok, még olyat is ami szerint esetleg teljessen máshogy kellene megoldani a feltöltést.
    Üdvözlettel: Peti
    Mutasd a teljes hozzászólást!
  • most vettem észre, hogy egy részt ki is hagytam, hogy hogya olvasom be a fájl tartalmát. persze ezt is a sugóban találtam.


    // fájlbeolvasás { int betoltott; int iFileLength; int iBytesRead; char *pszBuffer; betoltott = FileOpen("tetris.txt", fmOpenRead); iFileLength = FileSeek(betoltott,0,2); FileSeek(betoltott,0,0); pszBuffer = new char[iFileLength+1]; iBytesRead = FileRead(betoltott, pszBuffer, iFileLength); FileClose(betoltott); for (int i=0;i<iBytesRead;i++) { StringGrid1->RowCount += 1; StringGrid1->Cells[1][i+1] = pszBuffer[i]; StringGrid1->Cells[2][i+1] = IntToStr((int)pszBuffer[i]); } delete [] pszBuffer; } // fájlbeolvasás vége
    Mutasd a teljes hozzászólást!
  • a fájlbol beolvasás nem kötelező.
    sőt, talán job is beégetni a progiba, legalább nem veszhet el a fájl, és akkor arra nem is kell hibakelzelést csinálni.
    leirnád kicsit részletesebben a kódsorodat?
    nekem sajnos már ez is elég összetett.
    már sokféleképp probáltam feltölteni a mátrixokat, de sajna nekem nem sikerült, csak ha egyesével adtam meg neki az értékeket valahogy igy:


    alakzat[ 0 ][ 0 ][ 0 ]= 0 ; alakzat[ 0 ][ 0 ][ 1 ]= 1 ; alakzat[ 0 ][ 0 ][ 2 ]= 0 ; alakzat[ 0 ][ 0 ][ 3 ]= 0 ; alakzat[ 0 ][ 1 ][ 0 ]= 0 ; alakzat[ 0 ][ 1 ][ 1 ]= 1 ; alakzat[ 0 ][ 1 ][ 2 ]= 0 ; alakzat[ 0 ][ 1 ][ 3 ]= 0 ; alakzat[ 0 ][ 2 ][ 0 ]= 0 ; alakzat[ 0 ][ 2 ][ 1 ]= 1 ; alakzat[ 0 ][ 2 ][ 2 ]= 0 ; alakzat[ 0 ][ 2 ][ 3 ]= 0 ; alakzat[ 0 ][ 3 ][ 0 ]= 0 ; alakzat[ 0 ][ 3 ][ 1 ]= 1 ; alakzat[ 0 ][ 3 ][ 2 ]= 0 ; alakzat[ 0 ][ 3 ][ 3 ]= 0 ;

    ez meg 7 alakzatnál elég hosszú lenne, és ez csak egy lakazat egy dimenziója volt.
    azaz 7 alakzatnál: 7 X ( 4 X 4X 4) = 7X64
    aztza elég sok sort tenne ki.
    ezt akarom leegyszerüsiteni.
    meg terveim szerint késöbbb uj alakzatok lennének, vagyis nem csak a standart tetris es alakzatok lennének...

    köszi a segitséget. és örülök minden további hozzászolásnak. kodnak, mindennek.

    Üdvözlettel: Peti
    Mutasd a teljes hozzászólást!
  • És nem lehet beledrótozni a forráskódba valahogy így:

    boxshape->matrix[0] = { 0, 1, /*stb.*/ }; boxshape->matrix[1] = { ... }; // stb. shapes[0] = boxshape; shapes[1] = zshape; shapes[2] = jshape; // stb. currentshape = shapes[random(7)];

    A feladatkiirásban benne van, hogy fájlból kell beolvasni? Mert szvsz ezt a pár alakzatot felesleges.
    Mutasd a teljes hozzászólást!
  • Sziasztok!
    az iskolába szakdoga programot kell irni, sajnos kötelező jeleggel BC++ 4.0 ! Builderben. igaz válassztható más is, ha beviszem a jogttiszta báltozatot, pl a delphit ha abban irnám.
    az iskolában meg a tanár tudatlanságánk köszönhetően, semmit nem tanultunk meg C++ bol, mondhatni a tanár is velünk tanult.

    sok kisebb, nagyobb problémával küzdök, még az alapoknál tart a progi, vagy még ott se? hát szinte sehol. sajnos.

    akkor egy konkrét ptobléma:

    van egy tetris. txt fájl, tartalma az alakzatok mátrixának megfelelöje:

    1000100011000000000011101000000011000100010000000010111000000000
    0200020022000000200022200000000022002000200000000000222000200000
    0000033033000000300033000300000000000330330000003000330003000000
    0000440004400000040044004000000000004400044000000400440040000000
    0000050055500000500055005000000055500500000000000500550005000000
    0000660066000000000066006600000000006600660000000000660066000000
    0000000077770000700070007000700000000000777700007000700070007000

    ahol egy sor, egy alakzat, 3D mátrixos képe, kiteritve. pl az 1-es, az L alak:

    1000
    1000
    1100
    0000

    0000
    1110
    1000
    0000

    1100
    0100
    0100
    0000

    0010
    1110
    0000
    0000

    ezt szeretném beolvasni, random szerint, ugy hogy random lesz egy számom, ami a sor sorszáma, tehát ha 0 (C 0 bázisú) akkor az első sort olvassa be, ha 6 akkor a 7 sort, stb,

    amit már sokféleképp irtam, de sehogy se jó. no meg persze, ott vannak a sorvége jelek is.
    ha sikerülne, én igazábol egybol egy mátrixba szeretném majd betölteni, ugy hogy random választok egy sort, azaz egy alakzatot, és azt a sort betöltöm.

    Randomize(); int szam=random(5); if (szam!=0) { szam=szam*64; } int neznitol=szam; int nezniig=szam+64; int i=1; for (neznitol;nezniig;neznitol++) { StringGrid1->RowCount += 1; StringGrid1->Cells[1][i+1] = pszBuffer[i]; StringGrid1->Cells[2][i+1] = IntToStr((int)pszBuffer[i]); i=i+1; } [] pszBuffer;

    anno pascalban ezt igy oldottam meg:

    procedure kivalaszt;{k"vetkez&#8249; alakzat kiv laszt sa} var beolvasandosor,almafa,sorokszama,i,sor,oszlop,lap:byte; elem,b,poz:integer; a,c:string; f:text; begin sorokszama:=0; assign(f,'Tetris.txt'); {I-} reset(f); {I+} if ioresult<>0 then begin write('Hiba a alakzatf jlal!!!!!'); end; while not Eof(f) do begin ReadLn(f, a); Inc(sorokszama); end; close(f); assign(f,'tetris.txt'); {I-} reset(f); {I+} if ioresult<>0 then begin write('Hiba a alakzatf jlal!!!!!'); end; lap:=1; elem:=1; almafa:=0; randomize; beolvasandosor:=random(sorokszama)+1; repeat begin lap:=1; elem:=1; readln(f,a); for lap:=1 to 4 do for sor:=4 downto 1 do begin for oszlop:=1 to 4 do begin c:=a[elem]; elem:=elem+1; val(c,byte(b),poz); alakzat[lap][sor][oszlop]:=byte(b); end; end; end; almafa:=almafa+1; until beolvasandosor=almafa; close(f); forgatas:=random(4)+1; end;


    valami ilyasmit szeretnék, vagy szebb megoldást, bármit a mi müködik.
    levélben is irhattok, azt sürübben tudom olvasni.

    nullpetty-kp@fremail.hu

    elöre is köszönök minden segítséget.
    majd a többi problémást részt is ide irom majd,

    köszönettel: Kótai Péter
    Mutasd a teljes hozzászólást!
abcd