Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  18 1950
Startet med C++ i dag og forsøker å lage det klassiske "gjett hvilket tall det er" programmet

Kode

int main()
{
int randnumb = rand() % 50;
int useranswer;
int trycount = 0;
cout << "*** The Guessing Game ***" << endl << endl << "Try To Guess A Random Number Betweeen 0-50." << endl << "You Have " << trycount + 8 << " Tries." << endl;
do
{
cin >> useranswer;
trycount = trycount + 1;

if (useranswer < randnumb)
	cout << "Too Low! - " << "Tries " << trycount << " of 8" <<endl;
else if (useranswer > randnumb)
	cout << "Too High! - " << "Tries " << trycount << " of 8" <<endl;
else
	cout << "Correct! - You Guessed The Number In " << trycount <<" Tries" <<endl;
}
while (useranswer != randnumb || trycount !=8);
system("pause");
return 0;
}
Hva er riktig syntax på denne linjen?

Kode

while (useranswer != randnumb || trycount !=8);
Jeg vil at programmet avslutter hvis svaret er riktig eller antall forsøk har nådd 8.

Hvis jeg kjører koden slik den står vil programmet aldri avslutte. Hvis jeg fjerner "|| trycount !=8" avslutter programmet når svaret blir riktig.

er || riktig å bruke i denne situasjonen?
|| betyr OR/eller. Det betyr at programmet ikke avslutter før begge statements er false. Du er nok ute etter AND, &&.
Det er ingen syntaktisk, men en logisk feil. Du ønsker å fortsette så lenge useranswer ikke er lik randnumb OG trycount ikke er lik 8. Bruk && i stedet.
Orbiter's Avatar
Trådstarter
Sitat av ivioynar Vis innlegg
|| betyr OR/eller. Det betyr at programmet ikke avslutter før begge statements er false. Du er nok ute etter AND, &&.
Vis hele sitatet...
Takk, takk. Det fungerte.

Den aktuelle linjen ser nå slik ut:

Kode

while (useranswer != randnumb && trycount !=8);
Du kan jo saktens formulere det om som !(useranswer == randnumb || trycount == 8), som kanskje blir tettere opp til det du tenkte deg. Kan leses som så lenge ikke (gjetning treffer eller antall gjett blir for høyt)

edit: Du har jo nettopp startet med c++, så det kan jo være et illustrerende poeng å se at denne programsnutten kan skrives på mange måter. For eksempel kan du velge å i stedet for en do/while-løkke med termineringsbetingelse, så kan du ha en evig løkke du bryter ut av. Dette kan kanskje være mer intuitivt:

Kode

int main()
{
int randnumb = rand() % 50;
int useranswer;
int trycount = 0;
cout << "*** The Guessing Game ***" << endl << endl << "Try To Guess A Random Number Betweeen 0-50." << endl << "You Have " << trycount + 8 << " Tries." << endl;
while(True)
{
if(trycount == 8 || useranswer == randnumb){
     break;
}
cin >> useranswer;
trycount = trycount + 1;

if (useranswer < randnumb)
	cout << "Too Low! - " << "Tries " << trycount << " of 8" <<endl;
else if (useranswer > randnumb)
	cout << "Too High! - " << "Tries " << trycount << " of 8" <<endl;
else
	cout << "Correct! - You Guessed The Number In " << trycount <<" Tries" <<endl;
};
system("pause");
return 0;
}
Sist endret av ivioynar; 8. juli 2011 kl. 22:22.
Repost av ivioynar sitt inlegg for økt leslighet:

Kode

int main() {
	int randnumb = rand() % 50;
	int useranswer;
	int trycount = 0;

	cout << "*** The Guessing Game ***" << endl << endl << "Try To Guess A Random Number Betweeen 0-50." << endl << "You Have " << trycount + 8 << " Tries." << endl;

	while( True ) {
		if( trycount == 8 || useranswer == randnumb ) {
			break;
		}

		cin >> useranswer;
		trycount++;

		if( useranswer < randnumb )
			cout << "Too Low! - " << "Tries " << trycount << " of 8" << endl;
		else if( useranswer > randnumb )
			cout << "Too High! - " << "Tries " << trycount << " of 8" << endl;
		else
			cout << "Correct! - You Guessed The Number In " << trycount << " Tries" << endl;
	};
	system( "pause" );
	return 0;
}
Sitat av fxxked Vis innlegg
Repost av ivioynar sitt inlegg for økt leslighet:

Kode

int main() {
	int randnumb = rand() % 50;
	int useranswer;
	int trycount = 0;

	cout << "*** The Guessing Game ***" << endl << endl << "Try To Guess A Random Number Betweeen 0-50." << endl << "You Have " << trycount + 8 << " Tries." << endl;

	while( True ) {
		if( trycount == 8 || useranswer == randnumb ) {
			break;
		}

		cin >> useranswer;
		trycount++;

		if( useranswer < randnumb )
			cout << "Too Low! - " << "Tries " << trycount << " of 8" << endl;
		else if( useranswer > randnumb )
			cout << "Too High! - " << "Tries " << trycount << " of 8" << endl;
		else
			cout << "Correct! - You Guessed The Number In " << trycount << " Tries" << endl;
	};
	system( "pause" );
	return 0;
}
Vis hele sitatet...
Husk at

