Skip to content

Commit 798cdff

Browse files
committed
Add doc for guess
1 parent 5dcb802 commit 798cdff

File tree

1 file changed

+100
-14
lines changed

1 file changed

+100
-14
lines changed

fortran/solver/src/guess.f90

Lines changed: 100 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,49 @@ module guess_mod
22
use library_mod, only: library_t
33
implicit none
44
private
5+
6+
!> @brief helper type for guesses; contains simplified view of library_t
57
type :: simplified_library_t
6-
logical :: inited = .false.
7-
integer :: n_rooms
8-
integer, allocatable :: guess(:,:)
9-
logical, allocatable :: mask(:,:)
10-
logical, allocatable :: final_mask(:,:)
11-
integer(1), allocatable :: room_type(:)
8+
logical :: inited = .false. !< was initialised
9+
integer :: n_rooms !< number of rooms in labyrinth
10+
integer, allocatable :: guess(:,:) !< guessed labyrinth in form (room_out, door_out) -> (room_in)
11+
logical, allocatable :: mask(:,:) !< paired to guessed labyrinth; contains info about 100% sure guesses
12+
logical, allocatable :: final_mask(:,:) !< like mask, but contains info after checking plans
13+
integer(1), allocatable :: room_type(:) !< types of rooms (in range from 0 to 3)
1214
contains
1315
procedure :: init => sl_init
1416
procedure :: execute_plan
1517
procedure :: get_mask
1618
end type simplified_library_t
19+
20+
!> @brief contains guess of labyrinth
1721
type :: guess_t
18-
logical :: inited = .false.
19-
integer :: max_length
20-
type(library_t), pointer :: library
21-
integer, allocatable :: guess(:)
22-
logical, allocatable :: mask(:)
22+
logical :: inited = .false. !< was initialised
23+
integer :: max_length !< length of proper guess
24+
type(library_t), pointer :: library !< pointer to global labyrinth info
25+
integer, allocatable :: guess(:) !< guess of rooms' enters in 1D shape
26+
logical, allocatable :: mask(:) !< paired to guess of rooms'; contains info about 100% sure guesses
2327
contains
2428
procedure :: init => guess_init
2529
procedure :: eval
2630
procedure :: next
2731
procedure :: set_solution
2832
end type guess_t
33+
2934
public :: guess_t
3035
contains
36+
37+
!>
38+
!> @brief initialise simplified_library_t
39+
!>
40+
!> @param[in,out] library - simplified_library_t object
41+
!> @param[in] n_rooms - number of rooms in labyrinth
42+
!> @param[in] guess - guess about labyrinth in 1D form
43+
!> @param[in] mask - info about correct guess about labyrinth in 1D form
44+
!>
45+
!> @author foxtran
46+
!> @date Sep 8, 2025
47+
!>
3148
subroutine sl_init(library, n_rooms, guess, mask)
3249
class(simplified_library_t), intent(inout) :: library
3350
integer, intent(in) :: n_rooms
@@ -54,6 +71,16 @@ subroutine sl_init(library, n_rooms, guess, mask)
5471
library%room_type(room_id) = mod(room_id - 1, 4)
5572
end do
5673
end subroutine sl_init
74+
75+
!>
76+
!> @brief executes plan to validate guess
77+
!>
78+
!> @param[in,out] library - simplified_library_t object
79+
!> @param[in] plan - plan for check
80+
!>
81+
!> @author foxtran
82+
!> @date Sep 8, 2025
83+
!>
5784
integer function execute_plan(library, plan) result(max_length)
5885
use plan_mod, only: plan_t
5986
class(simplified_library_t), intent(inout) :: library
@@ -79,6 +106,16 @@ integer function execute_plan(library, plan) result(max_length)
79106
end do
80107
library%final_mask = library%final_mask .and. mask
81108
end function execute_plan
109+
110+
!>
111+
!> @brief return info about which guesses are correct
112+
!>
113+
!> @param[in] library - simplified_library_t object
114+
!> @return - 1D mask of correct guesses
115+
!>
116+
!> @author foxtran
117+
!> @date Sep 8, 2025
118+
!>
82119
function get_mask(library) result(mask)
83120
class(simplified_library_t), intent(in) :: library
84121
logical, allocatable :: mask(:)
@@ -92,8 +129,17 @@ function get_mask(library) result(mask)
92129
end do
93130
end do
94131
end function get_mask
132+
133+
!>
134+
!> @brief initialise guess_t
135+
!>
136+
!> @param[in,out] guess - guess_t object
137+
!> @param[in] library - info about labyrinth
138+
!>
139+
!> @author foxtran
140+
!> @date Sep 8, 2025
141+
!>
95142
subroutine guess_init(guess, library)
96-
use random_mod, only: shuffle
97143
class(guess_t), intent(inout) :: guess
98144
type(library_t), target, intent(in) :: library
99145
integer :: n_rooms, room_id, door_id, cnt, room_in
@@ -120,8 +166,16 @@ subroutine guess_init(guess, library)
120166
end do
121167

