2025(e)ko otsailaren 18(a), asteartea

4. jarduera (I) | Dadoen jokoa

ZER DAKIDAN:
Hainbat funtzio estandar ikasi dut eta for agindua ikasi dut ere.



ZER IKASIKO DUDAN:
Agindu errepikakor habiaratuen gaia sakonduko dut jarduera handiago batean. Bide batez, rand() eta srand() funtzioak praktikatuko ditut.

Artikulu honekin loturik dago 4. jarduera (II) | Dadoen jokoa izenburuko artikulua.



Planteamendua

Jokalarien kopurua ezezaguna da programaren hasieran, eta bere balioa teklatuaren bitartez eman beharko zaio programari.

Irudiak erakusten duen programaren exekuzio horretan jokalariak 5 dira

Jokalariek dado batekin jokatuko dute. Jokalari bakoitzak dadoaren hiru jaurtiketa egin ondoren, bere emaitza lortzeko dadoaren hiru jaurtiketen puntuak batu behar dira (baliorik txikiena 3 izango da eta baliorik handiena 18 izan daiteke). Programaren azken emaitza bikoitza izango da:

  • Jokalari guztien artean zenbatgarrenak irabazi duen
  • Zenbat puntuekin irabazi du jokalari horrek
Dadoaren jaurtiketa simulatzeko gogoratu blog honetako Ariketa 19 | Zenbakien funtzio estandarrak artikuluan ematen diren (a1) eta (a2) programak. Dadoaren balioa eskuratzeko rand() funtzio estandarra erabiliko da (gogoratu srand() funtzioaren beharra dagoela). Jakina denez, dadoaren aukerak 6 dira eta horregatik iJaurtiketarenBalioa%6+1 aplikatu beharko da:
...
srand(time(NULL));   // srand() zenbaki aleatorioak berriro hasiarazteko, 
                     // hazia behar du. Hazia, adibidez, time(NULL) funtzioa
                     // izan daiteke, zeinek igarotako segundoak long batean
                     // itzultzen dituen 1970-01-01 datatik hasita
iJaurtiketarenBalioa = rand();   // 0 eta RAND_MAX=32767 arteko balioa
iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1;   // 1 eta 6 artekoa
...


Irabazlea

Hiru jaurtiketak egin ondoren haien batura handiena lortuko duen jokalariak irabaziko du. Bi jokalarik (edo gehiagok) puntu-kopuru maximoa lortuz gero, irabazlea lehen jokalaria izango da.

Zenbat jokalari izango diren galdetuko du programak, eta zenbaki oso bat den erabiltzailearen erantzuna iJokalariKopurua aldagaian gordeko da. Hona hemen 4a1-Jarduera_DadoenJokoa programaren kodea:

/* 4a1-Jarduera_DadoenJokoa: lehen urratsa, jokalarien kopurua zehaztu */

#include <stdio.h>

int main()
{
    int iJokalariKopurua;

    do
    {
        printf("Zenbat jokalari dira? ");
        scanf("%d", &iJokalariKopurua);
    } while (iJokalariKopurua <= 1); // gutxienez 2 jokalari

    printf("%d jokalari izango dira.\n", iJokalariKopurua);

    printf("\nENTER sakatu exekuzioa amaitzeko... ");
    getchar(); // ENTER teklari itxaron (bufferra garbitzeko)
    getchar(); // edozein tekla sakatu programatik irteteko
    return 0;
}


Kanpoko begizta planteatzen da, prozesu errepikakor bat delako eta zenbat itzuli eman behar diren ezaguna delako for agindu bat erabiliko da. Emaitzak izango diren iMaximoa eta iIrabazlea aldagaien hasieraketak begiztatik kanpo egingo dira. Jarraian 4a2-Jarduera_DadoenJokoa programaren kodea hemen erakusten da:

/* 4a2-Jarduera_DadoenJokoa: bigarren urratsa, iterazioak burutu */

// Zenbat jokalari izango diren teklatuz zehaztu ondoren,
// kanpoko begiztan jokalarien txandak erakusten dira.
// iIrabazlea eta iMaximoa aldagaiak ez dira erabiltzen.

#include <stdio.h>

int main()
{
    int iJokalariKopurua, iMaximoa, iIrabazlea;
    int iKont1;

    do
    {
        printf("Zenbat jokalari dira? ");
        scanf("%d", &iJokalariKopurua);
    } while (iJokalariKopurua <= 1); // gutxienez 2 jokalari

    iIrabazlea = 0;
    iMaximoa = 0;

    // jokalarien jarduerak iteratu
    for (iKont1 = 1; iKont1 <= iJokalariKopurua; iKont1++)
    {
        printf("%d. jokalariaren jarduera, 3 jaurtiketen batura kalkulatu beharko da.\n", iKont1);
    }

    printf("\nENTER sakatu exekuzioa amaitzeko... ");
    getchar(); // ENTER teklari itxaron (bufferra garbitzeko)
    getchar(); // edozein tekla sakatu programatik irteteko
    return 0;
}


