Diskuze: Problem se zjistovanim opakovani a poctu opakovani
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


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í.
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?
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.
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.
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
+20 Zkušeností
+2,50 Kč

Ondrej Zadrapa:8.6.2020 14:45
Ze existuje něco jako pole v poli, to vidim prvne.
DarkCoder:8.6.2020 15:07
Ze existuje něco jako pole v poli, to vidim prvne.
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]++;
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?
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>.
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?
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.
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. Ale i tak diky za snahu, dneska
na to kaslu, zkusim to zítra.
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.
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.
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.
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?
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++;
}
}
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.
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.
Ondrej Zadrapa:9.6.2020 21:38
Paradoxne jsem s tim trosku pohnul.
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
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?
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.
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?
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.
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
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:
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?
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.
Ondrej Zadrapa:14.6.2020 14:18
Aha, tak uz podruhe za sebou jsem mel radek navic,
Console.WriteLine(PocetPadlych(cisla)), tam byl navic, kdyz jsem nechal
radek PocetPadlych(cisla) jako posledni v hlavni subrutine, vystup je tak, jak
ma byt.
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:
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
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í.
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.
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á.
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.
Zobrazeno 37 zpráv z 37.