Alice and Bob have a fight

24

6

  • Alice (A) and Bob (B) decided to have a battle.
  • Each combatant has 10 health.
  • They take turns to roll a 6 sided die for damage.
  • That damage is removed from their opponent's health.
  • In the end either Alice or Bob, will vanquish their foe.

Show me how the battle went. Outputting these codes for the actions which have taken place.

Attack

B a A    
^ Combatant
  ^ Action (attack)
    ^ Target

Roll

B r 4
^ Combatant
  ^ Action (roll)
    ^ Value

Health change

A h 6
^ Combatant
  ^ Attribute (health)
    ^ Value   

Win

A w 
^ Combatant
  ^ Action (win)

Example output:

A a B
A r 4
B h 6
B a A
B r 6
A h 4
A a B
A r 6
B h 0        
A w

Here are the rules:

  • Write in any language.
  • A single roll of the die should have an equal chance of resulting in any one of the numbers 1, 2, 3, 4, 5, or 6.
  • Alice always starts (Bob is chivalrous, in an old-fashioned way).
  • Output an action for each turn.
  • You must report the attack, roll, damage and win actions.
  • Combatants are upper case, actions are lower case.
  • It must not consistently produce the same result.
  • There must be at least one whitespace character between an output combatant, action and value.
  • The win action takes place when the opponent has zero or less health.
  • All parts of an action must be on the same line.
  • There should be one action per line.
  • Fewest bytes wins.

Have at it!

AJFaraday

Posted 2018-03-22T09:59:17.220

Reputation: 10 466

2Are you sure that "It must not consistently produce the same result" is what you want? I can just hardcode two possible outputs and randomly pick one of them. – user202729 – 2018-03-22T10:37:04.173

1@user202729 Curious point, it'd still have to produce the a valid output with the actions described. I'm not sure it'd be all that much shorter than writing the code. – AJFaraday – 2018-03-22T10:38:01.970

1You could specify that the number rolled each time must be uniformly distributed to a reasonable margin between 1 and 6. – HyperNeutrino – 2018-03-22T10:38:35.377

@HyperNeutrino It's virtually impossible to verify, tho. – AJFaraday – 2018-03-22T10:39:22.900

@user202729 "The distribution of dice rolls must look all-right to me" ;) – AJFaraday – 2018-03-22T10:45:59.850

9The names Alice (A) and Bob (B) are giving me flashbacks to network security class. Actor Alice (A) sends a packet to Bob (B) with key... etc... – Magic Octopus Urn – 2018-03-22T12:45:02.350

21@MagicOctopusUrn that’s them. They’re usually trying to communicate. Sadly conflict often ensues when communication breaks down. – AJFaraday – 2018-03-22T12:48:15.553

7I miss the days when we were trying to figure out how to hide our secrets from Mallory... those were simpler times... – Bob – 2018-03-22T13:36:21.683

4@Bob Mallory is something of a distraction, really. It's Eve you need to watch out for. – AJFaraday – 2018-03-22T13:37:13.070

@AJFaraday when they're locked in a *you* cage, I guess fighting would be the only option then. – Magic Octopus Urn – 2018-03-22T14:20:40.537

It can be hard to verify, but at least it prevents people from hardcoding the values and claiming it has 1/0/0/0/0/0 distribution (though that would probably be dealt with by DV+VTD or a mod anyway) – HyperNeutrino – 2018-03-22T14:29:49.790

@HyperNeutrino In the end I made it pretty prescriptive. Equal chances of each. – AJFaraday – 2018-03-22T14:31:06.117

I don't understand why your first line is AaB. A is attacking B before a roll? Your spec says a roll must be first to determine how much the attack will accomplish. – msh210 – 2018-03-22T16:46:20.307

3@msh210 well, the important detail in code golf is that everyone takes the same challenge, but here’s the logic: - if you were playing Dungeons and Dragons, you’d say “I’m going to kick the goblin”, then you’d roll for effectiveness, then implement the result of the roll. A roll is meaningless if nobody knows what you’re rolling for. – AJFaraday – 2018-03-22T16:52:53.760

