Gå til innhold

Tanker og forslag til mitt første spill


Anbefalte innlegg

Hei! Jeg er en sånn folk flest vil kalle nybegynner i C++. Har ikke programmert i mer enn noen uker i C++. Tidligere erfaringer er smått, som i Game Maker, om noen er kjent med scriptspråket der.

 

Dette er andre utgave av programmet (det første var tungt skrevet og ikke så effektivt).

 

Har du noen tanker angående spillet, som forbedring, bedre/raskere måter å skrive koden på osv. del dem med meg er du snill. Jeg vil at koden min skal være mest effektiv og rask som mulig. Jeg vil jo ikke utvikle dårlige vaner o.l.

 

Here is the code:

 

////////////////////////////////////////////////////////////////////////////////////
/*																				*/
/*		 Program name: Roll The Dice											*/
/*		 Creators name: Dørhåndtak											  */
/*		 Date: 29.07.2009													   */
/*		 Version: 2.5														   */
/*		 Purpose: This program lets you roll the dice against the computer.	 */
/*																				*/
////////////////////////////////////////////////////////////////////////////////////

#include <cstdlib>
#include <iostream>
#include <ctime>

#define RAND random(1,6);

using namespace std;

int Game(void);
int Roll(void);
int Check_wins(void);

// wins [0] = player wins
// wins [1] = computer wins
int wins [] = {0,0};

// This will make the random stay random, and not at a specific number it guesses the first time in use	 
void Step_random() {
 srand((unsigned)time(0));
}

// Here's the random generator, returns the random number it finds
// To be honest, i have little idea of what random_integer is doing here
int random(int lowest, int highest) {
int range = (highest - lowest)+1;
int random_integer = (rand() % range) + 1;
return random_integer;
}

// Creates n new lines
void Newline(int lines) {

for( int i = 0; i < lines; i++) {
	 cout<<endl;
}
}

// Roll the dice r times and returns true or false that players roll (roll [0]) is greater than computers roll (roll [1])
int Roll_result(int r) {
int roll [] = {0,0};

for (int i = 0; i < r; i++) {   
roll [0] += RAND;
cout<<"Players "<<i+1<<" time:   "<<roll [0]<<endl;
roll [1] += RAND;
cout<<"Computers "<<i+1<<" time: "<<roll [1]<<endl<<endl;

} if (roll [0] == roll [1]) {
	 return -1;
	 } else {   
	 return (roll [0] > roll [1]);
	 }
}

// Determines the winner
int Final_result(int r) {
switch (r) {
	   case -1:
		cout<<"Draw!"<<endl;
		break;

	   case 0:
		cout<<"You lost.."<<endl;
		wins[1] += 1;
		break;

	   case 1:
		cout<<"You won!"<<endl;
		wins[0] += 1;
		break;

		} return 0;  
}

// Controlls how many times you want to roll the dice
int Roll(void) {
int times;
short int check_won;
cout<<"How many times do you want to roll the dice?"<<endl;
cout<<"Choose: ";
cin>>times;
Newline(2);
check_won = Roll_result(times);
Final_result(check_won);
return 0;
}

// Checking amount of wins on both parts
int Check_wins(void) {
cout<<"Player wins:   "<<wins [0]<<endl;
cout<<"Computer wins: "<<wins [1]<<endl;
return 0;
}

// The "core" of the game
int Game(void) {
int menu_choice;

while(1) {

Newline(2);	   
cout<<"What would you like to do?"<<endl;
cout<<" 1) Roll against computer\n 2) Check wins\n 3) Quit program"<<endl;
cout<<"Choose: ";
cin>>menu_choice;
Newline(2);

switch (menu_choice) {

	   case 1:
			Roll();
			break;
	   case 2:
			Check_wins();
			break;
	   case 3:
			return 0;
			break;
	   default:
			   cout<<"Invalid key!"<<endl<<endl;
			   break;
	   }
} return 0;
}

// Where it all starts (and ends)
int main() {

Step_random();
cout<<"\t Roll The Dice!"<<endl;
cout<<"\t  Version 2.5"<<endl<<endl;
Game();
return 0;
}

Endret av Csvk!
Lenke til kommentar
Videoannonse
Annonse
<snip>

Har du noen tanker angående spillet, som forbedring, bedre/raskere måter å skrive koden på osv. del dem med meg er du snill. Jeg vil at koden min skal være mest effektiv og rask som mulig. Jeg vil jo ikke utvikle dårlige vaner o.l.

<snip>

Det høres klokt ut, jeg skal hjelpe.

 

