Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 27be1608 authored by BAROLLET Theo's avatar BAROLLET Theo
Browse files

first draft of interactive mode

parent 31d3f340
No related branches found
No related tags found
No related merge requests found
Subproject commit f544eee0875facb0a16518ed83d67e84c264cfb4 Subproject commit 61e8623bbe3e9518568b1b00a1ee5651ba56e79b
...@@ -40,7 +40,7 @@ void activate_switch(game_instance* game, int y, int x) { ...@@ -40,7 +40,7 @@ void activate_switch(game_instance* game, int y, int x) {
void touch(game_instance* game) { void touch(game_instance* game) {
map* m = current_map(game->map_stack); map* m = current_map(game->map_stack);
if(m->player_direction == DIR_UNKOWN) { if(m->player_direction == DIR_UNKNOWN) {
printf("Player is not oriented, cannot touch\n"); printf("Player is not oriented, cannot touch\n");
return; return;
} }
......
...@@ -24,7 +24,7 @@ void activate_switch(game_instance* game, int y, int x) { ...@@ -24,7 +24,7 @@ void activate_switch(game_instance* game, int y, int x) {
void touch(game_instance* game) { void touch(game_instance* game) {
map* m = current_map(game->map_stack); map* m = current_map(game->map_stack);
if(m->player_direction == DIR_UNKOWN) { if(m->player_direction == DIR_UNKNOWN) {
printf("Player is not oriented, cannot touch\n"); printf("Player is not oriented, cannot touch\n");
return; return;
} }
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
* level_name: crepes * level_name: crepes
* exec_name: crepes * exec_name: crepes
* engine_name: map_stack * engine_name: map_stack
* available_commands: edit next step interactive
* *
* player_mode: map_stack * player_mode: map_stack
* exit_x: 11 * exit_x: 11
* exit_y: 6 * exit_y: 7
* *
* map_height: 11 * map_height: 11
* map_width: 28 * map_width: 28
...@@ -34,7 +35,7 @@ ...@@ -34,7 +35,7 @@
#define COOK_Y INGREDIENT_Y #define COOK_Y INGREDIENT_Y
#define EXIT_X MAIN_DOOR_X; #define EXIT_X MAIN_DOOR_X;
#define EXIT_Y 6 #define EXIT_Y 7
char str_map[] = char str_map[] =
"\ "\
...@@ -43,11 +44,11 @@ char str_map[] = ...@@ -43,11 +44,11 @@ char str_map[] =
| | \n\ | | \n\
+-----+ D | \n\ +-----+ D | \n\
+--D--+ | | \n\ +--D--+ | | \n\
@ +-+ \n\
X | | \n\
D | \n\
| | \n\
+-+ \n\ +-+ \n\
| | \n\
> D | \n\
| | \n\
X +-+ \n\
\n\ \n\
"; ";
...@@ -261,7 +262,7 @@ int main() { ...@@ -261,7 +262,7 @@ int main() {
direction dir = direction_from_string(command); direction dir = direction_from_string(command);
// if the direction is meaningfull try to move // if the direction is meaningfull try to move
if (dir != DIR_UNKOWN) { if (dir != DIR_UNKNOWN) {
// Lookup for the predicted destination // Lookup for the predicted destination
main_map->player_direction = dir; main_map->player_direction = dir;
player_lookup(main_map, &dest_y, &dest_x); player_lookup(main_map, &dest_y, &dest_x);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
1,1,1,1,1,1,1,1,1,415,1,1,1,1,1,1,1,367,1,1,1,1,1,367,1,1,1,1, 1,1,1,1,1,1,1,1,1,415,1,1,1,1,1,1,1,367,1,1,1,1,1,367,1,1,1,1,
1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1125,1,1,1,1,1,1125,1,1,1,1, 1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1125,1,1,1,1,1,1125,1,1,1,1,
1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1125,1,1,1,1,1,1125,1,1,1,1, 1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1125,1,1,1,1,1,1125,1,1,1,1,
1,1,1,1114,1115,1115,1115,1115,1115,1131,1115,1115,1115,1115,1139,1115,1115,1131,1115,1115,1115,1115,1115,1130,1,1,1,1, 1,1,1,1,1114,1115,1115,1115,1115,1131,1115,1115,1115,1115,1139,1115,1115,1131,1115,1115,1115,1115,1115,1130,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1125,1,1,1,1,1,1,1,1,1,1,1,1,1
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,71,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data> </data>
</layer> </layer>
<layer id="4" name="decorations_top" width="28" height="11"> <layer id="4" name="decorations_top" width="28" height="11">
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
* map_height: 5 * map_height: 5
* map_width: 26 * map_width: 26
* *
* exit_x: 14
* exit_y: 2
*
* A vertical wall bars the passage to the exit. There is one locked door on * A vertical wall bars the passage to the exit. There is one locked door on
* the wall. A keys are generated at a random position on the same line. * the wall. A keys are generated at a random position on the same line.
* Just walking over the key should be sufficient to pick it up and open the * Just walking over the key should be sufficient to pick it up and open the
...@@ -25,7 +22,7 @@ ...@@ -25,7 +22,7 @@
* *
* player_mode: global_variables * player_mode: global_variables
* exit_x: 14 * exit_x: 14
* exit_y: 3 * exit_y: 2
* *
* OBJdoor: char_rep D * OBJdoor: char_rep D
* *
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="68" height="9" tilewidth="32" tileheight="32" infinite="0" backgroundcolor="#000000" nextlayerid="7" nextobjectid="39"> <map version="1.8" tiledversion="1.8.5" orientation="orthogonal" renderorder="right-down" width="68" height="9" tilewidth="32" tileheight="32" infinite="0" backgroundcolor="#000000" nextlayerid="7" nextobjectid="39">
<tileset firstgid="1" source="../../lib/level/arcade_utils/resources/tiles/[Base]BaseChip_pipo.json"/> <tileset firstgid="1" source="../../lib/level/arcade_utils/resources/tiles/[Base]BaseChip_pipo.json"/>
<tileset firstgid="1065" source="../../lib/level/arcade_utils/resources/tiles/[A]Grass_pipo.json"/> <tileset firstgid="1065" source="../../lib/level/arcade_utils/resources/tiles/[A]Grass_pipo.json"/>
<tileset firstgid="1593" source="../../lib/level/arcade_utils/resources/tiles/[A]Water_pipo.json"/> <tileset firstgid="1593" source="../../lib/level/arcade_utils/resources/tiles/[A]Water_pipo.json"/>
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
<point/> <point/>
</object> </object>
<object id="38" name="door" gid="496" x="1984" y="97.5" width="32" height="32"/> <object id="38" name="door" gid="496" x="1984" y="97.5" width="32" height="32"/>
<object id="37" name="key" gid="1056" x="1792.5" y="70.5" width="32" height="32"> <object id="37" name="key" gid="1056" x="1792.5" y="104.03" width="32" height="32">
<properties> <properties>
<property name="moving" value="teleport"/> <property name="moving" value="teleport"/>
</properties> </properties>
......
...@@ -112,6 +112,27 @@ class GameView(EmptyView): ...@@ -112,6 +112,27 @@ class GameView(EmptyView):
next_button.on_click = lambda _: self.level.send_console_command("step") next_button.on_click = lambda _: self.level.send_console_command("step")
self.cmd_buttons["step"] = next_button.with_space_around(top=20) self.cmd_buttons["step"] = next_button.with_space_around(top=20)
# interactive mode
interractive_mode_button = MenuButton(text="Interactive", width=200)
interractive_mode_button.on_click = (
lambda _: self.level.start_interactive_mode()
)
self.cmd_buttons["interactive"] = interractive_mode_button.with_space_around(
top=20
)
def stop_interactive_func(_):
if not self.level.interactive_mode:
self.box_message("Interactive mode was not started")
self.level.stop_interactive_mode()
self.level.start_inferior_internal()
stop_interractive_button = MenuButton(text="Stop Interactive", width=200)
stop_interractive_button.on_click = stop_interactive_func
self.cmd_buttons[
"stop_interactive"
] = stop_interractive_button.with_space_around(top=20)
# Record buttons # Record buttons
start_record_button = MenuButton(text="Start record", width=200) start_record_button = MenuButton(text="Start record", width=200)
start_record_button.on_click = lambda _: self.level.start_record() start_record_button.on_click = lambda _: self.level.start_record()
...@@ -155,6 +176,9 @@ class GameView(EmptyView): ...@@ -155,6 +176,9 @@ class GameView(EmptyView):
elif cmd == "edit": elif cmd == "edit":
for edt in ["edit", "make"]: for edt in ["edit", "make"]:
self.gui_first_col.add(self.cmd_buttons[edt]) self.gui_first_col.add(self.cmd_buttons[edt])
elif cmd == "interactive":
self.gui_third_col.add(self.cmd_buttons["interactive"])
# self.gui_third_col.add(self.cmd_buttons["stop_interactive"])
else: else:
self.gui_sec_col.add(self.cmd_buttons[cmd]) self.gui_sec_col.add(self.cmd_buttons[cmd])
...@@ -514,7 +538,11 @@ class GameView(EmptyView): ...@@ -514,7 +538,11 @@ class GameView(EmptyView):
# Read a command and run it # Read a command and run it
# if the inferior is running, put in on stdin # if the inferior is running, put in on stdin
# otherwise perform a next # otherwise perform a next
if self.level.tracker.is_running(): if self.level.interactive_mode:
if not self.level.tracker.is_running():
print(
"Warning the inferior is not waiting for an input there should be a bug"
)
self.level.tracker.send_to_inferior_stdin(dir_command + "\n") self.level.tracker.send_to_inferior_stdin(dir_command + "\n")
else: else:
self.level.send_console_command("next") self.level.send_console_command("next")
......
...@@ -63,10 +63,12 @@ class AbstractLevel(ABC): ...@@ -63,10 +63,12 @@ class AbstractLevel(ABC):
self.record = [] self.record = []
# Tracker # Tracker
self.tracker = init_tracker("GDB") self.tracker = init_tracker("GDB")
self.inferior_started = False
self.tracker.send_direct_command(f"cd {self.source_level_dir}") self.tracker.send_direct_command(f"cd {self.source_level_dir}")
self.internal_bp = set() self.interactive_bp = None
self.interactive_mode = False
self.print_thread = threading.Thread( self.print_thread = threading.Thread(
target=console_print_thread, args=(self.tracker.stdout_queue,) target=console_print_thread, args=(self.tracker.stdout_queue,)
...@@ -112,6 +114,8 @@ class AbstractLevel(ABC): ...@@ -112,6 +114,8 @@ class AbstractLevel(ABC):
def update_state(self) -> None: def update_state(self) -> None:
"""Run events for updated variables""" """Run events for updated variables"""
if not self.inferior_started:
return
globs = self.tracker.get_global_variables(as_raw_python_objects=True) globs = self.tracker.get_global_variables(as_raw_python_objects=True)
frames = self.tracker.get_current_frame(as_raw_python_objects=True) frames = self.tracker.get_current_frame(as_raw_python_objects=True)
...@@ -238,6 +242,7 @@ class AbstractLevel(ABC): ...@@ -238,6 +242,7 @@ class AbstractLevel(ABC):
:param cmd: The command to run. :param cmd: The command to run.
""" """
print("CMDMDMD", cmdline)
def not_implemented(cmd: str) -> None: def not_implemented(cmd: str) -> None:
"""Verbose error if not implemented.""" """Verbose error if not implemented."""
...@@ -278,6 +283,9 @@ class AbstractLevel(ABC): ...@@ -278,6 +283,9 @@ class AbstractLevel(ABC):
self.info(f"{cmd} is not a valid command.") self.info(f"{cmd} is not a valid command.")
return return
if cmd in ["start", "run"]:
self.inferior_started = True
if cmd in ["n", "next"]: if cmd in ["n", "next"]:
if arg_str is not None and arg_int is None: if arg_str is not None and arg_int is None:
usage(cmd, "[count_integer]") usage(cmd, "[count_integer]")
...@@ -290,11 +298,11 @@ class AbstractLevel(ABC): ...@@ -290,11 +298,11 @@ class AbstractLevel(ABC):
return return
self._gdb_step(arg_int) self._gdb_step(arg_int)
elif cmd in ["r", "run"]: # elif cmd in ["r", "run"]:
if arg_str is not None or arg_int is not None: # if arg_str is not None or arg_int is not None:
not_implemented(cmd) # not_implemented(cmd)
return # return
self._gdb_continue() # self._gdb_continue()
elif cmd in ["c", "continue"]: elif cmd in ["c", "continue"]:
if arg_str is not None or arg_int is not None: if arg_str is not None or arg_int is not None:
...@@ -323,6 +331,12 @@ class AbstractLevel(ABC): ...@@ -323,6 +331,12 @@ class AbstractLevel(ABC):
"record.in", "record.in",
) )
def start_interactive_mode(self):
self.in_queue.put_nowait("interactive_mode")
def stop_interactive_mode(self):
self.in_queue.put_nowait("stop_interactive_mode")
def start_record(self): def start_record(self):
self.recording = True self.recording = True
self.send_console_command("start") self.send_console_command("start")
......
...@@ -74,32 +74,50 @@ class LevelArcade(AbstractLevel, Thread): ...@@ -74,32 +74,50 @@ class LevelArcade(AbstractLevel, Thread):
log.info("Exit event set, quitting") log.info("Exit event set, quitting")
self.stop_level() self.stop_level()
return return
# Fetch variables # Fetch variables
self.update_state() self.update_state()
# Update the code visualizator
self.show_next_line()
# Show the map # Show the map
self.print_wop_msg() self.print_wop_msg()
# Update the code visualizator
self.show_next_line()
# Read a command and run it # Read a command and run it
print(PROMPT, end="") print(PROMPT, end="")
sys.stdout.flush() sys.stdout.flush()
cmd = self.in_queue.get() cmd = self.in_queue.get()
# if the command is None we terminate the level # if the command is None we terminate the level
if cmd is None: if cmd is None:
self.tracker.terminate() self.tracker.terminate()
return return
payload = {"topic": "cmd", "cmd": cmd} # we start interactive mode if requested
self.out_queue.put_nowait(payload) if cmd == "interactive_mode":
self.parse_and_eval(cmd) self.interactive_mode = True
self.interactive_bp = self.tracker.break_before_func("getline")
self.send_console_command("run")
elif cmd == "stop_interactive_mode":
print("ECQ")
if self.interactive_mode:
print("COCOU")
self.interactive_mode = False
self.tracker.delete_breakpoint(self.interactive_bp)
else:
# otherwise we send regular commands
payload = {"topic": "cmd", "cmd": cmd}
self.out_queue.put_nowait(payload)
self.parse_and_eval(cmd)
# different modes
if self.interactive_mode:
self.send_console_command("continue")
pause_type = self.tracker.pause_reason.type pause_type = self.tracker.pause_reason.type
print("END")
code = self.tracker.exit_code code = self.tracker.exit_code
self.inferior_started = False
self.unlock_next_level(code) self.unlock_next_level(code)
payload = {"topic": "inferior_exit", "code": code} payload = {"topic": "inferior_exit", "code": code}
self.out_queue.put_nowait(payload) self.out_queue.put_nowait(payload)
......
...@@ -17,6 +17,12 @@ _DIRECTION_DICT = { ...@@ -17,6 +17,12 @@ _DIRECTION_DICT = {
1: cst.Direction.DOWN, 1: cst.Direction.DOWN,
2: cst.Direction.LEFT, 2: cst.Direction.LEFT,
3: cst.Direction.RIGHT, 3: cst.Direction.RIGHT,
4: cst.Direction.RIGHT, # UNKNOWN is replaced by RIGHT
"DIR_UNKNOWN": cst.Direction.RIGHT,
"DIR_RIGHT": cst.Direction.RIGHT,
"DIR_LEFT": cst.Direction.LEFT,
"DIR_UP": cst.Direction.UP,
"DIR_DOWN": cst.Direction.DOWN,
} }
...@@ -39,7 +45,7 @@ class Object: ...@@ -39,7 +45,7 @@ class Object:
# dynamic properties # dynamic properties
self.coord_x: Union[int, None] = init_x self.coord_x: Union[int, None] = init_x
self.coord_y: Union[int, None] = init_y self.coord_y: Union[int, None] = init_y
self.direction: Union[int, None] = None self.direction: Union[int, None] = cst.Direction.RIGHT
self.visible: bool = False self.visible: bool = False
self._topic = "object_update" self._topic = "object_update"
...@@ -184,11 +190,12 @@ class Player(Object): ...@@ -184,11 +190,12 @@ class Player(Object):
# fetch actual coordinate # fetch actual coordinate
self.coord_x = top_map.player_x self.coord_x = top_map.player_x
self.coord_y = top_map.player_y self.coord_y = top_map.player_y
print(self.coord_x, self.coord_y) self.direction = _DIRECTION_DICT[top_map.player_direction]
else:
self.set_empty() self.set_empty()
else: else:
raise NotImplementedError
self.coord_x = global_vars["player_x"].value self.coord_x = global_vars["player_x"].value
self.coord_y = global_vars["player_y"].value self.coord_y = global_vars["player_y"].value
self.direction = global_vars["player_direction"].value self.direction = global_vars["player_direction"].value
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment