Terra Mystica: Radfahren macht


28

Das Brettspiel Terra Mystica hat einige sehr interessante Mechanismen für eine der wichtigsten Ressourcen, die Kraft. Anstatt Krafteinheiten von einer Bank zu erhalten und auszugeben, beginnt jeder Spieler das Spiel mit genau 12 Krafteinheiten, die auf drei "Schalen" mit den Bezeichnungen I, II und III verteilt sind. Macht gewinnen und ausgeben verschiebt dann einfach die Macht zwischen diesen Schalen:

  • Um eine Krafteinheit auszugeben, bewegen Sie sie von Schüssel III zu Schüssel I (vorausgesetzt, Sie haben eine Einheit in Schüssel III).
  • Wenn du eine Krafteinheit erhältst, lege sie in Schüssel II, wenn sich eine Einheit in Schüssel I befindet. Befindet sich keine Einheit in Schüssel I, aber eine Einheit in Schüssel II, stellen Sie sie in Schüssel III. Wenn sich alle Einheiten bereits in Schüssel III befinden, geschieht nichts.
  • Wenn Sie mehrere Einheiten auf einmal erhalten oder ausgeben, werden diese einzeln verarbeitet.

Hier ist ein Beispiel. Angenommen, ein Spieler beginnt mit der folgenden Leistungsverteilung (in der angegebenen Reihenfolge I | II | III):

5 | 7 | 0

Ihre Kraft ändert sich wie folgt, wenn sie einige Male Kraft aufnimmt und ausgibt:

               5 |  7 |  0
Gain  3  ==>   2 | 10 |  0
Gain  6  ==>   0 |  8 |  4   (move 2 power from I to II, 
                              then the remaining 4 from II to III)
Gain  7  ==>   0 |  1 | 11
Spend 4  ==>   4 |  1 |  7
Gain  1  ==>   3 |  2 |  7
Spend 7  ==>  10 |  2 |  0
Gain 12  ==>   0 | 10 |  2   (move 10 power from I to II,
                              then the remaining 2 from II to III)
Gain 12  ==>   0 |  0 | 12   (the two excess units go to waste)

Ihre Aufgabe ist es, das Ergebnis eines solchen Gewinn- oder Ausgabenereignisses zu berechnen.

Die Herausforderung

Sie erhalten vier Ganzzahlen als Eingabe. Die ersten drei, I, II, III, stellen die Energiemenge in jedem der drei Schalen. Sie sind nicht negativ und summieren sich zu 12. Die vierte Zahl Pgibt die Menge der gewonnenen oder verbrauchten Kraft an und befindet sich im Inklusivbereich [-III, 24](Sie können also davon ausgehen, dass der Spieler niemals versuchen wird, mehr Kraft zu verbrauchen als sie derzeit können, aber sie könnten mehr Kraft gewinnen, als sie brauchen, um die gesamte Kraft in die Schüssel III zu befördern.

Sie können diese Zahlen in einer beliebigen konsistenten Reihenfolge als separate Argumente, als Liste von Ganzzahlen oder als Zeichenfolge mit diesen Ganzzahlen verwenden. Sie kann auch Pals ein Argument, wie I, II, IIIals separate Liste Argument.

Die Ausgabe sollten drei ganze Zahlen I', II', aus III'denen die Menge an Energie in jeder Schale nach P Einheiten gewonnen wurden oder verbracht, nach den Regeln oben erläuterten.

Sie können ein Programm oder eine Funktion schreiben und eine unserer Standardmethoden zum Empfangen und Bereitstellen von Eingaben verwenden.

Sie können jede Programmiersprache verwenden , aber beachten Sie, dass diese Lücken standardmäßig verboten sind.

Das ist , also gewinnt die kürzeste gültige Antwort - gemessen in Bytes .

Testfälle

I II III P => I' II' III'
5 7 0 3    => 2 10 0
2 10 0 6   => 0 8 4
0 8 4 7    => 0 1 11
0 1 11 -4  => 4 1 7
4 1 7 0    => 4 1 7
4 1 7 1    => 3 2 7
3 2 7 -7   => 10 2 0
10 2 0 12  => 0 10 2
0 10 2 12  => 0 0 12

1
Ich empfehle, geschlechtsspezifische Pronomen zu entfernen und durch geschlechtsneutrale (oder umstrukturierende) zu ersetzen: Spieler müssen nicht männlich sein.
Greg Martin

1
@ GregMartin Natürlich. Habe ich sie alle gefangen?
Martin Ender

2
Sieh so aus; Danke, dass du darüber nachgedacht hast! Ist Terra Mystica so großartig, wie ich gehört habe?
Greg Martin

4
@ GregMartin ja. :)
Martin Ender

