PDA

Visualizza la versione completa : [C] Programma sorteggio giocatori


bicco3419
08-05-2017, 23:10
Salve a tutti, sono nuovo nel forum.
Sto cercando di creare un semplice programma per un torneo per il calcio balilla da terminale che sia in grado di sorteggiare un numero "npl" di giocatori, definiti dall'utente in equal modo per un numero "p" di partite, anch'esse definite dall'utente. Partite da 2 vs 2. La prima parte è funzionante e verificata, in quella nuova, non riesco a copiare le stringhe sorteggiate della matrice dei giocatori (player[][]) alle stringhe della matrice "temporanea" a[][]. Qualcuno è in grado di aiutarmi? Ringrazio in anticipo per l'aiuto e la pazienza! :zizi:



#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 256

int main()
{
int npl, i, j, y, z, p, n;
srand( time ( NULL) );
printf("Inserire numero giocatori: ");
scanf("%d", &npl);
y = (0 + rand() % npl);
char player[npl][N];
for (i = 0; i < npl; i++) {
printf("\ninserire nome giocatore %d:", i+1);
scanf("%s", player[i]);
}
for (j = 0; j < npl; j++) {
printf("\n%s", player[j]);
}
//PARTE NUOVA
printf("\nInserire numero partite totali: ");
scanf("%d", &n);
for (p = 0; p < n; ) {
char a[4][N];
for (z = 0; z < 4; z++) {
y = rand() % 4 + 1;
player[y][N] = a[z];
}

printf("\n%s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
p++;
}
return 0;
}

torn24
10-05-2017, 08:14
Ciao, in C devi usare la funzione strcpy()

http://www.cplusplus.com/reference/cstring/strcpy/

Ma il tuo programma potrebbe non dare i risultati voluti perché la funzione,istruzione y = rand() % 4 + 1; potrebbe restituire più volte lo stesso risultato-numero, quindi dovresti realizzare un controllo su i numeri generati.

bicco3419
10-05-2017, 11:01
Ciao, in C devi usare la funzione strcpy()

http://www.cplusplus.com/reference/cstring/strcpy/

Ma il tuo programma potrebbe non dare i risultati voluti perché la funzione,istruzione y = rand()%4+1; potrebbe restituire più volte lo stesso risultato-numero, quindi dovresti realizzare un controllo su i numeri generati.

Grazie mille per la risposta! Ieri sera ho ottimizzato il programma e ho risolto il problema copia della stringa...sto cercando un modo efficace per non ripetere lo stesso sorteggio in una partita, posso farlo con un controllo sui valori precedenti e non dovrebbe essere un problema, il problema principale è riuscire a contare quante volte ogni giocatore giocatore appare, di modo tale che ognuno giochi più o meno lo stesso numero di partite. Hai qualche idea/spunto per questo conto?
Codice:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 32

int main(){
int i, j, p, z, k, N, y;
char s[MAX];
srand(time(NULL));
do {
printf("Inserire numero giocatori: ");
gets(s);
N = atoi(s);
if (N < 4 || N > MAX)
printf("Valore errato: deve essere tra 4 e %d\n", MAX);
} while (N < 4 || N > MAX);
char player[N][MAX];
for (i = 0; i < N; i++) {
printf("Giocatore %d: ", i+1);
gets(s);
if (strlen(s) == 0) {
printf("Nessun giocatore specificato - ripeti\n");
i--;
}
else
strcpy(player[i], s);
}
for (j = 0; j < N; j++) { //CONTROLLO
printf("\n%s", player[j]);
}
printf("\nInserire numero partite totali: ");
scanf("%d", &p);
for (i = 0; i < p; i++) {
char a[4][MAX];
for (j = 0, z = 0; j < 4; j++, z++) {
y = (0 + rand() % N);
strcpy(a[j],player[y]);
}
}
printf("\n %s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
}
return 0;
}

torn24
10-05-2017, 11:54
Ciao, una soluzione da implementare "realizzare col codice"

1) dividi numero partite per numero giocatori, e trovi quante partite massime può fare un giocatore
2) Ti crei un array dome memorizzi il sorteggio PartiteGiocatori[] inizializzato a zero
Short PartiteGiocatori[MAXGIOCATORI]={0};

3) Ad ogni numero estratto verifichi che il giocatore ha giocato meno partite del massimo, e incrementi di uno

if(PartiteGiocatori[indice]<massimoPartite)
esegui....

bicco3419
10-05-2017, 11:59
Ciao, una soluzione da implementare "realizzare col codice"

1) dividi numero partite per numero giocatori, e trovi quante partite massime può fare un giocatore
2) Ti crei un array dome memorizzi il sorteggio PartiteGiocatori[] inizializzato a zero
Short PartiteGiocatori[MAXGIOCATORI]={0};

