Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann.

Russisches Roulette

Diskussion: Russisches Roulette im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige Ich hab mir für frustrierende Momente eben mal schnell das russische Roulette-Spiel in C programmiert. Das Programm ist zwar ...

Antwort
Alt 02.04.04, 11:28   #1 (permalink)
Member of Honour
 
Registriert seit: 02.10.01
Indi Leistung: Z3
Likes: 0
Lightbulb Russisches Roulette

Anzeige

Ich hab mir für frustrierende Momente eben mal schnell das russische Roulette-Spiel in C programmiert. Das Programm ist zwar wirklich total simple, dachte aber ich stell die Aufgabe trotzdem mal rein. Wer Spaß dran hat, kann es ja auch mal coden. Vor allem für Anfänger geeignet. )

Spielablauf:
Zwei Spieler sitzen sich gegenüber, in diesem Fall ist einer der PC. Es gibt einen Revolver mit sechs Kugelschächten (ich weiß nicht wie man das wirklich nennt). In einem der sechs Schächte befindet sich eine Kugel. Der Revolver wird nun immer ausgetauscht. Wenn man den Revolver bekommt, kann man entweder sofort schießen (natürlich auf sich selbst *g*) oder man dreht das Magazin einmal durch und schießt dann. Natürlich weiß man im Moment des "Abdrückens" nicht, ob sich im aktuellen Schacht nun eine Kugel befindet oder nicht. Das geht dann also solang bis einer nicht mehr lebt. Der hat dann auch verloren.

Werd in zwei Tagen dann mal meine Lösung reinstellen und kurz erläutern.

Indi ist offline   Mit Zitat antworten
Alt 02.04.04, 14:55   #2 (permalink)
 
Registriert seit: 27.01.02
JoBbE Leistung: Facit NTK
Likes: 0
Standard

So, ich hoffe ich bin weder zu früh noch zu spät..
Hier ist meine Lösung


edit:: scheisse, da war ein sehr übler Fehler drin
Hab ihn mal rausgetan
Code:
//**
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

int RandomInt(int iMin, int iMax)
{
	return iMin + int((float)(iMax+1) * rand()/(RAND_MAX+1.0));
};

enum player{user, pc};

class Gun
{
public:
	Gun()
	{
		m_BulletPos = 1;
		m_Player = NULL;
		// Am Anfang ist die Position zufällig!
		m_Pos = RandomInt(1, 6);
		m_NoShootCount = 0;
	};
	~Gun(){};

	void Spin()
	{
		if( *m_Player == user )
			cout << "Du bekommst kalte Füße und drehst die Trommel...\n";
		else
			cout << "Der PC bekommt kalte Füße und dreht die Trommel...\n";
		m_Pos = RandomInt(1, 6);
		m_NoShootCount = 0;
	};

	bool Shoot()
	{
		if( *m_Player == user )
			cout << "Heldenmutig drückst du dir den Revolver an die Schläfe und drückst ab.\n";
		else
			cout << "Heldenmutig drückt der PC sich den Revolver an den Bildschirm und drückt ab.\n";

		// Schießen, wenn die Patrone im Lauf liegt
		if( m_Pos == m_BulletPos)
			return true;
		// Ansonsten die Trommel eins weiter drehen
		else
		{
			m_Pos++;
			if( m_Pos > 6 )
				m_Pos = 1;
			m_NoShootCount++;
		}
			
		return false;
	};

	int GetNoShootCount()
	{
		return m_NoShootCount;
	}

	void SetActivePlayer(player *newPlayer)
	{
		m_Player = newPlayer;
	};

protected:
	int m_Pos,
		m_BulletPos,
		m_NoShootCount;
	player *m_Player;
};