5
Kein Strom brennt aus Schüssel 2? Das fühlt sich einfach so unvollständig an.
Mehron

Antworten:


6

Mathematica, 52 Bytes

{x=#-#4~Min~#,y=Max[#2+#-Abs[#4~Max~0-#],0],12-x-y}&

Dies ist eine unbenannte Funktion, die eine Liste aufnimmt {I, II, III, P} als Eingabe verwendet und eine Liste zurückgibt {I', II', III'}.

Eine geschlossene Lösung. Es fühlt sich noch nicht wirklich optimal an ...


Dachte ich könnte verkürzen, ist aber {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&ein Byte länger. Ich mag das 12-+##aber.
Greg Martin

1
@ GregMartin Ich habe das Gleiche versucht :)
Martin Ender

6

C, 97 94 Bytes

f(i,j,k,n){for(;n;n-=n/abs(n))n<0?k?++i+--k:0:i?++j+--i:j?++k+--j:0;printf("%d %d %d",i,j,k);}

In ungolfed Form:

f(i, j, k, n) {
    while (n) {
        if (n < 0) {
            if (k) {
                ++i; --k;
            }
            ++n;
        } else {
            if (i) {
                ++j; --i;
            }
            else if (j) {
                ++k; --j;
            }
            --n;
        }
    }
    printf("%d %d %d", i, j, k);
}

5

Python 2, 104 Bytes

def f(i,d,t,g):
 x=min(i,g);i-=x;q=g>0;g-=x
 if q:d+=x;x=min(d,g);g-=x;d-=x;t+=x
 else:t+=x
 print i,d,t

Probieren Sie es online aus

Ungolfed:

def f(i,d,t,g):
 if g>0:
    x=min(i,g)
    g-=x
    i-=x
    d+=x    
    x=min(d,g)
    g-=x
    d-=x
    t+=x
 else:
    x=min(i,g)
    g-=x
    i-=x
    t+=x
 print(i,d,t)

5

Haskell, 58 Bytes

f(a,b,c)d|m<-min a d,z<-min(c+d-max 0 m)12=(a-m,b+c+m-z,z)

Der Zwischenwert gibt mdie Kraftmenge an, die von der ersten Schüssel (oder, falls negativ) zu zder dritten Schüssel nach der Aktion fließt. Durch eine 1-Byte-Optimierung in letzter Minute wurde der alte Ausdruck für die zweite Schüssel von der 12-a+m-zVerwendung der Identität abgeändert a+b+c=12.

Der natürliche Ergebnistyp ist ein Tripel für die Schüsseln, sodass die Eingabe die Schüsseln auch als Tripel und die Leistungsänderung als zweites Argument betrachtet. Dies ermöglicht die Bearbeitung aller Testfälle mit einer Anwendung von scanl:

*Main> scanl f (5,7,0) [3,6,7,-4,0,1,-7,12,12]
[(5,7,0),(2,10,0),(0,8,4),(0,1,11),(4,1,7),(4,1,7),(3,2,7),(10,2,0),(0,10,2),(0,0,12)]

5

Röda , 100 94 Bytes

f a,b,c,p{{c+=p;a-=p}if[p<0]else{{a--;b++;p--}while[p*a>0];{b--;c++;p--}while[p*b>0]};[a,b,c]}

Ungolfed:

f a,b,c,p {
    if [ p < 0 ] do
        c += p
        a -= p
    else
        { a-=1; b+=1; p-=1 } while [ p > 0 and a > 0 ]
        { b-=1; c+=1; p-=1 } while [ p > 0 and b > 0 ]
    done
    return a, b, c
}

Hat Röda nicht die Operatoren ++und --?
Kritixi Lithos

@KritixiLithos Danke! Ja tut es.
Fergusq


3

GNU sed , 66 Bytes

Beinhaltet +1 für -r

/-/!{:
s/1,(.* )1/,1\1/
t}
s/(.*)(1+) -\2/\2\1/
s/(,,1{12}).*/\1/

Verwendet unary (siehe diesen Konsens ).

Probieren Sie es online!

/-/!{                  # If there is not a '-'
  :                    # start loop
  s/1,(.* )1/,1\1/     # move a 1 from before a ',' to after the ',' for every 1 after the space
                       # sed reads left to right, so this takes everything from the first bowl before starting on the second
  t                    # loop if something changed
}                      # end if
s/(.*)(1+) -\2/\2\1/   # take all of the 1s from after a '-' and move them to the begining.
                       # at the same time, remove that many 1s from the 3rd bowl
s/(,,1{12}).*/\1/      # remove everything after 12 1s in the third bowl

3

Retina ,  46  41 39 38 Bytes

Vielen Dank an Martin Ender für viele hilfreiche Vorschläge!

+`1,(.*¶)1
,1$1
(.*)(1+)¶-\2$
$2$1
G`,

Nimmt unäre Eingaben auf. Die erste Zeile enthält die Strommengen in den drei Schalen, kommasepariert, die zweite Zeile die zu zyklisierende Strommenge.

Testsuite - Fasst alle Eingaben in einer einzigen Zeile zusammen und konvertiert sie zur Vereinfachung von dezimal zu unär und umgekehrt.

Erläuterung

+`1,(.*¶)1
,1$1

Positiver Fall: Wir entfernen wiederholt den 1Strich aus der zweiten Zeile und verschieben einen Strich 1aus der ersten nicht leeren Schüssel in die folgende, solange dieser Vorgang möglich ist (dh die Anzahl der zu zyklierenden Striche ist ungleich Null und nicht alle) Macht ist in der dritten Schüssel). Dass Modifikator bedeutet single-line, dass .auch der Zeilenumbruch berücksichtigt werden kann.

(.*)(1+)¶-\2$
$2$1

Negativer Fall: Alles in einem Schritt erledigt, wobei die durch die letzte Eingabe angezeigte Leistungsmenge von der dritten in die erste Schüssel verschoben wird. Dadurch wird auch die Linie mit der negativen Bewegungsenergie entfernt.

G`,

Behalten Sie (grep) nur Zeilen bei, die ein Komma enthalten. Dadurch werden die eventuellen Reste der ersten Zeile entfernt.



2

Batch, 87 Bytes

@set/a"i=%4-%1,j=%4*(-%4>>5)-%2-2*i*(-i>>5),i*=i>>5,j*=j>>5,k=12-i-j
@echo %i% %j% %k%

Verwenden Sie die folgenden Formeln:

I' = min(I - P, 0)
II' = min(II + min(P, 0) - 2 * min(P - I, 0), 0)
III' = 12 - I' - II'

Da Batch nicht weniger als einen Operator hat, berechne ich i = min(-i, 0)mit i*=i>>5.


2

Perl 6 , 99 Bytes

->\a,\b,\c,\d{d>0??[»+»] (a,b,c),|(|((-1,1,0)xx a),|((0,-1,1)xx a+b),|(0 xx*))[^d]!!(a- d,b,c+d)}

Lassen Sie a, b, und c, die Anzahl der Start Token in Schalen I, II, und III. Dann wird für den Fall der Additionskraft eine Liste erstellt, die aKopien des Tripletts enthält (-1, 1, 0), gefolgt von a + bKopien des Tripletts (0, -1, 1), gefolgt von unendlichen Kopien von 0. Die ersten dElemente dieser Liste,d dh die Menge der hinzuzufügenden Leistung, werden der Startleistungsverteilung elementweise hinzugefügt.

Zum Subtrahieren Leistung (negative d), wird eine einfache geschlossene Form verwendet: (a - d, b, c + d).


2

tinylisp , 134 bytes

(d f(q((x y z p)(i p(i(l p 0)(f(s x p)y(a z p)0)(i x(f(s x 1)(a y 1)z(s p 1))(i y(f x(s y 1)(a z 1)(s p 1))(f x y z 0))))(c x(c y(c z(

Definiert eine Funktion f, die vier Argumente, die drei Bowls ( x y z) und die Menge der übertragenen Leistung ( p), akzeptiert und nach der Transaktion eine Liste der drei Bowls zurückgibt. Hier ist eine korrekt angeordnete Version mit allen Testfällen: Probieren Sie es online aus!

(d f                         Define f to be
 (q(                          a quoted two-item list (which acts as a function):
  (x y z p)                    Arglist: the three bowls x y z and power p
  (i p                         If p is nonzero
   (i (l p 0)                   then if p is negative (spending power)
    (f(s x p)y(a z p)0)          then take -p from z, add -p to x, and recurse with p=0
    (i x                         else (gaining power), if x is nonzero
     (f(s x 1)(a y 1)z(s p 1))    then take 1 from x, add to y, decrement p and recurse
     (i y                         else if y is nonzero
      (f x(s y 1)(a z 1)(s p 1))   then take 1 from y, add to z, decrement p and recurse
      (f x y z 0))))               else no moves possible; recurse with p=0
   (c x(c y(c z())))))))        else (p=0), cons x y z into a list and return it
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.