IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Problem se zjistovanim opakovani a poctu opakovani

Aktivity
Avatar
Ondrej Zadrapa:8.6.2020 12:40

Caute, snazim se vytvořit program, který nahodne vygeneruje nejakou posloupnost kladných cisel, ne ovšem linearni, cisla mají byt na přeskáčku, coz jsem pochopil, ze si mam proste vygenerovat nejaka cisla, nejlepe v takovem rozsahu a poctu, aby se občas nejake opakovalo. A chce se po me, abych zjisitl, které jsou ty, co se opakuji a zdokonalit, abych i vypsal, kolikrat se opakuji

Zkusil jsem:

Sub Main()
        Dim cisla(20) As Integer, rnd As New Random, opakovani As Byte = 0, cislo As Integer, pocet As Byte = 0
        For i = 0 To cisla.Length - 1
            cislo = rnd.Next(10)
            Console.Write(cislo & " ")
        Next
        Console.WriteLine()
        For i = 1 To pocet - 2
            If cisla(i) = cisla(i + 1) Then
                opakovani += 1
            End If
        Next
        Console.WriteLine("{0} se opakuje {1}x", cislo, opakovani)
        Console.ReadKey()
    End Sub

Chci docílit: Abych vypsal cisla, jez se opakuji a počet opakovani. Nevim, kde delam chybu, zkousel jsem to zpracovat jako když například hledam minimum a jestli se nahodou nevyskytuje vícekrát, to moc nefunguje, cili asi to opet ma byt nejak specialne, nebo nevim jak.

Editováno 8.6.2020 12:42
 
Odpovědět
8.6.2020 12:40
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:8.6.2020 13:03

Pro zjištění které číslo se opakuje a kolikrát je dobré (není to nutné, ale z hlediska vysoce doporučené) si vytvořit druhé pole o velikosti rozsahu náhodných hodnot, které lze generovat. Na tomto poli pak provádět inkrementaci na daném indexu odpovídající hodnotě vygenerovaného náhodného čísla. Toto pole poté projít a na základě podmínek vypsat index a hodnotu. Index představuje náhodně generované číslo, hodnota poté počet opakování.

Nahoru Odpovědět
8.6.2020 13:03
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:8.6.2020 13:09

Cili když mam rozsah nahodnych cisel třeba 10, tak si mam vytvořit pomocnePole(10), chapu to spravne, co s tim potom, nejak ho včlenit do tech cyklu, nebo vytvořit vlastní, nebo něco uplne jiného?

 
Nahoru Odpovědět
8.6.2020 13:09
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:8.6.2020 13:13

Ano, velikost pole je určena rozsahem generovaných náhodných čísel. V tomto poli je třeba inkrementovat hodnoty na indexu odpovídající náhodnému číslu.

Nahoru Odpovědět
8.6.2020 13:13
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:8.6.2020 13:37

Co teda s tim pomocnymPolem, nejak ho včlenit do prvního cyklu, nebo do druhého cyklu, nebo vytvořit extra cyklus jenom s pomocnym polem, nebo jak teda, ještě mi občas unika nazvoslovi, vyznam slova inkrementace mi tak nejak unika.

 
Nahoru Odpovědět
8.6.2020 13:37
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:8.6.2020 13:43

Pomocné pole slouží k uchování počtu generovaných náhodných čísel. Inkrementace znamená zvýšení hodnoty. Pokud není uvedeno jinak pak se pojem inkrementace bere jako navýšení hodnoty o 1.

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

#define SIZE 20
#define RANGE 10

int main(void) {
        int nums[SIZE], count[RANGE] = { 0 };

        srand((unsigned int)(time(NULL)));

        for (int i = 0; i < SIZE; i++) {
                nums[i] = rand() % RANGE;
                count[nums[i]]++;
        }

        for (int i = 0; i < SIZE; i++) printf("%d ", nums[i]);
        putchar('\n');

        for (int i = 0; i < RANGE; i++) {
                if(count[i] > 1) printf("%d - %dx\n", i, count[i]);
        }

        return 0;
}

Výstup programu:

6 3 1 5 4 1 9 7 5 9 0 7 0 5 7 6 5 3 3 0
0 - 3x
1 - 2x
3 - 3x
5 - 4x
6 - 2x
7 - 3x
9 - 2x
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
8.6.2020 13:43
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:8.6.2020 14:45

Ze existuje něco jako pole v poli, to vidim prvne. :D

 
Nahoru Odpovědět
8.6.2020 14:45
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:8.6.2020 15:07

