Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Nim-Variante (Felder)

Ein klassisches Beispiel der mathematischen Spieltheorie ist das Nim-Spiel. Bei der folgenden Variante liegt genau eine Reihe mit n Streichhölzern auf dem Tisch. Zwei Spieler nehmen abwechslungsweise 1, 2 oder 3 Hölzer weg. Wer das letzte Streichholz nehmen darf, gewinnt die Partie.

Entwickeln Sie eine Gewinnstrategie und schreiben Sie ein Programm, bei dem ein Spieler gegen den Computer antreten darf. Der Spieler darf die Anzahl anfänglicher Hölzer wählen und er darf bestimmen, ob er oder der Computer beginnen wird.

Abwechslungsweise wird ausgegeben, wie viele Hölzer der Computer wegnimmt bzw. erfragt, wie viele Hölzer der Anwender nehmen will. Nach jedem Zug wird ausgegeben, wie viele Hölzer noch vorhanden sind.

Zuletzt endet das Programm mit folgender Ausgabe:

"Glückwunsch, Sie haben gewonnen"

bzw.

"Der Computer hat gewonnen."

0 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

5 Lösung(en)

package ch.programmieraufgaben.nim;

import java.util.Scanner;

/**
 * @author Philipp Gressly Freimann (info@programmieraufgaben.ch)
 */

public class Nim {
  public static void main(String[] args) {
    new Nim().top();
  }
  
  public void top() {
    int      anzahl          = einlesenGanzzahl("Anzahl Hölzer");
    boolean  computerBeginnt = einlesenBool    ("der Computer beginnt");
      
    boolean  computerSieger  = simuliere(anzahl, computerBeginnt);
    ausgabeSieger(computerSieger);
  }
  
  Scanner sc = new Scanner(System.in);
  int einlesenGanzzahl(String menge) {
    System.out.println("Eingabe " + menge + ": ");
    return sc.nextInt();
  }
  
  boolean einlesenBool(String ob) {
    System.out.println("Bitte eingeben ob " + ob + "(ja/nein): ");
    String eingabe = sc.next();
    // Alles was mit "n" beginnt wird als "nein" aufgefasst, alles andere als "ja":
    return ! eingabe.trim().toLowerCase().startsWith("n");
  }

  boolean simuliere(int anzahl, boolean computerBeginnt) {
    boolean computerSieger = false;
    boolean computerAmZug  = computerBeginnt;
    while(anzahl > 0) {
      System.out.println("Es hat " + anzahl + " Hölzer.");
      if(computerAmZug) {
        anzahl = computerZug(anzahl);
        if(0 == anzahl) {
          computerSieger = true;
        }
      } else {
        anzahl = anzahl - frageBenutzerNachZug();
      }
      computerAmZug = ! computerAmZug; // nächster Spieler
    }
    return computerSieger;
  }

  int frageBenutzerNachZug() {
    int nim = 0;
    while(nim < 1 || nim > 3) {
      System.out.println("Bitte eingeben, wie viele Hölzer Sie nehmen wollen: ");
      nim = sc.nextInt();
    }
    System.out.println("OK, es wurden für Sie " + nim + " Stk. entfernt.");
    return  nim;
  }
  
  int computerZug(int anzahl) {
    int nim;
    nim = anzahl % 4; // optimal, falls > 0
    if(0 == nim) {
        nim = 1;
    }
    System.out.println("Computer nimmt " + nim + " Stk.");
    return anzahl - nim;
  }
  
  void ausgabeSieger(boolean computerSieger) {
    if(computerSieger) {
      System.out.println("Der Computer hat gewonnen.");
    } else {
       System.out.println("Glückwunsch, Sie haben gewonnen");
    }
  }
  
} // end of class Nim
                

Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

# @autor Philipp Gressly Freimann
# Okt 2011
#
# Aufgabe programmieraufgaben.ch
# NIM Variante mit lediglich einer Zeile Hölzer


def hauptprogramm() 
  anzahl          = einlesenGanzzahl("Anzahl Hölzer")
  computerBeginnt = einlesenBool("der Computer beginnt")
  computerSieger  = simuliere(anzahl, computerBeginnt)
  ausgabeSieger(computerSieger)
end

def ausgabeSieger(computerSieger)
  if(computerSieger) 
    print "Der Computer hat gewonnen.\n"
  else
    print "Glückwunsch, Sie haben gewonnen.\n"
  end
end

def einlesenGanzzahl(frageOB)
  print "Eingabe #{frageOB}: "
  return STDIN.gets.to_i
end

def einlesenBool(frageOB) 
  print "Bitte eingeben ob #{frageOB} (ja/nein): "
  eingabe = STDIN.gets.chomp.upcase
  # 74 = "N"
  return 74 == eingabe[0]