void main()
{
	// seed setzen
	srand( (unsigned)time( NULL ) );

        char c;
	bool bExit = false,
		bNoEnd = false;
	player myPlayer = user,
			deadPlayer;
	Gun myGun;
	myGun.SetActivePlayer(&myPlayer);

	do
	{
		// Spieler bestimmen
		if( myPlayer == user )
		{
			cout << "Du bist an der Reihe!\n'q' beendet, 's' dreht die Trommel und schießt, alle anderen Eingaben schießen sofort\n>";
			cin >> c;
			switch(c)
			{
			case 'q': 
				{
					bExit = true;
					bNoEnd = true;
					break;
				}
			case 's':
				{
					myGun.Spin();
					if(myGun.Shoot())
					{
						deadPlayer = user;
						bExit = true;
					}
					break;
				}
			default:
				{  
					if(myGun.Shoot())
					{
						deadPlayer = user;
						bExit = true;
					}
					break;
				}
			}
			
			//Spieler wechseln!
			myPlayer = pc;
		}
		//** COMPUTER
		else
		{
			// Testen, wie lange schon keine Kugel gefeuert wurde
			// wenn 5 Mal, dann auf jeden Fall Spin() ausführen
			// Ansonsten mit sinkender Wahrscheinlichkeit die Trommel drehen
			if( RandomInt(1, 5) <= myGun.GetNoShootCount() )
				myGun.Spin();
			if(myGun.Shoot())
			{
				deadPlayer = pc;
				bExit = true;
			}
			//Spieler wechseln!
			myPlayer = user;
		}
		
	}while(!bExit);

	if(bNoEnd)
		cout << "Weichei! Feiiigling! eifnach so das tolle Spiel abzubrechen... tststs...\n";
	else
	{
		if( deadPlayer == user)
			cout << "Pech gehabt, du bist tot...\n";
		else
			cout << "Toll, du hast überlebt, der Pc hat sich den Schädel weg geblasen.\nKauf dir nen Keks.\n";
	}
}
JoBbE ist offline   Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 03.04.04, 05:38   #3 (permalink)
 
Registriert seit: 03.04.04
D.Mon Leistung: Facit NTK
Likes: 0
Standard

hallo zusammen,

ich mache zum Ersten mal mit.
hier ist meine Lösung:
Code:
#include<stdio.h>

// Russisches Roulette
// D.Mon
// 04-04-03

int shoot(int chance);

int main()
{
    int c = 1, i = 1; // Leben auf 1 setzen
    int chance = 5;
    int retval;
    char help;
    int what;
    while(c==1 && i==1)
    {
	printf("Noch max. %i leere Kammern\n", chance);
	printf("Drehen[1] oder Schiessen[alles andere]?");
	scanf("%i", &what);
	switch (what)
	{
	    case 1: 
			 chance=5; // Chance zuruecksetzten durch drehen
			 break;
		     
	    default: 
			 chance--; // Chance reduzieren
			 break;
	}
	retval = shoot(chance); // Spieler schiesst
	if(i - retval == 0)
	{
	    i = 0 ; // Leben auf 0 setzen
	    printf("\n\t\t%cBang! - Du bist tot !\n\n", 7);
	    break;
	}
	
	else
	    printf("Noch max. %i leere Kammern\n", chance);
	    printf("Reiche mir die Waffe [irgendwas eingeben]: ");
	scanf("%d", &help);
	srandom(time(NULL));
	int comp = (random () % 2);
	if(comp==0)
	{
	    printf("Computer dreht\n");
	    chance=5;
	}
	else
	{
	    printf("Computer dreht nicht\n");
	    chance--;
	}
	// computer schiest
	retval = shoot(chance);
	if(i - retval == 0)
	{
	    c = 0 ; // Leben auf 0 setzen
	    printf("\n\t\t%cBang! - Computer ist tot !\n\n", 7);
	    break;
	}
    }
}

int shoot(int chance)
{
    int j;
    printf("chance: %i", chance);
    if(chance>0)
    {
	// Schiessen
	srandom(time(NULL));
	int bullet = (random () % chance) + 1 ;
	if(bullet!=1)
	printf("\t\tklick\n\n");
	int retval = bullet;
	return retval; 
    }
    else // beim sechsten Schuss ohne drehen: kein Chance zu ueberleben
	return 1;
}
-----------------
@JoBbE

Dein Code kompiliert bei mir gar nicht.
Mein Compiler (g++-3.3) mault, das main int zurückgeben muss.
wenn ich int von void auf main ändere und ein return 0 einfüge, kann ich zwar schießen, bin aber immer sofort tot.

Mit welchem Compiler auf welchem System arbeitest Du ?
D.Mon ist offline   Mit Zitat antworten
Alt 03.04.04, 13:36   #4 (permalink)
 
