PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/moul/x/daily/asciiart/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / x / daily / asciiart
Files
3 (README)(gnomod.toml)
Exported functions
6
Module
gno.land/r/moul/x/daily/asciiart/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • asciiart.gnogno
asciiart.gnogno
1// Package asciiart is a small on-chain ASCII art generator. Instead of a2// hand-authored font table, each pattern is produced by a short, pure,3// deterministic algorithm -- e.g. the Sierpinski triangle falls out of a4// single bitwise AND over row/column indices. Callers pick a pattern and a5// size; the realm renders it and keeps a gallery of everyone's generations.6package asciiart78import (9	"strconv"10	"strings"1112	"chain"13	"chain/runtime"1415	"gno.land/p/nt/avl/v0"16)1718// maxSize bounds every pattern's size parameter so a single Generate call19// can't blow the block gas limit on a pathologically large grid.20const maxSize = 322122// galleryPageSize caps how many pieces Render shows on the home page.23const galleryPageSize = 82425type piece struct {26	ID        string27	Pattern   string28	Size      int29	Author    address30	CreatedAt int6431	Art       string32}3334var (35	gallery avl.Tree // zero-padded ID -> *piece36	nextID  int37)3839// RenderDiamond draws a filled diamond of half-width n (2n-1 rows total),40// each row's stars centered and padded with spaces.41func RenderDiamond(n int) string {42	if n < 1 {43		panic("diamond size must be >= 1")44	}45	var b strings.Builder46	for i := 0; i < 2*n-1; i++ {47		d := i48		if i >= n {49			d = 2*n - 2 - i50		}51		b.WriteString(strings.Repeat(" ", n-1-d))52		b.WriteString(strings.Repeat("*", 2*d+1))53		if i < 2*n-2 {54			b.WriteString("\n")55		}56	}57	return b.String()58}5960// RenderPyramid draws a solid triangle n rows tall, widening by two stars61// per row and centered with leading spaces.62func RenderPyramid(n int) string {63	if n < 1 {64		panic("pyramid size must be >= 1")65	}66	var b strings.Builder67	for i := 0; i < n; i++ {68		b.WriteString(strings.Repeat(" ", n-1-i))69		b.WriteString(strings.Repeat("*", 2*i+1))70		if i < n-1 {71			b.WriteString("\n")72		}73	}74	return b.String()75}7677// RenderSierpinski draws a Sierpinski triangle in an n x n grid (n must be a78// power of two): cell (row, col) is filled exactly when row&col == 0, the79// classic bitwise identity for Pascal's-triangle-mod-2.80func RenderSierpinski(n int) string {81	if n < 1 || n&(n-1) != 0 {82		panic("sierpinski size must be a power of two (1, 2, 4, 8, 16, 32)")83	}84	var b strings.Builder85	for row := 0; row < n; row++ {86		for col := 0; col < n; col++ {87			if row&col == 0 {88				b.WriteString("#")89			} else {90				b.WriteString(" ")91			}92		}93		if row < n-1 {94			b.WriteString("\n")95		}96	}97	return b.String()98}99100// RenderChecker draws an n x n checkerboard of # and . cells.101func RenderChecker(n int) string {102	if n < 1 {103		panic("checker size must be >= 1")104	}105	var b strings.Builder106	for row := 0; row < n; row++ {107		for col := 0; col < n; col++ {108			if (row+col)%2 == 0 {109				b.WriteString("#")110			} else {111				b.WriteString(".")112			}113		}114		if row < n-1 {115			b.WriteString("\n")116		}117	}118	return b.String()119}120121func renderPattern(pattern string, size int) string {122	switch pattern {123	case "diamond":124		return RenderDiamond(size)125	case "pyramid":126		return RenderPyramid(size)127	case "sierpinski":128		return RenderSierpinski(size)129	case "checker":130		return RenderChecker(size)131	default:132		panic(`unknown pattern: use "diamond", "pyramid", "sierpinski", or "checker"`)133	}134}135136// padID zero-pads an ID so avl.Tree's key-ordered iteration matches numeric137// order.138func padID(n int) string {139	s := strconv.Itoa(n)140	for len(s) < 6 {141		s = "0" + s142	}143	return s144}145146// Generate renders a pattern, adds it to the on-chain gallery, and returns147// the rendered art.148func Generate(cur realm, pattern string, size int) string {149	if size < 1 || size > maxSize {150		panic("size must be between 1 and " + strconv.Itoa(maxSize))151	}152	art := renderPattern(pattern, size)153154	nextID++155	id := strconv.Itoa(nextID)156	author := cur.Previous().Address()157	p := &piece{158		ID:        id,159		Pattern:   pattern,160		Size:      size,161		Author:    author,162		CreatedAt: runtime.ChainHeight(),163		Art:       art,164	}165	gallery.Set(padID(nextID), p)166167	chain.Emit("ArtGenerated", "id", id, "pattern", pattern, "author", author.String())168169	return art170}171172// escapeInline neutralizes markdown-active characters in untrusted text173// before it's embedded inline in Render output.174func escapeInline(s string) string {175	r := strings.NewReplacer(176		"\\", "\\\\",177		"`", "\\`",178		"*", "\\*",179		"_", "\\_",180		"[", "\\[",181		"]", "\\]",182		"|", "\\|",183	)184	return r.Replace(s)185}186187func renderHome() string {188	var b strings.Builder189	b.WriteString("# ASCII Art Generator\n\n")190	b.WriteString("Four deterministic patterns, no font table required -- each shape " +191		"falls out of a short formula over row/column indices. Pick a pattern and a " +192		"size (1-" + strconv.Itoa(maxSize) + ", sierpinski wants a power of two) and " +193		"`Generate` adds it to the gallery below.\n\n")194	b.WriteString("## Patterns\n\n")195	b.WriteString("- `diamond` -- filled diamond, half-width `size`\n")196	b.WriteString("- `pyramid` -- solid triangle, `size` rows tall\n")197	b.WriteString("- `sierpinski` -- Sierpinski gasket in an n×n grid " +198		"(`row & col == 0`), `size` a power of two\n")199	b.WriteString("- `checker` -- n×n checkerboard\n\n")200	b.WriteString("Call `Generate(pattern, size)`. View a piece at this realm's path " +201		"plus its ID (e.g. `.../asciiart:3`).\n\n")202203	b.WriteString("## Gallery (total: " + strconv.Itoa(nextID) + ")\n\n")204	if nextID == 0 {205		b.WriteString("_nothing generated yet -- be the first_\n")206		return b.String()207	}208209	shown := 0210	gallery.ReverseIterate("", "", func(key string, value interface{}) bool {211		if shown >= galleryPageSize {212			return true213		}214		p := value.(*piece)215		b.WriteString("### #" + p.ID + " -- " + p.Pattern + " (size " + strconv.Itoa(p.Size) + ")\n\n")216		b.WriteString("by `" + p.Author.String() + "` at block " + strconv.Itoa(int(p.CreatedAt)) + "\n\n")217		b.WriteString("```\n" + p.Art + "\n```\n\n")218		shown++219		return false220	})221	return b.String()222}223224func renderPiece(idStr string) string {225	safe := escapeInline(idStr)226	n, err := strconv.Atoi(idStr)227	if err != nil || n < 1 {228		return "# Piece " + safe + "\n\nNo such piece.\n"229	}230	v := gallery.Get(padID(n))231	if v == nil {232		return "# Piece #" + safe + "\n\nNo such piece.\n"233	}234	p := v.(*piece)235236	var b strings.Builder237	b.WriteString("# Piece #" + p.ID + "\n\n")238	b.WriteString("- Pattern: " + p.Pattern + "\n")239	b.WriteString("- Size: " + strconv.Itoa(p.Size) + "\n")240	b.WriteString("- Author: `" + p.Author.String() + "`\n")241	b.WriteString("- Block: " + strconv.Itoa(int(p.CreatedAt)) + "\n\n")242	b.WriteString("```\n" + p.Art + "\n```\n")243	return b.String()244}245246// Render shows the pattern guide + gallery at "", or one piece by numeric ID.247func Render(path string) string {248	path = strings.TrimPrefix(strings.TrimSpace(path), "/")249	if path == "" {250		return renderHome()251	}252	return renderPiece(path)253}254

Functions

  • Generate(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pattern string, size int) string

  • Render(path string) string

  • RenderChecker(n int) string

  • RenderDiamond(n int) string

  • RenderPyramid(n int) string

  • RenderSierpinski(n int) string

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.