I'm not surprised their relationship isnt going well. They've been having communication issues for years. – Robert Fraser – 2018-06-04T10:19:49.073

I want to note that Alice wins 66% of the time because she goes first. Increasing the starting health will reduces the advantage, but player 1 still wins more often. Don't play as Bob. :) – Ben – 2018-06-04T16:08:08.053

1@Ben First rule of all RPG combat, be the protagonist. – AJFaraday – 2018-06-04T16:08:58.493

Answers

5

05AB1E, 49 bytes

"BaABr0Aha"S3ô»D„AB‡[6LΩ©Tǝ¤H®-©16ǝ=®0‹#s]н…ÿ w?

Try it online!

Explanation

"BaABr0Aha"                                        # push the initial state of B
           S                                       # split to list of characters
            3ô                                     # divide into 3 parts
              »                                    # join each part on space and all on nl
               D„AB‡                              # make a copy with A and B inverted
                     [                             # start a loop
                      6LΩ©                         # pick a random number in [1 ... 6]
                          Tǝ                       # insert at position 10 of the string
                            ¤H                     # get the last char of the string and
                                                   # convert from hex
                              ®-©                  # subtract the random number
                                 16ǝ=              # insert at position 16 and print
                                     ®0‹#          # if the hp is less than 0, break
                                         s         # swap the other string to the stack top
                                          ]        # end loop
                                           н…ÿ w?  # print the winner

Emigna

Posted 2018-03-22T09:59:17.220

Reputation: 50 798

13

Python 3, 131 bytes

x,y="AB"
from random import*
X=Y=10
p=print
while X>0:p(x,"a",y);d=randint(1,6);p(x,"r",d);Y-=d;p(y,"h",Y);x,y,X,Y=y,x,Y,X
p(y,"w")

Try it online!

-8 bytes thanks to officialaimm
-2 bytes thanks to ChooJeremy

HyperNeutrino

Posted 2018-03-22T09:59:17.220

Reputation: 26 575

5predefining p=print will save you around 8 bytes. – officialaimm – 2018-03-22T10:56:49.420

Since y always wins at this point (And only X attacks in the loop, which is later swapped to Y), you don't need to check if y has lost. -- ChooJeremy -- From Review

– NoOneIsHere – 2018-03-22T15:50:19.793

@NoOneIsHere thanks for passing the message on to me :D – HyperNeutrino – 2018-03-22T17:52:54.873

randint(1,6) could be replaced with id(X+Y)//3%6+1, although the distribution is not quite uniform. – Vincent – 2018-03-23T13:00:40.547

@Vincent I don't see the point in bending the rules if it doesn't even help make it shorter... – HyperNeutrino – 2018-03-23T13:12:00.320

Oh wait, I can remove the random import. Yeah I'd rather keep it uniform to conform to the rules though. – HyperNeutrino – 2018-03-23T13:12:16.133

@HyperNeutrino Yea it wasn't a great idea, although I finally found a shorter dice roll.

– Vincent – 2018-03-24T16:28:16.127

7

C (gcc), 146 141 bytes

f(A,B,r,t,a,b){for(A=B=10;r=1+clock()%6,A*B>0;t=!t)printf("%c a %c\n%c r %u\n%c h %i\n",a=65+t,b=66-t,a,r,b,t?A-=r:(B-=r));printf("%c w",a);}

Try it online!

De-golf:

f(A,B,r,t,a,b){
    for(A=B=10; //Initialize HP
        r=1+clock()%6, // Get the number of processor cycles the program has consumed. This is relatively random, so I call it good enough.
        A*B>0;t=!t) // Flip t for change of turns
        printf("%c a %c\n%c r %u\n%c h %i\n", // Print the turn
            a=65+t,b=65+!t,a,r,b, // 65 is ASCII for 'A', 66 for 'B'
            t?A-=r:(B-=r)); // Deduct the damage.
    printf("%c w",a); // Print the winner
}

user77406

Posted 2018-03-22T09:59:17.220

Reputation:

2Could you save a byte by using a=65+t,b=66-t ? – moopet – 2018-03-22T13:16:01.257

A*B>0 will save you a few bytes. – Olivier Grégoire – 2018-03-22T17:25:51.903

A*B will save even more, but I'm kind of in a hurry atm. I'll update in the evening – None – 2018-03-23T08:21:39.990

Found a bug in dice seq {6,4,3,1,5}. b wins with health -4. See TIO I changed your dice calculator to demo this bug.

– GPS – 2018-03-23T12:51:12.070

@GPS Thanks, I'll patch that now. – None – 2018-03-24T07:33:10.397

7

Python 3, 127 bytes

This is an improvement on @HyperNeutrino answer that wouldn't fit in a comment. See the explanation below.

x,y="AB"
s=id(0)
X=Y=10
p=print
while X>0:p(x,"a",y);s=s**7%~-2**67;d=s%6+1;p(x,"r",d);Y-=d;p(y,"h",Y);x,y,X,Y=y,x,Y,X
p(y,"w")

Try it online!


An epic quest for a shorter python dice roll

TL;DR: It's possible to shave 4 bytes off the standard python dice roll by using RSA encryption.

I wanted to see if the standard python dice roll (32 bytes) could be shortened a bit:

from random import*;randint(1,6)

In particular, id(x) is quite convenient to bring some non-deterministic value into the program. My idea then was to somehow hash this value to create some actual randomness. I tried a few approaches, and one of them paid off: RSA encryption.

RSA encryption, due to its simplicity, only requires a few bytes: m**e%n. The next random value can then be created by encrypting the previous one. Assuming the (e,n) key is available, the dice roll can be written with 22 bytes:

s=id(0);s=s**e%n;s%6+1

That means we have about 10 bytes to define a valid RSA key. Here I got lucky. During my experiments, I started to use the Mersenne prime M67 only to realize later on that Mersenne made a mistake including M67 in his list. It turns out to be the product of p=193707721 and q=761838257287. I had found my modulus:

n=~-2**67

Now, the exponent and the Charmichael totient (p-1)*(q-1) need to be coprime. Luckily again, the first prime number that do not divide the totient of n is only one digit long: 7. The dice roll can then be written using 28 bytes (4 bytes less than the standard approach):

s=id(0);s=s**7%~-2**67;s%6+1

One good thing with M67 is that the random value generated has 66 bits, which is more than the usual 64 bits RNG. Also, the use of RSA makes it possible to go back in time by decrypting the current value multiple times. Here are the encrypting and decrypting keys:

Encryption: (7,                    147573952589676412927)
Decryption: (42163986236469842263, 147573952589676412927)

I'm definitely not an expert in statistics or cryptography, so I can't really tell whether or not this RNG checks the criteria for "good randomness". I did write a small benchmark that compares the standard deviation of the occurrences of the 1 to 6 dice rolls using different RNGs. It seems like the proposed solution works just like other ones.

Vincent

Posted 2018-03-22T09:59:17.220

Reputation: 601

3Impressive work! :) – HyperNeutrino – 2018-03-24T18:25:40.040