3) Ad ogni numero estratto verifichi che il giocatore ha giocato meno partite del massimo, e incrementi di uno

if(PartiteGiocatori[indice]<massimoPartite)
esegui....

Grazie mille per il consiglio, sta sera cercherò di applicarlo!

bicco3419
11-05-2017, 00:55
Ciao, una soluzione da implementare "realizzare col codice"

1) dividi numero partite per numero giocatori, e trovi quante partite massime può fare un giocatore
2) Ti crei un array dome memorizzi il sorteggio PartiteGiocatori[] inizializzato a zero
Short PartiteGiocatori[MAXGIOCATORI]={0};

3) Ad ogni numero estratto verifichi che il giocatore ha giocato meno partite del massimo, e incrementi di uno

if(PartiteGiocatori[indice]<massimoPartite)
esegui....

Ciao, ho seguito le tue istruzioni sul programma, ma mi sono inceppato in un dilemma. Ho creato il controllo sulla ripetizione in una partita e funziona. Invece la ripetizione di un giocatore su tutte le partite è diventata un grosso problema, mi sa che sto sbagliando ragionamento: più che altro nel quando incrementare "partitegiocatori[y]. Potresti dare un'occhiata veloce al programma e indicarmi dov'è che sbaglio e dove dovrei mettere quell'incremento? :confused: Grazie, o in generale se qualcuno riesce a trovare una soluzione al mio problema



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 32

