-
Notifications
You must be signed in to change notification settings - Fork 375
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into enhance-grc20factory
- Loading branch information
Showing
9 changed files
with
344 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module gno.land/r/demo/games/shifumi | ||
|
||
require ( | ||
gno.land/p/demo/avl v0.0.0-latest | ||
gno.land/p/demo/seqid v0.0.0-latest | ||
gno.land/r/demo/users v0.0.0-latest | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package shifumi | ||
|
||
import ( | ||
"errors" | ||
"std" | ||
"strconv" | ||
|
||
"gno.land/p/demo/avl" | ||
"gno.land/p/demo/seqid" | ||
|
||
"gno.land/r/demo/users" | ||
) | ||
|
||
const ( | ||
empty = iota | ||
rock | ||
paper | ||
scissors | ||
last | ||
) | ||
|
||
type game struct { | ||
player1, player2 std.Address // shifumi is a 2 players game | ||
move1, move2 int // can be empty, rock, paper, or scissors | ||
} | ||
|
||
var games avl.Tree | ||
var id seqid.ID | ||
|
||
func (g *game) play(player std.Address, move int) error { | ||
if !(move > empty && move < last) { | ||
return errors.New("invalid move") | ||
} | ||
if player != g.player1 && player != g.player2 { | ||
return errors.New("invalid player") | ||
} | ||
if player == g.player1 && g.move1 == empty { | ||
g.move1 = move | ||
return nil | ||
} | ||
if player == g.player2 && g.move2 == empty { | ||
g.move2 = move | ||
return nil | ||
} | ||
return errors.New("already played") | ||
} | ||
|
||
func (g *game) winner() int { | ||
if g.move1 == empty || g.move2 == empty { | ||
return -1 | ||
} | ||
if g.move1 == g.move2 { | ||
return 0 | ||
} | ||
if g.move1 == rock && g.move2 == scissors || | ||
g.move1 == paper && g.move2 == rock || | ||
g.move1 == scissors && g.move2 == paper { | ||
return 1 | ||
} | ||
return 2 | ||
} | ||
|
||
// NewGame creates a new game where player1 is the caller and player2 the argument. | ||
// A new game index is returned. | ||
func NewGame(player std.Address) int { | ||
games.Set(id.Next().String(), &game{player1: std.PrevRealm().Addr(), player2: player}) | ||
return int(id) | ||
} | ||
|
||
// Play executes a move for the game at index idx, where move can be: | ||
// 1 (rock), 2 (paper), 3 (scissors). | ||
func Play(idx, move int) { | ||
v, ok := games.Get(seqid.ID(idx).String()) | ||
if !ok { | ||
panic("game not found") | ||
} | ||
if err := v.(*game).play(std.PrevRealm().Addr(), move); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
func Render(path string) string { | ||
mov1 := []string{"", " 🤜 ", " 🫱 ", " 👉 "} | ||
mov2 := []string{"", " 🤛 ", " 🫲 ", " 👈 "} | ||
win := []string{"pending", "draw", "player1", "player2"} | ||
|
||
output := `# 👊 ✋ ✌️ Shifumi | ||
Actions: | ||
* [NewGame](shifumi?help&__func=NewGame) opponentAddress | ||
* [Play](shifumi?help&__func=Play) gameIndex move (1=rock, 2=paper, 3=scissors) | ||
game | player1 | | player2 | | win | ||
--- | --- | --- | --- | --- | --- | ||
` | ||
// Output the 100 most recent games. | ||
maxGames := 100 | ||
for n := int(id); n > 0 && int(id)-n < maxGames; n-- { | ||
v, ok := games.Get(seqid.ID(n).String()) | ||
if !ok { | ||
continue | ||
} | ||
g := v.(*game) | ||
output += strconv.Itoa(n) + " | " + | ||
shortName(g.player1) + " | " + mov1[g.move1] + " | " + | ||
shortName(g.player2) + " | " + mov2[g.move2] + " | " + | ||
win[g.winner()+1] + "\n" | ||
} | ||
return output | ||
} | ||
|
||
func shortName(addr std.Address) string { | ||
user := users.GetUserByAddress(addr) | ||
if user != nil { | ||
return user.Name | ||
} | ||
if len(addr) < 10 { | ||
return string(addr) | ||
} | ||
return string(addr)[:10] + "..." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"std" | ||
) | ||
|
||
var ( | ||
main std.Address // leon's main address | ||
backup std.Address // backup address | ||
) | ||
|
||
func init() { | ||
main = "g125em6arxsnj49vx35f0n0z34putv5ty3376fg5" | ||
} | ||
|
||
func Address() std.Address { | ||
return main | ||
} | ||
|
||
func Backup() std.Address { | ||
return backup | ||
} | ||
|
||
func SetAddress(a std.Address) error { | ||
if !a.IsValid() { | ||
return errors.New("config: invalid address") | ||
} | ||
|
||
if err := checkAuthorized(); err != nil { | ||
return err | ||
} | ||
|
||
main = a | ||
return nil | ||
} | ||
|
||
func SetBackup(a std.Address) error { | ||
if !a.IsValid() { | ||
return errors.New("config: invalid address") | ||
} | ||
|
||
if err := checkAuthorized(); err != nil { | ||
return err | ||
} | ||
|
||
backup = a | ||
return nil | ||
} | ||
|
||
func checkAuthorized() error { | ||
caller := std.PrevRealm().Addr() | ||
if caller != main || caller != backup { | ||
return errors.New("config: unauthorized") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func AssertAuthorized() { | ||
caller := std.PrevRealm().Addr() | ||
if caller != main || caller != backup { | ||
panic("config: unauthorized") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module gno.land/r/leon/config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module gno.land/r/leon/home | ||
|
||
require ( | ||
gno.land/p/demo/ufmt v0.0.0-latest | ||
gno.land/r/demo/art/gnoface v0.0.0-latest | ||
gno.land/r/demo/art/millipede v0.0.0-latest | ||
gno.land/r/leon/config v0.0.0-latest | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package home | ||
|
||
import ( | ||
"std" | ||
"strconv" | ||
|
||
"gno.land/p/demo/ufmt" | ||
|
||
"gno.land/r/demo/art/gnoface" | ||
"gno.land/r/demo/art/millipede" | ||
"gno.land/r/leon/config" | ||
) | ||
|
||
var ( | ||
pfp string // link to profile picture | ||
pfpCaption string // profile picture caption | ||
abtMe [2]string | ||
) | ||
|
||
func init() { | ||
pfp = "https://i.imgflip.com/91vskx.jpg" | ||
pfpCaption = "[My favourite painting & pfp](https://en.wikipedia.org/wiki/Wanderer_above_the_Sea_of_Fog)" | ||
abtMe = [2]string{ | ||
`### About me | ||
Hi, I'm Leon, a DevRel Engineer at gno.land. I am a tech enthusiast, | ||
life-long learner, and sharer of knowledge.`, | ||
`### Contributions | ||
My contributions to gno.land can mainly be found | ||
[here](https://github.com/gnolang/gno/issues?q=sort:updated-desc+author:leohhhn). | ||
TODO import r/gh | ||
`, | ||
} | ||
} | ||
|
||
func UpdatePFP(url, caption string) { | ||
config.AssertAuthorized() | ||
pfp = url | ||
pfpCaption = caption | ||
} | ||
|
||
func UpdateAboutMe(col1, col2 string) { | ||
config.AssertAuthorized() | ||
abtMe[0] = col1 | ||
abtMe[1] = col2 | ||
} | ||
|
||
func Render(path string) string { | ||
out := "# Leon's Homepage\n\n" | ||
|
||
out += renderAboutMe() | ||
out += renderBlogPosts() | ||
out += "\n\n" | ||
out += renderArt() | ||
|
||
return out | ||
} | ||
|
||
func renderBlogPosts() string { | ||
out := "" | ||
//out += "## Leon's Blog Posts" | ||
|
||
// todo fetch blog posts authored by @leohhhn | ||
// and render them | ||
return out | ||
} | ||
|
||
func renderAboutMe() string { | ||
out := "<div class='columns-3'>" | ||
|
||
out += "<div>\n\n" | ||
out += ufmt.Sprintf("![my profile pic](%s)\n\n%s\n\n", pfp, pfpCaption) | ||
out += "</div>\n\n" | ||
|
||
out += "<div>\n\n" | ||
out += abtMe[0] + "\n\n" | ||
out += "</div>\n\n" | ||
|
||
out += "<div>\n\n" | ||
out += abtMe[1] + "\n\n" | ||
out += "</div>\n\n" | ||
|
||
out += "</div><!-- /columns-3 -->\n\n" | ||
|
||
return out | ||
} | ||
|
||
func renderArt() string { | ||
out := `<div class="jumbotron">` + "\n\n" | ||
out += "# Gno Art\n\n" | ||
|
||
out += "<div class='columns-3'>" | ||
|
||
out += renderGnoFace() | ||
out += renderMillipede() | ||
out += "Empty spot :/" | ||
|
||
out += "</div><!-- /columns-3 -->\n\n" | ||
|
||
out += "This art is dynamic; it will change with every new block.\n\n" | ||
out += `</div><!-- /jumbotron -->` + "\n" | ||
|
||
return out | ||
} | ||
|
||
func renderGnoFace() string { | ||
out := "<div>\n\n" | ||
out += gnoface.Render(strconv.Itoa(int(std.GetHeight()))) | ||
out += "</div>\n\n" | ||
|
||
return out | ||
} | ||
|
||
func renderMillipede() string { | ||
out := "<div>\n\n" | ||
out += "Millipede\n\n" | ||
out += "```\n" + millipede.Draw(int(std.GetHeight())%10+1) + "```\n" | ||
out += "</div>\n\n" | ||
|
||
return out | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters