A game that takes place in a virtual arena where programs written in a simplistic language fight one another. They attempt to stop each other by overwriting instructions that are about to be executed.
We explored the design of a VM (with the relevant instructions, records, etc.) and challenges related to compiling an assembly language into bytecode.
git clone --recurse-submodules https://github.com/rizkyario/corewar.git && cd corewar && make
usage: ./asm [-a] sourcefile.s
./asm [-a] [-m] sourcefile.s ...
-a : Prints a stripped and annoted version of the code
-m : Allows processing of multiple files
make assemble: compile every player within subdirectory tests/
usage: ./corewar [options] [-n number] champion1.cor ...
OPTIONS
-dump nbr_cycles : Dump the memory after nbr_cycles
-dumpc nbr_cycles : Colorized -dump
-v N : Verbosity levels, can be added together to enable several
- 2 : Show cycles
- 4 : Show operations
- 8 : Show deaths
- 16 : Show PC movements (Except for jumps)
-u : Decompile .cor back to .s
-g : Printf visualization
-G : Ncurses visualization
make tests: run an extensive set of tests of both the assembler and virtual machinemake tests_asm: test only the assemblermake tests_vm : test only the virtual machine
Parsing with our own regex library:
intasm_get_paramtype(intopcode, t_param*param)
{
if (ft_re_match("^r\\d+$", (*param).str) ==0)
{
(*param).value=asm_get_paramval((*param).str, "\\d+");
(*param).size=1;
return (T_REG);
}
elseif (ft_re_match("^%:[\\w_\\d]+$", (*param).str) ==0||ft_re_match("^%-?\\d+$", (*param).str) ==0)
{
(ft_re_match("^%:[\\w_\\d]+$", (*param).str) ==0) ?
(*param).is_label=1 : 0;
(*param).value=asm_get_paramval((*param).str, "-?\\d+");
(*param).size=g_op_dict[opcode].d_size;
return (T_DIR);
}
elseif (ft_re_match("^:[\\w_\\d]+$", (*param).str) ==0||ft_re_match("^-?\\d+$", (*param).str) ==0)
{
!ft_re_match(":[\\w_\\d]+$", (*param).str) ? (*param).is_label=1 : 0;
(*param).value=asm_get_paramval((*param).str, "-?\\d+");
(*param).size=2;
return (T_IND);
}
elsereturn (-1);
}Main function:
intmain(intac, char**av)
{
t_vmvm;
time_tstart;
statict_arrayprocesses=NEW_ARRAY(t_process);
ft_bzero(&vm, sizeof(t_vm));
vm.processes=processes;
if (ac<2||vm_options(av, &vm) ==-1)
return (vm_print_usage(av, -1));
if (vm_get_champions(av, &vm) ==-1)
return (vm_error(vm.champ_size<1 ? CHAMP_MIN : CHAMP_MAX, -1, NULL));
if (vm_read_binaries(vm.players, &vm) ==-1)
return (-1);
vm_load_champs(&vm);
while (vm_checker(&vm))
{
vm_executor(&vm);
if ((vm.dump&&vm.cycles==g_cycles) ||
(vm.option_g[VISU_2] &&vm_start_ncurses(&start, vm) ==-1))
break ;
}
(!vm.dump||g_cycles<vm.cycles) ?
ft_printfln("Contestant %d, \"%s\", has won !",
vm.winner+1, vm.champ[vm.winner].header.prog_name) : 0;
vm_free(&vm);
return (0);
}For a closer look at the project's development history, refer to the branches 'feature/assembler' and 'feature/virtual-machine'
Collaboration between
| Rizky Ario | Fabian Petras | Julianto Yeo | Martin Jozan |