Barruko begizta planteatzen da, prozesu errepikakor bat delako eta zenbat itzuli eman behar diren ezaguna delako, berriro ere, for agindu bat erabiliko da. Jokalari bakoitzaren puntuaketa diren iPuntuenBatura aldagaiaren hasieraketa begiztatik kanpo egingo da. Bestalde, random(6) funtzioak eman ditzaken balioak 0 eta 5 artean daudelako unitate bat gehitu behar zaie. Hona hemen 4a3-Jarduera_DadoenJokoa programaren kodea:

/* 4a3-Jarduera_DadoenJokoa: hirugarren urratsa, barruko iterazioak */

// Kanpoko begiztan jokalarien txandak erakusten dira.
// Barruko begiztan jokalarien puntuak lortzen dira.
// iIrabazlea eta iMaximoa aldagaiak ez dira erabiltzen.

#include <stdio.h>
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtziorako

int main()
{
    int iJokalariKopurua, iMaximoa, iIrabazlea, iPuntuak, iPuntuenBatura;
    int iKont1, iKont2;

    do
    {
        printf("Zenbat jokalari dira? ");
        scanf("%d", &iJokalariKopurua);
    } while (iJokalariKopurua <= 1); // gutxienez 2 jokalari

    srand(time(NULL)); // zenbaki sasi-aleatorioak sortzeko hazia
    iIrabazlea = 0;
    iMaximoa = 0;

    // jokalarien jarduerak iteratu
    for (iKont1 = 1; iKont1 <= iJokalariKopurua; iKont1++)
    {
        printf("\n");
        iPuntuenBatura = 0;

        for (iKont2 = 1; iKont2 <= 3; iKont2++)
        {
            iPuntuak = rand() % 6 + 1; // 1 eta 6 bitarteko zenbakiak
            printf("%d. jokalariak %d puntu lortu ditu %d. jaurtiketan.\n", iKont1, iPuntuak, iKont2);
            iPuntuenBatura += iPuntuak;
        }
        printf("%d. jokalariak guztira %d puntu lortu ditu.\n", iKont1, iPuntuenBatura);
        // irabazlea zein da dagoeneko?
    }

    printf("\nENTER sakatu exekuzioa amaitzeko... ");
    getchar(); // ENTER teklari itxaron (bufferra garbitzeko)
    getchar(); // edozein tekla sakatu programatik irteteko
    return 0;
}


Barruko begizta bukatzean, baina oraindik kanpoko begiztan gaudelarik, une horretan irabazlea zein den erabakitzen da. Ondorioz, emaitzak izango diren iMaximoa eta iIrabazlea aldagaien eguneraketak burutuko dira horrela badagokie. Hauxe da 4a4-Jarduera_DadoenJokoa programaren kodea:

/* 4a4-Jarduera_DadoenJokoa: laugarren urratsa, barruko iterazioak */

// Kanpoko begiztan jokalarien txandak erakusten dira.
// Barruko begiztan jokalarien puntuak lortzen dira eta
// irabazlea dagoeneko zein den erabakitzen da.

#include <stdio.h>
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtziorako

int main()
{
    int iJokalariKopurua, iMaximoa, iIrabazlea, iPuntuak, iPuntuenBatura;
    int iKont1, iKont2;

    do
    {
        printf("Zenbat jokalari dira? ");
        scanf("%d", &iJokalariKopurua);
    } while (iJokalariKopurua <= 1); // gutxienez 2 jokalari

    srand(time(NULL)); // zenbaki sasi-aleatorioak sortzeko hazia
    iIrabazlea = 0;
    iMaximoa = 0;

    // jokalarien jarduerak iteratu
    for (iKont1 = 1; iKont1 <= iJokalariKopurua; iKont1++)
    {
        printf("\n");
        iPuntuenBatura = 0;

        for (iKont2 = 1; iKont2 <= 3; iKont2++)
        {
            iPuntuak = rand() % 6 + 1; // 1 eta 6 bitarteko zenbakiak
            printf("%d. jokalariak %d puntu lortu ditu %d. jaurtiketan.\n", iKont1, iPuntuak, iKont2);
            iPuntuenBatura += iPuntuak;
        }
        printf("%d. jokalariak guztira %d puntu lortu ditu.\n", iKont1, iPuntuenBatura);
        if (iPuntuenBatura > iMaximoa)  // (>) irabazlea eguneratu
        {
            iMaximoa = iPuntuenBatura;
            iIrabazlea = iKont1;
        }
    }

    // azken emaitzak erakutsi

    printf("\nENTER sakatu exekuzioa amaitzeko... ");
    getchar(); // ENTER teklari itxaron (bufferra garbitzeko)
    getchar(); // edozein tekla sakatu programatik irteteko
    return 0;
}

