Is there still a race condition? [closed]

不想你离开。 提交于 2019-12-12 12:14:08

问题


this is the current state of my little unimportant async experiment. Can you spot any races or leaks? Common critique is also welcome.

class GameObject
{
    has Int $.id;
    has Int $.x is rw;
    has Int $.y is rw;
    has $.game;
    has Int $.speed; #the higher the faster

    multi method start( &action )
    {
        start {
            loop {
                &action();
                await Promise.in( 1 / self.speed );
            }
            #$.game.remove-object( self );
        }
    }

    method speed {
        $!speed + 
            # 33% variation from the base speed in either direction
            ( -($!speed / 3).Int .. ($!speed / 3).Int ).pick
            ;
    }

    submethod DESTROY { say "DESTROY" }
}

role UnnecessaryViolence
{
    has $.damage;
    has $.hitpoints is rw;
    has $.offense;
    has $.defense;

    method attack ( GameObject $target )
    {
        say "The {self.WHAT.perl} ({self.id}) attacks the {$target.WHAT.perl} ({$target.id})";

        my $attacker = roll( $.offense, 1 .. 6 ).sum;
        say "The {self.WHAT.perl} rolls $attacker";

        my $defender = roll( $target.defense, 1 .. 6 ).sum;
        say "The {$target.WHAT.perl} rolls $defender";

        if $attacker > $defender 
        {
            my $damage = ( 1 .. $!damage ).pick;
            say "The {self.WHAT.perl} inflicts {$damage} damage";

            $target.hitpoints -= $damage ;
        }

        if $target.hitpoints < 0
        {
            say "The {$target.WHAT.perl} is dead";
            return True;
        }
        else
        {
            say "The {$target.WHAT.perl} has { $target.hitpoints } hitpoints left";
            return False;
        }
    }
}

class Player is GameObject does UnnecessaryViolence
{
    has $.name;

    multi method start
    {
        say "A hero was born.";
        self.start({
            # say "The hero is moving";
            # keyboard logic here, in the meantime random movement
            $.game.channel.send( { object => self, x => (-1 .. 1).pick, y => (-1 .. 1).pick } );
        });
    }
}

class Monster is GameObject does UnnecessaryViolence
{
    has $.species;

    multi method start
    {
        say "A monster hatched.";
        self.start({
            # say "The monster {self.id} is moving";
            # AI logic here, in the meantime random movement
            $.game.channel.send( { object => self, x => (-1 .. 1).pick, y => (-1 .. 1).pick } );
        });
    }
}

class Game
{
  my $idc = 0;

    has GameObject @.objects is rw;
    has Channel $.channel = .new;

    method run{
        self.setup;
        self.mainloop;
    }

    method setup
    {
        self.add-object( Monster.new( :id(++$idc), :species("Troll"), :hitpoints(20), :damage(14), :offense(3), :speed(400), :defense(3), :x(4), :y(2), :game(self) ) );
        self.add-object( Monster.new( :id(++$idc), :species("Troll"), :hitpoints(25), :damage(16), :offense(3), :speed(300), :defense(3), :x(3), :y(2), :game(self) ) );
        self.add-object( Player.new( :id(++$idc), :name("Holli"), :hitpoints(50), :damage(60), :offense(4), :speed(200) :defense(2), :x(0), :y(0), :game(self) ) );
    }

    method add-object( GameObject $object )
    {
        @!objects.push( $object );
        $object.start;
    }

    method remove-object( GameObject $object )
    {
        @!objects = @!objects.grep({ !($_ === $object) });
    }

    method mainloop 
    { 
        react {
            whenever $.channel.Supply -> $event
            {
                self.process-movement( $event );

                if self.game-is-over
                {
                    "Game over. The {@!objects[0].WHAT.perl} has won".say;
                    $.channel.close;
                    done;
                };

            };
            whenever Supply.interval(0.01) {
                self.render;
            }
        }

    }

    method process-movement( $event )
    {
        #say "The {$event<object>.WHAT.perl} moves.";
        given $event<object>
        {
            my $to-x = .x + $event<x>;
            my $to-y = .y + $event<y>;

            for @!objects -> $object
            {
                # we don't care abour ourselves
                next 
                    if $_ === $object;

                # see if anything is where we want to be
                if ( $to-x == $object.x && $to-y == $object.y )
                {
                    # can't move, blocked by friendly
                    return 
                        if $object.WHAT eqv .WHAT;

                    # we found a monster, see if we can
                    # kill it and move there
                    return
                        unless .attack( $object );

                    # Something just died
                    self.remove-object( $object );
                    last;
                }
            }

            # we won the fight or the place is empty
            # so let's move
            .x = $to-x ==  5  ?? -4 !!
                 $to-x == -5  ?? 4  !!
                 $to-x;

            .y = $to-y ==  5  ?? -4 !!
                 $to-y == -5  ?? 4  !!
                 $to-y;

        }
    }

    method render
    {
        for @!objects -> $object {
            "The {$object.WHAT.perl} is at {$object.x},{$object.y}".say;
        }
    }

    method game-is-over {
        return (@!objects.map({.WHAT})).unique.elems == 1;
    }
}


Game.new.run;

来源:https://stackoverflow.com/questions/57562254/is-there-still-a-race-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!