122168
call guess%next()
123-
124169
end subroutine guess_init
170+
171+
!>
172+
!> @brief check how guess is good
173+
!>
174+
!> @param[in,out] guess - guess_t object
175+
!>
176+
!> @author foxtran
177+
!> @date Sep 8, 2025
178+
!>
125179
subroutine eval(guess)
126180
class(guess_t), intent(inout) :: guess
127181
type(simplified_library_t) :: library
@@ -136,6 +190,19 @@ subroutine eval(guess)
136190
guess%mask = library%get_mask()
137191
guess%max_length = max_length
138192
end subroutine eval
193+
194+
!>
195+
!> @brief generate new guess based on info after eval
196+
!>
197+
!> @details tries to generate random labyrinth that as least has proper connections.
198+
!> However, it does not respect rules about which connections are available in reality.
199+
!> So, it sucks a lot.
200+
!>
201+
!> @param[in,out] guess - guess_t object
202+
!>
203+
!> @author foxtran
204+
!> @date Sep 8, 2025
205+
!>
139206
subroutine next(guess)
140207
use random_mod, only: shuffle, rand_int
141208
class(guess_t), intent(inout) :: guess
@@ -148,6 +215,7 @@ subroutine next(guess)
148215
n_rooms = size(guess%library%rooms)
149216
allocate(rooms(n_rooms), source = 6)
150217

218+
! count, which connections are already know
151219
do cnt = 1, size(guess%guess)
152220
if (.not.guess%mask(cnt)) then
153221
guess%guess(cnt) = 0
@@ -157,6 +225,13 @@ subroutine next(guess)
157225
end if
158226
end do
159227

228+
! main loop to generate labyrinth
229+
! it implements the following algorithm:
230+
! 1 ) door by door, select random target room
231+
! 2 ) on targeted room, find already known connection
232+
! 3a) if connection exists: change sign of this connections
233+
! 3b) otherwise: assign first free door to originated room
234+
! 4) shuffle exit rooms in each room to prevent non-random in 3b
160235
do cnt = 1, size(guess%guess)
161236
if (guess%guess(cnt) /= 0) cycle
162237
curr_room = (cnt - 1) / 6 + 1
@@ -191,15 +266,26 @@ subroutine next(guess)
191266

192267
guess%guess = abs(guess%guess)
193268

269+
! shuffle after bad generation, otherwise the generation is not random, actually
194270
do room_id = 1, n_rooms
195271
i1 = (room_id - 1) * 6 + 1
196272
i2 = i1 + 5
197273
call shuffle(guess%guess(i1:i2), 6, guess%mask(i1:i2))
198274
end do
199275
end subroutine next
276+
277+
!>
278+
!> @brief apply guess to labyrinth
279+
!>
280+
!> @param[in] guess - guess_t object
281+
!> @param[in] library - solved labyrinth
282+
!>
283+
!> @author foxtran
284+
!> @date Sep 8, 2025
285+
!>
200286
subroutine set_solution(guess, library)
201287
class(guess_t), intent(in) :: guess
202-
type(library_t), target, intent(inout) :: library
288+
type(library_t), intent(inout) :: library
203289
integer :: room_id, door_id, n_rooms, cnt
204290
n_rooms = size(library%rooms)
205291
cnt = 1

0 commit comments

Comments
 (0)