Vojna (s kartami)

Peter in Pavel igrata vojno. Ker pa se igra lahko vleče v nedogled, sta jo nekoliko poenostavila.

V začetku vsak igralec dobi kupček kart (v Pythonu predstavljen s seznamom števil). V vsaki potezi vsak od njiju obrne gornjo karto. Tisti, čigar karta je višja, pobere obe karti - najprej svojo in nato še nasprotnikovo. Če sta karti (številki) enaki, pa ju ne dobi nihče. Razlika med običajno igro in njuno je torej v tem, zadnjem.

Obvezna naloga

Na začetek programa napiši tole:

from random import *

karte = list(range(1, 7)) * 2
shuffle(karte)
peter, pavel = karte[:6], karte[6:]

To bo razdelilo karte od 1 do 7; vsak jih bo dobil šest. S tem, kako dela program, se ne ubadaj. Pomembno je, da imaš po tem dva seznama peter in pavel, ki vsebujeta naključno razdeljene karte.

Napiši program, ki odsimulira en krog igre. Predpostaviti smeš, da imata oba igralca enako število kart, ne pa nujno, da jih je 6.

Na začetku programa izpiši, kakšne karte ima kdo. Na koncu izpiši, kakšne karte ima kdo po enem krogu igre.

Peter v začetku:  [6, 1, 5, 3, 1, 3]
Pavel v začetku:  [2, 6, 5, 2, 4, 4]

Peter na koncu:  [6, 2, 3, 2]
Pavel na koncu:  [6, 1, 4, 1, 4, 3]

Tule je najprej zmagal Peter, zato se njegov seznam začne s 6, 2. Nato je zmagal Pavel, zato 6, 1. Petic ni dobil nihče. Nato je zmagal Peter, zato sta v njegovem seznamu še 3, 2. Ostala dva para je dobil Pavel.

Izpis bo seveda vsakič drugačen, saj so karte razdeljene naključno. Če odkriješ, da program v določeni situaciji ne deluje, lahko (začasno) uporabiš konstantne sezname, tako da pod gornji začetek programa dopišeš, na primer,

peter = [6, 1, 5, 3, 1, 3]
pavel = [2, 6, 5, 2, 4, 4]

Nasvet: sestavi nova seznama in zlagaj karte vanju. Jaz sem ju poimenoval novi_peter in novi_pavel.

Rešitev

Če izpustimo print-e, je program takšen.

novi_peter = []
novi_pavel = []

for petrova, pavlova in zip(peter, pavel):
    if petrova > pavlova:
        novi_peter.append(petrova)
        novi_peter.append(pavlova)
    elif pavlova > petrova:
        novi_pavel.append(pavlova)
        novi_pavel.append(petrova)

Z zip(peter, pavel) dobimo seznam parov kart. Pobiramo ju v spremenljivki petrova in pavlova ter ju glede na to, katera je večja, damo v en ali drug seznam.

Dodatna naloga

Odsimuliraj celo igro, ne le enega kroga.

To se da narediti na dva načina. Lahko spremeniš gornji program tako, da bo v primeru, da ima en igralec več kart, te karte po izteku enega kroga postavil na začetek njegovega seznama. Potem pa okrog tako spremenjenega programa napišeš še eno zanko in izpišeš stanje po vsakem krogu igre.

Drugi, najbrž preprostejši način, je, da zavržeš gornji program in delaš tako: iz vsakega kupčka vzameš prvo karto. Nato obe karti daš na konec zmagovalčevega kupčka (najprej njegovo, nato nasprotnikovo). Končaš, ko je eden od tekmovalcev brez kart.

[2, 4, 2, 5, 5, 6]
[1, 6, 3, 1, 3, 4]

[4, 2, 5, 5, 6, 2, 1]
[6, 3, 1, 3, 4]

[2, 5, 5, 6, 2, 1]
[3, 1, 3, 4, 6, 4]

[5, 5, 6, 2, 1]
[1, 3, 4, 6, 4, 3, 2]

[5, 6, 2, 1, 5, 1]
[3, 4, 6, 4, 3, 2]

[6, 2, 1, 5, 1, 5, 3]
[4, 6, 4, 3, 2]

[2, 1, 5, 1, 5, 3, 6, 4]
[6, 4, 3, 2]

[1, 5, 1, 5, 3, 6, 4]
[4, 3, 2, 6, 2]

[5, 1, 5, 3, 6, 4]
[3, 2, 6, 2, 4, 1]

[1, 5, 3, 6, 4, 5, 3]
[2, 6, 2, 4, 1]

[5, 3, 6, 4, 5, 3]
[6, 2, 4, 1, 2, 1]

[3, 6, 4, 5, 3]
[2, 4, 1, 2, 1, 6, 5]

[6, 4, 5, 3, 3, 2]
[4, 1, 2, 1, 6, 5]

[4, 5, 3, 3, 2, 6, 4]
[1, 2, 1, 6, 5]

[5, 3, 3, 2, 6, 4, 4, 1]
[2, 1, 6, 5]

[3, 3, 2, 6, 4, 4, 1, 5, 2]
[1, 6, 5]

[3, 2, 6, 4, 4, 1, 5, 2, 3, 1]
[6, 5]

[2, 6, 4, 4, 1, 5, 2, 3, 1]
[5, 6, 3]

[6, 4, 4, 1, 5, 2, 3, 1]
[6, 3, 5, 2]

[4, 4, 1, 5, 2, 3, 1]
[3, 5, 2]

[4, 1, 5, 2, 3, 1, 4, 3]
[5, 2]

[1, 5, 2, 3, 1, 4, 3]
[2, 5, 4]

[5, 2, 3, 1, 4, 3]
[5, 4, 2, 1]

[2, 3, 1, 4, 3]
[4, 2, 1]

[3, 1, 4, 3]
[2, 1, 4, 2]

[1, 4, 3, 3, 2]
[1, 4, 2]

[4, 3, 3, 2]
[4, 2]

[3, 3, 2]
[2]

[3, 2, 3, 2]
[]

Na predavanjih sem povedal, da s peter[3:] dobimo seznam vseh Petrovih kar, razen prvih treh. Povedal sem tudi za funkcijo len. In za pop. Te stvari utegnejo priti prav. Sicer pa si lahko pomageš tudi s Pythonovo dokumentacijo o seznamih (seznam metod bo zadoščal).

Rešitev

To je pa skoraj isto, le da ne teče v dodatnem seznamu temveč kar v istem. Dokler ima kdo od njiju še kako karto (to je, dokler seznama nista prazna), poberemo iz vsakega prvo karto in ju damo na konec enega ali drugega seznama.

while peter and pavel:
    petrova, pavlova = peter.pop(0), pavel.pop(0)
    if petrova > pavlova:
        peter.append(petrova)
        peter.append(pavlova)
    elif pavlova > petrova:
        pavel.append(pavlova)
        pavel.append(petrova)
    print(peter)
    print(pavel)
    print()
Последнее изменение: суббота, 17 октября 2020, 15:13