Ze existuje něco jako pole v poli, to vidim prvne. :D

Výraz pole polí bývá někdy spojován s 2D polem. V příkladu však nikde pole v poli nemám, mám pouze dvě samostatná nezávislá pole. Avšak využívám hodnot jednoho pole pro druhé.

Jistě máš namysli následující příkaz:

count[nums[i]]++;

Pole nums uchovává náhodně vygenerovaná čísla. Pole count uchovává počty náhodně vygenerovaných čísel. Příkaz výše říka: Inkrementuj hodnotu uloženou v poli count na indexu odpovídající hodnotě uložené v poli nums na indexu i.

Jelikož jsem si vygenerované číslo uložil do pole count na konkrétní pozici, mohu si na tuto pozici sáhnout a použít tuto hodnotu jako index abych mohl hodnotu na tomto indexu inkrementovat. Důležitá je rovněž inicializace pole count všech prvků na nulu.

Pokud by mi nešlo o kontrolní výpis vygenerovaných náhodných čísel, pak by mi stačilo pouze pole count a toto pole bych přímo naplnil hodnotami následovně:

for (int i = 0; i < SIZE; i++) count[rand() % RANGE]++;
Nahoru Odpovědět
8.6.2020 15:07
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:8.6.2020 20:42
Sub Main()
        Dim vsechnyKarty(32) As Integer, rnd As New Random, prvniHrac As Integer, druhyHrac As Integer, pocet As Byte = 0
        Do
            prvniHrac = rnd.Next(7, 15)
            druhyHrac = rnd.Next(7, 15)
            If Not vsechnyKarty.Contains(prvniHrac And druhyHrac) Then
                vsechnyKarty(pocet) = prvniHrac And druhyHrac
                pocet += 1
            End If
        Loop Until pocet = vsechnyKarty.Length - 1
        Console.ReadKey()
    End Sub

Muzu takhle nejak zacit s programovanim hry Vojna pro dva, nebo by jsi mi mohl dokazal nastínit nejaky lepsi postup?

 
Nahoru Odpovědět
8.6.2020 20:42
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:8.6.2020 21:11

Začít by si měl tak, že by si měl nasimulovat zamíchání balíku karet. Každá karta v balíku se vyskytuje právě jednou. Poté by si měl nasimulovat rozdání karet. Pokud se jedná o klasické mariášové karty, pak počet různých hodnot je 8 (7,8,9,10, spodek, svršek, král, eso). Tedy by bylo i chybné provádět generování náhodného čísla v rozsahu <7,15>. Správně by bylo <7,14>.

Nahoru Odpovědět
8.6.2020 21:11
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:8.6.2020 21:48

Aha, dobře, ze dejme tomu, ze rozdani karet jsem zvladnul, ale vzhledem k poctu karet při generovani bez opakovani mi to vygeneruje jenom 8 karet a ja tim padem potrebuji, aby se mi karty opakovaly 2x, pokud ma mit každý hrac 16 karet, jak bych to mohl provest, ale abych vygeneroval 8 karet od cisla 7, musim koncit 15, moc tomu nerozumim, proc, ale je to tak. Cili jak muzu vygenerovat 2x 8 karet od 7 do 14, nebo jak bych mel postupovat?

 
Nahoru Odpovědět
8.6.2020 21:48
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:8.6.2020 22:00

Máš ještě barvu (srdce, listy, kule, žaludy). Pro realističnost bys toto měl do svého programu zahrnout. Pokud se chceš spokojit pouze s hodnotami, pak každá hodnota je v balíku obsažena 4x. Náhodné číslo se provádí podle vzorce:

RND = (rand() % 8) + 7

Výsledek v závorce dává rozsah 0 až 7, po přičtení posunu (7) se dostáváme na rozsah 7-14, což je rozsah který je správný.

Způsob, jakým se vygeneruje unikátnost jsem už psal. Napíšu ho znovu. Vytvoř si pole obsahující všechny karty. Karet je ze začátku 32. Vygeneruj náhodné číslo v rozsahu 0-31 (dle indexu) a ulož hodnotu na daném indexu do druhého pole představující balík. Vezmi poslední prvek z listu karet a přepiš místo odkud si vzal poslední kartu a sniž číslo představující počet karet v listu o 1. Takto si vytvoříš simulaci zamíchání balíku s unikátními hodnotami.

