Russisches Roulette

Indi

Member of Honour
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. 8o

Werd in zwei Tagen dann mal meine Lösung reinstellen und kurz erläutern.
 
So, ich hoffe ich bin weder zu früh noch zu spät..
Hier ist meine Lösung :D


edit:: scheisse, da war ein sehr übler Fehler drin ;)
Hab ihn mal rausgetan :D
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";
	}
}
 
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 ?
 
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*
 
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.
 
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 :D -

Hast Du meinen Code mal getestet ?
 
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... :D 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 :D
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 :D
 
hallo,

danke für Dein feedback

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 :D.
Das Spiel ist ja grundsätzlich ganz schön destruktiv.

Bin mal gespannt auf die Lösung von Indi
 
ka, ob das jetzt klugscheisserisch ;) rüberkommt, aber ich bin nunmal verfechter von gutem code und genauen erklärungen, insbesondere was c/c++ angeht

Original von JoBbE
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... :D 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
 
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

Original von JoBbE
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... :D 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 :D.
Ü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.

.
 
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 :D.

ok ok, ich meinte natürlich dass betriebssystem, oder das programm, welches dein programm aufruft, um genau zu sein ;)

Ü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
 
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

Original von JoBbE
Ja. Also folgendes...
Erstens: Deine main Funktion gibt keinen Wert zurück... :D 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 :D

Sry, musste sein *grins*
 
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 ?
 
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;
		}
	}
}
 
Das ist das erste Mal, dass ich ein C# Programm sehe. Und ich wundere mich. Das lehnt sich ja an Pascal an?!?

Interessante Sache.
 
ne also mit pascal hat das eigentlich nicht viel ähnlichkeit
am schnellsten könnte man das wohl in ein java programm umschreiben
C# ist so ne mischung aus c++ und java
 
Ich meinte sowohl das WriteLine als auch das using System...
Ich muss mal n bissel über C# lesen, diese Änderungen müssen ja einen Sinn gehabt haben.
Einfach die #include Anweisungen in using umzuändern macht für mich wenig Sinn, daher muss da ja mehr dahinter stecken...
Ich werd mal lesen.

[edit]
Uiuiui. Ich hab gerade so zwei, drei Artikel gelesen und gemerkt, dass ich eine völlig falsche Vorstellung von C# hatte.

Sry fürs extreme OT. Lasst es uns begraben.
 
lösung in python

hi,
hier mal eine einfache lösung in python
Code:
import random
def play(kugelnr,wer,start):
   if wer:
        print "abdruecken a neudrehen d "
        auswahl=raw_input()
        if auswahl=="d":
            print "du drehst neu"
            start=1
            kugelnr=random.randint(1, 6)
        print "du drueckst ab"
        if kugelnr == 6:
            print "dumm gelaufen, du hast dein Kopf verloren\n"
        else:
            print "glueckspilz, computer du bist dran\n"
            play(kugelnr+1,0,start+1)
   else:
        if start > 4:
            print "der Computer kann zaehlen er dreht neu"
            start=1
            kugelnr=random.randint(1, 6)
        print "der Computer drueckt ab"
        if kugelnr==6:
            print "dumm gelaufen fuer den Computer\n"
        else:
            print "glueck gehabt, du bist dran\n"
            play(kugelnr+1,1,start+1)


if __name__ == '__main__':
    print "wer faengt an Computer 0 oder du 1"
    wer=raw_input()
    play(random.randint(1, 6),int(wer),1)
gruß
 
Zurück
Oben