4

JavaScript (ES6), 122 bytes

f=(h=[10,10,p=0])=>`${x='AB'[p]} a ${y='BA'[p]}
${x} r ${d=Math.random()*6+1|0}
${y} h ${H=h[p^=1]-=d}
${H<1?x+' w':f(h)}`

Try it online!

Arnauld

Posted 2018-03-22T09:59:17.220

Reputation: 111 334

4

Java (JDK 10), 180 bytes

v->{var r="";int p=0,H[]={10,10},h=0;for(;H[0]*H[1]>0;)r+=r.format("%3$c a %4$c%n%3$c r %d%n%4$c h %d%n",h+=Math.random()*6-h+1,H[p]-=h,p+65,(p^=1)+65);return r+(char)(66-p)+" w";}

Try it online!

Credits

Olivier Grégoire

Posted 2018-03-22T09:59:17.220

Reputation: 10 647

1Java 10 has var? o.Ô I really need to investigate some of the new specs soon.. Anyway, you can golf 4 bytes by changing the char-array to int-array: v->{var r="";int P[]={65,66},p=0,H[]={10,10},h=0;for(;H[0]*H[1]>0;)r+=r.format("%3$c a %4$c%n%3$c r %d%n%4$c h %d%n",h+=Math.random()*6-h+1,H[p]-=h,P[p],P[p^=1]);return r+=P[p^1]+" w";} – Kevin Cruijssen – 2018-03-22T12:33:18.710