Nahoru Odpovědět
8.6.2020 22:00
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Ondrej Zadrapa:8.6.2020 22:54

Vůbec jsem s tim nepohnul. A uz me nebavi furt cekat ze prijde rozuzleni, které vždycky nakonec vypada tak jednoduse a jasne, na internetu nic, to za tech x let nikdo nepotreboval programovat, cloveku jako ja, co tomu horkotěžko rozumi to moc nevysvětlíš pomoci teorie. :D Ale i tak diky za snahu, dneska na to kaslu, zkusim to zítra. :D

 
Nahoru Odpovědět
8.6.2020 22:54
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:9.6.2020 0:25

To se občas stane. Trpělivost by však měla být neodmyslitelnou vlastností programátora. Ještě jedna věc, důležitá, kterou jsem Ti už jednou psal. Nesmíš pouze hledat hotová řešení, ať už na internetu, kdekoli. Je třeba se o to pokusit a nevzdávat se při prvním neúspěchu.

cloveku jako ja, co tomu horkotěžko rozumi to moc nevysvětlíš pomoci teorie.

To není teorie, to je algoritmizace. A tu je třeba neustále rozvíjet. A toho dosáhneš tak, že se budeš pokoušet vymýšlet řešení, ne ho někde dohledávat.

Nahoru Odpovědět
9.6.2020 0:25
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:9.6.2020 13:35
Sub Main()
        Dim karty(32) As Integer, rnd As New Random, pocet As Byte = 0
        Do
            Dim kule = rnd.Next(7, 14)
            Dim srdce = rnd.Next(7, 14)
            Dim zaludy = rnd.Next(7, 14)
            Dim piky = rnd.Next(7, 14)
            If Not karty.Contains(kule And zaludy And srdce And piky) Then
                karty(pocet) = kule And zaludy And srdce And piky
                pocet += 1
            End If
        Loop
        Console.ReadKey()

Vůbec jsem s tim nepohnul, to je jedine, co jsem dokazal dat dohromady, o cemz jsem si myslel, ze to muze fungovat, nefunguje a nevim, kde si mam dohledat informace, jak se pracuje s nahodnosti.

 
Nahoru Odpovědět
9.6.2020 13:35
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:9.6.2020 15:06

Jdeš na to přiliž kostrbatě. V prvé řadě by sis měl sestavit nezamíchaný balíček karet. Ten je tvořen z 32 karet ve kterém je 8 druhů hodnot, kde každá hodnota se opakuje 4x. Jakmile budeš mít balík hotov, provedeš simulaci zamíchání balíku. Jakmile budeš mít balík nasimulované zamíchání balíku, provedeš simulaci rozdání karet, atd, atd.. Není na tom nic těžkého. Je třeba si určit správný postup. V simulaci sestavení balíku a zamíchání balíku nepotřebuješ žádné if. Vše je o for cyklech, práce s polem, konkrétně s uloženými hodnotami a indexy.

Nahoru Odpovědět
9.6.2020 15:06
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:9.6.2020 15:55
Sub Main()
        Dim balikKaret(32) As Integer, rnd As New Random, pocet As Byte = 0, pomocnaKarty(32) As Integer
        For i = 1 To balikKaret.Length - 1
            balikKaret(i) = rnd.Next(7, 15)
            pomocnaKarty(balikKaret(i)) += 1
        Next
        For i = 1 To balikKaret.Length - 1
            Console.Write(balikKaret(i) & " ")
        Next
        Console.ReadKey()

Ted mi to sice konecne vygeneruje karty v rozpeti 7-14, ale nektere cisla mam vic nez 4x, nektere i třeba jenom 1, nekdy, jak to udelat, aby se mi opakovaly všechny 4x?

 
Nahoru Odpovědět
9.6.2020 15:55
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:9.6.2020 16:03

Pro sestavení balíku přeci nepotřebuješ generovat náhodná čísla, stačí 2 vnořené for cykly a máš hotov nezamíchaný balík karet.

index = 0;
for (int i = 7; i <= 14; i++) {
        for (int j = 0; j < 4; j++) {
                cards[index] = i;
                index++;
        }
}
Nahoru Odpovědět
9.6.2020 16:03
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:9.6.2020 21:12

Ja s tim proste nepohnu, ale vubec. Fakt neni nikde na siti neco, co by mi to pomohlo osvetlit, klidne v anglictine, cokoliv, protoze ja s tim nemam sanci pohnout, ani kdybych se posral, to se nepodoba nicemu, co jsem kdy zatim tvoril, nebo si to spis neumim predstavit.

 
Nahoru Odpovědět
9.6.2020 21:12
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:9.6.2020 21:34

