Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}