Thanks to visit codestin.com
Credit goes to github.com

Skip to content

VM summary

krsalmi edited this page Jan 24, 2021 · 1 revision

VM - Summary of the virtual machine chapter of Corewar Cookbook

	(avocadohooman - 42 Corewar Wiki)

-The program is called corewar and takes three champions (.cor files) as arguments
-arguments can even be the same champion 3 times, the VM will distinguish them as Player 1, Player 2 and Player 3 -max number of players is stated by MAX_PLAYERS which is set to 4
-however, the example corewar executable provided works already with just one champion! But the subject says: “Obviously, the virtual machine should allow for numerous simultaneous processes; we are asking you for a gladiator fight, not a one-man show simulator.” So we must decide if 2 players is enough

-n flag: The assignment of player numbers can be controlled with the -n flag, so that the player number wanted follows immediately and, after, the champion whose player number we want to affect. The number has to be 1 or greater, but it cannot exceed the number of arguments
-other players will be numbered in arg order and will be assigned the smallest number available

  • for ex: $ ./corewar batman.cor -n 1 antman.cor ironman.cor -> Player1 = antman, P2 = batman, P3 = ironman
    -players cannot have the same number
    -for some reason, the example VM provided uses -n as a flag for the visualizer

VALIDATION

-the max size for the executable code is defined for the VM, and it is 682 bytes. Maybe that should be checked already in the translator?? No min amount is specified, which means that it can be absent
-must check the presence of the magic header, and that it is the right byte size
-after receiving the data, the VM should know the following things: unique identification number, champion name, champion comment, size of executable code in bytes, executable code

ARENA INITIALIZATION

-Size of the arena is specified by MEM_SIZE which is 4096 bytes
-the total amount of memory area must be divided by the number of players fighting
-for ex, if we have 3 players ---> 4096 / 3 = 1365. Player 1 will have area cell 0 to cell 1364, Player 2 will have 1365 - 2729, and Player 3 from 2730 to 4094

ORGANIZATION OF MEMORY

-the memory area can be thought as a big circle: the first memory area follows the last and vice versa
-so if the total amount of memory is 4096, the first cell will be cell 0 and last will be cell 4095. In the case where a cell number is greater, the result of (number) % 4096 will be taken as the real number
QUESTION: if mem area is divided by 3, last cell is 4094. What about the remaining cells?

GAME PARAMETERS

Set the values of the following variables:
-player who was last told he was alive. It is initialized with a pointer to the player with the highest identification number and is updated in the live statement
-number of cycles that have passed since the beginning of the game
-number of completed live statements for the last period, with length cycles_to_die
-cycles-_to_die - length of the period before validation, which is initialized with the constant CYCLES_TO_DIE = 1536
-number of checks performed

CARRIAGE INITIALIZATION

-After the champions’ executable code is placed in the arena, a carriage is placed at the beginning of each of them

-carriage has inside:

-a unique carriage number
-carry flag, which some statements can modify, it is initialized to false
-a statement code on which the carriage stands, before the battle this is not set
-the cycle in which the live was last performed
-the number of cycles remaining until the above mentioned statement on which the carriage stands
-current carriage position
-the number of bytes that needs to be “crossed” to get to the next statement
-registries, number of which is specified by REG_NUMBER    --when a carriage is initialized, the registries will be set to 0 except r1, which contains the identification number of the player, but preceded with a ‘-’ sign

Carriage list

-carriages form a list and will be executed in order
-new items are pasted to the beginning, so before the start of the battle, the top will be the carriage of the last player (the one with the highest id number)

REPRESENTATION OF PLAYERS

Players must be announced before the battle:
''' Introducing contestants ...

  • Player 1, weighing 22 bytes, "Batman" ("This city needs me")!
  • Player 2, weighing 12 bytes, "Ant-Man" ("So small")!
  • Player 3, weighing 28 bytes, "Iron Man" ("Jarvis, check all systems!")! '''

BATTLE

BATTLE RULES:
-going through each carriage in order once is called a cycle. Depending on the state of the carriage, certain actions are performed - a new statement code is set, the number of cycles before execution is reduced, or the statement itself, on which the carriage stands, is performed.
-the battle continues as long as at least one living carriage remains
-a carriage can die during an event such as check

CHECKS

-MAX_CHECKS is set to 10
-a check occurs every cycles_to_die cycle, while the value o cycles_to_die is greater than zero. (remember that above it was initialized to 1536)
-after its value becomes less than or equal to zero, the check begins to be carried out after each cycle
-during the check, carriages that are dead are removed from the list
-a carriage is dead if a carriage hasn’t performed live in a long time (not in one whole cycles_to_die cycle or more) or if cycles_to_die is <= 0.

-during the check, the cycles_to_die is modified

-If the number of live statements performed during cycles_to_die period is greater than or equal to NBR_LIVE, the value of cycles_to_die is reduced by CYCLE_DELTA

-The value of the NBR_LIVE constant in the provided file is 21, and the value of CYCLE_DELTA is 50

-if the number of live is less than the limit set, the VM simply remembers that the check was performed

INSIDE A CYCLE

In each cycle, the virtual machine scans the list of carriages and performs the necessary actions on each of them:

SETS THE STATEMENT CODE

-if during the last cycle the carriage moved, the statement code of which the carriage is now on must be established -to determine the statement code, the byte on which the carriage is must be read
-If the received number corresponds to the code of the real statement, then it must be remembered.
-the value of the variable which stores the number of cycles before statement is completed must be set
-during the first execution cycle, all carriages will receive the statement code value because it is not installed during initialization
-if the read number doesn’t fall into the range (the received data indicates a statement which does not exist), it is necessary to remember the read code, and leave the value of the variable storing the number of cycles before execution equal to zero.

REDUCES THE NUMBER OF CYCLES BEFORE EXECUTION

-If the number of cycles before execution is greater than zero, it must be reduced by 1

PERFORMS A STATEMENT

-If the number of cycles before execution is zero, it is time to perform the statement whose code the carriage stores.

-If the stored code corresponds to an existing statement, check the validity of the code containing the types of arguments

-If this code is correct and indicates that there is a registry among the statement arguments, you must also verify that the registry number is correct.
-If all the necessary checks have been successfully completed, you need to perform the statement and move the carriage to the next position.
-If the statement code is wrong, you just need to move the carriage to the next byte.
-If everything is normal with the code itself, but the argument type code or the registry number is incorrect, you must skip this statement together with the argument type code and the arguments themselves.
-skipping statement code: skipping to the next argument means moving to the next byte. However, if for ex, the argument type code was incorrect, you need to skip the statement code, the type code of the arguments, as well as the arguments specified in the type code

-dump -FLAG and -d -FLAG
-both cause the program to quit and dumps the memory to STDOUT
-dump nbr_cycles → at the end of nbr_cycles of executions, dump the memory on the standard output and quit the game. The memory must be dumped in the hexadecimal format with 32 octets per line.
-The -d flag is the same, but it prints 64 octets in a row.

-Both flags receive a cycle number, after which it is necessary to display the memory status on the screen and stop the program corewar.