Kode

true
skal skrives med liten "T"
Sist endret av Opous; 11. juli 2011 kl. 20:00.
Ettersom det for meg i farten så ut som du har løst problemet, vil jeg bare tilføye at det er en forskjell mellom

Kode

do {
} while (statement);
og

Kode

while (statement) {
}
Det første eksemplet vil alltid utføre handlingen minst èn gang, for så og eventuelt repetere handlingen dersom statementer sier så, mens det andre eksemplet, vil "hoppe" over partiet i mellom, uten å kjøre den i det hele tatt.

Beklager dersom det er noe vanskelig å forstå - er svært dårlig til å forklare programmerings-relatert informasjon på norsk.
Orbiter's Avatar
Trådstarter
Kommet meg litt videre nå og velger å bumpe min egen tråd med en annen problemstilling.

Jeg lurer rett og slett på hvordan jeg kan forkorte/optimalisere denne funksjonen?

Kode

int _isoccupied(int x) /*Determines if any of the spaces are occupied, returns 1 if occupied*/
{
	/*~~~~~~~~~~~~~*/
	int occupied = 0;
	/*~~~~~~~~~~~~~*/

	x = PlayerMove;
	if((x == 1) && (one_used) == true)
		occupied = 1;
	else if((x == 2) && (two_used) == true)
		occupied = 1;
	else if((x == 3) && (three_used) == true)
		occupied = 1;
	else if((x == 4) && (four_used) == true)
		occupied = 1;
	else if((x == 5) && (five_used) == true)
		occupied = 1;
	else if((x == 6) && (six_used) == true)
		occupied = 1;
	else if((x == 7) && (seven_used) == true)
		occupied = 1;
	else if((x == 8) && (eight_used) == true)
		occupied = 1;
	else if((x == 9) && (nine_used) == true)
		occupied = 1;
	return occupied;
}
Dette er en del av et tre-på-rad spill jeg lager.

Hvordan gjør man det hvis man f.eks har 200 variabler istedet for 9 som i mitt tilfelle. Det blir utrolig mye repetitiv kode.
Sitat av Orbiter Vis innlegg
Kommet meg litt videre nå og velger å bumpe min egen tråd med en annen problemstilling.

Jeg lurer rett og slett på hvordan jeg kan forkorte/optimalisere denne funksjonen?

Hvordan gjør man det hvis man f.eks har 200 variabler istedet for 9 som i mitt tilfelle. Det blir utrolig mye repetitiv kode.
Vis hele sitatet...
Arrays.

Kode

/* Lager et globalt array initialisert med bare 0'er (False), lengde 9 (3x3) */
bool spaces[9] = {0};

/* Returnerer opptattstatusen til felt X, hvor X < 9 er et krav det egentlig bør sjekkes spesifikt etter */
int _isoccupied(int x){
  return spaces[x];
}

/* Setter et felt som opptatt */
void occupy(int x){
  spaces[x] = 1;
}
Husk at arrays er 0-indeksert, altså det første elementet har index 0 og det finnes ingen indeks = 9 for et array som er 9 elementer langt.
Sist endret av Dyret; 14. juli 2011 kl. 06:25.
Sitat av Orbiter Vis innlegg
Kommet meg litt videre nå og velger å bumpe min egen tråd med en annen problemstilling.

Jeg lurer rett og slett på hvordan jeg kan forkorte/optimalisere denne funksjonen?

Kode

int _isoccupied(int x) /*Determines if any of the spaces are occupied, returns 1 if occupied*/
{
	/*~~~~~~~~~~~~~*/
	int occupied = 0;
	/*~~~~~~~~~~~~~*/

	x = PlayerMove;
	if((x == 1) && (one_used) == true)
		occupied = 1;
	else if((x == 2) && (two_used) == true)
		occupied = 1;
	else if((x == 3) && (three_used) == true)
		occupied = 1;
	else if((x == 4) && (four_used) == true)
		occupied = 1;
	else if((x == 5) && (five_used) == true)
		occupied = 1;
	else if((x == 6) && (six_used) == true)
		occupied = 1;
	else if((x == 7) && (seven_used) == true)
		occupied = 1;
	else if((x == 8) && (eight_used) == true)
		occupied = 1;
	else if((x == 9) && (nine_used) == true)
		occupied = 1;
	return occupied;
}
Dette er en del av et tre-på-rad spill jeg lager.

Hvordan gjør man det hvis man f.eks har 200 variabler istedet for 9 som i mitt tilfelle. Det blir utrolig mye repetitiv kode.
Vis hele sitatet...
Her kunne man også istede for alle if-setningen brukt en case-switch

Kode

bool test = true;

switch(test) {
         case true: //Hva som skal skje
         case false: //Hva som skal skje
         default: //default statement. 
}
Sitat av Opous Vis innlegg
Her kunne man også istede for alle if-setningen brukt en case-switch

Kode

bool test = true;

