Malom játékhoz miylen adatszerkeszet

Címkék
Malom játékhoz miylen adatszerkeszet
2010-05-12T18:13:33+02:00
2016-05-07T13:04:40+02:00
2022-08-10T03:30:28+02:00
Evolution
Üdv,
Eddig egy 3dimenziós tömbben próbálkoztam, a malom játék leprogramozásához. Nos ez nem jött be, mert a malom ellenőrzésére alkotott kód annyira elbonyolódott, hogy már magam sem mentem el benne. Annyiból viszont jó volt, hogy minden más egyszerű maradt: A játékos megadja, hogy hova szeretne lépni: (1-7) (a-g) és egy konzolosan kirajzolt ábráról látja, hogy az hol lesz. Nos ennek a kikeresése pofonegyszerű a 3dimenziós tömbbel, ami így nézett ki:
char tabla[3][3][3];
De amikor eljött az idő, hogy na lássuk van e malom akkor már bejött a probléma. Ezen a ponton mondtam azt, hogy ez így nem lesz jó:
int ellenoriz(char t[SZINT][SOR][OSZLOP], poz utolso, char player_id) { if(utolso.sor == 1 && utolso.oszlop == 0) { if(t[utolso.szint][utolso.sor][1] != UNUSED && t[utolso.szint][utolso.sor][2] != UNUSED) { if(t[0][1][0] == t[1][1][0] && t[1][1][0] == t[2][1][0]) { return TRUE; } return FALSE; } else if(t[utolso.szint][0][utolso.oszlop] != UNUSED && t[utolso.szint][2][utolso.oszlop] != UNUSED) } else if(utolso.sor == 1 && utolso.oszlop == 2) { if(t[0][1][2] != UNUSED && t[1][1][2] != UNUSED && t[2][1][2] != UNUSED) { if(t[0][1][2] == t[1][1][2] && t[1][1][2] == t[2][1][2]) { return TRUE; } else { return FALSE; } } else { return FALSE; } } else if(utolso.oszlop == 1 && utolso.sor == 0) { if(t[0][0][1] != UNUSED && t[1][0][1] != UNUSED && t[2][0][1] != UNUSED) { if(t[0][0][1] == t[1][0][1] && t[1][0][1] == t[2][0][1]) { return TRUE; } else { return FALSE; } } else { return FALSE; } } else if(utolso.oszlop == 1 && utolso.sor == 2) { if(t[0][2][1] != UNUSED && t[1][2][1] != UNUSED && t[2][2][1] != UNUSED) { if(t[0][2][1] == t[1][0][1] && t[1][2][1] == t[2][2][1]) { return TRUE; } else { return FALSE; } } else { return FALSE; } } if(utolso.sor == 1 || utolso.oszlop == 1) { return FALSE; } else { if(t[utolso.szint][utolso.sor][0] != UNUSED && t[utolso.szint][utolso.sor][1] != UNUSED && t[utolso.szint][utolso.sor][2] != UNUSED) { if(t[utolso.szint][utolso.sor][0] == t[utolso.szint][utolso.sor][1] && t[utolso.szint][utolso.sor][1] == t[utolso.szint][utolso.sor][2]) { return TRUE; } else { return FALSE; } } else if(t[utolso.szint][0][utolso.oszlop] != UNUSED && t[utolso.szint][1][utolso.oszlop] != UNUSED && t[utolso.szint][2][utolso.oszlop] != UNUSED) { if(t[utolso.szint][0][utolso.oszlop] == t[utolso.szint][1][utolso.oszlop] && t[utolso.szint][1][utolso.oszlop] == t[utolso.szint][2][utolso.oszlop]) { return TRUE; } else { return FALSE; } } else { return FALSE; } } return FALSE; }
Szóval valami javaslatot szeretnék kérni erre a célra, mert már nem látom a fától az erdőt. Ja igen ki ne hagyjam a tábla maga így fest:
void rajzol(char t[SZINT][SOR][OSZLOP]) { printf(" 1 | %c ********* %c ********* %c\n", t[0][0][0], t[0][0][1], t[0][0][2]); printf(" | * * *\n"); printf(" 2 | * %c ***** %c ***** %c *\n", t[1][0][0], t[1][0][1], t[1][0][2]); printf(" | * * * * *\n"); printf(" 3 | * * %c * %c * %c * *\n", t[2][0][0], t[2][0][1], t[2][0][2]); printf(" | * * * * * *\n"); printf(" 4 | %c * %c * %c %c * %c * %c\n", t[0][1][0], t[1][1][0], t[2][1][0], t[2][1][2], t[1][1][2], t[0][1][2]); printf(" | * * * * * *\n"); printf(" 5 | * * %c * %c * %c * *\n", t[2][2][0], t[2][2][1], t[2][2][2]); printf(" | * * * * *\n"); printf(" 6 | * %c ***** %c ***** %c *\n", t[1][2][0], t[1][2][1], t[1][2][2]); printf(" | * * *\n"); printf(" 7 | %c ********* %c ********* %c\n", t[0][2][0], t[0][2][1], t[0][2][2]); printf(" -------------------------\n"); printf(" a b c d e f g\n"); }
Másodlagosnak éppen nem nevezhető szempont az sem, hogy mindezt TCP szerver-kliens alapú alkalmazásként kell majd megírnom. Ez úgy akart volna kinézni, hogy a tábla tömböt küldözgetem közöttük. Szóval én csak kliens programot írok ami használható szerverként és egy másik kliensel lehet rá csatlakozni. Tehát egyik lép valamit akkor küldi a táblát a másiknak és az felülírja a sajátját és ő is lép is küldi vissza. Tehát ez mind mind pofon egyszerű lett volna de a fönti ellenoriz kód annyira elbonyolodik, hogy egyszerűen képtelen vagyok kibogozni már, hogy mit akartam az elejével 5órával ezelőtt .