Pokud budeš pořád myslet na to, že najdeš řešení někde jinde nežli ve své hlavě, pak těžko budeš schopen řešit další zejména obtížnější úlohy. Je jasné, že nemáš ještě tolik zkušeností, o to víc je třeba zabrat. Vytvořit něco nového je právě na tom to zajímavé, zase se něco nového naučíš. Jak už jsem psal, je třeba umět si to i způsob představit, jak danou úlohu řešit. Čím více budeš znát možnosti jazyka ve kterém tvoříš, tím to pro tebe bude snazší.

Podívej na následující program, ve kterém je příprava balíčku karet - jeho sestavení, jeho zamíchání.

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

#define NUMCARD 32
#define REPCARD 4
#define MINVAL 7
#define MAXVAL 14

int main(void) {
        int cards[NUMCARD], index, rnd, tmp;

        srand((unsigned int)(time(NULL)));

        // Nezamichany balicek karet
        index = 0;
        for (int i = MINVAL; i <= MAXVAL; i++) {
                for (int j = 0; j < REPCARD; j++) {
                        cards[index] = i;
                        index++;
                }
        }

        for (int i = 0; i < NUMCARD; i++) printf("%d ", cards[i]);
        putchar('\n');

        // Zamichany balicek karet
        for (int i = NUMCARD; i > 0; i--) {
                rnd = rand() % i;
                tmp = cards[i - 1];
                cards[i - 1] = cards[rnd];
                cards[rnd] = tmp;
        }

        for (int i = 0; i < NUMCARD; i++) printf("%d ", cards[i]);
        putchar('\n');

        return 0;
}

Výstup programu:

7 7 7 7 8 8 8 8 9 9 9 9 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14
12 13 7 8 11 12 14 9 14 13 8 14 7 7 11 12 8 10 9 12 14 9 7 8 11 10 9 10 13 11 13 10

Zkus pochopit jak daný program funguje. To hlavně. Není to těžké.. Přepiš si to do svého jazyka. Až to budeš mít, můžeš pokračovat dál, simulace rozdání karet oběma hráčům.

Nahoru Odpovědět
9.6.2020 21:34
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:9.6.2020 21:38

Paradoxne jsem s tim trosku pohnul. :D

Sub Main()
        Dim karty(32) As Integer, rnd As New Random, pocet As Integer = 0, pomocna As Integer, retezec As String = ""
        For i = 7 To 14
            For j = 0 To 3
                karty(pocet) = i
                pocet += 1
            Next
        Next
        For i = 0 To pocet - 1
            Console.Write(karty(i) & " ")
        Next
        For i = pocet - 2 To 0 Step -1
            For j = pocet - 2 To 0 Step -1
                Dim namichat As Integer = rnd.Next(31)
                pomocna = karty(i) : karty(i) = karty(namichat) : karty(namichat) = pomocna
            Next
        Next
        For i = 0 To pocet - 1
            retezec += Chr(10) + Str(karty(i))
        Next
        Console.WriteLine(retezec)
        Console.ReadKey()
    End Sub
 
Nahoru Odpovědět
9.6.2020 21:38
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:9.6.2020 21:40

Ne, ze bych to nejak vyzname ze zacatku chapal, to vubec, ale neco jsem prece jen nasel a strasne se to podoba Bublinkovemu trideni, tak jsem zkusil a jde to, uz jsem si zamichal karty, ale jak je ted rozdam dvoum hracum?

 
Nahoru Odpovědět
9.6.2020 21:40
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:9.6.2020 22:32

ale jak je ted rozdam dvoum hracum?

No zkus na to přijít. :-) Rozdané karty je třeba někde uchovat, nemohou viset někde v luftu. Takže nejspíš budeš potřebovat nějaká pole o konkrétní velikosti. Pro to pole si budeš muset vytvořit proměnnou, která bude určovat aktuální vrchní kartu. Protože to pole bude specifické, takový krásný kruhový zásobník :-) Umět si to představit, to bude teď tvůj největší spojenec. A rozdávej karty pěkně na střídačku, jako v reálu. Žádné 16 karet sem, 16 karet tam.

