Files
gogogogogram/state/cell.go
Madison Rye Progress bef9cd248e State tests 100%
2025-08-28 22:16:29 -07:00

112 lines
2.7 KiB
Go

package state
const (
statebit = 1 // the current state of the cell (for field)
flagbit = statebit << 1 // whether or not the cell has been flagged as empty (for field)
markbit = statebit << 2 // whether or not the cell has been flagged as full (for field)
correctbit = statebit << 3 // whether or not the cell is correct (for field, section)
completebit = statebit << 4 // whether or not the cell is complete (for section)
)
// Cells {{{
// cell represents a single entry in the field managing various states.
type cell byte
// state returns whether the cell is alive or dead.
func (c cell) state() bool {
return (c & statebit) != 0
}
// correct returns whether or not the cell has been guessed correctly, or the section is made up of entirely correct guesses.
func (c cell) correct() bool {
return (c & correctbit) != 0
}
// complete marks the section as complete (that is, all sections in its row/column are correct.
func (c cell) complete() bool {
return (c & completebit) != 0
}
// flagged returns whether or not the cell is suspected to be dead.
func (c cell) flagged() bool {
return (c & flagbit) != 0
}
// marked returns whether or not the cell is suspected to be alive.
func (c cell) marked() bool {
return (c & markbit) != 0
}
// vivify sets the state of the cell to alive.
func (c cell) vivify() cell {
c = c | statebit
if c.marked() {
return c.setCorrect(true)
} else {
return c.setCorrect(false)
}
}
// kill sets the state of the cell to dead.
func (c cell) kill() cell {
c = c &^ statebit
if c.marked() {
return c.setCorrect(false)
} else {
return c.setCorrect(true)
}
}
// setCorrect marks the cell as being guessed correctly, or the section being made up of entirely correct guesses.
func (c cell) setCorrect(to bool) cell {
if to {
return c | correctbit
} else {
return c &^ correctbit
}
}
// setComplete marks the section as complete (that is, all sections in its row/column are correct).
func (c cell) setComplete(to bool) cell {
if to {
return c | completebit
} else {
return c &^ completebit
}
}
// mark marks a bit as suspected alive.
func (c cell) mark() cell {
c |= markbit
c = c &^ flagbit
if c.state() {
return c.setCorrect(true)
} else {
return c.setCorrect(false)
}
}
// flag marks a bit as suspected dead.
func (c cell) flag() cell {
c |= flagbit
c = c &^ markbit
if c.state() {
return c.setCorrect(false)
} else {
return c.setCorrect(true)
}
}
// clear clears all bits except for the status.
func (c cell) clear(deadCorrect bool) cell {
// Unset all bits except status
c = c &^ (markbit | flagbit | correctbit | completebit)
// If a dead cell is to be marked correct so long as it is *not* marked, set the correct bit
if deadCorrect && !c.state() {
c |= correctbit
}
return c
}