Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

encode.gno

1.82 Kb · 62 lines
 1package gno4
 2
 3import "strings"
 4
 5// Encode returns the whole game as one string: the 1-based column of each
 6// move, in order. An empty game is the empty string, a full game is 42 bytes.
 7//
 8// The position is not stored, because it is not information: replaying the
 9// moves reproduces it exactly, including the winner and the winning line. That
10// is what lets a match be a URL, a chain event and a test fixture without three
11// encoders that can disagree.
12func (b *Board) Encode() string {
13	var sb strings.Builder
14	for _, col := range b.moves {
15		sb.WriteByte(byte('1' + col))
16	}
17	return sb.String()
18}
19
20// Decode replays an encoding produced by [Board.Encode].
21//
22// It replays through [Board.Drop] rather than writing cells directly, so an
23// encoding that describes an impossible game (a column overflowing, a move
24// after the win) is rejected here instead of becoming a board no rule allows.
25// Nothing else in this package can construct an illegal position.
26func Decode(s string) (*Board, error) {
27	b := New()
28	for i := 0; i < len(s); i++ {
29		c := s[i]
30		if c < '1' || c > '7' {
31			return nil, ErrBadEncoding
32		}
33		if _, err := b.Drop(int(c - '1')); err != nil {
34			return nil, ErrBadEncoding
35		}
36	}
37	return b, nil
38}
39
40// String renders the board as seven columns of ASCII, top row first, the way a
41// player looks at it. Empty is '.', Red is 'R', Yellow is 'Y'.
42//
43// This is the debugging view and the one tests assert against. What gnoweb
44// shows is [Board.Image]; what a terminal or a diff shows is this.
45func (b *Board) String() string {
46	var sb strings.Builder
47	for row := Rows - 1; row >= 0; row-- {
48		for col := 0; col < Cols; col++ {
49			switch b.At(col, row) {
50			case Red:
51				sb.WriteByte('R')
52			case Yellow:
53				sb.WriteByte('Y')
54			default:
55				sb.WriteByte('.')
56			}
57		}
58		sb.WriteByte('\n')
59	}
60	sb.WriteString("1234567\n")
61	return sb.String()
62}