end

def simuliere(anzahl, computerBeginnt)
  computerSieger = false
  computerAmZug = computerBeginnt
  while(anzahl > 0) 
    print "Es hat #{anzahl} Hölzer.\n"
    if(computerAmZug)
      anzahl = computerZug(anzahl)
      if(0 == anzahl) 
        return true
      end
    else
      anzahl = anzahl - frageBenutzerNachZug()
    end
    computerAmZug ^= true; # nächster Spieler
  end
  return computerSieger
end

def computerZug(anzahl)
  nim = anzahl % 4
  if(0 == nim)
    nim = 1
  end
  print "Computer nimmt #{nim} Stk.\n"
  return anzahl - nim;
end

def frageBenutzerNachZug()
  nim = 0
  while(nim < 1 || nim > 3) 
    print "Bitte eingeben, wie viele Hölzer Sie nehmen wollen: "
    nim = STDIN.gets.to_i
  end
  print "OK, es wurden für Sie #{nim} Stk. entfernt.\n"
  return nim
end

# start
hauptprogramm()
                

Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

// Autor:				Andy Großhennig
// Solution for task:	Nim-Variante (Felder)

#include <iostream>
#include <Windows.h>

using namespace std;

// Function: Get the game settings
void getMode(short &shMatches, bool &isCompBegins)
{
	char chWhoBegins;

	cout << "Willkommen! Starte Nim-Spiel...\n\n";
	Sleep(1000);

	do
	{
		cout << "Mit wievielen Streichhoelzern willst du spielen? (Min: 10) ";
		cin >> shMatches;
	} while(shMatches < 10);

	cout << "\nWillst du beginnen? (j/n): ";
	cin >> chWhoBegins;
	cout << "\n\n";

	if(chWhoBegins == 'n')
		isCompBegins = true;
	else
		isCompBegins = false;
}

// Function: Show the amount of matches in lines and the amount in numbers below
void showField(short &shMatches)
{
	for(int i = 0;i < shMatches;i++)
	{
		cout << "| ";
	}
	cout << "\n\n" << shMatches << " verbleiben\n\n";

}

// Function: Calculate the turns for computer and player
void turn(bool &isCompTurns, short &shTake, short &shMatches)
{
	if(isCompTurns)
	{
		cout << "Der Computer ist an der Reihe.\n";
		Sleep(1500);
		shTake = shMatches % 4; // 100% win for computer if the player have an starting point of four matches
		if(shTake == 0)
			shTake++;
		shMatches -= shTake; //decrease the matches
		cout << "Der Computer nimmt " << shTake << " Streichhoelzer.\n\n";
		shTake = 0; //reset the amount of takes
		Sleep(1000);
		showField(shMatches); //show the field
	}
	else //Player turn
	{
		cout << "Du bist an der Reihe.\n";
		do
		{
			cout << "Wieviele Streichhoelzer nimmst du? (1-3) ";
			cin >> shTake;
			cout << endl;
		} while(shTake < 1 || shTake > 3);

		shMatches -= shTake;
		shTake = 0;
		showField(shMatches);
	}
}

// Function: Manage the game
void play()
{
	short shMatches = 10;
	bool isCompTurns;
	short shTake;

	getMode(shMatches, isCompTurns); //get the game settings

	showField(shMatches); //show the field

	// Loop: Continue the turns until the amount of matches is above zero
	while(shMatches > 0)
	{
		turn(isCompTurns, shTake, shMatches);
		Sleep(1500);
		if(isCompTurns)
		{
			// If: Is computer on turn
			if(shMatches <= 0)
			{
				cout << "\nYEAY Ich habe gewonnen! =)\n";
			}
			isCompTurns = false;
		}
		else
		{
			// If: Is player on turn
			if(shMatches <= 0)
			{
				cout << "\nHerzlichen Glueckwunsch! Du hast gewonnen!\n";
			}
			isCompTurns = true;
		}
	}
}

int main()
{
	play();

	cout << "\n\n";
	system("Pause");
	return 0;
}
                

Lösung von: Andy Großhennig (Bundeswehr)

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

using namespace std;

void printsh(int &shRest) // Restliche Streichhölzer anzeigen
{
 	int i;
 	
 	for (i = 1; i <= shRest; i++)
	{
		printf("%s", "| ");
	}
	printf("\n\n%s%i%s\n", "Noch ", shRest, " Streich\x94lzer verbleibend.");
}