Nahoru Odpovědět
9.6.2020 22:32
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:10.6.2020 19:58
Sub Main()
        Dim karty(32) As Integer, rnd As New Random, pocet As Integer = 0, pomocna As Integer, prvniHrac(16) As Integer, druhyHrac(16) As Integer
        For i = 7 To 14
            For j = 0 To 3
                karty(pocet) = i
                pocet += 1
            Next
        Next
        For i = 0 To pocet - 1
            Console.Write(karty(i) & " ")
        Next
        Console.WriteLine()
        For i = 0 To pocet - 1
            Dim namichat As Integer = rnd.Next(32)
            pomocna = karty(i) : karty(i) = karty(namichat) : karty(namichat) = pomocna
        Next
        For i = 0 To pocet - 1
            Console.Write(karty(i) & " ")
        Next
        Console.WriteLine()
        For i = 1 To pocet - 2
            Dim rozdat As Integer = rnd.Next(32)
            pomocna = karty(i) : karty(i) = karty(rozdat) : karty(rozdat) = pomocna
            prvniHrac(karty(i)) += 1
            If prvniHrac(karty(i)) = 16 Then
                druhyHrac(karty(i)) += 1
            End If
        Next
        Console.WriteLine()
        For i = 1 To pocet - 2
            Console.Write("Prvni hrac: {0}", prvniHrac(i) & " ")
            Console.Write("Druhy hrac: {0}", druhyHrac(i) & " ")
        Next
        Console.ReadKey()
    End Sub

Tohle me nahodou napadlo, jestli by to alespon vzdalene mohlo pripominat rozdani karet mezi dva hrace, program samozrejme nefunguje, ale jenom se chci zeptat, jestli alespon kracim dobrou cestou, kdyz zamichani karet bylo jinymi slovy trideni, tak vlastne dalsi trideni by mohlo byt rozdani karet a kdyz se naplni jedno pole, zacne se plnit druhe, mohlo by to teoreticky nejak podobne fungovat?

 
Nahoru Odpovědět
10.6.2020 19:58
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:10.6.2020 20:53

Třídění do toho vůbec nepleť, to s tím nemá nic společného. O třídění by se dalo bavit pokud by si chtěl vytvářet ze zamíchaného balíku nezamíchaný, nějakým způsobem seřazený. Minimální podobnost je akorát v tom, že při míchání dochází k prohazování prvků.

Rozdání lze simulovat mnoha způsoby. Aby se rozdání blížilo realitě, tak je nejprve třeba určit hráče kterému bude přiřazena první karta. To můžeš určit napevno, náhodně, popř. dle toho, kdo vyhrál předchozí hru, apod. Jakmile určíš hráče, tak tomuto hráči budeš dávat karty na sudých indexech (0, 2 , 4, ... 30) a druhému hráči budeš dávat karty co jsou na lichých indexech (1, 3 ,5, ... 31).

Takže rozdáš celý zamíchaný balík, po kterém hodnoty pole reprezentující zamíchaný balík budou nulové. Ty karty nebudou viset v luftu ale budou je mít hráči. Takže pro každého hráče vytvoříš pole do kterého budeš ukládat hodnoty, představující karty. Obě tyto pole musí být velké 32, jelikož vítězný hráč drží všech 32 karet, prohraný nemá žádnou. Ta pole si musíš představit jako sloupce, hodnoty do nich ukládáš ze shora ale v žádném případě je nepřehazuješ! Vyhrané karty dáváš v pořadí, jakém byly vyloženy na stůl, za poslední prvek s nenulovou hodnotou v poli. Může nastat, že poslední prvek bude zaplněný. Pak musíš ukládat hodnoty ze shora. Jak už jsem psal, pole má charakter kruhového zásobníku a pro něj je třeba udržovat si pozici představující vrchní kartu hráčova balíku. To už ale předbíhám. Je třeba si to představit a podle toho algoritmus napsat.

Nahoru Odpovědět
10.6.2020 20:53
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:14.6.2020 10:54

Cau, prosim Te, jestli bys mohl podivej se mi na to, co tam delam spatne, ze mi na vystupu hlasi System.Int32. Program by mel delat to, ze kdyz do nej zadam libovolne mnozstvi cisel ukoncenych nulou, cisla si ulozi a pote se me zepta, ktere cislo si chci zopakovat, ja nejake zadam a on mi sdeli, kolikrat bylo cislo zadano.