int main(){
int i, j, p, k, N, y, partitemax;
char s[MAX];
srand(time(NULL));
do {
printf("Inserire numero giocatori: ");
gets(s);
N = atoi(s);
if (N < 4 || N > MAX)
printf("Valore errato: deve essere tra 4 e %d\n", MAX);
} while (N < 4 || N > MAX);
short partitegiocatori[N];
for (i = 0; i < N; i++) {
partitegiocatori[i] = 0;
}
char player[N][MAX];
for (i = 0; i < N; i++) {
printf("Giocatore %d: ", i+1);
gets(s);
if (strlen(s) == 0) {
printf("Nessun giocatore specificato - ripeti\n");
i--;
}
else
strcpy(player[i], s);
}
printf("\nInserire numero partite totali: ");
scanf("%d", &p);
partitemax = p / N;
printf("Per un gioco totalmente equilibrato saranno giocate %d partite", partitemax*N);
for (i = 0; i < (partitemax*N); i++) {
char a[4][MAX];
for (j = 0; j < 4; j++) {
y = (0 + rand() % N);
if (partitegiocatori[y] < partitemax) {
strcpy(a[j],player[y]);
for (k = j-1; k >= 0; k--) {
if (strcmp(a[k], a[j]) == 0)
j--;
else
partitegiocatori[y]++;
}
}
}
printf("\n %s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
}
return 0;
}

torn24
11-05-2017, 07:51
Ciao. premetto che capire il codice di un altro può risultare più complicato che inventarsi una propria
soluzione, perché bisogna capire il ragionamento, l'idea di un altra persona.

Ti propongo una piccola modifica al codice, non ho provato e non so se funziona, ma potresti prendere ugualmente spunto per una soluzione...




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 32


int main(){
int i, j, p, k, N, y, partitemax;
char s[MAX];
srand(time(NULL));
do {
printf("Inserire numero giocatori: ");
gets(s);
N = atoi(s);
if (N < 4 || N > MAX)
printf("Valore errato: deve essere tra 4 e %d\n", MAX);
} while (N < 4 || N > MAX);
short partitegiocatori[N];
for (i = 0; i < N; i++) {
partitegiocatori[i] = 0;
}
char player[N][MAX];
for (i = 0; i < N; i++) {
printf("Giocatore %d: ", i+1);
gets(s);
if (strlen(s) == 0) {
printf("Nessun giocatore specificato - ripeti\n");
i--;
}
else
strcpy(player[i], s);
}
printf("\nInserire numero partite totali: ");
scanf("%d", &p);
partitemax = p / N;
printf("Per un gioco totalmente equilibrato saranno giocate %d partite", partitemax*N);
for (i = 0; i < (partitemax*N); i++) {
char a[4][MAX];
for (j = 0; j < 4; j++)
a[j][0]='\0';
int flag=0;
int estratto=0;
for (j = 0; j < 4; j++) { //Ripete per 4 giocatori

do{ // Ripete finché non viene estratto un numero valido
y = (0 + rand() % N);
for (k = 0; k < 4; k++) { //Verifica che non sia ripetuto nei 4 giocatori
if (K!=J && strcmp(a[k], a[j]) == 0){
estratto=1;
break;
}
else
estratto=0;
}
if(estratto==0 && partitegiocatori[y] < partitemax){
partitegiocatori[y]++;
strcpy(a[j],player[y]);
flag=1; // esce dal do while, il numero estratto è valido
}
else{
continue; // se il numero non è valido perché ha superato partitemax o perché il giocatore è gia estratto
}


}while(flag==0);
flag=0; // metto di nuovo a zero per il prossimo giocatore del for()
}
printf("\n %s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
}
return 0;
}

bicco3419
11-05-2017, 09:17
Ciao. premetto che capire il codice di un altro può risultare più complicato che inventarsi una propria
soluzione, perché bisogna capire il ragionamento, l'idea di un altra persona.

Ti propongo una piccola modifica al codice, non ho provato e non so se funziona, ma potresti prendere ugualmente spunto per una soluzione...




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 32


int main(){
int i, j, p, k, N, y, partitemax;
char s[MAX];
srand(time(NULL));
do {
printf("Inserire numero giocatori: ");
gets(s);
N = atoi(s);
if (N < 4 || N > MAX)
printf("Valore errato: deve essere tra 4 e %d\n", MAX);
} while (N < 4 || N > MAX);
short partitegiocatori[N];
for (i = 0; i < N; i++) {
partitegiocatori[i] = 0;
}
char player[N][MAX];
for (i = 0; i < N; i++) {
printf("Giocatore %d: ", i+1);
gets(s);
if (strlen(s) == 0) {
printf("Nessun giocatore specificato - ripeti\n");
i--;
}
else
strcpy(player[i], s);
}
printf("\nInserire numero partite totali: ");
scanf("%d", &p);
partitemax = p / N;
printf("Per un gioco totalmente equilibrato saranno giocate %d partite", partitemax*N);
for (i = 0; i < (partitemax*N); i++) {
char a[4][MAX];
for (j = 0; j < 4; j++)
a[j][0]='\0';
int flag=0;
int estratto=0;
for (j = 0; j < 4; j++) { //Ripete per 4 giocatori

do{ // Ripete finché non viene estratto un numero valido
y = (0 + rand() % N);
for (k = 0; k < 4; k++) { //Verifica che non sia ripetuto nei 4 giocatori
if (K!=J && strcmp(a[k], a[j]) == 0){
estratto=1;
break;
}
else
estratto=0;
}
if(estratto==0 && partitegiocatori[y] < partitemax){
partitegiocatori[y]++;
strcpy(a[j],player[y]);
flag=1; // esce dal do while, il numero estratto è valido
}
else{
continue; // se il numero non è valido perché ha superato partitemax o perché il giocatore è gia estratto
}


}while(flag==0);
flag=0; // metto di nuovo a zero per il prossimo giocatore del for()
}
printf("\n %s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
}
return 0;
}




Ciao, so che leggere il codice di qualcun altro puo' essere molto difficile, soprattutto se questo qualcun altro e' alle prime armi e non usa una certa formattazione (commenti specifici, dichiarazioni esplicite...) percio' apprezzo tantissimo il tuo sforzo e grazie mille per l'aiuto che mi stai dando. Oggi appena ho tempo provo ad eseguire il codice e soprattutto capirlo/adattarlo se c'e' qualcosa che non torna. Grazie ancora per l'aiuto e per la pazienza! :)

bicco3419
12-05-2017, 00:00
Ciao. premetto che capire il codice di un altro può risultare più complicato che inventarsi una propria
soluzione, perché bisogna capire il ragionamento, l'idea di un altra persona.

Ti propongo una piccola modifica al codice, non ho provato e non so se funziona, ma potresti prendere ugualmente spunto per una soluzione...




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 32


int main(){
int i, j, p, k, N, y, partitemax;
char s[MAX];
srand(time(NULL));
do {
printf("Inserire numero giocatori: ");
gets(s);
N = atoi(s);
if (N < 4 || N > MAX)
printf("Valore errato: deve essere tra 4 e %d\n", MAX);
} while (N < 4 || N > MAX);
short partitegiocatori[N];
for (i = 0; i < N; i++) {
partitegiocatori[i] = 0;
}
char player[N][MAX];
for (i = 0; i < N; i++) {
printf("Giocatore %d: ", i+1);
gets(s);
if (strlen(s) == 0) {
printf("Nessun giocatore specificato - ripeti\n");
i--;
}
else
strcpy(player[i], s);
}
printf("\nInserire numero partite totali: ");
scanf("%d", &p);
partitemax = p / N;
printf("Per un gioco totalmente equilibrato saranno giocate %d partite", partitemax*N);
for (i = 0; i < (partitemax*N); i++) {
char a[4][MAX];
for (j = 0; j < 4; j++)
a[j][0]='\0';
int flag=0;
int estratto=0;
for (j = 0; j < 4; j++) { //Ripete per 4 giocatori

do{ // Ripete finché non viene estratto un numero valido
y = (0 + rand() % N);
for (k = 0; k < 4; k++) { //Verifica che non sia ripetuto nei 4 giocatori
if (K!=J && strcmp(a[k], a[j]) == 0){
estratto=1;
break;
}
else
estratto=0;
}
if(estratto==0 && partitegiocatori[y] < partitemax){
partitegiocatori[y]++;
strcpy(a[j],player[y]);
flag=1; // esce dal do while, il numero estratto è valido
}
else{
continue; // se il numero non è valido perché ha superato partitemax o perché il giocatore è gia estratto
}


}while(flag==0);
flag=0; // metto di nuovo a zero per il prossimo giocatore del for()
}
printf("\n %s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
}
return 0;
}




Ciao! Sfortunatamente sono ancora io :ciauz: Ho controllato la tua proposta per il programma e ho capito il tuo funzionamento logico, il quale mi sembra giusto. Il programma non funziona, così l'ho analizzato col debugger e i watches attivi per controllare tutti i valori delle singole variabili. Da quel che ho capito, il problema sta nella variabile "short partitegiocaotori[N]", che anche se subito dopo viene avviato il comando, non si inizializza mai a 0. Ho provato a fare di tutto per cercare di inizializzarla, anche creandola come matrice, ma non ne vuole sapere. Per colpa di questa variabile non inizializzata ovviamente non parte il ciclo del flag, creando un loop infinito nel serteggio (ho messo un printf per il valore di y per controllare e infatti il programma non termina mai, ma continua a sorteggiare la y all'infinito). Se avresti una soluzione/proposta a tale problema te ne sarei enormemente grato, grazie!

torn24
12-05-2017, 10:26
NON QUOTARE sempre perch� non � necessario e rende meno leggibile :)

1) Premetto che sono un autodidatta in linguaggio C, quindi non sono certo l'insegnante migliore.

Ma il C non � il C++, le variabili e gli array, dovrebbero essere dichiarate a inizio programma per le variabili globali, e a inizio funzione per le variabili locali.
Le dimensioni degli array devono essere costanti e non variabili.
Tu dichiari le variabili in ogni posto e quando ti servono, molti compilatori ti darebbero errore, non vanno dichiarate all'interno di un ciclo perch� a ogni ciclo verrebbero "ricreate" e tu lo fai.

Ho provato a compilare, e a parte gli errori che ti ho detto, � l'algoritmo che non � corretto

Questa parte del codice che serve per vedere se nei 4 giocatori � stato gi� estratto il nome
non funziona molto bene :confused:



for(k =0; k <4; k++){//Verifica che non sia ripetuto nei 4 giocatori
if(K!=J && strcmp(a[k], a[j])==0){
estratto=1;
break;
}
else
estratto=0;
}



Questo � il programma con le variabili dichiarate a inizio funzione, e le dimensioni array costani.
Ora � lo stesso un po incasinato, funziona in parte per il problema del codice sopra postato.





#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 32
#define N 20


int main() {
int i, j, p, k,n, y, partitemax;
int flag = 0;
int estratto = 0;
char s[MAX];
char player[N][MAX];
short partitegiocatori[N] = { 0 };
char a[4][MAX];
for (j = 0; j < 4; j++)
a[j][0] = '\0';

srand(time(NULL));
do {
printf("Inserire numero giocatori: ");


scanf("%d",&n);
if (n < 4 || n > MAX)
printf("Valore errato: deve essere tra 4 e %d\n", MAX);
} while (n < 4 || n > MAX);


getchar();


for (i = 0; i < n; i++) {
printf("Giocatore %d: ", i + 1);
gets(s);
if (strlen(s) == 0) {
printf("Nessun giocatore specificato - ripeti\n");
i--;
}
else
strcpy(player[i], s);
}
printf("\nInserire numero partite totali: ");
scanf("%d", &p);


partitemax = p / n;
printf("Per un gioco totalmente equilibrato saranno giocate %d partite\n", partitemax*n);
for (i = 0; i < (partitemax*n); i++) {




for (j = 0; j < 4; j++) {


do {
y = (0 + rand() % n);


for (k = 0; k < 4; k++) {
if ( strcmp(player[y], a[k]) == 0) {
estratto = 1;
break;
}
else
estratto = 0;
}


if (estratto == 0 && partitegiocatori[y] < partitemax) {
partitegiocatori[y]++;
strcpy(a[j], player[y]);
flag = 1;
}
else {


continue;


}




} while (flag == 0);
flag = 0;




}
printf("\n %s - %s VS %s - %s", a[0], a[1], a[2], a[3]);
for (j = 0; j < 4; j++)
a[j][0] = '\0';
}
getchar();
return 0;
}






Ha degli errori, ma io mi fermo qui SAREBBE DA RIVEDERE COMPLETAMENTE ;) :)

Loading