2dimenziós tömböt azért nem akarok mert akkor kikeresni, az [1-7][ ][a-g] beolvasott párból, hogy hova kell rakni a játékos betűjelét mégdurvább lenne mint ahogy most kinéz a malom csekkolás.

A tömb első dimenziója azt mondja meg, hogy melyik négyzetben vagyunk. Külső/középső avagy a legbelső. Ezzel nem is lenne gond, a gond akkor van ha szinteken is átvág a malom. Tehát a 010 110 210 -ás illetve 212 112 012-es illetve a függőleges: 001 101 201 és 221 121 021 -es malmok. Valamit vagy nagyon túlbonyolítottam az ellenoriz függvényben vagy abszolúte nemjó hozzá ez a 3d tömb.
Mutasd a teljes hozzászólást!
Mutasd a teljes hozzászólást!

  • Szerintem pont jó a három dimenziós tömb a malom kikeresésére, mert az akkor van, ha fogsz két konstans számot 0 és 2 közt, és egy változót, ami 0,1,2 értékeken megy végig, és bármilyen "felállásban" a három tömb értéke azonos.
    Szemléltetve:

    Konstansok: C, D {0..2}
    Változó: x
    [C][D][x]
    ha ([C][D][0] == [C][D][1] == [C][D][2]) akkor malom // vízszintes (egy négyzetben)
    ha ([C][0][D] == [C][1][D] == [C][2][D]) akkor malom // függőleges (egy négyzetben)
    ha ([0][C][D] == [1][C][D] == [2][C][D]) akkor malom // négyzetek közt

    Ezt lefuttatod minden C-D párosra, és megtudod, hogy van-e malom.
    Persze arra figyelni kell, hogy 3^3 = 27, de ebből csak 24 van használatban.

    (A fenti példában azt, hogy a tömb elemek egyenlőek úgy értettem, hogy nem üresek, és ugyanaz a játékos rakta le a bogyóját).
    Mutasd a teljes hozzászólást!
  • Oké akkor íme a kettőtök javaslatából előállított változat:
    int ellenoriz(char t[SZINT][SOR][OSZLOP], poz utolso, char player_id) { if(utolso.sor == 1 && utolso.oszlop == 0) { /*Bal vízszintes elemek nem 0-k és egyenlőek akkor ott malom van.*/ if((t[0][1][0] != UNUSED && t[1][1][0] != UNUSED && t[2][1][0] != UNUSED) && (t[0][1][0] == t[1][1][0] && t[1][1][0] == t[2][1][0])) { return TRUE; } /*Az aktuális elem oszlopán kell végigmászni.*/ if((t[utolso.szint][0][utolso.oszlop] != UNUSED && t[utolso.szint][2][utolso.oszlop] != UNUSED) && (t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][0][utolso.oszlop] && t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][2][utolso.oszlop])) { return TRUE; } return FALSE; } else if(utolso.sor == 1 && utolso.oszlop == 2) { /*Jobb vízszintes elemek nem 0-k és egyenlőek akkor ott malom van.*/ if((t[0][1][2] != UNUSED && t[1][1][2] != UNUSED && t[2][1][2] != UNUSED) && (t[0][1][2] == t[1][1][2] && t[1][1][2] == t[2][1][2])) { return TRUE; } /*Az aktuális elem oszlopán kell végigmászni.*/ if((t[utolso.szint][0][utolso.oszlop] != UNUSED && t[utolso.szint][2][utolso.oszlop] != UNUSED) && (t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][0][utolso.oszlop] && t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][2][utolso.oszlop])) { return TRUE; } return FALSE; } else if(utolso.oszlop == 1 && utolso.sor == 0) { /*Fönt a függőleges elemek nem 0-k és egyenlőek akkor malom.*/ if((t[0][0][1] != UNUSED && t[1][0][1] != UNUSED && t[2][0][1] != UNUSED) && (t[0][0][1] == t[1][0][1] && t[1][0][1] == t[2][0][1])) { return TRUE; } /*Az aktuális elem során kell végigmászni.*/ if((t[utolso.szint][utolso.sor][0] != UNUSED && t[utolso.szint][utolso.sor][2] != UNUSED) && (t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][utolso.sor][0] && t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][utolso.sor][2])) { return TRUE; } return FALSE; } else if(utolso.oszlop == 1 && utolso.sor == 2) { /*Lent a függőleges elemek nem 0-k és egyenlőek akkor malom.*/ if((t[0][2][1] != UNUSED && t[1][2][1] != UNUSED && t[2][2][1] != UNUSED) && (t[0][2][1] == t[1][2][1] && t[1][2][1] == t[2][2][1])) { return TRUE; } /*Az aktuális elem során kell végigmászni.*/ if((t[utolso.szint][utolso.sor][0] != UNUSED && t[utolso.szint][utolso.sor][2] != UNUSED) && (t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][utolso.sor][0] && t[utolso.szint][utolso.sor][utolso.oszlop] == t[utolso.szint][utolso.sor][2])) { return TRUE; } return FALSE; } /*Egyetlen elem van ami nem létezik a tömbben: EZ!*/ if(utolso.sor == 1 || utolso.oszlop == 1) { return FALSE; } else { if(t[utolso.szint][utolso.sor][0] != UNUSED && t[utolso.szint][utolso.sor][1] != UNUSED && t[utolso.szint][utolso.sor][2] != UNUSED) { if(t[utolso.szint][utolso.sor][0] == t[utolso.szint][utolso.sor][1] && t[utolso.szint][utolso.sor][1] == t[utolso.szint][utolso.sor][2]) { return TRUE; } else { return FALSE; } } else if(t[utolso.szint][0][utolso.oszlop] != UNUSED && t[utolso.szint][1][utolso.oszlop] != UNUSED && t[utolso.szint][2][utolso.oszlop] != UNUSED) { if(t[utolso.szint][0][utolso.oszlop] == t[utolso.szint][1][utolso.oszlop] && t[utolso.szint][1][utolso.oszlop] == t[utolso.szint][2][utolso.oszlop]) { return TRUE; } else { return FALSE; } } else { return FALSE; } } return FALSE; }
    Ez egyenlőre elég jónak tünik de több szem többet lát kihagytam valamit?
    Mutasd a teljes hozzászólást!
  • Ez egyenlőre elég jónak tünik de több szem többet lát kihagytam valamit?


    Te vagy a fejlesztője. Tesztelgesd!
    Mutasd a teljes hozzászólást!
  • Nem muszáj többdimenziós tömböt használni. Egy egyszerű 24 bájtos tömb is megteszi 0-tól 23-ig indexelve az ábra szerint:

    0--------1--------2 | | | | 3-----4-----5 | | | | | | | | 6--7--8 | | | | | | | | 9-10-11 12-13-14 | | | | | | | | 15-16-17 | | | | | | | | 18----19----20 | | | | 21-------22-------23

    Minden bájtnak 3 állapota lesz (pl üres=0, fehér=1, fekete=2)

    Ezután egy másik inicializált adattömbben felsoroljuk a lehetőségeket a malmokra:
    0 1 2
    3 4 5
    6 7 8
    ....
    2 14 23

    Összesen 16 féle lehetőség van, tehát 16*3 byte. Amikor azt akarod megnézni, hogy van-e malom,
    egyszerűen csinálsz egy ciklust, ami 16-szor lefut, minden ciklusban veszed a következő 3 bájtot a tömbből, majd azok szerint megcímzel 3 helyet az aktuális állás adattömbjéből, megnézed, nincs-e ott 3 egyforma.

    Legalábbis én így csinálnám, ez a legegyszerűbb.
    Mutasd a teljes hozzászólást!
  • Helyesbítek, most néztem meg a pelz által írt linket, és leesett, hogy a négyzetek közti malomból csak a függőleges és vízszintes jó, az átlós nem.

    Így viszont elnézve van 16 lehetséges malom helyzet, ezt szerintem egyszerűbb megírni, mint for ciklusokkal leutánozni. (Utóbbinak akkor van értelme, ha csavarsz egyet a dolgon, és a user megadhatja, hogy hány szintű malom játékkal akar játszani )


    // tegyuk fel, hogy a t 3 dimenzios valtozo ertekei: // 0: nincs rajta semmi // 1: fekete // -1: feher int winner = 0; int isMalom(int a, int b, int c) { int ret = a+b+c; winner = abs(ret) == 3 ? ret/abs(ret) : 0; return winner != 0; } int check() { for (int i=0; i<3; i++) { // függőleges if (isMalom(t[i][0][0], t[i][1][0], t[i][2][0])) return winner; if (isMalom(t[i][0][2], t[i][1][2], t[i][2][2])) return winner; // vízszintes if (isMalom(t[i][0][0], t[i][0][1], t[i][0][2])) return winner; if (isMalom(t[i][2][0], t[i][2][1], t[i][2][2])) return winner; } // négyzetek között if (isMalom(t[0][0][1], t[1][0][1], t[2][0][1])) return winner; if (isMalom(t[0][1][0], t[1][1][0], t[2][1][0])) return winner; if (isMalom(t[2][1][2], t[1][1][2], t[0][1][2])) return winner; if (isMalom(t[2][2][1], t[1][2][1], t[0][2][1])) return winner; return 0; } int chk = check(); if (chk == 1) printf("Nyert a feher"); elseif (chk == -1) printf("Nyert a fekete"); else printf("Meg nem nyert senki");

    remélem nem rontottam el az indexeléseket
    A C szintax meg biztos hagy némi kivetni valót maga után, nézd el, két-három éve nem kódoltam C-ben.
    Mutasd a teljes hozzászólást!
  • Én is.
    Mutasd a teljes hozzászólást!
  • isMalom(malom)==TRUE


    bocccs
    Mutasd a teljes hozzászólást!
  • Ha erre gondoltal, akkor igen, lusta voltam kikeresni, hogy hogy van angolul a malom.

    De azert latom, nalad is hosszu volt a nap
    Mutasd a teljes hozzászólást!
  • Helyesbítek, most néztem meg a pelz által írt linket, és leesett, hogy a négyzetek közti malomból csak a függőleges és vízszintes jó, az átlós nem.

    Attól függ.

    Nekem is tetszik az az isMalom().
    De inkább
    ez_
    isMalom,
    az_
    isMalom ...
    Vagy
    ez_sem
    Malom,
    az_sem
    Malom ...
    Vagy
    úccse
    Malom,
    azéccse
    Malom ...


    ---
    demégazéccse
    Malom!
    Mutasd a teljes hozzászólást!
  • Na megint okosabb lettem. Szóval van több változata.
    Akkor legyen: checkNájnMenszMorrisz() meg checkTvelvMenszMorrisz()

    Azé' ez komoly: link
    Ők is biztos 24 bites bitmap-ben nézték meg, hogy ki győzött

    szerk: mégegy szavazat a bitmap mellett, de arra most nem vállalkoznék, hogy kódot írok
    Mutasd a teljes hozzászólást!
  • 3 dimenzio egy ketdimenzios jatekhoz ?
    Mutasd a teljes hozzászólást!
  • Szerintem semmi szükség 3 dimenzióra. Egyesek túlbonyolítják a helyzetet.
    Mutasd a teljes hozzászólást!
  • Nahát! A linkben, amit elfogadtál csak a játékszabályok vannak.
    Nem az algoritmus érdekelt?
    Mutasd a teljes hozzászólást!
  • A házifeladatot megoldotta, nem mindegy mostmár, hogy ki és mennyit segített?
    Mutasd a teljes hozzászólást!
  • mill....
    Mutasd a teljes hozzászólást!
  • igen, azóta már dict.sztaki-ztam egyet
    Mutasd a teljes hozzászólást!
  • Akkor ez ennyi? Elfogadtál egy olyan megoldást, aminek még csak köze sincs a programozáshoz, és még egy köszit se böktél volna ide a másfél oldalnyi segítségért?
    Mutasd a teljes hozzászólást!
  • Ezen most miért kell csodálkozni? Én feltettem egy kérdést, kaptam rá rögtön egy linket amiből megtanultam malmozni . Ja valamikor 2éves koromban malmozhattam azóta max sakk. Utánna semmi olyan választ nem kaptam ami új lett volna max ugyanazt leprogramozva. Kösz de azt én is meg tudom csinálni, egy szóval nem mondtam, hogy kódot kérek.
    Kérdés ez volt: Milyen adatszerkezet lenne a legmegfelelőbb, mert a malom ellenőrzése elég körülményes a 3d karaktertömbbel?
    Erre kaptam a választ a linken és voala jahogy ez volt malom! Ettől fogva miről beszélünk? Nem kellett átalakítanom a kész program 97%-át csak a malom ellenőrzést normálisan megírni 74sorban 4-5 soros egyszerű elágazásokkal. Miért fogadtam volna el akármelyik kódot is, ha mindegyikhez totál alapjaiban az egész kódom újra kellett volna írni a nulláról?

    Pelz adta a legjobb megoldást a leggyorsabban. Te lekésted kemény 2perccel most ezen nem értem mit problémázol. Ja meg nem is beszélve arról, hogy nem is működik amit írtál bár ez nekem is újdonság volt:
    t[0][1][0] = 'B'; t[1][1][0] = 'B'; t[2][1][0] = 'B'; if(t[0][1][0] == t[1][1][0] == t[2][1][0]) { printf("MALOM"); } else { printf("NINCS MALOM!"); }
    Próbáld ki, nézd meg mit dob ki . Nem jöttem rá, hogy miért azt írja ki amit kiír mert 1d-s karkatertömbbel azt csinálja amit elvárok, de magasabb dimenzióban már meghal.

    Szóval problémák a javaslatoddal:
    1. Nem műödik.
    2. k-adik körben lesz egy malom mondjuk 'W' játékosnál => Levesz egy 'B'-t a tábláról. A k+1-edik körben mit fog adni a kódod? A malom ottvan... Igen ismét meg fogja találni függetlenül attól, hogy hová rakta a 'W' betűjét a játékos ő akkoris levesz mégegyet.
    3. Nem kértem kódot semmilyen értelemben sem. Ez a pszeudo kódot is magában foglalja mert azt meg tudom írni én is.
    4. Pelz gyorsabb volt és nem írt fölöslegesen semmit ami ráadásul nem is jó.

    Az egyéb javaslatokra és kérdésekre, mint például miért használtam 3d-s tömböt egy 2d-s játékhoz meg 1d-vel is lehet. => Persze képben vagyok vele. Van egy icipici probléma ezzel és ezért másoltam be a tábla kirajzolásának eljárását:
    void rajzol(char t[SZINT][SOR][OSZLOP]) { printf(" 1 | %c ********* %c ********* %c\n", t[0][0][0], t[0][0][1], t[0][0][2]); printf(" | * * *\n"); printf(" 2 | * %c ***** %c ***** %c *\n", t[1][0][0], t[1][0][1], t[1][0][2]); printf(" | * * * * *\n"); printf(" 3 | * * %c * %c * %c * *\n", t[2][0][0], t[2][0][1], t[2][0][2]); printf(" | * * * * * *\n"); printf(" 4 | %c * %c * %c %c * %c * %c\n", t[0][1][0], t[1][1][0], t[2][1][0], t[2][1][2], t[1][1][2], t[0][1][2]); printf(" | * * * * * *\n"); printf(" 5 | * * %c * %c * %c * *\n", t[2][2][0], t[2][2][1], t[2][2][2]); printf(" | * * * * *\n"); printf(" 6 | * %c ***** %c ***** %c *\n", t[1][2][0], t[1][2][1], t[1][2][2]); printf(" | * * *\n"); printf(" 7 | %c ********* %c ********* %c\n", t[0][2][0], t[0][2][1], t[0][2][2]); printf(" -------------------------\n"); printf(" a b c d e f g\n"); }
    Vagyis egy-egy lépésből a program egy ilyet fog bekapni:
    scanf("%d %c", &sor, &oszlop);
    Nyernék vele annyit, hogy malmot könnyen tudok keresni de elvesztem vele a csompópont kereső függvény egyszerűségét. Vagyis hová is akar pakolni a játékos?
    Honnan is akarja mozgatni a bábut ha egyáltalán van ott?
    Hová is akarja áthelyezni a bábuját, ha egyáltalán az a hely szabad és elérhető?
    Szóval remélem érthető és világos voltam. Persze ha valaki úgy érzi, hogy márpedig ő érdemelte meg volna a pontot az nyugodtan mehet moderátorhoz mert én annak adtam a pontot aki közelebb lendített a megoldáshoz a leggyorsabban és mindezt úgy, hogy nem kellett újraírnom a 738soros program 97%-át hanem ebből mindösszesen 74-et.

    Szeretne még valaki idegösszeroppanni mert nem kapott pontot pedig mutatott nekem szép elegáns C kódot amit én is megtudok írni?
    Mutasd a teljes hozzászólást!
  • Én inkább egy 1d-s tömbben tárolnám valahogy úgy ahogy a mellékletben csatolt képen látszik.

    Egy malomtáblán van három négyzet és minden négyzeten 8 mező.
    Ha a mezők tömbbeli helyét vizsgálatkor átalakítod úgy, hogy megkapd, hogy melyik négyzet hányadik mezején van akkor már egyszerűen tudod vizsgálni azt is, hogy melyik bábuk vannak malomban.

    Nekem c#-ban sikerült megcsinálnom 470 sorból a működést a tábla kirajzolását pedig kb 200-ból.
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • Valószínűleg már nem él a kérdés, de azért a magam szórakoztatására én is lerajzolnék egy változatot a tiéd alapján, egy kétdimenziós tömbbel (3x8 elem):

    .00-------01-------02 ..|........|........| ..|.10----11----12..| ..|..|.....|.....|..| ..|..|.20-21-22..|..| ..|..|..|.....|..|..| .07-17-27....23-13-03 ..|..|..|.....|..|..| ..|..|.26-25-24..|..| ..|..|.....|.....|..| ..|.16----15----14..| ..|........|........| .06-------05-------04


    A 'be/ki-irányú' illetve átlós malmokat könnyű megtalálni (mert csak az első koordinátát kell variálni), a többinél viszont az is figyelni kell, hogy középső vagy szélső-e (második koordinátája páros-e vagy páratlan), illetve ügyelni kell arra, hogy modulo 8 számoljuk (tehát a 06 szomszédai balra 05 és 04, fölfelé 07 és 00)

    Megj: ha nem a programozók fórumán lennénk, szót sem érdemelne, hogy nem jól működik a fix szélességű formázás szóközökkel, ezért cseréltem őket pontokra, amitől most tök ronda.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
Címkék
abcd