Sub Main()
        Dim cisla(100) As Integer, cislo As Integer, pocet As Byte = 0, i As Integer
        Do
            Console.WriteLine("Zadej libovolne cislo: [0 ukoncuje zadavani]") : cislo = Console.ReadLine()
            If cislo <> 0 Then
                cisla(pocet) = cislo
                pocet += 1
            End If
        Loop While cislo <> 0
        For i = 0 To pocet - 1
            Console.Write(cisla(i) & " ")
        Next
        Console.WriteLine()
        Console.WriteLine("Zadej opakovane cislo:") : Dim opakovane As Integer = Console.ReadLine()
        cisla = PocetVyskytu(cisla, opakovane)
        Console.WriteLine(cisla)
        Console.ReadKey()
    End Sub
    Function PocetVyskytu(a() As Integer, c As Integer) As Integer()
        Dim opakovani As Integer = 0
        For Each i In a
            If a.Contains(c) Then
                opakovani += 1
            End If
        Next
        Return a
    End Function
End Module
 
Nahoru Odpovědět
14.6.2020 10:54
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:14.6.2020 11:55

V programu máš několik chyb. Úvodní načítací smyčka neobsahuje ochranu proti přetečení pole. Dále funkce PocetVyskytu() by měla obsahovat 3 parametry. První předávané pole, druhý počet prvků pole které funkce bude procházet a třetí číslo, ke kterému se bude vztahovat počet opakování. Další chybou je, že funkce má vracet počet opakování. A nakonec End Module je v kódu osamocený.

Zde je program napsaný v C.

#include <stdio.h>

#define SIZE 100

int pocetVyskytu(int pole[], int velikost, int num);

int main(void) {
        int cislo, pocet = 0, cisla[SIZE];

        do {
                printf("Zadej cislo: ");
                scanf("%d", &cislo);
                if (!cislo) break;
                cisla[pocet++] = cislo;
        } while (pocet < SIZE);

        for(int i = 0; i < pocet; i++) printf("%d ", cisla[i]);
        putchar('\n');

        printf("Zadej cislo: ");
        scanf("%d", &cislo);

        printf("Cislo %d se v poli vyskytuje: %dx: ", cislo, pocetVyskytu(cisla, pocet, cislo));

        return 0;
}

int pocetVyskytu(int pole[], int velikost, int num) {
        int n = 0;

        for (int i = 0; i < velikost; i++) if (pole[i] == num) n++;

        return n;
}

Výstup programu:

Zadej cislo: 1
Zadej cislo: 2
Zadej cislo: 3
Zadej cislo: 4
Zadej cislo: 5
Zadej cislo: 2
Zadej cislo: 3
Zadej cislo: 4
Zadej cislo: 5
Zadej cislo: 2
Zadej cislo: 4
Zadej cislo: 5
Zadej cislo: 0
1 2 3 4 5 2 3 4 5 2 4 5
Zadej cislo: 2
Cislo 2 se v poli vyskytuje: 3x:
Nahoru Odpovědět
14.6.2020 11:55
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:14.6.2020 12:54

Diky, ale to uz je v cajku, spis mam dalsi problem, nebo problem, spis se mi nelibi muj zpusob zpracovani, proste mi v aplikaci neco precniva, ja vim, co to je, ale jak se toho zbavit, je vec druha.

Sub Main()
        Dim rnd As New Random, pocet As Integer = 0
        Console.WriteLine("Kolikrat si hodime kostkou?") : Dim pocetHodu As Integer = Console.ReadLine()
        Dim cisla() As Integer = New Integer(pocetHodu - 1) {}
        For i = 0 To cisla.Length - 1
            cisla(i) = rnd.Next(1, 7)
            Console.Write(cisla(i) & " ")
            pocet += 1
        Next
        Console.WriteLine()
        Console.WriteLine(PocetPadlych(cisla))
        Console.ReadKey()
    End Sub
    Function PocetPadlych(hodyKostkou() As Integer) As Integer()
        Dim hod As Integer, cetnosti(6) As Integer
        For i = 0 To hodyKostkou.Length - 1
            hod = hodyKostkou(i)
            cetnosti(hod) = cetnosti(hod) + 1
        Next
        For i = 1 To 6
            Console.WriteLine("{0} padlo {1}x", i, cetnosti(i))
        Next
        Return Nothing
    End Function

Jak vidis, navratova hodnota je Nothing, ktera ale vytvori prazdny radek, coz neni uplne dobre, jelikoz sam nevim, jak to nahradit, aby navratova hodnota dala pouze vystup bez radku Sys.Int32, ktery prave prekryju hodnotou Nothing. Poradil bys mi, prosim Te?

 
Nahoru Odpovědět
14.6.2020 12:54
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:14.6.2020 13:48

