andere opgaven: acht koninginnen | boter, kaas en eieren | logiquiz | sudoku | laatste wint

Laatste wint

Dit is een spel waarmee je anderen versteld kan laten staan, omdat het lijkt dat jij onverslaanbaar bent !
Het spel is hier in Python nagebouwd, zodat je het tegen de computer kan opnemen...

Het spel:

Dit is een spel voor twee personen. Op tafel liggen een aantal lucifers (of muntjes, of knikkers, of wat dan ook). Er wordt afgesproken hoeveel lucifers er per beurt maximaal mogen worden weggenomen.
Een van de spelers begint, en neemt minimaal één, en maximaal het afgesproken aantal lucifers weg. Dan is de andere speler aan de beurt, deze neemt ook lucifer(s) weg, enzovoort. Degene die de laatste lucifer wegneemt, heeft gewonnen.
 
Voor de onwetende speler, lijkt het erop dat het aantal weg te nemen lucifers willekeurig is, maar de geoefende speler zal (bijna) altijd winnen. Hoe kan dat ?

Benadering:

Je kan altijd winnen door vanaf het begin van het spel, het aantal lucifers dat je trekt zodanig te kiezen dat er aan het einde van jouw beurt een veelvoud van (1 + maximaal aantal te trekken lucifers per beurt) overblijft voor de ander.
Je tegenstander kan alleen winnen als hij hetzelfde doet,maar daar eerder in het spel mee begint.
De animatie laat zien hoe dat gaat (in werkelijkheid liggen de lucifers uiteraard kriskras door elkaar).

Programma afloop:

In de python code wordt de hierboven genoemde getallen berekend en in een lijst vastgelegd computer_zetten. Wanneer de computer aan de beurt is, wordt bepaald wat het eerst lagere getal uit die lijst is computer_zetten_over, zodat de tegenzet kan worden berekend deze_zet.

Variaties:

De hoeveelheid lucifers waarmee het spel begint, het maximaal aantal te pakken lucifers per beurt, en ook wie begint kan worden gekozen.
 
Dit spel kent nog een andere variant, nl. waarbij het de bedoeling is niet de laatste lucifer te pakken.
 
Veel plezier !
 

De code



"""een klassiek spel voor twee personen"""
__author__ = "Mark Nauta"
__copyright__ = "Copyright 2021"
__credits__ = "Mark Nauta"
__license__ = "GPL"
__version__ = "0.0.1"
__maintainer__ = "Mark Nauta"
__email__ = "markatnadropuntnl"
__status__ = "Production"

# toelichting: https://nadro.nl/mark/puzzels/laatste_wint.html 

from math import floor
from random import randint
import re
import sys

def initialisatie():
    print('\'Laatste die overblijft\'')
    print('er zijn twee varianten:\n[1] laatste lucifer wint\n[2] laatste lucifer verliest')
    while True:
        variant = input('kies variant [Enter=1]: ')
        if len(variant) == 0:
            variant = '1'
        if variant in ['1', '2']:
            break
    while True:
        start_lucifers = input('aantal startlucifers [10..100]: ')
        if re.match('^\d+$', start_lucifers) and int(start_lucifers) in range(10, 101):
            break
    start = int(start_lucifers)
    while True:
        beurt_lucifers = input('maximaal aantal lucifers te pakken per beurt [2..{}]: '.format(start//4, ))
        if re.match('^\d+$', beurt_lucifers) and int(beurt_lucifers) in range(2, (start//4+1)):
            break
    beurt = int(beurt_lucifers)
    computer_beurt = input('wie begint, jij of de computer [Enter=jij]: ')
    begin = (len(computer_beurt) > 0 )

    return (variant, start, beurt, begin)

if __name__ == '__main__':
    variant, start_lucifers, beurt_lucifers, is_computer_beurt = initialisatie()

    if variant == '1':
        computer_zetten = [ i*(beurt_lucifers+1) for i in range(start_lucifers//(beurt_lucifers+1)+1)]  
    else:
        computer_zetten = [ 1 + i*(beurt_lucifers+1) for i in range(start_lucifers//(beurt_lucifers+1)+1)]  
    str_bericht = 'Als je de laatste lucifer van tafel pakt, {} je.'.format('win' if variant == '1' else 'verlies')

    lucifers_over = start_lucifers
    while True:
        print('\nop tafel: {} lucifers'.format(lucifers_over, ))
        if is_computer_beurt:
            computer_zetten_over = [ x for x in computer_zetten if x < lucifers_over ] 
            deze_zet = lucifers_over - computer_zetten_over[-1]
            if deze_zet > beurt_lucifers:
                deze_zet = randint(1, beurt_lucifers)
            print('computer pakt: {} lucifer{}'.format(deze_zet, 's' if deze_zet > 1 else '', ))
        else:
            print(str_bericht)            
            while True: 
                max_inzet = min(beurt_lucifers, lucifers_over)
                deze_zet = input('\nhoeveel lucifers die speler wil trekken [1..{}]: '.format(max_inzet, ) )
                if re.match('^\d+$', deze_zet) and int(deze_zet) in range(1, max_inzet+1):
                    break
                else:
                    print('ongeldige invoer')
        lucifers_over -= int(deze_zet)
        if lucifers_over > 1:
            is_computer_beurt = not is_computer_beurt
        else:
            break
    print(('computer' if is_computer_beurt else 'jij'), 'wint')