Starter, med en liten bug....

Unfortunetly, you lost: You rolled a lower number than the computer!

The evil computer took -9999$ from you

Noo!!!

 

Nok om det

 

Jeg liker (med flere) liker best at { og } er på egne linjer.

Det gjør den enklere å lese

 

player_roll_0 (og flere) er globale variabler, men de trenger ikke være det. Det å bruke globale variabler når man ikke trenger det er definitivt et no no.

Du burde legge variabler så små scope som mulig.

 

player_roll_0 (og flere) blir satt til 0 i starten av Game_core, men jeg ser ikke hvorfor.. gjør du?

 

Aha nå fant jeg ut hvorfor du gjør som du gjør.

Du kaller på Game_core() flere steder.. rett programmet går opp til starten av do loopen.... Hvorfor i alle dager gjør du det?

Du vil eventuelt fylle opp stacken og det er ikke bra for å si det mildt.

 

Ja da tror du har nok å jobbe med, du bør i det minste fjerne alle kallene til Game_core() (utenom fra main).

Hvis du vil jeg/noen skal ta en ny titt etterpå er jeg klar jeg.

 

Lykke til

Endret av Giddion
Lenke til kommentar

Først og fremst, takk for opplysningene :)

 

Den bugen du snakket om, hvordan fant du den? Jeg har forsøkt å fremkalle den, men finner ikke rett kombinasjon. What's the magic trick?

 

Jeg liker (med flere) liker best at { og } er på egne linjer.

Det gjør den enklere å lese

 

Hørtes fornuftig ut.

 

player_roll_0 (og flere) er globale variabler, men de trenger ikke være det. Det å bruke globale variabler når man ikke trenger det er definitivt et no no.

Du burde legge variabler så små scope som mulig.

 

Dette er jeg klar over. Grunnen til dette var fordi det oppstod problemer når de var satt opp som lokale variabler, sånn som at den ene funksjonen ikke fant en variabel osv.

 

player_roll_0 (og flere) blir satt til 0 i starten av Game_core, men jeg ser ikke hvorfor.. gjør du?

 

Gjorde dette for å "renvaske" verdiene ;)

 

Aha nå fant jeg ut hvorfor du gjør som du gjør.

Du kaller på Game_core() flere steder.. rett programmet går opp til starten av do loopen.... Hvorfor i alle dager gjør du det?

Du vil eventuelt fylle opp stacken og det er ikke bra for å si det mildt.

 

Sprø ide, ikke sant? Det var den eneste måten jeg kom på å bruke for å få funksjonen til å gjenta seg fra starten av. Har du et tips til bedre måte å gjenta ting på?

 

Ja da tror du har nok å jobbe med, du bør i det minste fjerne alle kallene til Game_core() (utenom fra main).

Hvis du vil jeg/noen skal ta en ny titt etterpå er jeg klar jeg.

 

Takk for det :) Jeg skal legge ut ny version etter jeg har rettet feil, men jeg trenger din hjelp på veien ;)

Endret av Csvk!
Lenke til kommentar
Jeg har ikke så god tid så jeg svarer bare på buggen.

 

Har du prøvd å satse en negativ verdi?

 

Ah, jeg forstår! Buggen er nå rettet :) Det jeg trenger å vite nå er hvordan jeg gjentar en loop/funksjon, og hvordan jeg fikser globale om til lokale variabler uten krøll med andre funksjoner :)

 

EDIT: Siden dette er et pengespill, tror jeg faktisk bare noen få ville komme på å satse "negative penger". Det er jo forsåvidt ikke en bug vi snakker om...

 

Eller, om det så absolutt skulle være en bug, er det bare en ubetydelig, pirkete, men også uungåelig bug: Dette er jo trossalt et av mine første programmer i et avansert og komplisert språk som jeg kun har brukt noen uker på. Jeg vil si jeg gjør det bra!

 

Nok om det.

Jeg venter fortsatt på hjelp ;)

Endret av Csvk!
Lenke til kommentar
Nok om det.

Jeg venter fortsatt på hjelp ;)

 