Registriert seit: 27.01.02
JoBbE Leistung: Facit NTK
Likes: 0
Standard

VC++ 6

Also die Sache mit int main/void main dürfte dann vom compiler abhängen, VC++ kommt mit void gut klar.

Und dass du immer sofort gestorben bist liegt daran, dass ich hampel den seed nach dem Gun-Konstruktor gesetzt habe. Hab das mal schnell korrigiert, jetzt dürfte das auch kein Problem mehr sein...


Mahn, ich schreib vlt verbugten code... *g*
JoBbE ist offline   Mit Zitat antworten
Alt 03.04.04, 15:42   #5 (permalink)
Ray
 
Registriert seit: 06.08.02
Ray Leistung: Facit NTK
Likes: 0
Standard

Code:
uses crt;

var slot   :byte;
    player:boolean;
    choice:char;

begin
  randomize; player:=FALSE; slot:=(random(6)+1);
  clrscr;
  repeat
   player:=player XOR TRUE;
   dec(slot);
   if player then
               begin
                 writeln('Drehen? j/n');choice:=readkey;
                 if choice='j' then slot:=random(6);
               end
             else
               if (random(2)=1) then
                                 begin
                                   slot:=random(6);
                                   Writeln('PC dreht');
                                 end
                               else
                                 WriteLn('PC dreht nicht');
  until slot=0;
  if player then writeln('Du bist tot') else Writeln('PC ist tot');
end.
Ray ist offline   Mit Zitat antworten
Alt 03.04.04, 16:54   #6 (permalink)
 
Registriert seit: 03.04.04
D.Mon Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Original von JoBbE
VC++ 6

Also die Sache mit int main/void main dürfte dann vom compiler abhängen, VC++ kommt mit void gut klar.

Und dass du immer sofort gestorben bist liegt daran, dass ich hampel den seed nach dem Gun-Konstruktor gesetzt habe. Hab das mal schnell korrigiert, jetzt dürfte das auch kein Problem mehr sein...


Mahn, ich schreib vlt verbugten code... *g*
Da sollte ich mal im wahren Leben lieber nicht mit Dir Russisch Roulette spielen -

Hast Du meinen Code mal getestet ?
D.Mon ist offline   Mit Zitat antworten
Alt 03.04.04, 17:47   #7 (permalink)
 
Registriert seit: 27.01.02
JoBbE Leistung: Facit NTK
Likes: 0
Standard

Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... Sollte sie aber, wenn sie vom Typ int ist...

Zweitens: Unsere Compiler haben offensichtlich verschiedene Zufalls-Funktionen, ist aber kein großes Problem.
Bei dir srandom -> bei mir srand
Bei dir random -> bei mir rand
Aber warum setzt du jedes Mal den seed? Einmal am Programmstart sollte reichen...

Und ich finde die KI etwas.. naja... dumm
Der Computer sollte zumindest wissen, wenn er garnichtmehr überleben kann und dann drehen -> momentan ist seine Wahl ja grundsätzlich zufällig.

Code:
int comp = (rand () % 2);
if(comp==0)
		{
		    printf("Computer dreht\n");
			chance=5;
		}
		else
		{
		    printf("Computer dreht nicht\n");
			chance--;
		}
		// computer schiest
		retval = shoot(chance);
Ansonsten ein interessanter Ansatz, wie ich finde.
Hab allerdings noch nit so oft gespielt, ich sterb dauernd
JoBbE ist offline   Mit Zitat antworten
Alt 03.04.04, 18:57   #8 (permalink)
 
Registriert seit: 03.04.04
D.Mon Leistung: Facit NTK
Likes: 0
Standard

hallo,

danke für Dein feedback

Zitat:
Zweitens: Unsere Compiler haben offensichtlich verschiedene Zufalls-Funktionen, ist aber kein großes Problem.
Bei dir srandom -> bei mir srand
Bei dir random -> bei mir rand
Um ehrlich zu sein:
Ich bin noch einblutiger Anfänger - mein Code ist ja C (mit Anleihen aus einem Buch über Objective-C).
Jedenfalls mit nur einer seed am Anfang hatte ich immer identische Ergebnisse.

