CSCI3180 Perl and Dynamic Scoping

CSCI3180 – Principles of Programming Languages – Spring 2022
Assignment 3 — Perl and Dynamic Scoping
Deadline: Apr 10, 2022 (Sunday) 23:59
1 Introduction
The purpose of this assignment is to offer most of you the first experience with Perl, a language
supporting both dynamic and static scoping. Our main focus is on dynamic scoping.
The assignment consists of three parts. You need to implement a new game designed by the TAs,
called “Tournament Duel”, step by step. First, you are required to implement a simple version
of this game in Perl, with the Python implementation provided to you for reference. Second, you
need to implement a more complex version of this game in Perl with dynamic scoping. Third,
you are required to re-implement the same game using Python with static scoping. The detailed
Object-Oriented (OO) design for the Perl implementation is given. The OO design for the Python
implementation is exactly the same. In the process, you will experience both programming flexi￾bility and readability (good or bad) with dynamic scoping. Your implementation should be able
to run on our VM environment with Perl v5.18.2 and Python 3.4.0. Besides, you are required to
add “use warnings;” and “use strict;” at the start of your Perl programs. Good coding styles are
expected.
IMPORTANT: All your codes will be graded on a VM that will be provided to you. You are
welcome to write and test your codes in your own computing environments, but please test them
on the given VM before your submission (run your Python code with the “python3” command
instead of “python” on the VM).
NO PLAGIARISM! You are free to devise and implement the algorithms for the given tasks, but
you must not “steal/borrow” codes from your classmates/friends without proper acknowledgement.
If you use some code snippets from public sources or your classmates/friends, ensure you cite them
in the comments of your code. Failure to comply will be considered as plagiarism. You are not
allowed to ask/hire others to do the assignment for you either. All these are considered as serious
cheating acts, which will be dealt with severely.
2 Task 1: Basic Tournament Duel
In this task, you need to implement the basic Tournament Duel game. The complete Python code
and a Perl template are provided. You should strictly follow the specified OO design and game
rules for this task. You have to follow the prototypes of the given classes exactly and you cannot
change the provided skeleton code.
2.1 The Story
In an ancient tribe, the chief of the tribe wanted to select the most intelligent person as the next
chief to rule the tribe. The chief of the tribe deployed a game called Tournament Duel to judge
the candidates’ intelligence. Tournament Duel is a strategy game played in rounds involving two
players. Each player in Tournament Duel is a team leader with four fighters. In each round of
the game, each team leader has to make an order list of the undefeated fighters of the team. The
fighters are then paired according to the order positions in the two order lists. The pair of fighters
1
with the same order positions in the two teams’ order lists will have to duel against each other in
the round. If the HP of a fighter is reduced to 0 or below in a duel, the fighter is defeated and
cannot be deployed in the remaining rounds. If all the fighters in one team are defeated, this team
loses the game.
You, a promising and smart citizen in the tribe, made up your mind to participate in the qualifi￾cation contest to be the next chief of the tribe. Meanwhile, other competitors are also striving for
the chief title. So please be cool and quick; start your tournament duel now.
2.1.1 Task Description
You are required to realize the Tournament Duel game that involves two teams: Team 1 and Team

  1. Each team consists of four fighters. We number Fighter 1 to Fighter 4 for Team 1, and Fighter
  2. to Fighter 8 for Team 2 for simplicity. In particular, each fighter has four properties, which are
    HP, attack, defense, and speed respectively.
    • HP: the health point of the fighter. If HP is less than or equal to 0. The fighter is defeated.
    • attack: the attack strength of the fighter.
    • defense: the defense ability of the fighter.
    • speed: the speed of the fighter. The fighter with a higher speed attacks first in a duel.
    HP, attack, defense, and speed are related to the duels. The properties are all in integers.
    The initial values of HP, attack, defense and speed are specified through user inputs that must
    satisfy the following constraint:
    HP + 10 ∗ (attack + defense + speed) ≤ 500 (1)
    After the initialization, each team leader has to decide the dueling order of the undefeated fighters
    in each round. In each round, fighters are picked from the team’s order list one by one and duel
    against the fighter with the same order from the opponent team. If one team has more undefeated
    fighters than the other team, the excess players will take a nap in the round.
    Example 1 The undefeated fighters in Team 1 are Fighter 1 and Fighter 2, while the undefeated
    fighters in Team 2 are Fighter 5, Fighter 6, and Fighter 8. The proposed order of Team 1 is [2, 1]
    and the input order of Team 2 is [8, 5, 6]. Thus, Fighter 2 duels against Fighter 8 and Fighter 1
    against Fighter 5. However, Fighter 6 takes a rest in this round.
    The duels are launched one by one according to the order in the order lists. Note that each duel
    allows only one strike from each fighter. The fighter with higher speed strikes first, followed by the
    other fighter striking back. The duel is then completed. If the two fighters have the same speed,
    the fighter from Team 1 strikes first. The first attacking fighter will cast damage to the latter
    attacking fighter. The damage is defined as the attack value of the attacker minus the defense
    value of the defender, but the damage is also an integer and should be no less than 1 as shown in
    (2).
    damage = max(attackattacker ∇ defensedef ender, 1) (2)
    Afterwards, the defending fighter gets a HP reduction by the value of the damage. If the HP of the
    defending fighter becomes non-positive, the defending fighter is defeated. If the defending fighter
    is not defeated, the roles of the two fighters are reversed. After a duel, the fighter casting more
    damage wins the round. If the damages are the same, this round is a tie.
    After each round, we also monitor the states of all the fighters in each team. If all fighters in
    one team are defeated, this team loses the Tournament Duel game. We should announce that the
    winner is the other team.
    2
    2.2 Workflow
    In this section, we specify the workflow of the basic Tournament Duel game. In the beginning,
    we initialize the tournament, teams, and fighters. The program asks the user to input the initial
    properties of each fighter satisfying the constraint in inequality 1. The program first output “Please
    input properties for fighters in Team 1”. Then the user enters the properties of the first fighter
    by four integers and ends by pressing enter. We assume the input format and type are valid. The
    program only checks the semantic validity of the input that violate the constraint and recursively
    asks the user to enter properties of the remaining fighters. If the input properties violate the
    constraint, the program should output “Properties violate the constraint” and ask the user to
    input the properties again until the constraint is satisfied. After the user inputs four fighters’
    properties, the program outputs “Please input properties for fighters in Team 2” and follows the
    same process for Team 1. An example screenshot of the initialization is shown in Figure 1.
    Figure 1: An example screenshot of the initialization.
    After the initialization, the game starts with the program outputting “Game Begins” (as shown in
    Figure 2). Afterwards, the program asks the user to input the order of the first team, outputting
    “Team1: please input order”. Then the user enters the fighter order of the first team by the fighters’
    numbers (NOs) and ends by pressing enter. We assume the input format and type are valid. The
    program only checks the semantic validity of the input that violates four simple constraints. The
    checking includes:
    • The number of NOs is inconsistent with the number of undefeated fighters.
    • There are duplicated fighters in the order.
    • Fighter NO is not in the team.
    • Fighter NO is defeated.
    If the input order is invalid, the program outputs “Invalid input order”. An example screenshot of
    the inputting orders is shown in Figure 2.
    After the user inputs fighters’ orders, the tournament engine could pair two fighters of the same
    order on each team to start a duel. The excess fighters have a rest in this round. The detailed
    dueling rules are given in Section 2.1.1. After each duel, we call the print info() function to output
    the summaries of the duel and the properties of fighters. An example screenshot of the output in
    this round is shown in Figure 3.
    3
    Figure 2: An example screenshot of inputting orders.
    Figure 3: An example screenshot of the output for a round.
    At the end of each round, we should check if there is a winner of the Tournament Duel game. If
    all the fighters in one team are defeated, this team loses, and we announce the other team as the
    winner. If not, we will continue the next round of duels until we find the winning team. If Team
    NO is the winning team, the program should output “Team NO wins”. An example screenshot of
    the winner output is shown in Figure 4.
    Figure 4: An example screenshot of the output at the end of a game.
    2.3 Perl Classes
    Please follow the classes Tournament, Team, Fighter defined below in your Perl implementation.
    You cannot add new variables, methods or classes.
    4
  3. Class Tournament
    This class represents the game engine.
    • Instance Variables
    team1
  4. This is a Team object for Team 1.
    team2
  5. This is a Team object for Team 2.
    round cnt
  6. An integer to record the current round of the game. The initial value is 1.
    • Instance Methods
    new()
  7. Initialize a Tournament object.
    play game()
  8. Start a new game and administer the whole process of the game. In each round, the
    user is asked for the fighters’ order for both teams and then the duels are simulated
    accordingly. Finally, the winner of the game will be announced.
    set teams(Team1, Team2)
  9. Initialize the two Team object variables.
    play one round()
  10. Simulate the duels in one round.
    check winner()
  11. Check the fighter states in each team and return the winning team NO if there is a
    winner. Otherwise, return 0.
    input fighters(team NO)
  12. Input attributes for the 4 players in Team team NO.
  13. Class Team
    The class represents a team in the game. You have to implement it with the following
    components:
    • Instance Variables
    NO
  14. The NO of the team. We name the two teams in the game with “Team 1” and
    “Team 2” respectively.
    fighter list
  15. An array recording all the fighters in the team. The order of each element is
    determined in the initialization.
    order
  16. An array recording the fighters’ order in each round. The order of each element is
    determined by user input.
    fight cnt
  17. An integer recording current fight number in one round, which is used to find the
    next fighter. The initial value is 0.
    • Instance Methods
    new(team NO)
  18. Initialize a Team object with the input team NO.
    set fighter list(fighter list)
  19. Initialize all the fighters for the team.
    5
    get fighter list()
  20. Return the fighter list in the team.
    set order(order)
  21. Ask user for the fighters’ order in each round for the team and also reset the
    fight cnt.
    get next fighter()
  22. Return the Fighter object of the next fight.
  23. Class Fighter
    The class represents a fighter in the game. You have to implement it with the following
    components:
    • Instance Variables
    NO
  24. The number of the fighter. We number the fighters in the game from “Fighter 1”
    to “Fighter 8” respectively.
    HP
  25. The current health point of the fighter. If the HP of the fighter is not positive, the
    fighter is defeated. Note that HP is an integer.
    attack
  26. The current attack value of the fighter. Note that attack is an integer.
    defense
  27. The current defense value of the fighter. Note that defense is an integer.
    speed
  28. The current speed value of the fighter. Note that speed is an integer.
    defeated
  29. The state of the fighter is defeated or not.
    • Instance Methods
    new(NO, HP, attack, defense, speed)
  30. Initialize a Fighter object.
    get properties()
  31. Return a hash including all the properties of the fighter, which has the format [NO,
    HP, attack, defense, speed, defeated].
    reduce HP(damage)
  32. Reduce the HP of the fighter by the damage point.
    check defeated()
  33. Check the state of the fighter is defeated or not.
    print info()
  34. Output the state of the fighter. The code is provided. Do not change.
    The complete Python code is provided, and the OO design is the same as Perl. Note that property
    decorator is used for the setter and getter methods in the Python code.
    2.4 Grading Criteria
    Your program should run by calling perl main.pl and will be tested this way. Do not change the
    file folder’s directory structure. Otherwise, marks for the part will be lost. We will give one test
    case as an example. To obtain full marks in this part, the outputs of the program should be exactly
    the same as those given Python code. Moreover, proper error handling and good programming
    style are important. Poor programming style will receive mark deduction.
    6
  35. Task 2: Advanced Tournament Duel
    A tribe elder thought that the basic Tournament Duel game was too easy and suggested to make
    it more complicated and harder. In this task, you are required to implement the advanced Tour￾nament Duel game, which is an extension of the basic version. Dynamic scoping will be useful. A
    Python template and a Perl template are provided. You should strictly follow the specified OO
    design and game rules for this task. You have to follow the prototypes of the given classes exactly,
    and cannot add new member variables and methods.
    3.1 Task Description
    The advanced Tournament Duel game is an extension of the basic version with more fighter prop￾erties and several new dueling rules. The additional property of a fighter is coins and the new
    dueling rules can change fighters’ properties. Each fighter possesses some coins, which can utilized
    to upgrade the properties permanently. The upgradable properties are attack, defense and speed.
  36. coins can be used to upgrade one of the upgradable properties once, which increases the prop￾erty by one point permanently. Initially, each fighter has 0 coins, and has to earn their coins after
    each round. There are two new variables relating to coins in Fighter objects:
    • coins: The number of coins possessed by the fighter. Each fighter obtains some coins after
    each round and they can spend coins to upgrade their properties (attack, defense, and
    speed).
    • history record: An array recording the history of the recent three duels of the fighter. This
    is used to implement the new dueling rules.
    There is one new package variable relating to coins:
    • coins to obtain: the number of coins each fighter will obtain after one round. It is a package
    variable storing the default number of coins to be earned by a fighter after each round.
    Besides, since fighters will get tired after each duel, their attack, defense, and speed will de￾crease by a certain value until the values become 1. We use three package variables delta attack,
    delta defense and delta speed to maintain the changes of their properties correspondingly for
    each round. To be more specific, after each round, attack ←− max(attack + delta attack, 1),
    defense ←− max(defense + delta defense, 1), and speed ←− max(speed + delta speed, 1). These
    three variables are ⌉1 by default. However, under some situations, their values may vary tem￾porarily and the related rules will be described in the following.
    The team leaders also need to determine the strategy for fighters involved to upgrade properties
    before a duel starts in each round. If a fighter has 50 coins or more, the interface will ask the user
    to input the upgrade strategies repeatedly until the user has less than 50 coins or wants no more
    upgrades. The possible upgrade strategies are [A: attack, D: defense, S: speed, N: no], where A,
    D, or S represents upgrading the corresponding property, while N means no upgrade in this round.
    After the team leader chooses an upgrade strategy for a fighter, the fighter gets one point up on
    attack, defense or speed permanently and has 50 coins deducted. If the number of possessed coins
    is still no less than 50, the interface will continue to ask the user to upgrade until the leader inputs
    “N” or the number of possessed coins is less than 50. Then, the duel can begin. Each fighter
    obtains 20 coins by default after a duel in one round. Some fighters may obtain extra coins by
    satisfying advanced rules. The advanced rules which may also change delta attack, delta defense,
    delta speed and coins to obtain for one round temporarily are listed as follows:
    7
    • Fighters at rest earn only half of the coins in that round. In addition, their delta attack,
    delta defense and delta speed will be +1 for that round temporarily since they have built up
    their strength during the rest.
    • A consecutive winner is a fighter winning three consecutive duels including the one in the
    latest round, and will take a more aggressive strategy for the next round. A consecutive
    winner is willing to sacrifice some defense in exchange for speed and attack, so that a consec￾utive winner’s delta attack and delta speed will be +1, and delta defense will be ⌉2 for that
    round temporarily. Besides, a consecutive winner will obtain more coins in rewards and the
    coins to obtain will be increased by 10% in this round. Note that the history record for the
    consecutive winner will be cleared after this round for the balance of the game in prevention
    of dominating players.
    To be more specific, assume that a fighter wins the (i ⟩ 2)th, the (i ⟩ 1)th, and the i
    th round.
    The fighter’s coins to obtain will increase by 10% at the end of the i
    th round temporarily.
    Meanwhile, the fighter’s delta attack and delta speed will be +1, and delta defense will be
    طي2 at the (i + 1)th round temporarily. • A consecutive loser is a fighter losing three consecutive duels including the one in the
    latest round. A consecutive loser will take a more conservative strategy for the next round
    and will put nearly all the focus on defense and speed for survival. Therefore, a consec￾utive loser’s delta defense and delta speed will be +2, and delta attack will be ⌉2 in that
    round temporarily. Besides, a consecutive loser will obtain more coins in rewards and the
    coins to obtain will be increased by 10% in this round temporarily for compensation. Note
    that the history record for the consecutive loser will be cleared after this round too.
    • A fighter defeating another fighter will have morality boosted and thus the fighter’s
    delta attack will be increased by 1 for the next round temporarily. Beside, the coins to
    obtain becomes doubled for the current round temporarily.
    3.2 Workflow
    In this section, we specify the workflow of the advanced Tournament Duel game. The workflow
    is essentially the same as the basic version, except that the user will obtain coins and have their
    properties updated.
    The tournament starts with asking two teams to input their fighters’ orders. After that, the
    tournament checks whether each fighter has enough coins to upgrade their properties permanently
    before each duel. If a fighter has enough coins, the program outputs “Do you want to upgrade
    properties for Fighter NO? A for attack. D for defense. S for speed. N for no” to ask the user to
    input the upgrade strategy for the fighter, and upgrades the fighter’s properties accordingly. We
    assume inputs are valid, so that you do not need to check the inputs.
    The tournament also checks whether the fighter satisfies the four advanced rules in Section 3.1.
    If the fighter satisfies some advanced rules, the tournament changes delta attack, delta defense,
    delta speed and coins to obtain for one round temporarily. If a fighter is a consecutive winner
    and defeats another fighter in the current round, the advanced rules should change delta attack,
    delta defense, delta speed and coins to obtain for one round temporarily as: delta attack = +2,
    delta defense = ℑ2, delta speed = +1, coins to obtain = int(2 ∗ int(1.1 ∗ coins to obtain)). An
    example screenshot of permanent upgrading and temporary updating is shown in Figure 5.
    Example 2 Take Fighter 5 in Figure 5 as an example. In round 3, the properties of Fighter 5 is:
    attack = 18, defense = 18, speed = 3. Since Fighter 5 is a consecutive winner, i.e. Fighter 5 wins
    the first round, second round and the third round, the properties of Fighter 5 should be changed
    into: attack = 19, defense = 16, speed = 4. Besides, Fighter 5 defeats Fighter 1 in round 3, the
    properties of Fighter 5 should be changed into: attack = 20, defense = 16, speed = 4. Lastly, in
    8
    Figure 5: An example of screenshot of permanent upgrading and temporary updating.
    the beginning of round 4, Fighter 5 uses 50 coins to upgrade defense by one point. Therefore, the
    properties of Fighter 5 should be changed into: attack = 20, defense = 17, speed = 4.
    After a duel is finished, fighters obtain their coins in this round. We should check the fighter again
    whether the fighter satisfies the advanced rules in Section 3.1. If the fighter satisfies some advanced
    rules, the coins to obtain for the fighter has a temporary change. Otherwise, the fighter obtains
  37. coins by default. Remember to give coins to fighters at rest in the round too.
    After each duel, you should output the duel results and call print info() to generate a summary
    string containing fighters’ states after the duel, which is the same as the basic version. At the end
    of each round, we should check if there is a winner of the Tournament Duel game. If all fighters
    in one team are defeated, this team loses, and we announce the other team as winner. If not, we
    will continue the next round of duels until we find the winning team. If we find the winning team,
    the program should output “Team NO wins”, where NO is the number of the winning team. This
    part is the same as the basic version.
    3.3 Perl Classes
    Please follow the classes Tournament, Team, Fighter defined below in your Perl implementation.
    You cannot add other variables, methods or classes. We would start the program by running: perl
    9
    main.pl.
  38. Class AdvancedTournament
    The class represents an advanced tournament in the advanced version. This class inherits
    the variables and methods in the class Tournament. You have to implement it with the
    following components:
    • Instance Variables
    defeat record
  39. An array recording the defeated fighter NOs in the last round.
    • Instance Methods
    new()
  40. Initialize a AdvancedTournament object.
    input fighters(team NO)
  41. Input attributes for the 4 advanced fighters in team NO.
    play one round()
  42. Execute all the duels in one round.
    update fighter properties and award coins(fighter, flag defeat, flag rest)
  43. Update fighter’s properties and award coins to fighters. Check whether the fighter
    satisfies the four advanced rules and temporarily change delta attack, delta defense,
    delta speed and coins to obtain. Please follow the advanced rules in Section 3.1.
    The amount of awarded coins follow the rules we mention in Section 3.1 too.
  44. Class AdvancedFighter
    The class represents an advanced fighter in the advanced version. This class inherits the
    variables and methods in the class Fighter. You have to implement it with the following
    components:
    • Instance Variables
    coins
  45. The coins possessed by the fighter.
    history record
  46. An array storing the latest three duel results. The initial value is an empty array.
    • Instance Methods
    new(NO, HP, attack, defense, speed)
  47. Initialize an AdvancedFighter object.
    record fight(fight result)
  48. Record the latest fight result into the history record.
    obtain coins()
  49. Fighter obtains coins according to rules.
    buy prop upgrade()
  50. Check whether the possessed coins are enough to upgrade the properties of the
    fighter recursively. If the coins are enough, asks the user to input the strategy re￾peatedly until the fighter has less than 50 coins or refuse to upgrade. The strategies
    are [A: attack, D: defense, S: speed, N: no]. Upgrade the properties of the fighter
    based on the upgrade strategy for the fighter and change the possessed coins of the
    fighter, and repeat until the user wants no more upgrade or there are less than 50
    coins.
    update properties()
  51. Update the fighter’s attack, defense and speed properties using delta attack, delta defense,
    and delta speed.
    10
    3.4 Grading Criteria
    Your program should run by calling perl main.pl and we will test your basic or advanced version
    by changing the main file. The variable coins to obtain is a default value for all the fighters and
    we will change the value of this variable to test your code under different settings. Do not change
    the locations of the file. Before submission. Otherwise, marks for the part will be lost. We will
    give one test case as an example. To obtain full marks in this part, the outputs of the program
    should be exactly the same as the given. Moreover, proper error handling and good programming
    style are important. Poor programming style will receive mark deduction.
    3.5 Implementation in Python
    In this task, you are asked to implement the Advanced Tournament Dual using Python with exactly
    the same class design. The skeleton code is provided. Do not change! Also, the input/output
    specifications and grading criteria are the same as those in the previous task. We will run python3
    main.py during evaluation. Note that Python does not support dynamic scoping.
  52. Report
    You should give a simple report to answer the following questions within two A4 pages:
  53. Provide example code and necessary elaborations for demonstrating the advantages of Dynamic Scoping in using Perl to implement the Advanced Tournament Dual game as compared
    to the corresponding codes in Python.
  54. Discuss the keyword local in Perl (e.g. its origin, its role in Perl, and real practical applications
    of it) and give your own opinions.

你可能感兴趣的:(后端)