Beklager sent svar, men mitt skjermkort har tatt kvelden så jeg har ikke tilgang til mine vanlige programmer.... Som f. eks. en kompilator og debugger :(

 

Slik jeg ser det nå så vil programmet gå i en uendelig loop hvis du ikke kaller på Game_core(), er det derfor du kaller på Game_core()?

 

loopen vil gå i det uendelige ettersom command_key ikke endres inne i loopen, du vil heller ikke få opp noe serlig med hjelpende tekst så jeg mener at du burde flytte "do{" til rett under "current_pott = 0.0;"

 

Så det blir noe slikt noe:

	current_pott = 0.0;
do{
//Determines when to show the start menu or the ingame menu
 if (first_message != true){

 

Gjør det og se om det fungerer da.

 

Lykke til

Lenke til kommentar
Beklager sent svar, men mitt skjermkort har tatt kvelden så jeg har ikke tilgang til mine vanlige programmer.... Som f. eks. en kompilator og debugger :(

 

Slik jeg ser det nå så vil programmet gå i en uendelig loop hvis du ikke kaller på Game_core(), er det derfor du kaller på Game_core()?

 

loopen vil gå i det uendelige ettersom command_key ikke endres inne i loopen, du vil heller ikke få opp noe serlig med hjelpende tekst så jeg mener at du burde flytte "do{" til rett under "current_pott = 0.0;"

 

Så det blir noe slikt noe:

	current_pott = 0.0;
do{
//Determines when to show the start menu or the ingame menu
 if (first_message != true){

 

Gjør det og se om det fungerer da.

 

Lykke til

 

Takk for svar! Synd med skjermkortet, er virkelig noe møkk når det ryker (Har skjedd meg 2-3 ganger).

 

Grunnen til at jeg kaller Game_core() flere ganger er for å få funksjonen Game_core() til å starte forfra, fra toppen av igjen. Gjør jeg ikke dette vil ikke programmet fungere skikkelig. Det finnes helt sikkert en mye smartere måte gjøre dette på.

 

Det jeg lurer på er om det er noe som stadig hoper seg opp i minnet når jeg holder på sånt - og kaller funksjoner om igjen og om igjen.

Endret av Csvk!
Lenke til kommentar
<snip>

Grunnen til at jeg kaller Game_core() flere ganger er for å få funksjonen Game_core() til å starte forfra, fra toppen av igjen. Gjør jeg ikke dette vil ikke programmet fungere skikkelig. Det finnes helt sikkert en mye smartere måte gjøre dette på.

Hva mener du med ikke fungere skikkelig?

 

Du kan gjøre det ved å bruke en do-while loop (som alt finnes i koden din), men du må gjøre endringer for at det skal fungere (etter det jeg kan se).

 

Det jeg lurer på er om det er noe som stadig hoper seg opp i minnet når jeg holder på sånt - og kaller funksjoner om igjen og om igjen.

Ja stacken fylles opp og vil til slutt gi en stack overflow, men etter det jeg har erfart vil du måtte spille ekstremt mange runder før programmet krasjer.

Lenke til kommentar

Da var andre utgave ute på nett (se første innlegg).

Dette er betydelig mindre (142 linjer).

 

Endret:

- Skrev hele sullamitten på nytt

- Fjernet pengesystemet

- Kan skjekke antall ganger du og dataen har vunnet

- Kan kaste terningen så mange ganger som du vil

 

Er bruken av #define her en effektiv måte å bruke den på?

Endret av Csvk!
Lenke til kommentar
//Here's the random generator, returns the random number it finds
//To be honest, i have little idea of what random_integer is doing here
int random(int lowest, int highest){
int range = (highest - lowest)+1;
int random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
return random_integer;
}

 

Denne gir også alltid 1 for meg. Jeg bruker gcc kompilator. Denne derimot fungerer helt fint for meg.

int random(int lowest, int highest) {
int range = (highest - lowest) + 1;
int random_integer = (rand() % range) + 1;
return random_integer;
}

 

Jeg liker (med flere) liker best at { og } er på egne linjer.

Det gjør den enklere å lese

 

Og jeg liker det slik:

if (i ==1) {
i = 2;
} else if (i == 2) {
i = 3;
} else {
i = 4;
}

 

int Roll_result(int r)
{
int roll [] = {0,0};

for (int i = 0; i < r; i++)
{
roll [0] += RAND;
cout<<"Players "<<i+1<<" time:   "<<roll [0]<<endl;
roll [1] += RAND;
cout<<"Computers "<<i+1<<" time: "<<roll [1]<<endl<<endl;
}
return (roll [0] > roll [1]);
}

 

Det sjekkes bare om roll[0] er større enn roll[1]. Det betyr at computeren vinner også om det er uavgjort.

Endret av olejl1
Lenke til kommentar

Først og fremst, takk for svar og hjelp :)

 

int random(int lowest, int highest) {
int range = (highest - lowest) + 1;
int random_integer = (rand() % range) + 1;
return random_integer;
}

 

Denne fungerte også for meg, og var litt mer forståelig ;)

 

Og jeg liker det slik:

if (i ==1) {
i = 2;
} else if (i == 2) {
i = 3;
} else {
i = 4;
}

 

Dette syntes jeg holdt bedre orden, så jeg skal prøve og skrive slik frem over

 

Det sjekkes bare om roll[0] er større enn roll[1]. Det betyr at computeren vinner også om det er uavgjort.

 

Dette stemte, og jeg var ikke klar over dette. Buggen er nå fikset :)

 

Versjon 2.5 er nå lagt ut, følgende er fikset:

 

- Spillet kan bli uavgjort

- Bedre orden på kode

- Bedre "random funksjon"

 

Jeg har hørt mye diskusjon rundt #define, om det er bra og bruke eller ikke. Det jeg lurer på, er om måten jeg bruker #define på i programmet mitt, gjør programmet tregere enn hva det hadde gått uten?

Endret av Csvk!
Lenke til kommentar
Jeg har hørt mye diskusjon rundt #define, om det er bra og bruke eller ikke. Det jeg lurer på, er om måten jeg bruker #define på i programmet mitt, gjør programmet tregere enn hva det hadde gått uten?

 

Slik du bruker #define kalles vel en makro. Hovedfordelen er at makroen da blir inkludert "inline", altså ingen funksjonskall. Det vil gi en ytelses gevinst dersom funksjonen er ofte brukt.

 

Slik du har gjort det så er makroen din et funskonskall. Det gir ikke mening siden du da ikke sparer noe funksjonskall.

 

Personlig ville nok jeg bare ha droppet makroen og kalt random(1,6) funksjonen direkte, eventuelt så kunne du ha implementert hele random funksjonen som en makro og ikke bare funksjonskallet.

 

Du kan lese mer her:

http://www.cprogramming.com/tutorial/cpreprocessor.html

 

Se spesielt siste heading: "Avoiding Macros in C++"

Lenke til kommentar

Hvis man på død og liv vil at en funksjon skal være inline, kan man bruke inline-nøkkelordet til C++. Dette garanterer ikke at funksjonen blir inline, men den gir et hint til kompilatoren om at "denne her kan du godt gjøre inline hvis det er greit".

 

Uansett, premature optimization is the root of all evil, osv. :)

 

Forresten, trådstarter, du har en bra attitude. Mange har en "bare det funker så gir jeg faen"-mentalitet, og det er ikke bra når man koder i C++. Så fort det blir litt størrelse på programmene man lager, er man avhengig av å forstå hva man holder på med og også ha gode vaner mht. koding. Keep up the good work.

Lenke til kommentar
Forresten, trådstarter, du har en bra attitude. Mange har en "bare det funker så gir jeg faen"-mentalitet, og det er ikke bra når man koder i C++. Så fort det blir litt størrelse på programmene man lager, er man avhengig av å forstå hva man holder på med og også ha gode vaner mht. koding. Keep up the good work.

 

Det var godt å høre, takk skal du ha :D

Har alltid vært interessert i best mulig ytende kode, og hvilken metoder programmerere bruker. Ytelse er noe jeg vil sette som førsteprioritet når jeg skriver koder, selv om det kanskje kan bli mye vanskeligere og kan ta litt lenger tid enn ellers. Siden C++ tar tid både å lære, skrive og produsere, burde jeg vel bruke den tida på å gjøre det best mulig :)

 

Er det noen tråder, nettsider etc. som tar opp dette?

Lenke til kommentar

Jeg tror ikke det er så mange nettsider som retter seg spesifikt mot dette. Hvis jeg var deg, så ville jeg ha fulgt med på C++ USENET-gruppene og kanskje kikka litt på kildekoden til open source prosjekter som du veit det er litt kvalitet over. (Det er ikke noe vits i å lære av kode hvis koden er ræva, og det er nok av ræva kode der ute.)

 

Forresten, det er bra at du har fokus på effektivitet osv., men ikke bli for opptatt av dette i læringsprosessen. Det viktigste først er at du lærer deg ordentlig syntaksen og bruken av språket.

Lenke til kommentar

Har egentlig bare en bitteliten kommentar, ikke noe viktig, men hvis du definerer en makro som er en makro for et eller flere funksjonskall vil jeg påstå det er god skikk at også makroen ser ut som et funksjonskall.

 

Eksempelvis din RAND ville jeg skrevet slik:

#define RAND() random(1, 6)
int i = RAND; // ÆRRÅR KÅMPAILFÆIL!!1
int j = RAND(); // Korrekt med flere r-er og i kursiv

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...