Und ja, du hast Recht, der Computer begeht auch schon mal Selbstmord - halt wie ein Mensch .
Das Spiel ist ja grundsätzlich ganz schön destruktiv.

Bin mal gespannt auf die Lösung von Indi
D.Mon ist offline   Mit Zitat antworten
Alt 04.04.04, 23:32   #9 (permalink)
 
Registriert seit: 21.02.04
pacman Leistung: Facit NTK
Likes: 0
Standard

ka, ob das jetzt klugscheisserisch rüberkommt, aber ich bin nunmal verfechter von gutem code und genauen erklärungen, insbesondere was c/c++ angeht

Zitat:
Original von JoBbE
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... Sollte sie aber, wenn sie vom Typ int ist...
jede funktion gibt einen wert zurück, sonst wäre sie keine funktion sondern eine prozedur (und prozeduren gibt es im ganzen c-sprachraum nicht). auch wenn man 'void main' schreibt, wird etwas an windows zurückgegeben, dass nennt man dann implizites return. aber machne compiler unterstürzend dies nicht, und melden einen fehler (was laut standart c++ auch richtg ist). ich weiß nicht, wie die entwickler von VS und co. überhaupt auf die idee kommen, sowas einzuführen.
naja, ich hoff ich hab mal wieder etwas wissen verbreitet

mfg,
pacman
pacman ist offline   Mit Zitat antworten
Alt 04.04.04, 23:40   #10 (permalink)
 
Registriert seit: 03.04.04
D.Mon Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Original von pacman
ka, ob das jetzt klugscheisserisch rüberkommt, aber ich bin nunmal verfechter von gutem code und genauen erklärungen, insbesondere was c/c++ angeht

Zitat:
Original von JoBbE
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... Sollte sie aber, wenn sie vom Typ int ist...
jede funktion gibt einen wert zurück, sonst wäre sie keine funktion sondern eine prozedur (und prozeduren gibt es im ganzen c-sprachraum nicht). auch wenn man 'void main' schreibt, wird etwas an windows zurückgegeben, d
...
Vielen Dank für Deien Beitrag,

Im Grunde geb ich Dir ja völlig Recht (was die Qualität von Erklärungen angeht), aber wenn Du es ganz genau wissen willst, gibt diese main Funktion bei mir bestimmt nichts an windows zurück, weil sie nämlich hier kein windows zu sehen bekommt .
Übrigens mault mein Compiler bei "void main" auch, er will nämlich, dass man "int main" schreibt.
Und wenn man kein "return" hat, komiliert er oft gar nicht erst.

.
D.Mon ist offline   Mit Zitat antworten
Alt 04.04.04, 23:51   #11 (permalink)
 
Registriert seit: 21.02.04
pacman Leistung: Facit NTK
Likes: 0
Standard

Zitat:
aber wenn Du es ganz genau wissen willst, gibt diese main Funktion bei mir bestimmt nichts an windows zurück, weil sie nämlich hier kein windows zu sehen bekommt .
ok ok, ich meinte natürlich dass betriebssystem, oder das programm, welches dein programm aufruft, um genau zu sein

Zitat:
Übrigens mault mein Compiler bei "void main" auch, er will nämlich, dass man "int main" schreibt.
Und wenn man kein "return" hat, komiliert er oft gar nicht erst.
und genau so ist es eigentlich auch richtig. eine main mit dem rückgabewert void ist laut standard c++ nicht erlaubt. ich arbeite aber hauptsächlich mit dem visual studio, welches sich da nicht drum kümmert, ob man nun etwas zurück gibt, oder nicht. schade eigentlich, es ist teuer genug und sollte für den preis eigentlich solche 'fehler' bemerken. naja, was wäre eine perfekte entwicklungsumgebung, dann würde das coden ja nurnoch halb so viel spass machen

mfg,
pacman
pacman ist offline   Mit Zitat antworten
Alt 05.04.04, 17:02   #12 (permalink)
 
Registriert seit: 27.01.02
JoBbE Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Original von pacman
ka, ob das jetzt klugscheisserisch rüberkommt, aber ich bin nunmal verfechter von gutem code und genauen erklärungen, insbesondere was c/c++ angeht