1@KevinCruijssen Yep, Java 10 has var. Don't need to read further, it's basically the only change that's usable for us golfers. And no I can't do what you suggest: check the last line of the result: it becomes 65 w instead of A w. That's why I extracted it from the int ... statement: to golf a few bytes ;-) – Olivier Grégoire – 2018-03-22T12:42:09.147

1

@KevinCruijssen I complied a few examples here: https://codegolf.stackexchange.com/a/159922/16236

– Olivier Grégoire – 2018-03-22T13:06:22.763

4

Perl 5, 93 88 87 bytes

$A=$B=10;$_=B;${$_^=v3}-=$%=1+rand 6,say"$_ a $'
$_ r $%
$' h $$_"until//>$$_;say"$_ w"

Try it online!

Ton Hospel

Posted 2018-03-22T09:59:17.220

Reputation: 14 114

3

Ruby, 122 120 96 92 91 bytes

f=->x=?A,y=?B,m=10,n=m{p [x,?a,y],[x,?r,r=1+rand(6)],[y,?h,t=n-r]
t<1?p([x,?w]):f[y,x,t,m]}

Saved 1 byte thanks to Asone Tuhid.

Try it online!

Cristian Lupascu

Posted 2018-03-22T09:59:17.220

Reputation: 8 369

1It's like I don't even know how to Ruby any more ;) – AJFaraday – 2018-03-22T10:41:12.250

I'm afraid your alternative doesn't work, "All parts of an action must be on the same line." Although, might it be possible to make the same optimisation with a tab character? – AJFaraday – 2018-03-22T11:21:34.467

@AJFaraday Would it be acceptable to output lines in the format ["A", "a", "B"]? If so, I have this 96-byte solution.

– Cristian Lupascu – 2018-03-22T12:09:42.670

If they’re output one per line. That should do. – AJFaraday – 2018-03-22T12:16:51.857

-1 byte if you replace ?(p [x,?w]): with ?p([x,?w]): – Asone Tuhid – 2018-03-22T13:01:28.420

@AsoneTuhid I've tried that, but it doesn't work.

– Cristian Lupascu – 2018-03-22T13:04:00.257

No, like this

– Asone Tuhid – 2018-03-22T13:06:39.663

3

Java 8, 230 bytes

v->{for(int h=104,a=h,x=0,y=1,A=10,B=A,r=0,t=0,T;a<119;)System.out.printf("%c %3$c %c%n",(x=a>h|A*B<1?x^1:x)+65,y=(a<98?t=r+=Math.random()*6-r+1:a>h?(T=x<1?A-=t:(B-=t))<0?0:T:A*B<1?-16:(x^1)+17)+48,a=a<98?114:a>h?104:A*B<1?119:97);}

Note: there is already a much shorter Java answer, so make sure to upvote his! I use a completely different approach however, so figured it was worth posting as well.

Explanation:

Try it online.

