5 sokoban_screen
*add_coord(int x
, int y
, sokoban_tile tile
, sokoban_screen
*screen
)
7 sokoban_screen
*r
= NULL
;
9 r
= (sokoban_screen
*)malloc(sizeof(sokoban_screen
));
10 memset(r
, 0, sizeof(sokoban_screen
));
14 HASH_ADD(hh
, screen
, coord
, sizeof(record_key
), r
);
18 sokoban_screen
*get_coord(int x
, int y
, sokoban_screen
*screen
)
20 sokoban_screen k
, *r
= NULL
;
21 memset(&k
, 0, sizeof(sokoban_screen
));
24 HASH_FIND(hh
, screen
, &k
.coord
, sizeof(record_key
), r
);
28 sokoban_screen
*delete_coord(int x
, int y
, sokoban_screen
*screen
)
30 sokoban_screen
*r
= NULL
;
31 r
= get_coord(x
, y
, screen
);
32 if (r
) HASH_DEL(screen
, r
);
36 void sokoban_print(sokoban_screen
*screen
)
39 for(r
=screen
; r
!= NULL
; r
= (sokoban_screen
*)(r
->hh
.next
)){
41 case FREE
: printf("x = %d y = %d FREE\n", r
->coord
.x
, r
->coord
.y
); break;
42 case WALL
: printf("x = %d y = %d WALL\n", r
->coord
.x
, r
->coord
.y
); break;
43 case BOX
: printf("x = %d y = %d BOX\n", r
->coord
.x
, r
->coord
.y
); break;
44 case TARGET
: printf("x = %d y = %d TARGET\n", r
->coord
.x
, r
->coord
.y
); break;
45 case AGENT
: printf("x = %d y = %d AGENT\n", r
->coord
.x
, r
->coord
.y
); break;
46 case TARGAGENT
: printf("x = %d y = %d TARGAGENT\n", r
->coord
.x
, r
->coord
.y
); break;
47 case TARGBOX
: printf("x = %d y = %d TARGBOX\n", r
->coord
.x
, r
->coord
.y
); break;
52 sokoban_screen
*sokoban_shrink(int x
, int y
, sokoban_screen
*screen
, sokoban_screen
*newscreen
)
54 sokoban_screen
*c
, *nc
= NULL
;
55 c
= get_coord(x
, y
, screen
);
57 nc
= get_coord(c
->coord
.x
, c
->coord
.y
, newscreen
);
58 if (c
->tile
!= WALL
&& nc
== NULL
) {
59 newscreen
= add_coord(x
, y
, c
->tile
, newscreen
);
60 newscreen
= sokoban_shrink(x
-1, y
, screen
, newscreen
);
61 newscreen
= sokoban_shrink(x
+1, y
, screen
, newscreen
);
62 newscreen
= sokoban_shrink(x
, y
-1, screen
, newscreen
);
63 newscreen
= sokoban_shrink(x
, y
+1, screen
, newscreen
);
69 void sokoban_free(sokoban_screen
*screen
)
71 sokoban_screen
*r
, *tmp
= NULL
;
72 HASH_ITER(hh
, screen
, r
, tmp
) {
78 sokoban_screen
*parse_screen(FILE *stream
, bool safe
)
80 int buffer
, x
, y
, agent_x
, agent_y
, boxes
, targets
, agents
;
88 sokoban_screen
*screen
= NULL
;
89 while((buffer
= fgetc(stream
)) != EOF
){
96 case ' ': screen
= add_coord(x
, y
, FREE
, screen
); break;
98 screen
= add_coord(x
, y
, AGENT
, screen
);
104 screen
= add_coord(x
, y
, TARGET
, screen
);
107 case '#': screen
= add_coord(x
, y
, WALL
, screen
); break;
109 screen
= add_coord(x
, y
, BOX
, screen
);
113 screen
= add_coord(x
, y
, TARGBOX
, screen
);
118 screen
= add_coord(x
, y
, TARGAGENT
, screen
);
124 default: return NULL
;
129 if(safe
== true && boxes
== 0){
131 "Invalid screen. You need at least 1 box\n");
134 if(safe
== true && boxes
!= targets
){
136 "Invalid screen. Boxes: %d, Targets: %d\n", boxes
, targets
);
139 if(safe
== true && agents
!= 1){
141 "Invalid screen. There has to be exactly one agent. Found: %d\n",
146 sokoban_screen
*newscreen
= NULL
;
147 newscreen
= sokoban_shrink(agent_x
, agent_y
, screen
, newscreen
);
148 sokoban_free(screen
);