Zitat:
Original von JoBbE
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... Sollte sie aber, wenn sie vom Typ int ist...
jede funktion gibt einen wert zurück, sonst wäre sie keine funktion sondern eine prozedur (und prozeduren gibt es im ganzen c-sprachraum nicht). auch wenn man 'void main' schreibt, wird etwas an windows zurückgegeben, dass nennt man dann implizites return. aber machne compiler unterstürzend dies nicht, und melden einen fehler (was laut standart c++ auch richtg ist). ich weiß nicht, wie die entwickler von VS und co. überhaupt auf die idee kommen, sowas einzuführen.
naja, ich hoff ich hab mal wieder etwas wissen verbreitet

mfg,
pacman


Okok, du hast Recht. Danke für die Anmerkung (das meine ich ernst...)
Aber wo wir grad am Klugscheissen sind, 'Standard' schreibt sich immernoch mit 'd' am Schluss

Sry, musste sein *grins*
JoBbE ist offline   Mit Zitat antworten
Alt 05.04.04, 22:04   #13 (permalink)
 
Registriert seit: 03.04.04
D.Mon Leistung: Facit NTK
Likes: 0
Standard

hallo zusammen,

wenn wir hier Standards besprechen, dann möchte ich noch anfügen, dass "void main" nicht ganz korrekt ist.
Standard ist "int main"

Aber mal was anderes:
Wo ist Indi eigentlich abgeblieben ?
D.Mon ist offline   Mit Zitat antworten
Alt 06.04.04, 00:10   #14 (permalink)
Member of Honour
 
Benutzerbild von ivegotmail
 
Registriert seit: 28.05.03
ivegotmail Leistung: Z3
Likes: 1
Standard

hier meine lösung in C#

ein wort noch zur angesprochenen KI
wenn der computer wirklich intelligent sein soll, dann müsste er immer drehen
hab ihn bei mir aber auch n bisschen dümmer bzw risikofreudiger gemacht

Code:
using System;

class RussischRoulette
{
	int kugelplatz, trommelPosition;
	int igorsMind; // speichert anzahl schiessen ohne drehen hintereinander
	
	public static void Main(string[] args)
	{
		RussischRoulette spiel = new RussischRoulette();
		
		do {
			spiel.kugelplatz = new Random().Next(6);
			spiel.trommelPosition = spiel.igorsMind = 0;
			
			while(true)	{		
				// Spieler
				Console.Write("Schiessen (1) oder Drehen & Schiessen(2): ");
				if(Console.ReadLine().Equals("2"))
					spiel.drehen();
				if(spiel.schiessenundtot()) {
					Console.WriteLine("Du bist total tot!");
					break;				
				}
				else Console.WriteLine("Glück gehabt!");
				
				// Igor die russische Suicide-KI
				if(spiel.igorsMind>2 || new Random().Next(2).Equals(1)) {
					Console.WriteLine("Igor dreht und schiesst");
					spiel.drehen();
				}
				else Console.WriteLine("Igor schiesst");
				if(spiel.schiessenundtot()) {
					Console.WriteLine("Igor ist total tot!");
					break;
				}
				else Console.WriteLine("Igor is n lukor!");
			}			
			Console.Write("Nochmal spielen? ( j | n ): ");
		}while(Console.ReadLine().Equals("j"));
	}
	
	public void drehen() {
		igorsMind = 0;
		trommelPosition = new Random().Next(6);
	}

	// es wird geschossen und true zurückgegeben wenn sich jemand erschossen hat
	public bool schiessenundtot() {
		igorsMind++;
		if(trommelPosition == kugelplatz)
			return 	true;
		else {
			if(trommelPosition == 5)
				trommelPosition = 0;
			else trommelPosition++;
				return false;
		}
	}
}
__________________
http://livehabo.hackerboard.de | http://livebb.sourceforge.net
ivegotmail ist offline   Mit Zitat antworten
Alt 06.04.04, 02:25   #15 (permalink)
 
Registriert seit: 27.01.02
JoBbE Leistung: Facit NTK
Likes: 0
Standard

Das ist das erste Mal, dass ich ein C# Programm sehe. Und ich wundere mich. Das lehnt sich ja an Pascal an?!?

Interessante Sache.
JoBbE ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » Russisches Roulette
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
"Sicher" gewinnen bei Roulette? Pastor Off topic-Zone 19 10.09.10 17:27


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61