switch(test) {
         case true: //Hva som skal skje
         case false: //Hva som skal skje
         default: //default statement. 
}
Vis hele sitatet...
To kommentarer:
1. Husk break;, med mindre du ønsker at alle caser nedenfor den som er en match også skal utføres.

2. Det er liten vits med default-case når du tester på en bool og har case for både true og false.
Orbiter's Avatar
Trådstarter
Takk for hjelpen folkens. Har da laget et lite tre-på-rad spill uten å følge tutorial.

Jeg tar vel imot hjelp til å optimalisere koden der det lar seg gjøre, gjerne med kommentarer.

http://pastebin.com/0r4HCabq
Sitat av Orbiter Vis innlegg
Takk for hjelpen folkens. Har da laget et lite tre-på-rad spill uten å følge tutorial.

Jeg tar vel imot hjelp til å optimalisere koden der det lar seg gjøre, gjerne med kommentarer.

http://pastebin.com/0r4HCabq
Vis hele sitatet...
Ikke dårlig (du glemmer forresten å inkludere <limits>, noe du trenger for å bruke numeric_limits slik du gjør). Bare skummet raskt over koden, men ser du har noen unødvendige funksjoner. Ta for eksempel bool _isOccupied(). Alt denne gjør er å returnere om occupied[playerMove] er lik 1, og det også på en litt tungvinn måte. Du kunne skrevet funksjonen slik:

Kode

bool _isOccupied(){
	return (occupied[playerMove] == 1);
}
Og da ser du at funksjonen er ganske overflødig. Du kan like gjerne teste rett på occupied[ ] i stedet for å gjøre det via en egen funksjon. Samtidig ser det ut som occupied[ ] er en array av ints med verdier på enten 1 eller 0, og da er det nok mer fornuftig å definere den som en bool array. Du kan da erstatte kodesnutter som dette:

Kode

do {
	playerMove = _playerInput(); 
}while (_isOccupied() == true);
Med dette:

Kode

do {
	playerMove = _playerInput(); 
}while (occupied[playerMove]);
...og droppe hele funksjonen _isOccupied(). Det samme kan man si om funksjonen _validNumber(int x). Funksjonene void _mark() og void _displayScore() er også såpass korte (2 og 1 linje) at det strengt tatt er like greit å droppe de og bruke koden direkte.

Et annet poeng er at du bruker kun globale variable. Ofte forsøker man å unngå dette når det er mulig uten å gjøre ting vanskeligere, så du kan jo prøve å skrive om programmet slik at du har færrest mulig globale variable, og heller lar funksjoner som int _checkIfWin() (som for øvrig heller burde returnere bool enn int) ha playerPlayer som parameter.

Som et aller siste tips: Du skriver relativt ryddig kode, men det er fortsatt rom for litt forbedringer. Pass på å være konsekvent med indenteringer og plasseringer av { og }. Dette spiller ingen rolle for hvor effektivt programmet er, men det gjør det mye lettere for deg å ha oversikt i koden og spotte både feil og unødvendigheter.

Hvis du vil ha ytterligere utfordringer med programmet, så kan du jo prøve å lage det skalerbart. Slik at spilleren velger hvor stort brettet skal være, og hvor mange som skal være på rad. Den største utfordringen blir da å skrive koden som skal se om spilleren har vunnet.
Sitat av Provo Vis innlegg
To kommentarer:
1. Husk break;, med mindre du ønsker at alle caser nedenfor den som er en match også skal utføres.

2. Det er liten vits med default-case når du tester på en bool og har case for både true og false.
Vis hele sitatet...
Hva om bool'en er deklarert som NULL? Har dog ikke testet dette mot en kompilator.
NULL er per def lik 0, og en bool som er 0 er false...
Sist endret av ZeRKoX; 16. juli 2011 kl. 02:49.
Sitat av ZeRKoX Vis innlegg
NULL er per def lik 0, og en bool som er 0 er false...
Vis hele sitatet...
Nei NULL er ikke lik 0. Den innehar ingen verdi.
Sitat av Opous Vis innlegg
Nei NULL er ikke lik 0. Den innehar ingen verdi.
Vis hele sitatet...
Jo, NULL er en macro i C++ som er definert som 0. Det går ikke an at noe ikke innehar noen verdi.

http://www2.research.att.com/~bs/bs_faq2.html#null

EDIT: Og for å svare på spørsmålet om hvorvidt bool er satt til NULL, så vil det innebære en implisitt cast fra 0 til false. En bool kan kun ha to verdier: true og false.
Sist endret av Provo; 16. juli 2011 kl. 20:34.
Sitat av Provo Vis innlegg
Jo, NULL er en macro i C++ som er definert som 0. Det går ikke an at noe ikke innehar noen verdi.

http://www2.research.att.com/~bs/bs_faq2.html#null

EDIT: Og for å svare på spørsmålet om hvorvidt bool er satt til NULL, så vil det innebære en implisitt cast fra 0 til false. En bool kan kun ha to verdier: true og false.
Vis hele sitatet...
Da har jeg blitt utsatt for vranglære. Kjekt å vite, takk!