v->{                     // Method with empty unused parameter and no return-type
  for(int h=104,         //  Temp integer with unicode for 'h' to save bytes
          a=h,           //  Second part (Action)
          x=0,           //  First part
          y=1,           //  Third part
          A=10,          //  Score player A, starting at 10
          B=A,           //  Score player B, starting at 10
          r=0,           //  Random dice-roll
          t=0,           //  Previous dice-roll
          T;             //  Temp integer
      a<119;)            //  Loop until there is a winner
     System.out.printf(  //   Print
      "%c %3$c %c,%n",   //    The three parts with spaces, and a new-line
      (x=                //    First part:
         a>h             //     If the previous action is 'r',
         |A*B<1?         //     or there is a winner:
           x^1           //      Change A→B or B→A
         :               //     Else:
          x)             //      A/B remains unchanged
       +65,              //     Add 65 to convert 0/1 to 65/66 (unicode values of A/B)
      (y=                //    Third part:
         (a<98?          //     If the previous action was 'a'
           t=r+=Math.random()*6-r+1
                         //      Roll the dice, and save it in `t`
          :a>h?          //     Else-if the previous action was 'r':
           (T=x<1?       //      If the first part changed to player A:
            A-=t         //       Subtract the previous dice-roll from A
           :             //      Else:
            (B-=t))      //       Subtract the previous dice-roll from B
           <0?           //      If this score is below 0:
            0            //       Use 0
           :             //      Else:
            T            //       Use this score
         :               //     Else (the previous action was 'h'):
          A*B<1?         //      Is there a winner:
           -16           //       Change the third part to a space
          :              //      Else:
           (x^1)+17)     //       Change the third part to the other player
       +48,              //     Add 48 to convert it to unicode
       a=                //    Second part:
         a<98?           //     If the previous action was 'a': 
          114            //      Change it to 'r'
         :a>h?           //     Else-if the previous action was 'r':
          h              //      Change it to 'h'
         :               //     Else (the previous action was 'h'):
          A*B<1?         //      If either score is 0:
           119           //       Use 'w'
          :              //      Else:
           97);}         //       Use 'a'

Kevin Cruijssen

Posted 2018-03-22T09:59:17.220

Reputation: 67 575

3

C (gcc), 142 bytes

#define R(c,t)r=rand()%6+1,c&&printf(#c" a "#t"\n"#c" r %d\n"#t" h %d\n",r,t-=t<r?t:r),t||puts(#c" w")
f(A,B,r){for(A=B=10;A*B;R(B,A))R(A,B);}

Try it online!

nwellnhof

Posted 2018-03-22T09:59:17.220

Reputation: 10 037

Just one problem, this didn't end in a win. – AJFaraday – 2018-03-22T14:52:26.763

@AJFaraday Oh yes, fixed. – nwellnhof – 2018-03-22T15:01:33.830

2

Batch, 174 bytes

@set/aA=B=10
@set c=A
@set d=B
:g
@set/ar=%random%%%6+1,h=%d%-=r
@echo %c% a %d%
@echo %c% r %r%
@echo %d% h %h%
@if %h% gtr 0 set c=%d%&set d=%c%&goto g
@echo %c% w

Explanation: % variable references are substituted at parse time. This has two useful benefits:

  • %d%-=r subtracts r from the variable named by d (i.e. indirect reference)
  • set c=%d%&set d=%c% is simply a straight swap.

Neil

Posted 2018-03-22T09:59:17.220

Reputation: 95 035

2

PHP 7.1: 159 bytes

<?php $A=$B=10;$t='AB';while($A>0&&$B>0){$a=$t[0];$b=$t[1];$d=rand(1,6);$$b-=$d;echo"$a a $b\n$a r $d\n$b h {$$b}\n";$t=strrev($t);}echo($A>0?'A':'B')." w\n";

Run it in the browser here!

PHP 5.6: 156 bytes

<?php $A=$B=10;$t='AB';while($A>0&&$B>0){list($a,$b)=$t;$d=rand(1,6);$$b-=$d;echo"$a a $b\n$a r $d\n$b h {$$b}\n";$t=strrev($t);}echo($A>0?'A':'B')." w\n";

Run it in the browser here!

Here's what the PHP 5.6 solution looks like with formatting and comments:

<?php
// Initialize both HP counters
$A = $B = 10;

// Set the turn order as a string (which 5.6 allows to be unpacked into a list)
$t = 'AB';

// Run this loop as long as both players have HP
while ($A > 0 && $B > 0) {
    // Unpack the turn string into $a and $b variables; on the first run, $a = 'A'
    // and $b = 'B'. This is no longer possible in PHP 7.0, so the PHP 7.0
    // solution needed to use an array instead.
    list($a, $b) = $t;

    // Set damage to a random number between 1 and 6
    $d = rand(1, 6);

    // Subtract the damage from the referenced value $b. On the first turn, this
    // is 'B', so this ends up subtracting $d from $B. Next turn, $b will be 'A',
    // so it'll subtract $d from $A
    $$b -= $d;

    // Echo the string (interpolated values)
    echo "$a a $b\n$a r $d\n$b h {$$b}\n";

    // Reverse the turn order string ('AB' becomes 'BA', which will affect the
    // call to list in the first line of the while-loop)
    $t = strrev($t);
}

// Someone's run out of HP; figure out whom by figuring out who still has HP
echo ($A > 0 ? 'A' : 'B') . " w\n";

Chris Forrence

Posted 2018-03-22T09:59:17.220

Reputation: 141

1

Bash, 178 bytes

A=10 B=10 e=echo
a(){ $e $1 a $2;d=$((RANDOM%6+1));$e $1 r $d;eval $2=$((${!2}-$d));$e $2 h ${!2};[ ${!2} -gt 0 ];}
while a A B && a B A;do cd;done;[ $A -gt 0 ]&&$e A w||$e B w

crystalgecko

Posted 2018-03-22T09:59:17.220

Reputation: 51

1

F#, 238 235 bytes

I thought I was doing well, but you've all far outclassed me!

let p=printfn
let mutable A=10
let mutable B=A
let x h a d=
 p"%s a %s"a d
 let i=(new System.Random()).Next(1,7)
 let j=h-i
 p"%s r %i"a i
 p"%s h %i"d j
 if j<=0 then p"%s w"a
 j
while A*B>0 do
 B<-x B"A""B"
 if B>0 then A<-x A"B""A"

Try it online!

Thanks to Rogem for the brilliant advice to use A*B>0 instead of A>0&&B>0 (takes off 3 bytes).

Thank you also to officialaimm, whose hint about predefining printf in the Python answer helped me shave a few bytes off too.

Ciaran_McCarthy

Posted 2018-03-22T09:59:17.220

Reputation: 689

1An advice that I got from @OlivierGregoire: A*B>0 will save you a couple more. – None – 2018-03-24T08:25:26.837

That is absolutely brilliant. Love it. Thank you very much! – Ciaran_McCarthy – 2018-03-24T12:02:45.043

1

Haskell, 204 bytes

My attempt with Haskell, I wasn't able to get it more competitive unfortunately

import System.Random
main=getStdGen>>= \g->putStr$q(randomRs(1,6)g)10(10::Int)"A ""B "
(!)=(++)
l="\n"
q(x:z)a b p o=p!"a "!o!l!p!"r "!show x!l!o!"h "!show n!l!if n<1then p!"w"else q z n a o p where n=b-x

Try it online!

Explanations:

import System.Random  --import random module
main=                        --main function, program entry point
 getStdGen                   -- get the global random number generator
   >>= \g->                  --using the random generator g
       putStr $ q            --print the result of function q, passing in ..
          (randomRs (1,6) g) --an infinite list of random numbers, 1 to 6 generated by g
           10 (10::Int)      --the starting health of both players, 
                             --type annotation sadly seems to be required
           "A " "B "         --The names of the players,
                             --with an extra space for formatting
(!)=(++) --define the operator ! for list (String) concatenation, 
         -- we do this a lot so we save a bit by having a one byte operator
l="\n"   -- define l as the newline character

q      --define function q                         
 (x:z) --our list of random numbers, split into the next number (x) and the rest (z)
 a     -- the health of the active player
 b     -- the health of the player getting attacked
 p     -- the name of the active player
 o     -- the name of the player getting attacked
=
  p!"a "!o!l --create the attack action string with a newline
 !p!"r "!show x!l -- append the roll action
 !o!"h "!show n!l -- append the health remaining
 !           -- append the result of the following if
  if n<1     -- if the player being attacked has been defeated
  then p!"w" -- append the win string for the active player
  else q z n a o p  --otherwise append the result of calling q again with 
                    --rest of the random numbers, and the active players swapped
  where n=b-x -- define the attacked player's new health n
              -- their current health b - the random roll x

puhlen

Posted 2018-03-22T09:59:17.220

Reputation: 161

You could have a look at our Tips for golfing in Haskell. E.g. where m=b-x can be put into a guard: |m<-b-x=.

– Laikoni – 2018-03-25T01:57:33.910

You can lose the lambda and one set of parentheses by rearranging some parameters: main=putStr=<<q"A "10"B "10.randomRs(1,6::Int)<$>getStdGen. You can also use a list and concat it to get rid of redefining (++). The last where doesn't seem to be beneficial to just using b-x everywhere. – Angs – 2018-03-29T21:29:40.480

1

Julia 0.6, 175 bytes

p=println()
f(l="AB",h=[10,10],a=1)=(while min(h...)>0;d=3-a;p(l[a]," a ",l[d]);r=rand(1:6);h[d]-=r;p(l[a]," r ",r);p(l[d]," h ",max(h[d],0));a=d;end;p(l[findmax(h)[2]]," w"))

Try it online!

Long, ungolfed version:

function status(player, health)
    println("$player h $(max(0,health))")
end

function roll(player)
    x = rand(1:6)
    println("$player r $x")
    x
end

function play()
    players = ["A","B"]
    healths = [10, 10]
    attacker = 1

    while min(healths...) > 0
        println("$(players[attacker]) a $(players[3-attacker])")
        healths[3-attacker]-=roll(players[attacker])
        status(players[3-attacker], healths[3-attacker])

        attacker = 3 - attacker
    end

    winner = findmax(healths)[2]
    println("$(players[winner]) w")
end

niczky12

Posted 2018-03-22T09:59:17.220

Reputation: 301

There doesn’t seem to be any output in your TIO link. – AJFaraday – 2018-03-29T19:20:53.773

Yeah I don't know why tio doesn't like it. It works fine on my machine. I'll look into it if I have time. – niczky12 – 2018-03-30T08:23:10.080

1

VBA, 222 185 179 Bytes

This recursive solution involves 3 subs

  1. g is the game start that kicks off the first turn
  2. t is called for each turn. It uses recursion.
  3. p is shorter than Debug.Print when used more than 3 times (only 4 in this solution) Edit: Now that I learned that Debug.? is an acceptable alternative to Debug.Print, Debug.?x is shorter than calling a Sub to print.
Sub g()
t "A",10,"B",10
End Sub
Sub t(i,j,x,h)
d=Int(Rnd()*6)+1
Debug.?i &" a "&x
Debug.?i &" r "&d
h=h-d
If h<1Then
Debug.?i &" w"
Else
Debug.?x &" h "&h
t x,h,i,j
End If
End Sub

This was a fun challenge. If you know of an online interpreter like TIO for VB6/VBScript/VBA please leave a comment. Then I can post a link to a working solution.

If you want to test this code and have Microsoft Excel, Word, Access, or Outlook installed (Windows only), press Alt+F11 to open the VBA IDE. Insert a new code module (Alt+I,M) and clear out Option Explicit. Then paste in the code and press F5 to run it. The results should appear in the Immediate Window (press Ctrl+G if you don't see it).

Edit 1: Removed whitespace that the VBA editor will automatically add back in. Reduced by 37 bytes
Edit 2: Removed Sub p()* to save 6 bytes after learning Debug.? is an acceptable alternative to Debug.Print. Calling a Sub to handle Debug.? only saves bytes after more than six calls.

Ben

Posted 2018-03-22T09:59:17.220

Reputation: 201