To co Ti v programu přečnívá je proměnná pocet a její použítí ve for cyklu, které je úplně zbytečné. Funkce PocetPadlych() má vracet čeločíselnou hodnotu, takže použít return Nothing je v programu chybné. Navíc toto nezpůsobuje to že funkce vytvíří prázdný řádek. Pro zjištění četnosti bude hodnota nabývat v oboru přirozených čísel (0 .. N). Prvky pole pro zjištění četnosti by mělo být nastaveny na 0. Uvnitř funkce by se mělo procházet pole jehož argument je použit při volání funkce. U toho se zvyšuje hodnota na indexu odpovídající hodnotě pole. Nakonec procházíš cyklem celé pole četnosti a zjišťuješ, kde hodnota na daném indexu není nulová. Počet těchto nenulových hodnot je to co funkce má vracet.

Nahoru Odpovědět
14.6.2020 13:48
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:14.6.2020 14:18

Aha, tak uz podruhe za sebou jsem mel radek navic, Console.Write­Line(PocetPadlych(cis­la)), tam byl navic, kdyz jsem nechal radek PocetPadlych(cisla) jako posledni v hlavni subrutine, vystup je tak, jak ma byt. :D

 
Nahoru Odpovědět
14.6.2020 14:18
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:14.6.2020 14:34

Volání funkce v hlavní části programu je správné. Funkce Ti vypisuje četnosti, ale nikoli unikátní.

Takto by to třeba vypadalo v C:

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

#define CUBE 6

int uniqueThrows(int arr[], int size, int cube);

int main(void) {
        int throws, *list = NULL;

        srand((unsigned int)(time(NULL)));

        printf("Zadej pocet hodu: ");
        scanf("%d", &throws);

        list = (int *)malloc(throws * sizeof(int));
        if (!list) exit(1);

        for (int i = 0; i < throws; i++) {
                list[i] = (rand() % CUBE) + 1;
                printf("%d ", list[i]);
        }
        putchar('\n');

        printf("Pocet unikatnich hodu: %dx: ", uniqueThrows(list, throws, CUBE));

        free(list);
        list = NULL;

        return 0;
}

int uniqueThrows(int arr[], int size, int cube) {
        int count = 0, *list = NULL;

        list = (int *)calloc(cube, sizeof(int));
        if (!list) exit(1);

        for (int i = 0; i < size; i++) list[arr[i] - 1]++;
        for (int i = 0; i < cube; i++) {
                printf("%d: %dx\n", i+1, list[i]);
                if (list[i]) count++;
        }

        free(list);
        list = NULL;

        return count;
}

Výstup programu:

Zadej pocet hodu: 10
3 2 6 2 4 6 1 2 3 3
1: 1x
2: 3x
3: 3x
4: 1x
5: 0x
6: 2x
Pocet unikatnich hodu: 5x:
Editováno 14.6.2020 14:35
Nahoru Odpovědět
14.6.2020 14:34
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:18.6.2020 20:02

Cau, muzu Te poprosit o radu, zkusil jsem si k Te Vojne znovu sednout a povedlo se mi prerozdelit karty mezi 2 hrace, nebo si alespon myslim, ze se mi neco takoveho povedlo, ale spis mam pocit, ze jsem si svym zpusobem moc nepomohl, dokazal bys mi poradit necim, co by me posunulo dal dopredu? Diky

Sub Main()
        Dim pocet As Byte = 0, cisla(31) As Integer, rnd As New Random
        Dim pomocna As Integer
        For i = 7 To 14
            For j = 0 To 3
                cisla(pocet) = i
                pocet += 1
            Next
        Next
        Console.WriteLine("Nezamichany balicek:")
        For i = 0 To pocet - 1
            Console.Write(cisla(i) & " ")
        Next
        Console.WriteLine()
        For i = 0 To pocet - 1
            Dim nahodne As Integer = rnd.Next(32)
            pomocna = cisla(i) : cisla(i) = cisla(nahodne) : cisla(nahodne) = pomocna
        Next
        Console.WriteLine("Zamichany balicek:")
        For i = 0 To pocet - 1
            Console.Write(cisla(i) & " ")
        Next
        Console.WriteLine()
        Console.WriteLine("Prvni hrac:")
        For i = 0 To pocet - 1
            If i Mod 2 = 0 Then
                Console.Write(cisla(i) & " ")
            End If
        Next
        Console.WriteLine()
        Console.WriteLine("Druhy hrac:")
        For i = 0 To pocet - 1
            If Not i Mod 2 = 0 Then
                Console.Write(cisla(i) & " ")
            End If
        Next
        Console.ReadKey()
    End Sub
 
