Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Battle script

by Anonymous Monk
on Jun 06, 2002 at 12:54 UTC ( [id://172170]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hey, i'm looking for a script where two "variables" can duke it out, until one reaches 0 HP or whatever. Anyone have something like this, or know where I can locate one. The barer the bones, the better. Thanks! clutch76@hotmail.com

Replies are listed 'Best First'.
Re: Battle script
by vladb (Vicar) on Jun 06, 2002 at 13:01 UTC
    Weird,

    I believe one could come up with pretty much anything and it'll fit your description. Just the other day I wrote this line of code,
    my $max_lines = 100; . . . while ($line--) { . . . # do stuff . . . }
    So, basically, variable $max_lines leaves variable $line in the dumps if you consider $line-- as a variable loosing HP, {GRIN}.

    UPDATE:

    Or how abut this:
    my $playera = 100; my $playerb = 100; print "player A HP | player B HP\n"; while (1) { $playera -= rand(10); $playerb -= rand(10); print "$playera | $playerb\n"; die (($playera < $playerb) ? "player A lost!" : "player B lost!") if ($playera < 0 || $playerb < 0); }
    This 'game' playes out as follows:
    player A HP | player B HP 94.0023803710938 | 99.3478393554688 88.4292602539063 | 96.0552978515625 88.1494140625 | 94.9520874023438 86.5380859375 | 93.8046264648438 82.1652221679688 | 84.6536254882813 75.5804443359375 | 76.0702514648438 69.7055053710938 | 75.4898071289063 67.3040771484375 | 68.40087890625 63.6215209960938 | 64.7930908203125 58.9315795898438 | 60.8502197265625 50.4647827148438 | 57.1435546875 40.8901977539063 | 49.0029907226563 34.7552490234375 | 39.5355224609375 27.4127197265625 | 33.8937377929688 24.0670776367188 | 31.5869140625 19.4973754882813 | 22.3440551757813 10.3622436523438 | 14.5086669921875 9.0966796875 | 11.1148071289063 7.37579345703125 | 9.4158935546875 2.77679443359375 | 0.14801025390625 -1.7657470703125 | -7.55615234375 player B lost! at temp.pl line 11.
    you says: "The barer the bones, the better"

    I guess my code is as 'bare' as you can get (unless some monk out there wants to challange me)! ;-)

    _____________________
    $"=q;grep;;$,=q"grep";for(`find . -name ".saves*~"`){s;$/;;;/(.*-(\d+) +-.*)$/; $_=["ps -e -o pid | "," $2 | "," -v "," "];`@$_`?{print"+ $1"}:{print" +- $1"}&&`rm $1`; print$\;}
      A variation where the stronger one strikes (potentially)harder (and the one that gets the upper hand has the advantage):
      > perl -e "$a=$b=100;while($a>0&&$b>0){$a-=rand($b/10);$b-=rand($a/10) +;print qq($a | $b\n)}"

      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.
        Oh no! You have inadvertantly tipped the scale of battle to favour the a opponent by the fact of its first attack and the effect which this has on the probability (random seed) for the retalitory attack of b - But what if the battle forces of b launch a preemptory attack?

        Consider the following where Quantum::Entanglement has been used such that the victor is truly not known until the battle has been fought!

        #!/usr/bin/perl use Quantum::Entanglement; my $opponent1 = entangle(1, 'a', 1, 'b'); my $opponent2 = p_op($opponent1, 'eq', 'a', sub{'b'}, sub{'a'}); $a = $b = 100; $opponent1 = "$opponent1"; $opponent2 = "$opponent2"; { no strict 'refs'; while ($$opponent1 > 0 && $$opponent2 > 0){ $$opponent1 -= rand($$opponent2 / 10); $$opponent2 -= rand($$opponent1 / 10); print qq($$opponent1 | $$opponent2\n) } print "And the winner is ... '", (($$opponent1 < 0) ? $opponent1 : $opponent2), "'\n"; }

        Yes, I was bored :-)

         

Re: Battle script
by Joost (Canon) on Jun 06, 2002 at 13:32 UTC
    What a strangely intruiging post... :-)

    Ok. I'll bite... For this you need a ithreading perl (this is only tested on 5.8.0 RC1)

    #!/opt/perl-latest/bin/perl -w use threads; use threads::shared; use strict; my @scores : shared = (10,10); my @ts; for my $num (0 .. 1) { my $t =threads->new(sub { battle($num) } ); push @ts,$t; } $_->join() for @ts; sub battle { my $me = shift; my $other = $me ? 0 : 1; while ($scores[$me] > 0 && $scores[$other] > 0) { $scores[$other]--; print "Bot $me hit bot $other\n"; select(undef,undef,undef,rand 0.1); threads->yield; } print "Bot $me ".($scores[$me] > 0 ? 'won' : 'lost')."\n"; }

    Maybe not bare bones, but certainly bleading edge :-)

    -- Joost downtime n. The period during which a system is error-free and immune from user input.
      Of course, one doesn't need those newfangled thread thingies. Here's one that can easily be backported to old versions of perl, and is using fork() and signals.

      #!/usr/bin/perl -w my $hp = 100; my $pid; sub get_hit; sub get_hit { unless (-- $hp) { kill USR2 => $pid or warn "Failed to send victory: $!\n"; print "$$: Arrrgh, I am dying!\n"; exit; } print "$$: I got hit! $hp hitpoints left.\n"; $SIG {USR1} = \&get_hit; } $SIG {USR1} = \&get_hit; $SIG {USR2} = sub {print "$$: I won! I won!\n"; exit}; $pid = fork; die "Fork failed\n" unless defined $pid; $pid ||= getppid; while (1) { my $timeleft = rand 1; (undef, $timeleft) = select (undef, undef, undef, $timeleft) while $timeleft; kill USR1 => $pid; # Ignore errors. } __END__
      Abigail