int randTake(int &maxTake, int &shRest) // Anzahl Streichhölzer die der Computer nimmt
{
	int cTake;
	
	if (shRest == 3)
	{
		cTake = 3; // Wenn 3 übrig, Computer entnimmt 3
	}
	else if (shRest == 2)
	{
		cTake = 2; // Wenn 2 übrig, Computer entnimmt 2
	}
	else if (shRest == 1)
	{
		cTake = 1; // Wenn 1 übrig, Computer entnimmt 1
	}
	else if (shRest > 3) //Wenn > 3 übrig random Entnahme
	{
		srand (time(NULL));
		cTake = rand() % maxTake + 1;
	}
	return cTake;
}

int main()
{
	int shAnzahl;
	
	do
	{
		printf("%s", "Bitte die Streichholzanzahl angeben (min 10): ");
		scanf("%i", &shAnzahl);
		system("cls");
	} while (shAnzahl < 10);
	
	printf("%s", "Soll der Computer beginnen? (j/n): ");
	char begin;
	fflush(stdin);
	scanf("%c", &begin);
	int shTaken = 0; // Bisher 0 taken Streichhölzer
	system("cls");
	
	int shRest = shAnzahl - shTaken; // Restliche Streichhölzer, momentan alle verbleibend
	int maxTake;
	
	if (shRest <= 3) // maxTake definiren
	{
		maxTake = shRest;
	}
	else if (shRest > 3)
	{
		maxTake = 3;
	}
	
	if (begin == 'j')
		{
			int cTake = randTake(maxTake, shRest); // Computer Take
			printf("%s%i%s\n\n", "Der Computer entnimmt ", cTake, " Streichh\x94lzer.");
			shRest -= cTake;
			shTaken += cTake;
		}
	
	int cTake;
	
	printsh(shRest); // Start Ausgabe der restlichen Streichhölzer
	
	while (shRest >= 1)  // Hauptschleife, endet sobald Streichhölzerrest < 1
	{
		int uTake; // User Take
		
		do 
		{ 
			printf("\n%s", "Wie viele Streichh\x94lzer entnimmst du?: ");
			scanf("%i", &uTake);
			system("cls");
			if (uTake < 0 || uTake > 3)
			{
				printf("%s", "Eingabe ung\x81ltig.");
				Sleep(1000);
				system("cls");
			}
		} while (uTake <= 0 || uTake > 3);
		
		
		
		shRest -= uTake;
		shTaken += uTake;
		printf("%s%i%s\n", "Du entnimmst ", uTake, " Streichh\x94lzer.");
		
		if (shRest == 0)
		{
			printf("\n\n%s", "Yeah. Du hast gewonnen!!");
			getch();
			return 0;
		}
		
				
		
		cTake = randTake(maxTake, shRest);
		printf("\n%s%i%s\n\n", "Der Computer entnimmt ", cTake, " Streichh\x94lzer.");
		shRest -= cTake;
		shTaken += cTake;
		
		if (shRest == 0)
		{
			printf("\n\n%s", "Schade. Der Computer hat gewonnen.");
			getch();
			return 0;
		}
		printsh(shRest);
	}
	return 0;
}
                

Lösung von: Name nicht veröffentlicht

// eingabemaske
document.write(
  '<button onclick="userMove(1)">Nimm 1</button> ' +
  '<button onclick="userMove(2)">Nimm 2</button> ' +
  '<button onclick="userMove(3)">Nimm 3</button>' +
  '<div id="msg"></div>' +
  '<div><h1 id="heapsize"></h1></div>'
);

var theHeap = prompt("Anzahl der Streichhölzer:"),
    userStart = confirm("Willst du das Spiel beginnen?"),
    msg = document.getElementById("msg"),
    heapSize = document.getElementById("heapsize");

function computerMove() {
  var howMany,
      tookTxt;
  // anzahlentscheidung
  if (theHeap <= 3) howMany = theHeap;
  else {
    howMany = theHeap % 4;
    if (howMany == 0) howMany = 1;
  }
  // entnahme
  theHeap -= howMany;
  heapSize.innerText = theHeap;
  tookTxt = "Ich habe " + howMany + " genommen.";
  // gewinncheck
  if (theHeap == 0) msg.innerText = tookTxt + " Du hast verloren.";
  else msg.innerText = tookTxt;
}

function userMove(howMany) {
  msg.innerText = "Du bist dran.";
  // entnahme
  theHeap -= howMany;
  heapSize.innerText = theHeap;
  // gewinncheck
  if (theHeap == 0) msg.innerText = "Du hast gewonnen...";
  else computerMove();
}

/* start */
heapSize.innerText = theHeap;
if (userStart) msg.innerText = "Du bist dran.";
else computerMove();                                        // lissalanda@gmx.at

                

Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit:
Schwierigkeit: k.A.
Webcode: ehee-z3qd
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen