History loading

This commit is contained in:
Madison Rye Progress
2025-09-14 20:50:00 -07:00
parent 6198c794d5
commit 6b5674308e
4 changed files with 81 additions and 44 deletions

View File

@ -1,57 +1,113 @@
package state package state
func (s *State) CursorCellUp() { func (s *State) CursorCellUp() {
if s.cursor.Y >= 1 { if s.cursorCellUp() {
s.cursor.Y--
s.history += "u" s.history += "u"
} }
} }
func (s *State) CursorCellDown() { func (s *State) CursorCellDown() {
if s.cursor.Y < s.size()-1 { if s.cursorCellDown() {
s.cursor.Y++
s.history += "d" s.history += "d"
} }
} }
func (s *State) CursorCellRight() { func (s *State) CursorCellRight() {
if s.cursor.X < s.size()-1 { if s.cursorCellRight() {
s.cursor.X++
s.history += "r" s.history += "r"
} }
} }
func (s *State) CursorCellLeft() { func (s *State) CursorCellLeft() {
if s.cursor.X >= 1 { if s.cursorCellLeft() {
s.cursor.X--
s.history += "l" s.history += "l"
} }
} }
func (s *State) CursorSectionUp() { func (s *State) CursorSectionUp() {
if s.cursor.Y >= s.cellsPerSection { if s.cursorSectionUp() {
s.cursor.Y -= s.cellsPerSection
s.history += "U" s.history += "U"
} }
} }
func (s *State) CursorSectionDown() { func (s *State) CursorSectionDown() {
if s.cursor.Y < s.size()-s.cellsPerSection { if s.cursorSectionDown() {
s.cursor.Y += s.cellsPerSection
s.history += "D" s.history += "D"
} }
} }
func (s *State) CursorSectionRight() { func (s *State) CursorSectionRight() {
if s.cursor.X < s.size()-s.cellsPerSection { if s.cursorSectionRight() {
s.cursor.X += s.cellsPerSection
s.history += "R" s.history += "R"
} }
} }
func (s *State) CursorSectionLeft() { func (s *State) CursorSectionLeft() {
if s.cursor.X >= s.cellsPerSection { if s.cursorSectionLeft() {
s.cursor.X -= s.cellsPerSection
s.history += "L" s.history += "L"
} }
} }
func (s *State) cursorCellUp() bool {
if s.cursor.Y >= 1 {
s.cursor.Y--
return true
}
return false
}
func (s *State) cursorCellDown() bool {
if s.cursor.Y < s.size()-1 {
s.cursor.Y++
return true
}
return false
}
func (s *State) cursorCellRight() bool {
if s.cursor.X < s.size()-1 {
s.cursor.X++
return true
}
return false
}
func (s *State) cursorCellLeft() bool {
if s.cursor.X >= 1 {
s.cursor.X--
return true
}
return false
}
func (s *State) cursorSectionUp() bool {
if s.cursor.Y >= s.cellsPerSection {
s.cursor.Y -= s.cellsPerSection
return true
}
return false
}
func (s *State) cursorSectionDown() bool {
if s.cursor.Y < s.size()-s.cellsPerSection {
s.cursor.Y += s.cellsPerSection
return true
}
return false
}
func (s *State) cursorSectionRight() bool {
if s.cursor.X < s.size()-s.cellsPerSection {
s.cursor.X += s.cellsPerSection
return true
}
return false
}
func (s *State) cursorSectionLeft() bool {
if s.cursor.X >= s.cellsPerSection {
s.cursor.X -= s.cellsPerSection
return true
}
return false
}

View File

@ -10,10 +10,14 @@ type field struct {
// newField returns a field of cells, all unset. // newField returns a field of cells, all unset.
func newField(size int) *field { func newField(size int) *field {
return &field{ f := &field{
cells: make([]cell, size*size), cells: make([]cell, size*size),
size: size, size: size,
} }
for i := 0; i < size*size; i++ {
f.cells[i].clear(false)
}
return f
} }
// fieldFromBytes returns a field of cells given a bytearray; it assumes that the bytearray is a square. // fieldFromBytes returns a field of cells given a bytearray; it assumes that the bytearray is a square.

View File

@ -11,7 +11,7 @@ type Point struct {
} }
func (p Point) String() string { func (p Point) String() string {
return fmt.Sprintf("%d,%d", p.X, p.Y) return fmt.Sprintf("(%d,%d)", p.X, p.Y)
} }
type State struct { type State struct {
@ -20,7 +20,8 @@ type State struct {
clears, score, factor int clears, score, factor int
blackout []bool blackout []bool
history string history string
historyIndex int
sectionSize, cellsPerSection int sectionSize, cellsPerSection int
cells, sections *field cells, sections *field
@ -34,7 +35,7 @@ func New(sectionSize, cellsPerSection int) *State {
sections: newField(sectionSize), sections: newField(sectionSize),
cursor: &Point{0, 0}, cursor: &Point{0, 0},
} }
s.history = fmt.Sprintf("g%d,%d", sectionSize, cellsPerSection) s.history = fmt.Sprintf("g(%d,%d)", sectionSize, cellsPerSection)
for x := 0; x < sectionSize; x++ { for x := 0; x < sectionSize; x++ {
for y := 0; y < sectionSize; y++ { for y := 0; y < sectionSize; y++ {
s.initSection(Point{x, y}) s.initSection(Point{x, y})
@ -49,11 +50,6 @@ func (s *State) size() int {
return s.sectionSize * s.cellsPerSection return s.sectionSize * s.cellsPerSection
} }
// History returns the gameplay history for replays
func (s *State) History() string {
return s.history
}
func (s *State) String() string { func (s *State) String() string {
var buf bytes.Buffer var buf bytes.Buffer
for x := 0; x < s.sectionSize*s.cellsPerSection; x++ { for x := 0; x < s.sectionSize*s.cellsPerSection; x++ {

View File

@ -1,7 +1,6 @@
package state package state
import ( import (
"regexp"
"testing" "testing"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
@ -49,24 +48,6 @@ func TestState(t *testing.T) {
}) })
}) })
Convey("You can maintain a history of all actions", func() {
s.Flag()
s.Mark()
s.Clear()
s.CursorSectionRight()
s.CursorSectionLeft()
s.CursorSectionDown()
s.CursorSectionUp()
s.CursorCellRight()
s.CursorCellLeft()
s.CursorCellDown()
s.CursorCellUp()
matches, err := regexp.Match(`g2,2(i\d,\d[xo]{4}){4}fmcRLDUrldu`, []byte(s.History()))
So(matches, ShouldBeTrue)
So(err, ShouldBeNil)
})
Convey("You can complete sections and clear portions of the board", func() { Convey("You can complete sections and clear portions of the board", func() {
s.cells.vivify(Point{0, 0}) s.cells.vivify(Point{0, 0})
s.cells.vivify(Point{2, 0}) s.cells.vivify(Point{2, 0})