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
Re: Battle script
by vladb (Vicar) on Jun 06, 2002 at 09: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$\;}
| [reply] [d/l] [select] |
|
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. | [reply] [d/l] |
|
| [reply] [d/l] [select] |
Re: Battle script
by Joost (Canon) on Jun 06, 2002 at 09:32 UTC
|
#!/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.
| [reply] [d/l] [select] |
|
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
| [reply] [d/l] |
Re: fighting script
by broquaint (Abbot) on Jun 06, 2002 at 09:03 UTC
|
| [reply] |
Re: fighting script
by Juerd (Abbot) on Jun 06, 2002 at 09:13 UTC
|
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.
| [reply] [d/l] |
Re: Battle script
by Ovid (Cardinal) on Jun 06, 2002 at 11: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):
- 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)
- Move a null command to that address
- Add 4 to that address
- 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.
| [reply] |
|
| [reply] |
|
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.
| [reply] |
|
| [reply] |
|
|