Goiko kodean maximoa lortzen da; ikusten denez, bigarren jokalariren batek puntuazio maximoarekin berdinketa suertatzen denean irabazlea ez da aldatzen; beraz, maximoaren lehen jokalaria irabazletzat jotzen den. Baina, nahi izanez gero berdinketaren bigarren jokalaria irabazlea izatea, alderaketa honela izan beharko litzateke:

...
    if (iPuntuenBatura >= iMaximoa)  // (>=) berdinketan irabazlea eguneratu
    {
        iMaximoa = iPuntuenBatura;
        iIrabazlea = iKont1;
    }
...


Programatik irten aurretik, azken emaitzak iMaximoa eta iIrabazlea aldagaien edukiak erakusten dira. Hona hemen 4a5-Jarduera_DadoenJokoa programaren kodea:

/* 4a5-Jarduera_DadoenJokoa: bosgarren urratsa, emaitzak erakutsi */

// Kanpoko begiztan jokalarien txandak erakusten dira.
// Barruko begiztan jokalarien puntuak lortzen dira eta
// dagoeneko irabazlea zein den ezaguna da. Bukatzeko,
// azken emaitzak erakusten dira (irabazlea eta puntuak).

#include <stdio.h>
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtziorako

int main()
{
    int iJokalariKopurua, iMaximoa, iIrabazlea, iPuntuak, iPuntuenBatura;
    int iKont1, iKont2;

    do
    {
        printf("Zenbat jokalari dira? ");
        scanf("%d", &iJokalariKopurua);
    } while (iJokalariKopurua <= 1); // gutxienez 2 jokalari

    srand(time(NULL)); // zenbaki sasi-aleatorioak sortzeko hazia
    iIrabazlea = 0;
    iMaximoa = 0;

    // jokalarien jarduerak iteratu
    for (iKont1 = 1; iKont1 <= iJokalariKopurua; iKont1++)
    {
        printf("\n");
        iPuntuenBatura = 0;

        for (iKont2 = 1; iKont2 <= 3; iKont2++)
        {
            iPuntuak = rand() % 6 + 1; // 1 eta 6 bitarteko zenbakiak
            printf("%d. jokalariak %d puntu lortu ditu %d. jaurtiketan.\n", iKont1, iPuntuak, iKont2);
            iPuntuenBatura += iPuntuak;
        }
        printf("%d. jokalariak guztira %d puntu lortu ditu.\n", iKont1, iPuntuenBatura);
        if (iPuntuenBatura > iMaximoa)  // irabazlea eguneratu
        {
            iMaximoa = iPuntuenBatura;
            iIrabazlea = iKont1;
        }
    }

    printf("\nIrabazlea %d. jokalaria da, %d punturekin!\n", iIrabazlea, iMaximoa);

    printf("\nENTER sakatu exekuzioa amaitzeko... ");
    getchar(); // ENTER teklari itxaron (bufferra garbitzeko)
    getchar(); // edozein tekla sakatu programatik irteteko
    return 0;
}


Esan bezala, bi jokalarik (edo gehiagok) puntu-kopuru maximoa lortuz gero, irabazlea lehen jokalaria izango da. Baina berdinketak beste modu batez hautsi beharko litzateke, adibidez: Dadoa hiru aldiz jaurti ondoren iPuntuenBatura puntuen baturak iMaximoa edukiarekin bat egiten badu, berdinketa hausteko txanpon bat erabil daiteke 4. jarduera (II) | Dadoen jokoa artikuluan erakusten den bezala:

/* 4a4-Jarduera_DadoenJokoa: laugarren urratsa, barruko iterazioak */

    ...

    // kanpoko begizta
    for (iKont1 = 1; iKont1 <= iJokalariKopurua; iKont1++)
    {
        printf("\n");
        iPuntuenBatura = 0;
        // barruko begizta
        for (iKont2 = 1; iKont2 <= 3; iKont2++)
        {
            iPuntuak = rand() % 6 + 1; // 1 eta 6 bitarteko zenbakiak
            printf("%d. jokalariak %d puntu lortu ditu %d. jaurtiketan.\n", iKont1, iPuntuak, iKont2);
            iPuntuenBatura += iPuntuak;
        }
        printf("%d. jokalariak guztira %d puntu lortu ditu.\n", iKont1, iPuntuenBatura);
        if (iPuntuenBatura > iMaximoa)  // irabazlea eguneratu
        {
            iMaximoa = iPuntuenBatura;
            iIrabazlea = iKont1;
        }
        else
        {
            if (iPuntuenBatura == iMaximoa) // berdinketan zein da irabazlea?
            {
                      // berdinketa hausteko kodea
            } // if
        } // else
    } // for

    ...
}






  • 4a1-Jarduera_DadoenJokoa.cbp | main.c  
  • 4a2-Jarduera_DadoenJokoa.cbp | main.c  
  • 4a3-Jarduera_DadoenJokoa.cbp | main.c  
  • 4a4-Jarduera_DadoenJokoa.cbp | main.c  
  • 4a5-Jarduera_DadoenJokoa.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina