github.com/joshprzybyszewski/masyu@v0.0.0-20230508015604-f31a025f6e7e/solve/rule_black_invert.go (about)

     1  package solve
     2  
     3  import "github.com/joshprzybyszewski/masyu/model"
     4  
     5  func newInvertHorizontalBlack(
     6  	nodeRow, nodeCol model.Dimension,
     7  ) rule {
     8  	if nodeRow < 2 || nodeCol < 2 {
     9  		panic(`dev error`)
    10  	}
    11  
    12  	r := rule{
    13  		affects: 3,
    14  		row:     nodeRow,
    15  		col:     nodeCol,
    16  	}
    17  	r.check = r.checkInvertHorizontalBlack
    18  	return r
    19  }
    20  
    21  func (r *rule) checkInvertHorizontalBlack(
    22  	s *state,
    23  ) {
    24  
    25  	// In this case, we are checking the paths at the %:
    26  	// * % * ? B ? * % *
    27  
    28  	ll, la := s.horAt(r.row, r.col-2)
    29  	rl, ra := s.horAt(r.row, r.col+1)
    30  	if la && ra {
    31  		// if they are both avoided, then we are invalid.
    32  		r.setInvalid(s)
    33  		return
    34  	}
    35  	if !ll || !rl {
    36  		// we aren't about to infer anything
    37  		return
    38  	}
    39  
    40  	// In this case, both paths exist:
    41  	// * - * ? B ? * - *
    42  
    43  	if s.verAvoidAt(r.row-2, r.col) {
    44  		// the turn can't go up. Send it down instead.
    45  		s.avoidVer(r.row-1, r.col)
    46  		s.lineVer(r.row, r.col)
    47  		s.lineVer(r.row+1, r.col)
    48  	} else if s.verAvoidAt(r.row+1, r.col) {
    49  		// the turn can't go down. Send it up instead.
    50  		s.avoidVer(r.row, r.col)
    51  		s.lineVer(r.row-1, r.col)
    52  		s.lineVer(r.row-2, r.col)
    53  	}
    54  }
    55  
    56  func newInvertVerticalBlack(
    57  	nodeRow, nodeCol model.Dimension,
    58  ) rule {
    59  	if nodeRow < 2 || nodeCol < 2 {
    60  		panic(`dev error`)
    61  	}
    62  
    63  	r := rule{
    64  		affects: 3,
    65  		row:     nodeRow,
    66  		col:     nodeCol,
    67  	}
    68  	r.check = r.checkInvertVerticalBlack
    69  	return r
    70  }
    71  
    72  func (r *rule) checkInvertVerticalBlack(
    73  	s *state,
    74  ) {
    75  	// In this case, we are checking the paths at the %:
    76  	// *
    77  	// %
    78  	// *
    79  	// ?
    80  	// W
    81  	// ?
    82  	// *
    83  	// %
    84  	// *
    85  
    86  	ul, ua := s.verAt(r.row-2, r.col)
    87  	dl, da := s.verAt(r.row+1, r.col)
    88  	if ua && da {
    89  		// if they are both avoided, then we are invalid.
    90  		r.setInvalid(s)
    91  		return
    92  	}
    93  	if !ul || !dl {
    94  		// we aren't about to infer anything
    95  		return
    96  	}
    97  
    98  	// In this case, both paths exist:
    99  
   100  	if s.horAvoidAt(r.row, r.col-2) {
   101  		// the turn can't go left. Send it right instead.
   102  		s.avoidHor(r.row, r.col-1)
   103  		s.lineHor(r.row, r.col)
   104  		s.lineHor(r.row, r.col+1)
   105  	} else if s.horAvoidAt(r.row, r.col+1) {
   106  		// the turn can't go right. Send it left instead.
   107  		s.avoidHor(r.row, r.col)
   108  		s.lineHor(r.row, r.col-1)
   109  		s.lineHor(r.row, r.col-2)
   110  	}
   111  }