Re: fighting script
by broquaint (Abbot) on Jun 06, 2002 at 13:03 UTC
Re: fighting script
by Juerd (Abbot) on Jun 06, 2002 at 13:13 UTC

    Errrh.....

    package Tie::Scalar::Battle; my %pool; our $attacker; sub TIESCALAR { my ($class, $name, $health) = @_; return $pool{$self + 0} = bless { name => $name, health => $health }, $class; } sub DESTROY { delete $pool{shift() + 0} } sub FETCH { shift->{health} } sub STORE { my ($self, $value) = @_; die "$self->{name} died" if $value <= 0; my $old_value = $self->{health}; $self->{health} = $value; if ($value < $old_value) { my $target = $attacker || (values %pool)[rand keys %pool]; local $attacker = $self; # print "$target->{name}, $target->{health}\n"; $target->STORE( $target->FETCH() - (1 + int rand 3) ); } return $value; } package main; tie $foo, 'Tie::Scalar::Battle', foo => 300; tie $bar, 'Tie::Scalar::Battle', bar => 300; # First punch $foo--;
    /me laughs

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

Re: Battle script
by Ovid (Cardinal) on Jun 06, 2002 at 15:57 UTC

    That reminds me of an article I had read some time ago. I can't recall where, but I'll summarize it and if anyone wants to work with it. This was a long time ago, so my memory is probably wrong about some aspects.

    Essentially, the article was about a computer program that allows you to use two programs to fight. You have a series of addresses (the arena) where the last address connects to the first (like a circle) and each program "lives" in the arena. There was a very basic assembler-like language that controlled what each could do. Commands were fairly straightforward and the language was, IIRC, turing-complete. The goal of each program was to disable the other.

    For example, one of the most successful programs, the "imp gun", was four lines long (and addresses, the way the languages worked):

    1. Assign a value to a variable representing an address (this value was the first address after the end of the program - I don't remember how initialization worked)
    2. Move a null command to that address
    3. Add 4 to that address
    4. Goto 2

    With a program that small, it was awfully tough to disable (by moving a bad instruction to it). It simply laid down a string of null commands and if any of them hit the opponent, the opponent would be disabled. Some programs would try to find the other program (maybe a binary search of an imp-gun trail, for example), others would lay decoys and move themselves, etc. This could be a fun project :)

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      I believe you're referring to core wars. Take a gander at koth.org for more information.

      perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

      That would indeed be Corewar. Sadly, my skills at writing warriors for that never grew beyond mediocre - but I wrote some Perl tools for it anyway. :-)
      ____________

      Makeshifts last the longest.
      If I recall correctly, this is part of where the knowledge and skills for writing virus programs came from - the programmers became very skilled in concealing their programs, modifying other pieces of code, etc.

      Really too bad that some of them decided to use their knowledge that way. Not to say that all (or even most) virus writers had that kind of background, or that playing that game was a bad thing - it really sounds like tremendous fun. :)


      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://172170]
Approved by rob_au
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-04-19 21:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found