Nahoru Odpovědět
18.6.2020 20:02
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:18.6.2020 20:28

Karty stále nemáš rozdělené mezi hráče. Pouze si vypsal karty které by každý hráč měl mít, ale to takto nemůžeš. Ty karty musí být na straně hráčů. Jak jsem psal, každý hráč má zásobník a ze zamíchaného balíku je třeba ty karty přesunout do hráčova zásobníku. Tím dáváš najevo, že karty má hráč. Vypsání karet je orientační ale logicky nesprávné, neboť karty jsou komukoli skryty. Takže vytvoř pro každého hráče pole o velikosti počtu karet, do těchto polí nakopíruj podle výsledku modula 2 karty z balíku a vytvoř si proměnné pro to, kde začínají a kočí karty s nenulovou hodnotou. Nenulová hodnota značí že na daném indexu je karta, nulová hodnota že na daném indexu pole karta není.

Nahoru Odpovědět
18.6.2020 20:28
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:18.6.2020 22:22

Dík za radu, ale moc mi to nepomohlo.

 
Nahoru Odpovědět
18.6.2020 22:22
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:18.6.2020 22:52

Je třeba si to představit, deklarovaná pole představují to co mají hráči na ruce. Určuje to počet karet, pořadí karet, to která karta je na vrchu a která na spodu. To vše se mění v průběhu hry.

int pack1[NUMCARD] = { 0 }, pack2[NUMCARD] = { 0 };
int top1 = 0, bot1 = 0, top2 = 0, bot2 = 0;

for (int i = 0; i < NUMCARD; i++) {
        if (!(i % 2)) {
                pack1[bot1] = cards[i];
                bot1++;
        }
        else {
                pack2[bot2] = cards[i];
                bot2++;
        }
}

for (int i = 0; i < NUMCARD; i++) printf("%d ", pack1[i]);
putchar('\n');

for (int i = 0; i < NUMCARD; i++) printf("%d ", pack2[i]);
putchar('\n');

printf("%d %d %d %d\n", top1, bot1, top2, bot2);

Výstup programu (doplněn i výpis o nezamíchaný a zamíchaný balíček karet):

7 7 7 7 8 8 8 8 9 9 9 9 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14
12 12 9 8 13 7 10 9 14 14 13 7 11 14 8 11 11 14 11 7 9 10 10 7 10 8 9 12 12 8 13 13
12 9 13 10 14 13 11 8 11 11 9 10 10 9 12 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
12 8 7 9 14 7 14 11 14 7 10 7 8 12 8 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 16 0 16

Jak vidíš, každý hráč drží na ruce 16 karet. Hodnoty jsou pouze ilustrativní a kontrolního charakteru, ty normálně pro nikoho vidět nejsou. Dále vidíš, z jakého indexu oba hráči budou brát následující kartu (index 0) a od jakého indexu se budou ukládat vyhrané karty (index 16). Není zde kontrola přetečení zásobníku, pro rozdávání karet to není třeba. Avšak pro samostatná kola hry bude kontrola mezi zásobníku důležitá.

Dalším krokem je vybrání hráče, který bude začínat hru a samotný průběh hry. Můžeš pokračovat.

Nahoru Odpovědět
18.6.2020 22:52
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Ondrej Zadrapa
DarkCoder:18.6.2020 23:00

Aby to bylo úplně správně, je třeba nasimulovat vydání karet z balíku odstraněním karet z balíku.

Je tedy třeba přidat řádek:

cards[i] = 0;

Takto je to správně:

for (int i = 0; i < NUMCARD; i++) {
        if (!(i % 2)) {
                pack1[bot1] = cards[i];
                bot1++;
        }
        else {
                pack2[bot2] = cards[i];
                bot2++;
        }
        cards[i] = 0;
}

Nyní každý hráč má 16 karet a v balíku, ze kterého se karty rozdávaly, není žádná.

Nahoru Odpovědět
18.6.2020 23:00
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Ondrej Zadrapa:18.6.2020 23:57

No, tak uz to mam i hotove, mam z toho takove smisene pocity, ale jestli mi to ma v necem pomoci, beru to. Diky moc.

 
Nahoru Odpovědět
18.6.2020 23:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 37 zpráv z 37.